@liveblocks/react-tiptap 2.18.2 → 2.18.4-uns1

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 (100) hide show
  1. package/dist/{LiveblocksExtension.mjs → LiveblocksExtension.cjs} +41 -38
  2. package/dist/{LiveblocksExtension.mjs.map → LiveblocksExtension.cjs.map} +1 -1
  3. package/dist/LiveblocksExtension.js +37 -40
  4. package/dist/LiveblocksExtension.js.map +1 -1
  5. package/dist/ai/{AiExtension.mjs → AiExtension.cjs} +36 -32
  6. package/dist/ai/AiExtension.cjs.map +1 -0
  7. package/dist/ai/AiExtension.js +31 -35
  8. package/dist/ai/AiExtension.js.map +1 -1
  9. package/dist/ai/{AiToolbar.mjs → AiToolbar.cjs} +145 -142
  10. package/dist/ai/{AiToolbar.mjs.map → AiToolbar.cjs.map} +1 -1
  11. package/dist/ai/AiToolbar.js +141 -144
  12. package/dist/ai/AiToolbar.js.map +1 -1
  13. package/dist/{classnames.mjs → classnames.cjs} +4 -2
  14. package/dist/{classnames.mjs.map → classnames.cjs.map} +1 -1
  15. package/dist/classnames.js +1 -3
  16. package/dist/classnames.js.map +1 -1
  17. package/dist/comments/{AnchoredThreads.mjs → AnchoredThreads.cjs} +38 -36
  18. package/dist/comments/{AnchoredThreads.mjs.map → AnchoredThreads.cjs.map} +1 -1
  19. package/dist/comments/AnchoredThreads.js +35 -37
  20. package/dist/comments/AnchoredThreads.js.map +1 -1
  21. package/dist/comments/{CommentsExtension.mjs → CommentsExtension.cjs} +34 -32
  22. package/dist/comments/{CommentsExtension.mjs.map → CommentsExtension.cjs.map} +1 -1
  23. package/dist/comments/CommentsExtension.js +31 -33
  24. package/dist/comments/CommentsExtension.js.map +1 -1
  25. package/dist/comments/{FloatingComposer.mjs → FloatingComposer.cjs} +34 -31
  26. package/dist/comments/{FloatingComposer.mjs.map → FloatingComposer.cjs.map} +1 -1
  27. package/dist/comments/FloatingComposer.js +30 -33
  28. package/dist/comments/FloatingComposer.js.map +1 -1
  29. package/dist/comments/{FloatingThreads.mjs → FloatingThreads.cjs} +39 -36
  30. package/dist/comments/{FloatingThreads.mjs.map → FloatingThreads.cjs.map} +1 -1
  31. package/dist/comments/FloatingThreads.js +35 -38
  32. package/dist/comments/FloatingThreads.js.map +1 -1
  33. package/dist/context.cjs +24 -0
  34. package/dist/{context.mjs.map → context.cjs.map} +1 -1
  35. package/dist/context.js +8 -11
  36. package/dist/context.js.map +1 -1
  37. package/dist/index.cjs +29 -0
  38. package/dist/{index.mjs.map → index.cjs.map} +1 -1
  39. package/dist/index.js +13 -27
  40. package/dist/index.js.map +1 -1
  41. package/dist/mentions/{Avatar.mjs → Avatar.cjs} +16 -14
  42. package/dist/mentions/Avatar.cjs.map +1 -0
  43. package/dist/mentions/Avatar.js +13 -15
  44. package/dist/mentions/Avatar.js.map +1 -1
  45. package/dist/mentions/Mention.cjs +31 -0
  46. package/dist/mentions/Mention.cjs.map +1 -0
  47. package/dist/mentions/Mention.js +25 -25
  48. package/dist/mentions/Mention.js.map +1 -1
  49. package/dist/mentions/{MentionExtension.mjs → MentionExtension.cjs} +35 -33
  50. package/dist/mentions/{MentionExtension.mjs.map → MentionExtension.cjs.map} +1 -1
  51. package/dist/mentions/MentionExtension.js +32 -34
  52. package/dist/mentions/MentionExtension.js.map +1 -1
  53. package/dist/mentions/{MentionNode.mjs → MentionNode.cjs} +12 -10
  54. package/dist/mentions/{MentionNode.mjs.map → MentionNode.cjs.map} +1 -1
  55. package/dist/mentions/MentionNode.js +9 -11
  56. package/dist/mentions/MentionNode.js.map +1 -1
  57. package/dist/mentions/{MentionsList.mjs → MentionsList.cjs} +39 -35
  58. package/dist/mentions/{MentionsList.mjs.map → MentionsList.cjs.map} +1 -1
  59. package/dist/mentions/MentionsList.js +34 -38
  60. package/dist/mentions/MentionsList.js.map +1 -1
  61. package/dist/toolbar/{FloatingToolbar.mjs → FloatingToolbar.cjs} +67 -64
  62. package/dist/toolbar/{FloatingToolbar.mjs.map → FloatingToolbar.cjs.map} +1 -1
  63. package/dist/toolbar/FloatingToolbar.js +63 -66
  64. package/dist/toolbar/FloatingToolbar.js.map +1 -1
  65. package/dist/toolbar/{Toolbar.mjs → Toolbar.cjs} +116 -91
  66. package/dist/toolbar/{Toolbar.mjs.map → Toolbar.cjs.map} +1 -1
  67. package/dist/toolbar/Toolbar.js +90 -115
  68. package/dist/toolbar/Toolbar.js.map +1 -1
  69. package/dist/toolbar/shared.cjs +36 -0
  70. package/dist/toolbar/{shared.mjs.map → shared.cjs.map} +1 -1
  71. package/dist/toolbar/shared.js +12 -15
  72. package/dist/toolbar/shared.js.map +1 -1
  73. package/dist/types.cjs +39 -0
  74. package/dist/{types.mjs.map → types.cjs.map} +1 -1
  75. package/dist/types.js +8 -19
  76. package/dist/types.js.map +1 -1
  77. package/dist/{utils.mjs → utils.cjs} +23 -14
  78. package/dist/{utils.mjs.map → utils.cjs.map} +1 -1
  79. package/dist/utils.js +13 -22
  80. package/dist/utils.js.map +1 -1
  81. package/dist/version-history/{HistoryVersionPreview.mjs → HistoryVersionPreview.cjs} +36 -34
  82. package/dist/version-history/{HistoryVersionPreview.mjs.map → HistoryVersionPreview.cjs.map} +1 -1
  83. package/dist/version-history/HistoryVersionPreview.js +33 -35
  84. package/dist/version-history/HistoryVersionPreview.js.map +1 -1
  85. package/dist/version.cjs +10 -0
  86. package/dist/{version.mjs.map → version.cjs.map} +1 -1
  87. package/dist/version.js +3 -7
  88. package/dist/version.js.map +1 -1
  89. package/package.json +18 -17
  90. package/styles.css.d.cts +1 -0
  91. package/dist/ai/AiExtension.mjs.map +0 -1
  92. package/dist/context.mjs +0 -21
  93. package/dist/index.mjs +0 -15
  94. package/dist/mentions/Avatar.mjs.map +0 -1
  95. package/dist/mentions/Mention.mjs +0 -27
  96. package/dist/mentions/Mention.mjs.map +0 -1
  97. package/dist/toolbar/shared.mjs +0 -33
  98. package/dist/types.mjs +0 -28
  99. package/dist/version.mjs +0 -6
  100. /package/dist/{index.d.mts → index.d.cts} +0 -0
@@ -1,19 +1,21 @@
1
- import { autoRetry, HttpError } from '@liveblocks/core';
2
- import { Extension } from '@tiptap/core';
3
- import { Slice, Fragment } from '@tiptap/pm/model';
4
- import { Plugin } from '@tiptap/pm/state';
5
- import { DecorationSet, Decoration } from '@tiptap/pm/view';
6
- import { ySyncPluginKey, yXmlFragmentToProseMirrorFragment } from 'y-prosemirror';
7
- import { createDocFromSnapshot, emptySnapshot, snapshot, equalSnapshots } from 'yjs';
8
- import { AI_TOOLBAR_SELECTION_PLUGIN } from '../types.mjs';
9
- import { getContextualPromptContext } from '../utils.mjs';
1
+ 'use strict';
2
+
3
+ var core$1 = require('@liveblocks/core');
4
+ var core = require('@tiptap/core');
5
+ var model = require('@tiptap/pm/model');
6
+ var state = require('@tiptap/pm/state');
7
+ var view = require('@tiptap/pm/view');
8
+ var yProsemirror = require('y-prosemirror');
9
+ var yjs = require('yjs');
10
+ var types = require('../types.cjs');
11
+ var utils = require('../utils.cjs');
10
12
 
11
13
  const DEFAULT_AI_NAME = "AI";
12
14
  const DEFAULT_STATE = { phase: "closed" };
13
15
  const RESOLVE_AI_PROMPT_RETRY_ATTEMPTS = 3;
14
16
  const RESOLVE_AI_PROMPT_RETRY_DELAYS = [1e3, 2e3, 4e3];
15
17
  function getYjsBinding(editor) {
16
- return ySyncPluginKey.getState(editor.view.state).binding;
18
+ return yProsemirror.ySyncPluginKey.getState(editor.view.state).binding;
17
19
  }
18
20
  function getLiveblocksYjsProvider(editor) {
19
21
  return editor.extensionStorage.liveblocksExtension?.provider;
@@ -36,12 +38,12 @@ function getRevertTransaction(tr, editor, storage, doc) {
36
38
  const binding = getYjsBinding(editor);
37
39
  if (binding) {
38
40
  binding.mapping.clear();
39
- const docFromSnapshot = createDocFromSnapshot(
41
+ const docFromSnapshot = yjs.createDocFromSnapshot(
40
42
  binding.doc,
41
43
  storage.snapshot
42
44
  );
43
45
  const type = docFromSnapshot.getXmlFragment("default");
44
- const fragmentContent = yXmlFragmentToProseMirrorFragment(
46
+ const fragmentContent = yProsemirror.yXmlFragmentToProseMirrorFragment(
45
47
  type,
46
48
  editor.state.schema
47
49
  );
@@ -49,9 +51,9 @@ function getRevertTransaction(tr, editor, storage, doc) {
49
51
  tr.replace(
50
52
  0,
51
53
  editor.state.doc.content.size,
52
- new Slice(Fragment.from(fragmentContent), 0, 0)
54
+ new model.Slice(model.Fragment.from(fragmentContent), 0, 0)
53
55
  );
54
- tr.setMeta(ySyncPluginKey, {
56
+ tr.setMeta(yProsemirror.ySyncPluginKey, {
55
57
  snapshot: null,
56
58
  prevSnapshot: null
57
59
  });
@@ -64,7 +66,7 @@ function getRevertTransaction(tr, editor, storage, doc) {
64
66
  }
65
67
  return null;
66
68
  }
67
- const AiExtension = Extension.create({
69
+ const AiExtension = core.Extension.create({
68
70
  name: "liveblocksAi",
69
71
  addOptions() {
70
72
  return {
@@ -100,7 +102,7 @@ const AiExtension = Extension.create({
100
102
  if (!binding) {
101
103
  return false;
102
104
  }
103
- const fragmentContent = yXmlFragmentToProseMirrorFragment(
105
+ const fragmentContent = yProsemirror.yXmlFragmentToProseMirrorFragment(
104
106
  binding.type,
105
107
  this.editor.state.schema
106
108
  );
@@ -108,9 +110,9 @@ const AiExtension = Extension.create({
108
110
  tr.replace(
109
111
  0,
110
112
  this.editor.state.doc.content.size,
111
- new Slice(Fragment.from(fragmentContent), 0, 0)
113
+ new model.Slice(model.Fragment.from(fragmentContent), 0, 0)
112
114
  );
113
- tr.setMeta(ySyncPluginKey, {
115
+ tr.setMeta(yProsemirror.ySyncPluginKey, {
114
116
  snapshot: null,
115
117
  prevSnapshot: null
116
118
  });
@@ -208,12 +210,12 @@ const AiExtension = Extension.create({
208
210
  previousResponse: currentState.response
209
211
  };
210
212
  this.editor.setEditable(false);
211
- autoRetry(
213
+ core$1.autoRetry(
212
214
  async () => {
213
215
  await provider?.pause();
214
216
  const response = await this.options.resolveContextualPrompt({
215
217
  prompt,
216
- context: getContextualPromptContext(this.editor, 3e3),
218
+ context: utils.getContextualPromptContext(this.editor, 3e3),
217
219
  signal: abortController.signal,
218
220
  previous: withPreviousResponse && currentState.phase === "reviewing" ? {
219
221
  prompt: currentState.prompt,
@@ -232,7 +234,7 @@ const AiExtension = Extension.create({
232
234
  RESOLVE_AI_PROMPT_RETRY_ATTEMPTS,
233
235
  RESOLVE_AI_PROMPT_RETRY_DELAYS,
234
236
  (error) => {
235
- return abortController.signal.aborted || error instanceof HttpError && error.status >= 400 && error.status < 500;
237
+ return abortController.signal.aborted || error instanceof core$1.HttpError && error.status >= 400 && error.status < 500;
236
238
  }
237
239
  ).then((response) => {
238
240
  if (abortController.signal.aborted) {
@@ -271,9 +273,9 @@ const AiExtension = Extension.create({
271
273
  if (!this.options.doc || !this.storage.snapshot) {
272
274
  return false;
273
275
  }
274
- const previousSnapshot = this.storage.snapshot ?? emptySnapshot;
275
- const currentSnapshot = snapshot(this.options.doc);
276
- if (equalSnapshots(previousSnapshot, currentSnapshot)) {
276
+ const previousSnapshot = this.storage.snapshot ?? yjs.emptySnapshot;
277
+ const currentSnapshot = yjs.snapshot(this.options.doc);
278
+ if (yjs.equalSnapshots(previousSnapshot, currentSnapshot)) {
277
279
  return true;
278
280
  }
279
281
  getYjsBinding(this.editor)?.renderSnapshot(
@@ -301,7 +303,7 @@ const AiExtension = Extension.create({
301
303
  return false;
302
304
  }
303
305
  this.options.doc.gc = false;
304
- this.storage.snapshot = snapshot(this.options.doc);
306
+ this.storage.snapshot = yjs.snapshot(this.options.doc);
305
307
  this.storage.state = {
306
308
  phase: "reviewing",
307
309
  initialSelection: currentState.initialSelection,
@@ -353,20 +355,20 @@ const AiExtension = Extension.create({
353
355
  },
354
356
  addProseMirrorPlugins() {
355
357
  return [
356
- new Plugin({
357
- key: AI_TOOLBAR_SELECTION_PLUGIN,
358
+ new state.Plugin({
359
+ key: types.AI_TOOLBAR_SELECTION_PLUGIN,
358
360
  props: {
359
361
  decorations: ({ doc, selection }) => {
360
362
  if (this.storage.state.phase === "closed" || this.storage.state.phase === "reviewing" && isContextualPromptDiffResponse(this.storage.state.response)) {
361
- return DecorationSet.create(doc, []);
363
+ return view.DecorationSet.create(doc, []);
362
364
  }
363
365
  const { from, to } = selection;
364
366
  const decorations = [
365
- Decoration.inline(from, to, {
367
+ view.Decoration.inline(from, to, {
366
368
  class: "lb-root lb-selection lb-tiptap-active-selection"
367
369
  })
368
370
  ];
369
- return DecorationSet.create(doc, decorations);
371
+ return view.DecorationSet.create(doc, decorations);
370
372
  }
371
373
  }
372
374
  })
@@ -374,5 +376,7 @@ const AiExtension = Extension.create({
374
376
  }
375
377
  });
376
378
 
377
- export { AiExtension, DEFAULT_STATE, isContextualPromptDiffResponse };
378
- //# sourceMappingURL=AiExtension.mjs.map
379
+ exports.AiExtension = AiExtension;
380
+ exports.DEFAULT_STATE = DEFAULT_STATE;
381
+ exports.isContextualPromptDiffResponse = isContextualPromptDiffResponse;
382
+ //# sourceMappingURL=AiExtension.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AiExtension.cjs","sources":["../../src/ai/AiExtension.ts"],"sourcesContent":["import {\n autoRetry,\n type ContextualPromptResponse,\n HttpError,\n} from \"@liveblocks/core\";\nimport type { LiveblocksYjsProvider } from \"@liveblocks/yjs\";\nimport type { CommandProps, Editor } from \"@tiptap/core\";\nimport { Extension } from \"@tiptap/core\";\nimport { Fragment, Slice } from \"@tiptap/pm/model\";\nimport type { Transaction } from \"@tiptap/pm/state\";\nimport { Plugin } from \"@tiptap/pm/state\";\nimport { Decoration, DecorationSet } from \"@tiptap/pm/view\";\nimport {\n ySyncPluginKey,\n yXmlFragmentToProseMirrorFragment,\n} from \"y-prosemirror\";\nimport type { Doc, Snapshot } from \"yjs\";\nimport {\n createDocFromSnapshot,\n emptySnapshot,\n equalSnapshots,\n snapshot as takeSnapshot,\n} from \"yjs\";\n\nimport {\n AI_TOOLBAR_SELECTION_PLUGIN,\n type AiCommands,\n type AiExtensionOptions,\n type AiExtensionStorage,\n type AiToolbarState,\n type LiveblocksExtensionStorage,\n type ResolveContextualPromptResponse,\n type YSyncPluginState,\n} from \"../types\";\nimport { getContextualPromptContext } from \"../utils\";\n\nconst DEFAULT_AI_NAME = \"AI\";\nexport const DEFAULT_STATE: AiToolbarState = { phase: \"closed\" };\n\nconst RESOLVE_AI_PROMPT_RETRY_ATTEMPTS = 3;\nconst RESOLVE_AI_PROMPT_RETRY_DELAYS = [1000, 2000, 4000];\n\nfunction getYjsBinding(editor: Editor) {\n return (ySyncPluginKey.getState(editor.view.state) as YSyncPluginState)\n .binding;\n}\n\nfunction getLiveblocksYjsProvider(editor: Editor) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n return (\n editor.extensionStorage.liveblocksExtension as\n | LiveblocksExtensionStorage\n | undefined\n )?.provider as LiveblocksYjsProvider | undefined;\n}\n\nexport function isContextualPromptDiffResponse(\n response: ContextualPromptResponse\n): response is Extract<\n ContextualPromptResponse,\n { type: \"replace\" | \"insert\" }\n> {\n return response.type === \"replace\" || response.type === \"insert\";\n}\n\nfunction isResolveContextualPromptResponse(\n response: unknown\n): response is ResolveContextualPromptResponse {\n return (\n typeof response === \"object\" &&\n response !== null &&\n typeof (response as { text: unknown }).text === \"string\" &&\n typeof (response as { type: unknown }).type === \"string\" &&\n [\"insert\", \"replace\", \"other\"].includes((response as { type: string }).type)\n );\n}\n\nfunction createParagraph(editor: Editor, text: string) {\n const paragraph =\n editor.schema.nodes.paragraph ??\n Object.values(editor.schema.nodes).find((node) => node.isBlock);\n\n if (!paragraph) {\n throw new Error(\"Could not create a paragraph.\");\n }\n\n return paragraph.create(null, text ? editor.schema.text(text) : undefined);\n}\n\nfunction getRevertTransaction(\n tr: Transaction,\n editor: Editor,\n storage: AiExtensionStorage,\n doc?: Doc\n): Transaction | null {\n if (storage.snapshot) {\n const binding = getYjsBinding(editor);\n\n if (binding) {\n binding.mapping.clear();\n\n const docFromSnapshot = createDocFromSnapshot(\n binding.doc,\n storage.snapshot\n );\n const type = docFromSnapshot.getXmlFragment(\"default\"); // TODO: field\n const fragmentContent = yXmlFragmentToProseMirrorFragment(\n type,\n editor.state.schema\n );\n\n tr.setMeta(\"addToHistory\", false);\n tr.replace(\n 0,\n editor.state.doc.content.size,\n new Slice(Fragment.from(fragmentContent), 0, 0)\n );\n tr.setMeta(ySyncPluginKey, {\n snapshot: null,\n prevSnapshot: null,\n });\n\n if (doc) {\n doc.gc = true;\n }\n\n storage.snapshot = undefined;\n\n return tr;\n }\n }\n return null;\n}\n\nexport const AiExtension = Extension.create<\n AiExtensionOptions,\n AiExtensionStorage\n>({\n name: \"liveblocksAi\",\n addOptions() {\n return {\n doc: undefined,\n pud: undefined,\n\n // The actual default resolver is set in LiveblocksExtension via AiExtension.configure()\n resolveContextualPrompt: () => Promise.reject(),\n name: DEFAULT_AI_NAME,\n };\n },\n addStorage() {\n return {\n state: DEFAULT_STATE,\n name: this.options.name,\n };\n },\n addCommands() {\n return {\n askAi: (prompt) => () => {\n if (typeof prompt === \"string\") {\n (\n this.editor.commands as unknown as AiCommands\n ).$startAiToolbarThinking(prompt);\n } else {\n (\n this.editor.commands as unknown as AiCommands\n ).$openAiToolbarAsking();\n }\n\n return true;\n },\n\n $acceptAiToolbarResponse:\n () =>\n ({ tr, view }: CommandProps) => {\n const currentState = this.storage.state;\n\n // 1. If NOT in \"reviewing\" phase, do nothing\n if (currentState.phase !== \"reviewing\") {\n return false;\n }\n\n // 2. Accept the response\n if (isContextualPromptDiffResponse(currentState.response)) {\n // 2.a. If the response is a diff, apply it definitely\n const binding = getYjsBinding(this.editor);\n if (!binding) {\n return false;\n }\n\n const fragmentContent = yXmlFragmentToProseMirrorFragment(\n binding.type,\n this.editor.state.schema\n );\n tr.setMeta(\"addToHistory\", false);\n tr.replace(\n 0,\n this.editor.state.doc.content.size,\n new Slice(Fragment.from(fragmentContent), 0, 0)\n );\n tr.setMeta(ySyncPluginKey, {\n snapshot: null,\n prevSnapshot: null,\n });\n\n this.storage.snapshot = undefined;\n } else {\n // 2.b. If the response is not a diff, insert it below the selection\n\n const paragraphs = currentState.response.text\n .split(\"\\n\")\n .map((paragraph) => createParagraph(this.editor, paragraph));\n\n tr.insert(this.editor.state.selection.$to.end(), paragraphs);\n tr.setMeta(\"addToHistory\", true);\n view.dispatch(tr);\n // Prevent TipTap from dispatching this transaction, because we already did (this is a hack)\n tr.setMeta(\"preventDispatch\", true);\n }\n\n // 3. Unblock the editor\n getLiveblocksYjsProvider(this.editor)?.unpause();\n this.editor.setEditable(true);\n\n // 4. Set to \"closed\" phase\n this.storage.state = { phase: \"closed\" };\n\n return true;\n },\n\n $closeAiToolbar:\n () =>\n ({ tr, view }: CommandProps) => {\n const currentState = this.storage.state;\n\n // 1. If already in \"closed\" phase, do nothing\n if (currentState.phase === \"closed\") {\n return false;\n }\n\n // 2. If in \"thinking\" phase, cancel the current AI request\n if (currentState.phase === \"thinking\") {\n currentState.abortController.abort();\n }\n\n // 3. If in \"thinking\" or \"reviewing\" phase, revert the editor if possible and unblock it\n if (\n currentState.phase === \"thinking\" ||\n currentState.phase === \"reviewing\"\n ) {\n // Get the revert transaction and dispatch it\n const revertTr = getRevertTransaction(\n tr,\n this.editor,\n this.storage,\n this.options.doc\n );\n if (revertTr) {\n view.dispatch(revertTr);\n // Prevent TipTap from dispatching this transaction, because we already did (this is a hack)\n tr.setMeta(\"preventDispatch\", true);\n }\n }\n\n // 4. Restore the initial selection\n this.editor.commands.setTextSelection(currentState.initialSelection);\n\n // 5. Unblock the editor\n getLiveblocksYjsProvider(this.editor)?.unpause();\n this.editor.setEditable(true);\n\n // 6. Set to \"closed\" phase\n this.storage.state = { phase: \"closed\" };\n\n return true;\n },\n\n $openAiToolbarAsking: () => () => {\n const currentState = this.storage.state;\n\n // 1. If NOT in \"closed\" phase, do nothing\n if (currentState.phase !== \"closed\") {\n return false;\n }\n\n // 2. Blur the editor if needed\n if (this.editor.isFocused) {\n this.editor.commands.blur();\n }\n\n // 3. Set to \"asking\" phase\n this.storage.state = {\n phase: \"asking\",\n // Store the initial selection\n initialSelection: {\n from: this.editor.state.selection.from,\n to: this.editor.state.selection.to,\n },\n // Initialize the custom prompt as empty\n customPrompt: \"\",\n };\n\n return true;\n },\n\n $startAiToolbarThinking:\n (prompt: string, withPreviousResponse?: boolean) =>\n ({ tr, view }: CommandProps) => {\n const currentState = this.storage.state;\n\n // 1. If in \"thinking\" phase already, do nothing\n if (currentState.phase === \"thinking\") {\n return false;\n }\n\n // 2. Blur the editor if needed\n if (this.editor.isFocused) {\n this.editor.commands.blur();\n }\n\n const abortController = new AbortController();\n const provider = getLiveblocksYjsProvider(this.editor);\n\n // 3. If this is a retry or a refinement, revert the editor and restore the initial selection\n if (currentState.phase === \"reviewing\") {\n // 3.a. Revert the editor\n const revertTr = getRevertTransaction(\n tr,\n this.editor,\n this.storage,\n this.options.doc\n );\n if (revertTr) {\n // Important: in this scenario we do not unpause the provider\n view.dispatch(revertTr);\n // Prevent Tiptap from dispatching this transaction, because we already did (this is a hack)\n tr.setMeta(\"preventDispatch\", true);\n }\n\n // 3.b. Restore the initial selection\n this.editor.commands.setTextSelection(\n currentState.initialSelection\n );\n }\n\n // 4. Set to \"thinking\" phase\n this.storage.state = {\n phase: \"thinking\",\n // Store the initial selection if the toolbar is opened directly in the \"thinking\" phase\n initialSelection: currentState.initialSelection ?? {\n from: this.editor.state.selection.from,\n to: this.editor.state.selection.to,\n },\n // Initialize the custom prompt as empty if the toolbar is opened directly in the \"thinking\" phase\n customPrompt: currentState.customPrompt ?? \"\",\n prompt,\n abortController,\n previousResponse: currentState.response,\n };\n\n // 5. Block the editor\n this.editor.setEditable(false);\n\n // 6. Start the AI request\n autoRetry(\n async () => {\n await provider?.pause();\n\n // 6.a. Resolve the AI prompt\n const response = (await this.options.resolveContextualPrompt({\n prompt,\n context: getContextualPromptContext(this.editor, 3_000),\n signal: abortController.signal,\n previous:\n withPreviousResponse && currentState.phase === \"reviewing\"\n ? {\n prompt: currentState.prompt,\n response: {\n type: currentState.response?.type,\n text: currentState.response?.text,\n },\n }\n : undefined,\n })) as unknown;\n\n // 6.b. Validate the response\n if (isResolveContextualPromptResponse(response)) {\n return response;\n } else {\n throw new Error(\"Failed to resolve AI prompt.\");\n }\n },\n RESOLVE_AI_PROMPT_RETRY_ATTEMPTS,\n RESOLVE_AI_PROMPT_RETRY_DELAYS,\n\n (error) => {\n // Don't retry on 4xx errors or if the request was aborted\n return (\n abortController.signal.aborted ||\n (error instanceof HttpError &&\n error.status >= 400 &&\n error.status < 500)\n );\n }\n )\n .then((response) => {\n if (abortController.signal.aborted) {\n return;\n }\n\n // 6.a. If the AI request succeeds, set to \"reviewing\" phase with the response\n (\n this.editor.commands as unknown as AiCommands\n )._handleAiToolbarThinkingSuccess({\n type: response.type,\n text: response.text,\n });\n })\n .catch((error) => {\n if (abortController.signal.aborted) {\n return;\n }\n\n // 6.b. If the AI request fails, set to \"asking\" phase with error\n (\n this.editor.commands as unknown as AiCommands\n )._handleAiToolbarThinkingError(error);\n });\n\n return true;\n },\n\n $cancelAiToolbarThinking: () => () => {\n const currentState = this.storage.state;\n\n // 1. If NOT in \"thinking\" phase, do nothing\n if (currentState.phase !== \"thinking\") {\n return false;\n }\n\n // 2. Cancel the current AI request\n currentState.abortController.abort();\n\n // 3. Unblock the editor\n this.editor.setEditable(true);\n\n // 4. Set to \"asking\" phase\n this.storage.state = {\n phase: \"asking\",\n initialSelection: currentState.initialSelection,\n // If the custom prompt is different than the prompt, reset it\n customPrompt:\n currentState.prompt === currentState.customPrompt\n ? currentState.customPrompt\n : \"\",\n };\n\n return true;\n },\n\n _showAiToolbarReviewingDiff: () => () => {\n // The diff is applied right before moving to the \"reviewing\" phase\n if (this.storage.state.phase !== \"reviewing\") {\n return false;\n }\n\n if (!this.options.doc || !this.storage.snapshot) {\n return false;\n }\n\n const previousSnapshot: Snapshot =\n this.storage.snapshot ?? emptySnapshot;\n const currentSnapshot = takeSnapshot(this.options.doc);\n\n if (equalSnapshots(previousSnapshot, currentSnapshot)) {\n return true;\n }\n\n getYjsBinding(this.editor)?.renderSnapshot(\n currentSnapshot,\n previousSnapshot\n );\n\n return true;\n },\n\n _handleAiToolbarThinkingSuccess:\n (response: ContextualPromptResponse) =>\n ({ view, tr }: CommandProps) => {\n const currentState = this.storage.state;\n\n // 1. If NOT in \"thinking\" phase, do nothing\n if (currentState.phase !== \"thinking\") {\n return false;\n }\n\n // 2. If this is not a diff, the response will just be in the toolbar, set to \"reviewing\" phase directly with the response\n if (!isContextualPromptDiffResponse(response)) {\n this.storage.state = {\n phase: \"reviewing\",\n initialSelection: currentState.initialSelection,\n customPrompt: \"\",\n prompt: currentState.prompt,\n response,\n };\n\n return true;\n }\n\n if (!this.options.doc) {\n return false;\n }\n\n // 3. Otherwise, the response is a diff, apply it to the editor\n this.options.doc.gc = false;\n this.storage.snapshot = takeSnapshot(this.options.doc);\n\n // 4. Set to \"reviewing\" phase with the new range\n this.storage.state = {\n phase: \"reviewing\",\n initialSelection: currentState.initialSelection,\n customPrompt: \"\",\n prompt: currentState.prompt,\n response,\n };\n\n // 5. Insert the response's text as inline first (and replace the selection if it's a replace) then as block if there are multiple paragraphs\n const [firstParagraph, ...otherParagraphs] =\n response.text.split(\"\\n\");\n\n tr.insertText(\n firstParagraph,\n response.type === \"insert\"\n ? this.editor.state.selection.to\n : this.editor.state.selection.from,\n this.editor.state.selection.to\n );\n\n if (otherParagraphs.length > 0) {\n const paragraphs = otherParagraphs.map((paragraph) =>\n createParagraph(this.editor, paragraph)\n );\n\n tr.insert(tr.selection.$to.pos, paragraphs);\n }\n\n view.dispatch(tr);\n // Prevent Tiptap from dispatching this transaction, because we already did (this is a hack)\n tr.setMeta(\"preventDispatch\", true);\n\n // 6. Show the diff\n (\n this.editor.commands as unknown as AiCommands\n )._showAiToolbarReviewingDiff();\n\n // We moved to the \"reviewing\" phase, so even if `_showAiToolbarReviewingDiff`\n // returns `false` somehow, we still want to return `true`\n return true;\n },\n\n _handleAiToolbarThinkingError: (error: unknown) => () => {\n const currentState = this.storage.state;\n\n // 1. If NOT in \"thinking\" phase, do nothing\n if (currentState.phase !== \"thinking\") {\n return false;\n }\n\n // 2. Unblock the editor\n this.editor.setEditable(true);\n\n // 3. Log the error\n console.error(error);\n\n // 4. Set to \"asking\" phase with error\n this.storage.state = {\n phase: \"asking\",\n initialSelection: currentState.initialSelection,\n // If the custom prompt is different than the prompt, reset it\n customPrompt:\n currentState.prompt === currentState.customPrompt\n ? currentState.customPrompt\n : \"\",\n // Pass the error so it can be displayed\n error:\n error instanceof Error\n ? error\n : new Error(String(error), { cause: error }),\n };\n\n return true;\n },\n\n _updateAiToolbarCustomPrompt:\n (customPrompt: string | ((currentCustomPrompt: string) => string)) =>\n () => {\n const currentState = this.storage.state;\n\n // 1. If NOT in a phase with a custom prompt, do nothing\n if (typeof currentState.customPrompt !== \"string\") {\n return false;\n }\n\n // 2. Update the custom prompt\n this.storage.state.customPrompt =\n typeof customPrompt === \"function\"\n ? customPrompt(currentState.customPrompt)\n : customPrompt;\n\n return true;\n },\n };\n },\n addProseMirrorPlugins() {\n return [\n new Plugin({\n key: AI_TOOLBAR_SELECTION_PLUGIN,\n props: {\n decorations: ({ doc, selection }) => {\n // Don't show the AI toolbar selection if the toolbar is closed or when reviewing diff responses\n if (\n this.storage.state.phase === \"closed\" ||\n (this.storage.state.phase === \"reviewing\" &&\n isContextualPromptDiffResponse(this.storage.state.response))\n ) {\n return DecorationSet.create(doc, []);\n }\n\n const { from, to } = selection;\n const decorations: Decoration[] = [\n Decoration.inline(from, to, {\n class: \"lb-root lb-selection lb-tiptap-active-selection\",\n }),\n ];\n\n return DecorationSet.create(doc, decorations);\n },\n },\n }),\n ];\n },\n});\n"],"names":["ySyncPluginKey","createDocFromSnapshot","yXmlFragmentToProseMirrorFragment","Slice","Fragment","Extension","autoRetry","getContextualPromptContext","HttpError","emptySnapshot","takeSnapshot","equalSnapshots","Plugin","AI_TOOLBAR_SELECTION_PLUGIN","DecorationSet","Decoration"],"mappings":"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"}
@@ -1,21 +1,19 @@
1
- 'use strict';
2
-
3
- var core$1 = require('@liveblocks/core');
4
- var core = require('@tiptap/core');
5
- var model = require('@tiptap/pm/model');
6
- var state = require('@tiptap/pm/state');
7
- var view = require('@tiptap/pm/view');
8
- var yProsemirror = require('y-prosemirror');
9
- var yjs = require('yjs');
10
- var types = require('../types.js');
11
- var utils = require('../utils.js');
1
+ import { autoRetry, HttpError } from '@liveblocks/core';
2
+ import { Extension } from '@tiptap/core';
3
+ import { Slice, Fragment } from '@tiptap/pm/model';
4
+ import { Plugin } from '@tiptap/pm/state';
5
+ import { DecorationSet, Decoration } from '@tiptap/pm/view';
6
+ import { ySyncPluginKey, yXmlFragmentToProseMirrorFragment } from 'y-prosemirror';
7
+ import { createDocFromSnapshot, emptySnapshot, snapshot, equalSnapshots } from 'yjs';
8
+ import { AI_TOOLBAR_SELECTION_PLUGIN } from '../types.js';
9
+ import { getContextualPromptContext } from '../utils.js';
12
10
 
13
11
  const DEFAULT_AI_NAME = "AI";
14
12
  const DEFAULT_STATE = { phase: "closed" };
15
13
  const RESOLVE_AI_PROMPT_RETRY_ATTEMPTS = 3;
16
14
  const RESOLVE_AI_PROMPT_RETRY_DELAYS = [1e3, 2e3, 4e3];
17
15
  function getYjsBinding(editor) {
18
- return yProsemirror.ySyncPluginKey.getState(editor.view.state).binding;
16
+ return ySyncPluginKey.getState(editor.view.state).binding;
19
17
  }
20
18
  function getLiveblocksYjsProvider(editor) {
21
19
  return editor.extensionStorage.liveblocksExtension?.provider;
@@ -38,12 +36,12 @@ function getRevertTransaction(tr, editor, storage, doc) {
38
36
  const binding = getYjsBinding(editor);
39
37
  if (binding) {
40
38
  binding.mapping.clear();
41
- const docFromSnapshot = yjs.createDocFromSnapshot(
39
+ const docFromSnapshot = createDocFromSnapshot(
42
40
  binding.doc,
43
41
  storage.snapshot
44
42
  );
45
43
  const type = docFromSnapshot.getXmlFragment("default");
46
- const fragmentContent = yProsemirror.yXmlFragmentToProseMirrorFragment(
44
+ const fragmentContent = yXmlFragmentToProseMirrorFragment(
47
45
  type,
48
46
  editor.state.schema
49
47
  );
@@ -51,9 +49,9 @@ function getRevertTransaction(tr, editor, storage, doc) {
51
49
  tr.replace(
52
50
  0,
53
51
  editor.state.doc.content.size,
54
- new model.Slice(model.Fragment.from(fragmentContent), 0, 0)
52
+ new Slice(Fragment.from(fragmentContent), 0, 0)
55
53
  );
56
- tr.setMeta(yProsemirror.ySyncPluginKey, {
54
+ tr.setMeta(ySyncPluginKey, {
57
55
  snapshot: null,
58
56
  prevSnapshot: null
59
57
  });
@@ -66,7 +64,7 @@ function getRevertTransaction(tr, editor, storage, doc) {
66
64
  }
67
65
  return null;
68
66
  }
69
- const AiExtension = core.Extension.create({
67
+ const AiExtension = Extension.create({
70
68
  name: "liveblocksAi",
71
69
  addOptions() {
72
70
  return {
@@ -102,7 +100,7 @@ const AiExtension = core.Extension.create({
102
100
  if (!binding) {
103
101
  return false;
104
102
  }
105
- const fragmentContent = yProsemirror.yXmlFragmentToProseMirrorFragment(
103
+ const fragmentContent = yXmlFragmentToProseMirrorFragment(
106
104
  binding.type,
107
105
  this.editor.state.schema
108
106
  );
@@ -110,9 +108,9 @@ const AiExtension = core.Extension.create({
110
108
  tr.replace(
111
109
  0,
112
110
  this.editor.state.doc.content.size,
113
- new model.Slice(model.Fragment.from(fragmentContent), 0, 0)
111
+ new Slice(Fragment.from(fragmentContent), 0, 0)
114
112
  );
115
- tr.setMeta(yProsemirror.ySyncPluginKey, {
113
+ tr.setMeta(ySyncPluginKey, {
116
114
  snapshot: null,
117
115
  prevSnapshot: null
118
116
  });
@@ -210,12 +208,12 @@ const AiExtension = core.Extension.create({
210
208
  previousResponse: currentState.response
211
209
  };
212
210
  this.editor.setEditable(false);
213
- core$1.autoRetry(
211
+ autoRetry(
214
212
  async () => {
215
213
  await provider?.pause();
216
214
  const response = await this.options.resolveContextualPrompt({
217
215
  prompt,
218
- context: utils.getContextualPromptContext(this.editor, 3e3),
216
+ context: getContextualPromptContext(this.editor, 3e3),
219
217
  signal: abortController.signal,
220
218
  previous: withPreviousResponse && currentState.phase === "reviewing" ? {
221
219
  prompt: currentState.prompt,
@@ -234,7 +232,7 @@ const AiExtension = core.Extension.create({
234
232
  RESOLVE_AI_PROMPT_RETRY_ATTEMPTS,
235
233
  RESOLVE_AI_PROMPT_RETRY_DELAYS,
236
234
  (error) => {
237
- return abortController.signal.aborted || error instanceof core$1.HttpError && error.status >= 400 && error.status < 500;
235
+ return abortController.signal.aborted || error instanceof HttpError && error.status >= 400 && error.status < 500;
238
236
  }
239
237
  ).then((response) => {
240
238
  if (abortController.signal.aborted) {
@@ -273,9 +271,9 @@ const AiExtension = core.Extension.create({
273
271
  if (!this.options.doc || !this.storage.snapshot) {
274
272
  return false;
275
273
  }
276
- const previousSnapshot = this.storage.snapshot ?? yjs.emptySnapshot;
277
- const currentSnapshot = yjs.snapshot(this.options.doc);
278
- if (yjs.equalSnapshots(previousSnapshot, currentSnapshot)) {
274
+ const previousSnapshot = this.storage.snapshot ?? emptySnapshot;
275
+ const currentSnapshot = snapshot(this.options.doc);
276
+ if (equalSnapshots(previousSnapshot, currentSnapshot)) {
279
277
  return true;
280
278
  }
281
279
  getYjsBinding(this.editor)?.renderSnapshot(
@@ -303,7 +301,7 @@ const AiExtension = core.Extension.create({
303
301
  return false;
304
302
  }
305
303
  this.options.doc.gc = false;
306
- this.storage.snapshot = yjs.snapshot(this.options.doc);
304
+ this.storage.snapshot = snapshot(this.options.doc);
307
305
  this.storage.state = {
308
306
  phase: "reviewing",
309
307
  initialSelection: currentState.initialSelection,
@@ -355,20 +353,20 @@ const AiExtension = core.Extension.create({
355
353
  },
356
354
  addProseMirrorPlugins() {
357
355
  return [
358
- new state.Plugin({
359
- key: types.AI_TOOLBAR_SELECTION_PLUGIN,
356
+ new Plugin({
357
+ key: AI_TOOLBAR_SELECTION_PLUGIN,
360
358
  props: {
361
359
  decorations: ({ doc, selection }) => {
362
360
  if (this.storage.state.phase === "closed" || this.storage.state.phase === "reviewing" && isContextualPromptDiffResponse(this.storage.state.response)) {
363
- return view.DecorationSet.create(doc, []);
361
+ return DecorationSet.create(doc, []);
364
362
  }
365
363
  const { from, to } = selection;
366
364
  const decorations = [
367
- view.Decoration.inline(from, to, {
365
+ Decoration.inline(from, to, {
368
366
  class: "lb-root lb-selection lb-tiptap-active-selection"
369
367
  })
370
368
  ];
371
- return view.DecorationSet.create(doc, decorations);
369
+ return DecorationSet.create(doc, decorations);
372
370
  }
373
371
  }
374
372
  })
@@ -376,7 +374,5 @@ const AiExtension = core.Extension.create({
376
374
  }
377
375
  });
378
376
 
379
- exports.AiExtension = AiExtension;
380
- exports.DEFAULT_STATE = DEFAULT_STATE;
381
- exports.isContextualPromptDiffResponse = isContextualPromptDiffResponse;
377
+ export { AiExtension, DEFAULT_STATE, isContextualPromptDiffResponse };
382
378
  //# sourceMappingURL=AiExtension.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AiExtension.js","sources":["../../src/ai/AiExtension.ts"],"sourcesContent":["import {\n autoRetry,\n type ContextualPromptResponse,\n HttpError,\n} from \"@liveblocks/core\";\nimport type { LiveblocksYjsProvider } from \"@liveblocks/yjs\";\nimport type { CommandProps, Editor } from \"@tiptap/core\";\nimport { Extension } from \"@tiptap/core\";\nimport { Fragment, Slice } from \"@tiptap/pm/model\";\nimport type { Transaction } from \"@tiptap/pm/state\";\nimport { Plugin } from \"@tiptap/pm/state\";\nimport { Decoration, DecorationSet } from \"@tiptap/pm/view\";\nimport {\n ySyncPluginKey,\n yXmlFragmentToProseMirrorFragment,\n} from \"y-prosemirror\";\nimport type { Doc, Snapshot } from \"yjs\";\nimport {\n createDocFromSnapshot,\n emptySnapshot,\n equalSnapshots,\n snapshot as takeSnapshot,\n} from \"yjs\";\n\nimport {\n AI_TOOLBAR_SELECTION_PLUGIN,\n type AiCommands,\n type AiExtensionOptions,\n type AiExtensionStorage,\n type AiToolbarState,\n type LiveblocksExtensionStorage,\n type ResolveContextualPromptResponse,\n type YSyncPluginState,\n} from \"../types\";\nimport { getContextualPromptContext } from \"../utils\";\n\nconst DEFAULT_AI_NAME = \"AI\";\nexport const DEFAULT_STATE: AiToolbarState = { phase: \"closed\" };\n\nconst RESOLVE_AI_PROMPT_RETRY_ATTEMPTS = 3;\nconst RESOLVE_AI_PROMPT_RETRY_DELAYS = [1000, 2000, 4000];\n\nfunction getYjsBinding(editor: Editor) {\n return (ySyncPluginKey.getState(editor.view.state) as YSyncPluginState)\n .binding;\n}\n\nfunction getLiveblocksYjsProvider(editor: Editor) {\n return (\n editor.extensionStorage.liveblocksExtension as\n | LiveblocksExtensionStorage\n | undefined\n )?.provider as LiveblocksYjsProvider | undefined;\n}\n\nexport function isContextualPromptDiffResponse(\n response: ContextualPromptResponse\n): response is Extract<\n ContextualPromptResponse,\n { type: \"replace\" | \"insert\" }\n> {\n return response.type === \"replace\" || response.type === \"insert\";\n}\n\nfunction isResolveContextualPromptResponse(\n response: unknown\n): response is ResolveContextualPromptResponse {\n return (\n typeof response === \"object\" &&\n response !== null &&\n typeof (response as { text: unknown }).text === \"string\" &&\n typeof (response as { type: unknown }).type === \"string\" &&\n [\"insert\", \"replace\", \"other\"].includes((response as { type: string }).type)\n );\n}\n\nfunction createParagraph(editor: Editor, text: string) {\n const paragraph =\n editor.schema.nodes.paragraph ??\n Object.values(editor.schema.nodes).find((node) => node.isBlock);\n\n if (!paragraph) {\n throw new Error(\"Could not create a paragraph.\");\n }\n\n return paragraph.create(null, text ? editor.schema.text(text) : undefined);\n}\n\nfunction getRevertTransaction(\n tr: Transaction,\n editor: Editor,\n storage: AiExtensionStorage,\n doc?: Doc\n): Transaction | null {\n if (storage.snapshot) {\n const binding = getYjsBinding(editor);\n\n if (binding) {\n binding.mapping.clear();\n\n const docFromSnapshot = createDocFromSnapshot(\n binding.doc,\n storage.snapshot\n );\n const type = docFromSnapshot.getXmlFragment(\"default\"); // TODO: field\n const fragmentContent = yXmlFragmentToProseMirrorFragment(\n type,\n editor.state.schema\n );\n\n tr.setMeta(\"addToHistory\", false);\n tr.replace(\n 0,\n editor.state.doc.content.size,\n new Slice(Fragment.from(fragmentContent), 0, 0)\n );\n tr.setMeta(ySyncPluginKey, {\n snapshot: null,\n prevSnapshot: null,\n });\n\n if (doc) {\n doc.gc = true;\n }\n\n storage.snapshot = undefined;\n\n return tr;\n }\n }\n return null;\n}\n\nexport const AiExtension = Extension.create<\n AiExtensionOptions,\n AiExtensionStorage\n>({\n name: \"liveblocksAi\",\n addOptions() {\n return {\n doc: undefined,\n pud: undefined,\n\n // The actual default resolver is set in LiveblocksExtension via AiExtension.configure()\n resolveContextualPrompt: () => Promise.reject(),\n name: DEFAULT_AI_NAME,\n };\n },\n addStorage() {\n return {\n state: DEFAULT_STATE,\n name: this.options.name,\n };\n },\n addCommands() {\n return {\n askAi: (prompt) => () => {\n if (typeof prompt === \"string\") {\n (\n this.editor.commands as unknown as AiCommands\n ).$startAiToolbarThinking(prompt);\n } else {\n (\n this.editor.commands as unknown as AiCommands\n ).$openAiToolbarAsking();\n }\n\n return true;\n },\n\n $acceptAiToolbarResponse:\n () =>\n ({ tr, view }: CommandProps) => {\n const currentState = this.storage.state;\n\n // 1. If NOT in \"reviewing\" phase, do nothing\n if (currentState.phase !== \"reviewing\") {\n return false;\n }\n\n // 2. Accept the response\n if (isContextualPromptDiffResponse(currentState.response)) {\n // 2.a. If the response is a diff, apply it definitely\n const binding = getYjsBinding(this.editor);\n if (!binding) {\n return false;\n }\n\n const fragmentContent = yXmlFragmentToProseMirrorFragment(\n binding.type,\n this.editor.state.schema\n );\n tr.setMeta(\"addToHistory\", false);\n tr.replace(\n 0,\n this.editor.state.doc.content.size,\n new Slice(Fragment.from(fragmentContent), 0, 0)\n );\n tr.setMeta(ySyncPluginKey, {\n snapshot: null,\n prevSnapshot: null,\n });\n\n this.storage.snapshot = undefined;\n } else {\n // 2.b. If the response is not a diff, insert it below the selection\n\n const paragraphs = currentState.response.text\n .split(\"\\n\")\n .map((paragraph) => createParagraph(this.editor, paragraph));\n\n tr.insert(this.editor.state.selection.$to.end(), paragraphs);\n tr.setMeta(\"addToHistory\", true);\n view.dispatch(tr);\n // Prevent TipTap from dispatching this transaction, because we already did (this is a hack)\n tr.setMeta(\"preventDispatch\", true);\n }\n\n // 3. Unblock the editor\n getLiveblocksYjsProvider(this.editor)?.unpause();\n this.editor.setEditable(true);\n\n // 4. Set to \"closed\" phase\n this.storage.state = { phase: \"closed\" };\n\n return true;\n },\n\n $closeAiToolbar:\n () =>\n ({ tr, view }: CommandProps) => {\n const currentState = this.storage.state;\n\n // 1. If already in \"closed\" phase, do nothing\n if (currentState.phase === \"closed\") {\n return false;\n }\n\n // 2. If in \"thinking\" phase, cancel the current AI request\n if (currentState.phase === \"thinking\") {\n currentState.abortController.abort();\n }\n\n // 3. If in \"thinking\" or \"reviewing\" phase, revert the editor if possible and unblock it\n if (\n currentState.phase === \"thinking\" ||\n currentState.phase === \"reviewing\"\n ) {\n // Get the revert transaction and dispatch it\n const revertTr = getRevertTransaction(\n tr,\n this.editor,\n this.storage,\n this.options.doc\n );\n if (revertTr) {\n view.dispatch(revertTr);\n // Prevent TipTap from dispatching this transaction, because we already did (this is a hack)\n tr.setMeta(\"preventDispatch\", true);\n }\n }\n\n // 4. Restore the initial selection\n this.editor.commands.setTextSelection(currentState.initialSelection);\n\n // 5. Unblock the editor\n getLiveblocksYjsProvider(this.editor)?.unpause();\n this.editor.setEditable(true);\n\n // 6. Set to \"closed\" phase\n this.storage.state = { phase: \"closed\" };\n\n return true;\n },\n\n $openAiToolbarAsking: () => () => {\n const currentState = this.storage.state;\n\n // 1. If NOT in \"closed\" phase, do nothing\n if (currentState.phase !== \"closed\") {\n return false;\n }\n\n // 2. Blur the editor if needed\n if (this.editor.isFocused) {\n this.editor.commands.blur();\n }\n\n // 3. Set to \"asking\" phase\n this.storage.state = {\n phase: \"asking\",\n // Store the initial selection\n initialSelection: {\n from: this.editor.state.selection.from,\n to: this.editor.state.selection.to,\n },\n // Initialize the custom prompt as empty\n customPrompt: \"\",\n };\n\n return true;\n },\n\n $startAiToolbarThinking:\n (prompt: string, withPreviousResponse?: boolean) =>\n ({ tr, view }: CommandProps) => {\n const currentState = this.storage.state;\n\n // 1. If in \"thinking\" phase already, do nothing\n if (currentState.phase === \"thinking\") {\n return false;\n }\n\n // 2. Blur the editor if needed\n if (this.editor.isFocused) {\n this.editor.commands.blur();\n }\n\n const abortController = new AbortController();\n const provider = getLiveblocksYjsProvider(this.editor);\n\n // 3. If this is a retry or a refinement, revert the editor and restore the initial selection\n if (currentState.phase === \"reviewing\") {\n // 3.a. Revert the editor\n const revertTr = getRevertTransaction(\n tr,\n this.editor,\n this.storage,\n this.options.doc\n );\n if (revertTr) {\n // Important: in this scenario we do not unpause the provider\n view.dispatch(revertTr);\n // Prevent Tiptap from dispatching this transaction, because we already did (this is a hack)\n tr.setMeta(\"preventDispatch\", true);\n }\n\n // 3.b. Restore the initial selection\n this.editor.commands.setTextSelection(\n currentState.initialSelection\n );\n }\n\n // 4. Set to \"thinking\" phase\n this.storage.state = {\n phase: \"thinking\",\n // Store the initial selection if the toolbar is opened directly in the \"thinking\" phase\n initialSelection: currentState.initialSelection ?? {\n from: this.editor.state.selection.from,\n to: this.editor.state.selection.to,\n },\n // Initialize the custom prompt as empty if the toolbar is opened directly in the \"thinking\" phase\n customPrompt: currentState.customPrompt ?? \"\",\n prompt,\n abortController,\n previousResponse: currentState.response,\n };\n\n // 5. Block the editor\n this.editor.setEditable(false);\n\n // 6. Start the AI request\n autoRetry(\n async () => {\n await provider?.pause();\n\n // 6.a. Resolve the AI prompt\n const response = (await this.options.resolveContextualPrompt({\n prompt,\n context: getContextualPromptContext(this.editor, 3_000),\n signal: abortController.signal,\n previous:\n withPreviousResponse && currentState.phase === \"reviewing\"\n ? {\n prompt: currentState.prompt,\n response: {\n type: currentState.response?.type,\n text: currentState.response?.text,\n },\n }\n : undefined,\n })) as unknown;\n\n // 6.b. Validate the response\n if (isResolveContextualPromptResponse(response)) {\n return response;\n } else {\n throw new Error(\"Failed to resolve AI prompt.\");\n }\n },\n RESOLVE_AI_PROMPT_RETRY_ATTEMPTS,\n RESOLVE_AI_PROMPT_RETRY_DELAYS,\n\n (error) => {\n // Don't retry on 4xx errors or if the request was aborted\n return (\n abortController.signal.aborted ||\n (error instanceof HttpError &&\n error.status >= 400 &&\n error.status < 500)\n );\n }\n )\n .then((response) => {\n if (abortController.signal.aborted) {\n return;\n }\n\n // 6.a. If the AI request succeeds, set to \"reviewing\" phase with the response\n (\n this.editor.commands as unknown as AiCommands\n )._handleAiToolbarThinkingSuccess({\n type: response.type,\n text: response.text,\n });\n })\n .catch((error) => {\n if (abortController.signal.aborted) {\n return;\n }\n\n // 6.b. If the AI request fails, set to \"asking\" phase with error\n (\n this.editor.commands as unknown as AiCommands\n )._handleAiToolbarThinkingError(error);\n });\n\n return true;\n },\n\n $cancelAiToolbarThinking: () => () => {\n const currentState = this.storage.state;\n\n // 1. If NOT in \"thinking\" phase, do nothing\n if (currentState.phase !== \"thinking\") {\n return false;\n }\n\n // 2. Cancel the current AI request\n currentState.abortController.abort();\n\n // 3. Unblock the editor\n this.editor.setEditable(true);\n\n // 4. Set to \"asking\" phase\n this.storage.state = {\n phase: \"asking\",\n initialSelection: currentState.initialSelection,\n // If the custom prompt is different than the prompt, reset it\n customPrompt:\n currentState.prompt === currentState.customPrompt\n ? currentState.customPrompt\n : \"\",\n };\n\n return true;\n },\n\n _showAiToolbarReviewingDiff: () => () => {\n // The diff is applied right before moving to the \"reviewing\" phase\n if (this.storage.state.phase !== \"reviewing\") {\n return false;\n }\n\n if (!this.options.doc || !this.storage.snapshot) {\n return false;\n }\n\n const previousSnapshot: Snapshot =\n this.storage.snapshot ?? emptySnapshot;\n const currentSnapshot = takeSnapshot(this.options.doc);\n\n if (equalSnapshots(previousSnapshot, currentSnapshot)) {\n return true;\n }\n\n getYjsBinding(this.editor)?.renderSnapshot(\n currentSnapshot,\n previousSnapshot\n );\n\n return true;\n },\n\n _handleAiToolbarThinkingSuccess:\n (response: ContextualPromptResponse) =>\n ({ view, tr }: CommandProps) => {\n const currentState = this.storage.state;\n\n // 1. If NOT in \"thinking\" phase, do nothing\n if (currentState.phase !== \"thinking\") {\n return false;\n }\n\n // 2. If this is not a diff, the response will just be in the toolbar, set to \"reviewing\" phase directly with the response\n if (!isContextualPromptDiffResponse(response)) {\n this.storage.state = {\n phase: \"reviewing\",\n initialSelection: currentState.initialSelection,\n customPrompt: \"\",\n prompt: currentState.prompt,\n response,\n };\n\n return true;\n }\n\n if (!this.options.doc) {\n return false;\n }\n\n // 3. Otherwise, the response is a diff, apply it to the editor\n this.options.doc.gc = false;\n this.storage.snapshot = takeSnapshot(this.options.doc);\n\n // 4. Set to \"reviewing\" phase with the new range\n this.storage.state = {\n phase: \"reviewing\",\n initialSelection: currentState.initialSelection,\n customPrompt: \"\",\n prompt: currentState.prompt,\n response,\n };\n\n // 5. Insert the response's text as inline first (and replace the selection if it's a replace) then as block if there are multiple paragraphs\n const [firstParagraph, ...otherParagraphs] =\n response.text.split(\"\\n\");\n\n tr.insertText(\n firstParagraph,\n response.type === \"insert\"\n ? this.editor.state.selection.to\n : this.editor.state.selection.from,\n this.editor.state.selection.to\n );\n\n if (otherParagraphs.length > 0) {\n const paragraphs = otherParagraphs.map((paragraph) =>\n createParagraph(this.editor, paragraph)\n );\n\n tr.insert(tr.selection.$to.pos, paragraphs);\n }\n\n view.dispatch(tr);\n // Prevent Tiptap from dispatching this transaction, because we already did (this is a hack)\n tr.setMeta(\"preventDispatch\", true);\n\n // 6. Show the diff\n (\n this.editor.commands as unknown as AiCommands\n )._showAiToolbarReviewingDiff();\n\n // We moved to the \"reviewing\" phase, so even if `_showAiToolbarReviewingDiff`\n // returns `false` somehow, we still want to return `true`\n return true;\n },\n\n _handleAiToolbarThinkingError: (error: unknown) => () => {\n const currentState = this.storage.state;\n\n // 1. If NOT in \"thinking\" phase, do nothing\n if (currentState.phase !== \"thinking\") {\n return false;\n }\n\n // 2. Unblock the editor\n this.editor.setEditable(true);\n\n // 3. Log the error\n console.error(error);\n\n // 4. Set to \"asking\" phase with error\n this.storage.state = {\n phase: \"asking\",\n initialSelection: currentState.initialSelection,\n // If the custom prompt is different than the prompt, reset it\n customPrompt:\n currentState.prompt === currentState.customPrompt\n ? currentState.customPrompt\n : \"\",\n // Pass the error so it can be displayed\n error:\n error instanceof Error\n ? error\n : new Error(String(error), { cause: error }),\n };\n\n return true;\n },\n\n _updateAiToolbarCustomPrompt:\n (customPrompt: string | ((currentCustomPrompt: string) => string)) =>\n () => {\n const currentState = this.storage.state;\n\n // 1. If NOT in a phase with a custom prompt, do nothing\n if (typeof currentState.customPrompt !== \"string\") {\n return false;\n }\n\n // 2. Update the custom prompt\n this.storage.state.customPrompt =\n typeof customPrompt === \"function\"\n ? customPrompt(currentState.customPrompt)\n : customPrompt;\n\n return true;\n },\n };\n },\n addProseMirrorPlugins() {\n return [\n new Plugin({\n key: AI_TOOLBAR_SELECTION_PLUGIN,\n props: {\n decorations: ({ doc, selection }) => {\n // Don't show the AI toolbar selection if the toolbar is closed or when reviewing diff responses\n if (\n this.storage.state.phase === \"closed\" ||\n (this.storage.state.phase === \"reviewing\" &&\n isContextualPromptDiffResponse(this.storage.state.response))\n ) {\n return DecorationSet.create(doc, []);\n }\n\n const { from, to } = selection;\n const decorations: Decoration[] = [\n Decoration.inline(from, to, {\n class: \"lb-root lb-selection lb-tiptap-active-selection\",\n }),\n ];\n\n return DecorationSet.create(doc, decorations);\n },\n },\n }),\n ];\n },\n});\n"],"names":["ySyncPluginKey","createDocFromSnapshot","yXmlFragmentToProseMirrorFragment","Slice","Fragment","Extension","autoRetry","getContextualPromptContext","HttpError","emptySnapshot","takeSnapshot","equalSnapshots","Plugin","AI_TOOLBAR_SELECTION_PLUGIN","DecorationSet","Decoration"],"mappings":"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"}
1
+ {"version":3,"file":"AiExtension.js","sources":["../../src/ai/AiExtension.ts"],"sourcesContent":["import {\n autoRetry,\n type ContextualPromptResponse,\n HttpError,\n} from \"@liveblocks/core\";\nimport type { LiveblocksYjsProvider } from \"@liveblocks/yjs\";\nimport type { CommandProps, Editor } from \"@tiptap/core\";\nimport { Extension } from \"@tiptap/core\";\nimport { Fragment, Slice } from \"@tiptap/pm/model\";\nimport type { Transaction } from \"@tiptap/pm/state\";\nimport { Plugin } from \"@tiptap/pm/state\";\nimport { Decoration, DecorationSet } from \"@tiptap/pm/view\";\nimport {\n ySyncPluginKey,\n yXmlFragmentToProseMirrorFragment,\n} from \"y-prosemirror\";\nimport type { Doc, Snapshot } from \"yjs\";\nimport {\n createDocFromSnapshot,\n emptySnapshot,\n equalSnapshots,\n snapshot as takeSnapshot,\n} from \"yjs\";\n\nimport {\n AI_TOOLBAR_SELECTION_PLUGIN,\n type AiCommands,\n type AiExtensionOptions,\n type AiExtensionStorage,\n type AiToolbarState,\n type LiveblocksExtensionStorage,\n type ResolveContextualPromptResponse,\n type YSyncPluginState,\n} from \"../types\";\nimport { getContextualPromptContext } from \"../utils\";\n\nconst DEFAULT_AI_NAME = \"AI\";\nexport const DEFAULT_STATE: AiToolbarState = { phase: \"closed\" };\n\nconst RESOLVE_AI_PROMPT_RETRY_ATTEMPTS = 3;\nconst RESOLVE_AI_PROMPT_RETRY_DELAYS = [1000, 2000, 4000];\n\nfunction getYjsBinding(editor: Editor) {\n return (ySyncPluginKey.getState(editor.view.state) as YSyncPluginState)\n .binding;\n}\n\nfunction getLiveblocksYjsProvider(editor: Editor) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n return (\n editor.extensionStorage.liveblocksExtension as\n | LiveblocksExtensionStorage\n | undefined\n )?.provider as LiveblocksYjsProvider | undefined;\n}\n\nexport function isContextualPromptDiffResponse(\n response: ContextualPromptResponse\n): response is Extract<\n ContextualPromptResponse,\n { type: \"replace\" | \"insert\" }\n> {\n return response.type === \"replace\" || response.type === \"insert\";\n}\n\nfunction isResolveContextualPromptResponse(\n response: unknown\n): response is ResolveContextualPromptResponse {\n return (\n typeof response === \"object\" &&\n response !== null &&\n typeof (response as { text: unknown }).text === \"string\" &&\n typeof (response as { type: unknown }).type === \"string\" &&\n [\"insert\", \"replace\", \"other\"].includes((response as { type: string }).type)\n );\n}\n\nfunction createParagraph(editor: Editor, text: string) {\n const paragraph =\n editor.schema.nodes.paragraph ??\n Object.values(editor.schema.nodes).find((node) => node.isBlock);\n\n if (!paragraph) {\n throw new Error(\"Could not create a paragraph.\");\n }\n\n return paragraph.create(null, text ? editor.schema.text(text) : undefined);\n}\n\nfunction getRevertTransaction(\n tr: Transaction,\n editor: Editor,\n storage: AiExtensionStorage,\n doc?: Doc\n): Transaction | null {\n if (storage.snapshot) {\n const binding = getYjsBinding(editor);\n\n if (binding) {\n binding.mapping.clear();\n\n const docFromSnapshot = createDocFromSnapshot(\n binding.doc,\n storage.snapshot\n );\n const type = docFromSnapshot.getXmlFragment(\"default\"); // TODO: field\n const fragmentContent = yXmlFragmentToProseMirrorFragment(\n type,\n editor.state.schema\n );\n\n tr.setMeta(\"addToHistory\", false);\n tr.replace(\n 0,\n editor.state.doc.content.size,\n new Slice(Fragment.from(fragmentContent), 0, 0)\n );\n tr.setMeta(ySyncPluginKey, {\n snapshot: null,\n prevSnapshot: null,\n });\n\n if (doc) {\n doc.gc = true;\n }\n\n storage.snapshot = undefined;\n\n return tr;\n }\n }\n return null;\n}\n\nexport const AiExtension = Extension.create<\n AiExtensionOptions,\n AiExtensionStorage\n>({\n name: \"liveblocksAi\",\n addOptions() {\n return {\n doc: undefined,\n pud: undefined,\n\n // The actual default resolver is set in LiveblocksExtension via AiExtension.configure()\n resolveContextualPrompt: () => Promise.reject(),\n name: DEFAULT_AI_NAME,\n };\n },\n addStorage() {\n return {\n state: DEFAULT_STATE,\n name: this.options.name,\n };\n },\n addCommands() {\n return {\n askAi: (prompt) => () => {\n if (typeof prompt === \"string\") {\n (\n this.editor.commands as unknown as AiCommands\n ).$startAiToolbarThinking(prompt);\n } else {\n (\n this.editor.commands as unknown as AiCommands\n ).$openAiToolbarAsking();\n }\n\n return true;\n },\n\n $acceptAiToolbarResponse:\n () =>\n ({ tr, view }: CommandProps) => {\n const currentState = this.storage.state;\n\n // 1. If NOT in \"reviewing\" phase, do nothing\n if (currentState.phase !== \"reviewing\") {\n return false;\n }\n\n // 2. Accept the response\n if (isContextualPromptDiffResponse(currentState.response)) {\n // 2.a. If the response is a diff, apply it definitely\n const binding = getYjsBinding(this.editor);\n if (!binding) {\n return false;\n }\n\n const fragmentContent = yXmlFragmentToProseMirrorFragment(\n binding.type,\n this.editor.state.schema\n );\n tr.setMeta(\"addToHistory\", false);\n tr.replace(\n 0,\n this.editor.state.doc.content.size,\n new Slice(Fragment.from(fragmentContent), 0, 0)\n );\n tr.setMeta(ySyncPluginKey, {\n snapshot: null,\n prevSnapshot: null,\n });\n\n this.storage.snapshot = undefined;\n } else {\n // 2.b. If the response is not a diff, insert it below the selection\n\n const paragraphs = currentState.response.text\n .split(\"\\n\")\n .map((paragraph) => createParagraph(this.editor, paragraph));\n\n tr.insert(this.editor.state.selection.$to.end(), paragraphs);\n tr.setMeta(\"addToHistory\", true);\n view.dispatch(tr);\n // Prevent TipTap from dispatching this transaction, because we already did (this is a hack)\n tr.setMeta(\"preventDispatch\", true);\n }\n\n // 3. Unblock the editor\n getLiveblocksYjsProvider(this.editor)?.unpause();\n this.editor.setEditable(true);\n\n // 4. Set to \"closed\" phase\n this.storage.state = { phase: \"closed\" };\n\n return true;\n },\n\n $closeAiToolbar:\n () =>\n ({ tr, view }: CommandProps) => {\n const currentState = this.storage.state;\n\n // 1. If already in \"closed\" phase, do nothing\n if (currentState.phase === \"closed\") {\n return false;\n }\n\n // 2. If in \"thinking\" phase, cancel the current AI request\n if (currentState.phase === \"thinking\") {\n currentState.abortController.abort();\n }\n\n // 3. If in \"thinking\" or \"reviewing\" phase, revert the editor if possible and unblock it\n if (\n currentState.phase === \"thinking\" ||\n currentState.phase === \"reviewing\"\n ) {\n // Get the revert transaction and dispatch it\n const revertTr = getRevertTransaction(\n tr,\n this.editor,\n this.storage,\n this.options.doc\n );\n if (revertTr) {\n view.dispatch(revertTr);\n // Prevent TipTap from dispatching this transaction, because we already did (this is a hack)\n tr.setMeta(\"preventDispatch\", true);\n }\n }\n\n // 4. Restore the initial selection\n this.editor.commands.setTextSelection(currentState.initialSelection);\n\n // 5. Unblock the editor\n getLiveblocksYjsProvider(this.editor)?.unpause();\n this.editor.setEditable(true);\n\n // 6. Set to \"closed\" phase\n this.storage.state = { phase: \"closed\" };\n\n return true;\n },\n\n $openAiToolbarAsking: () => () => {\n const currentState = this.storage.state;\n\n // 1. If NOT in \"closed\" phase, do nothing\n if (currentState.phase !== \"closed\") {\n return false;\n }\n\n // 2. Blur the editor if needed\n if (this.editor.isFocused) {\n this.editor.commands.blur();\n }\n\n // 3. Set to \"asking\" phase\n this.storage.state = {\n phase: \"asking\",\n // Store the initial selection\n initialSelection: {\n from: this.editor.state.selection.from,\n to: this.editor.state.selection.to,\n },\n // Initialize the custom prompt as empty\n customPrompt: \"\",\n };\n\n return true;\n },\n\n $startAiToolbarThinking:\n (prompt: string, withPreviousResponse?: boolean) =>\n ({ tr, view }: CommandProps) => {\n const currentState = this.storage.state;\n\n // 1. If in \"thinking\" phase already, do nothing\n if (currentState.phase === \"thinking\") {\n return false;\n }\n\n // 2. Blur the editor if needed\n if (this.editor.isFocused) {\n this.editor.commands.blur();\n }\n\n const abortController = new AbortController();\n const provider = getLiveblocksYjsProvider(this.editor);\n\n // 3. If this is a retry or a refinement, revert the editor and restore the initial selection\n if (currentState.phase === \"reviewing\") {\n // 3.a. Revert the editor\n const revertTr = getRevertTransaction(\n tr,\n this.editor,\n this.storage,\n this.options.doc\n );\n if (revertTr) {\n // Important: in this scenario we do not unpause the provider\n view.dispatch(revertTr);\n // Prevent Tiptap from dispatching this transaction, because we already did (this is a hack)\n tr.setMeta(\"preventDispatch\", true);\n }\n\n // 3.b. Restore the initial selection\n this.editor.commands.setTextSelection(\n currentState.initialSelection\n );\n }\n\n // 4. Set to \"thinking\" phase\n this.storage.state = {\n phase: \"thinking\",\n // Store the initial selection if the toolbar is opened directly in the \"thinking\" phase\n initialSelection: currentState.initialSelection ?? {\n from: this.editor.state.selection.from,\n to: this.editor.state.selection.to,\n },\n // Initialize the custom prompt as empty if the toolbar is opened directly in the \"thinking\" phase\n customPrompt: currentState.customPrompt ?? \"\",\n prompt,\n abortController,\n previousResponse: currentState.response,\n };\n\n // 5. Block the editor\n this.editor.setEditable(false);\n\n // 6. Start the AI request\n autoRetry(\n async () => {\n await provider?.pause();\n\n // 6.a. Resolve the AI prompt\n const response = (await this.options.resolveContextualPrompt({\n prompt,\n context: getContextualPromptContext(this.editor, 3_000),\n signal: abortController.signal,\n previous:\n withPreviousResponse && currentState.phase === \"reviewing\"\n ? {\n prompt: currentState.prompt,\n response: {\n type: currentState.response?.type,\n text: currentState.response?.text,\n },\n }\n : undefined,\n })) as unknown;\n\n // 6.b. Validate the response\n if (isResolveContextualPromptResponse(response)) {\n return response;\n } else {\n throw new Error(\"Failed to resolve AI prompt.\");\n }\n },\n RESOLVE_AI_PROMPT_RETRY_ATTEMPTS,\n RESOLVE_AI_PROMPT_RETRY_DELAYS,\n\n (error) => {\n // Don't retry on 4xx errors or if the request was aborted\n return (\n abortController.signal.aborted ||\n (error instanceof HttpError &&\n error.status >= 400 &&\n error.status < 500)\n );\n }\n )\n .then((response) => {\n if (abortController.signal.aborted) {\n return;\n }\n\n // 6.a. If the AI request succeeds, set to \"reviewing\" phase with the response\n (\n this.editor.commands as unknown as AiCommands\n )._handleAiToolbarThinkingSuccess({\n type: response.type,\n text: response.text,\n });\n })\n .catch((error) => {\n if (abortController.signal.aborted) {\n return;\n }\n\n // 6.b. If the AI request fails, set to \"asking\" phase with error\n (\n this.editor.commands as unknown as AiCommands\n )._handleAiToolbarThinkingError(error);\n });\n\n return true;\n },\n\n $cancelAiToolbarThinking: () => () => {\n const currentState = this.storage.state;\n\n // 1. If NOT in \"thinking\" phase, do nothing\n if (currentState.phase !== \"thinking\") {\n return false;\n }\n\n // 2. Cancel the current AI request\n currentState.abortController.abort();\n\n // 3. Unblock the editor\n this.editor.setEditable(true);\n\n // 4. Set to \"asking\" phase\n this.storage.state = {\n phase: \"asking\",\n initialSelection: currentState.initialSelection,\n // If the custom prompt is different than the prompt, reset it\n customPrompt:\n currentState.prompt === currentState.customPrompt\n ? currentState.customPrompt\n : \"\",\n };\n\n return true;\n },\n\n _showAiToolbarReviewingDiff: () => () => {\n // The diff is applied right before moving to the \"reviewing\" phase\n if (this.storage.state.phase !== \"reviewing\") {\n return false;\n }\n\n if (!this.options.doc || !this.storage.snapshot) {\n return false;\n }\n\n const previousSnapshot: Snapshot =\n this.storage.snapshot ?? emptySnapshot;\n const currentSnapshot = takeSnapshot(this.options.doc);\n\n if (equalSnapshots(previousSnapshot, currentSnapshot)) {\n return true;\n }\n\n getYjsBinding(this.editor)?.renderSnapshot(\n currentSnapshot,\n previousSnapshot\n );\n\n return true;\n },\n\n _handleAiToolbarThinkingSuccess:\n (response: ContextualPromptResponse) =>\n ({ view, tr }: CommandProps) => {\n const currentState = this.storage.state;\n\n // 1. If NOT in \"thinking\" phase, do nothing\n if (currentState.phase !== \"thinking\") {\n return false;\n }\n\n // 2. If this is not a diff, the response will just be in the toolbar, set to \"reviewing\" phase directly with the response\n if (!isContextualPromptDiffResponse(response)) {\n this.storage.state = {\n phase: \"reviewing\",\n initialSelection: currentState.initialSelection,\n customPrompt: \"\",\n prompt: currentState.prompt,\n response,\n };\n\n return true;\n }\n\n if (!this.options.doc) {\n return false;\n }\n\n // 3. Otherwise, the response is a diff, apply it to the editor\n this.options.doc.gc = false;\n this.storage.snapshot = takeSnapshot(this.options.doc);\n\n // 4. Set to \"reviewing\" phase with the new range\n this.storage.state = {\n phase: \"reviewing\",\n initialSelection: currentState.initialSelection,\n customPrompt: \"\",\n prompt: currentState.prompt,\n response,\n };\n\n // 5. Insert the response's text as inline first (and replace the selection if it's a replace) then as block if there are multiple paragraphs\n const [firstParagraph, ...otherParagraphs] =\n response.text.split(\"\\n\");\n\n tr.insertText(\n firstParagraph,\n response.type === \"insert\"\n ? this.editor.state.selection.to\n : this.editor.state.selection.from,\n this.editor.state.selection.to\n );\n\n if (otherParagraphs.length > 0) {\n const paragraphs = otherParagraphs.map((paragraph) =>\n createParagraph(this.editor, paragraph)\n );\n\n tr.insert(tr.selection.$to.pos, paragraphs);\n }\n\n view.dispatch(tr);\n // Prevent Tiptap from dispatching this transaction, because we already did (this is a hack)\n tr.setMeta(\"preventDispatch\", true);\n\n // 6. Show the diff\n (\n this.editor.commands as unknown as AiCommands\n )._showAiToolbarReviewingDiff();\n\n // We moved to the \"reviewing\" phase, so even if `_showAiToolbarReviewingDiff`\n // returns `false` somehow, we still want to return `true`\n return true;\n },\n\n _handleAiToolbarThinkingError: (error: unknown) => () => {\n const currentState = this.storage.state;\n\n // 1. If NOT in \"thinking\" phase, do nothing\n if (currentState.phase !== \"thinking\") {\n return false;\n }\n\n // 2. Unblock the editor\n this.editor.setEditable(true);\n\n // 3. Log the error\n console.error(error);\n\n // 4. Set to \"asking\" phase with error\n this.storage.state = {\n phase: \"asking\",\n initialSelection: currentState.initialSelection,\n // If the custom prompt is different than the prompt, reset it\n customPrompt:\n currentState.prompt === currentState.customPrompt\n ? currentState.customPrompt\n : \"\",\n // Pass the error so it can be displayed\n error:\n error instanceof Error\n ? error\n : new Error(String(error), { cause: error }),\n };\n\n return true;\n },\n\n _updateAiToolbarCustomPrompt:\n (customPrompt: string | ((currentCustomPrompt: string) => string)) =>\n () => {\n const currentState = this.storage.state;\n\n // 1. If NOT in a phase with a custom prompt, do nothing\n if (typeof currentState.customPrompt !== \"string\") {\n return false;\n }\n\n // 2. Update the custom prompt\n this.storage.state.customPrompt =\n typeof customPrompt === \"function\"\n ? customPrompt(currentState.customPrompt)\n : customPrompt;\n\n return true;\n },\n };\n },\n addProseMirrorPlugins() {\n return [\n new Plugin({\n key: AI_TOOLBAR_SELECTION_PLUGIN,\n props: {\n decorations: ({ doc, selection }) => {\n // Don't show the AI toolbar selection if the toolbar is closed or when reviewing diff responses\n if (\n this.storage.state.phase === \"closed\" ||\n (this.storage.state.phase === \"reviewing\" &&\n isContextualPromptDiffResponse(this.storage.state.response))\n ) {\n return DecorationSet.create(doc, []);\n }\n\n const { from, to } = selection;\n const decorations: Decoration[] = [\n Decoration.inline(from, to, {\n class: \"lb-root lb-selection lb-tiptap-active-selection\",\n }),\n ];\n\n return DecorationSet.create(doc, decorations);\n },\n },\n }),\n ];\n },\n});\n"],"names":["takeSnapshot"],"mappings":";;;;;;;;;;AAoCA,MAAM,eAAkB,GAAA,IAAA,CAAA;AACX,MAAA,aAAA,GAAgC,EAAE,KAAA,EAAO,QAAS,GAAA;AAE/D,MAAM,gCAAmC,GAAA,CAAA,CAAA;AACzC,MAAM,8BAAiC,GAAA,CAAC,GAAM,EAAA,GAAA,EAAM,GAAI,CAAA,CAAA;AAExD,SAAS,cAAc,MAAgB,EAAA;AACrC,EAAA,OAAQ,cAAe,CAAA,QAAA,CAAS,MAAO,CAAA,IAAA,CAAK,KAAK,CAC9C,CAAA,OAAA,CAAA;AACL,CAAA;AAEA,SAAS,yBAAyB,MAAgB,EAAA;AAEhD,EACE,OAAA,MAAA,CAAO,iBAAiB,mBAGvB,EAAA,QAAA,CAAA;AACL,CAAA;AAEO,SAAS,+BACd,QAIA,EAAA;AACA,EAAA,OAAO,QAAS,CAAA,IAAA,KAAS,SAAa,IAAA,QAAA,CAAS,IAAS,KAAA,QAAA,CAAA;AAC1D,CAAA;AAEA,SAAS,kCACP,QAC6C,EAAA;AAC7C,EACE,OAAA,OAAO,aAAa,QACpB,IAAA,QAAA,KAAa,QACb,OAAQ,QAAA,CAA+B,SAAS,QAChD,IAAA,OAAQ,SAA+B,IAAS,KAAA,QAAA,IAChD,CAAC,QAAU,EAAA,SAAA,EAAW,OAAO,CAAE,CAAA,QAAA,CAAU,SAA8B,IAAI,CAAA,CAAA;AAE/E,CAAA;AAEA,SAAS,eAAA,CAAgB,QAAgB,IAAc,EAAA;AACrD,EAAA,MAAM,SACJ,GAAA,MAAA,CAAO,MAAO,CAAA,KAAA,CAAM,aACpB,MAAO,CAAA,MAAA,CAAO,MAAO,CAAA,MAAA,CAAO,KAAK,CAAE,CAAA,IAAA,CAAK,CAAC,IAAA,KAAS,KAAK,OAAO,CAAA,CAAA;AAEhE,EAAA,IAAI,CAAC,SAAW,EAAA;AACd,IAAM,MAAA,IAAI,MAAM,+BAA+B,CAAA,CAAA;AAAA,GACjD;AAEA,EAAO,OAAA,SAAA,CAAU,OAAO,IAAM,EAAA,IAAA,GAAO,OAAO,MAAO,CAAA,IAAA,CAAK,IAAI,CAAA,GAAI,KAAS,CAAA,CAAA,CAAA;AAC3E,CAAA;AAEA,SAAS,oBACP,CAAA,EAAA,EACA,MACA,EAAA,OAAA,EACA,GACoB,EAAA;AACpB,EAAA,IAAI,QAAQ,QAAU,EAAA;AACpB,IAAM,MAAA,OAAA,GAAU,cAAc,MAAM,CAAA,CAAA;AAEpC,IAAA,IAAI,OAAS,EAAA;AACX,MAAA,OAAA,CAAQ,QAAQ,KAAM,EAAA,CAAA;AAEtB,MAAA,MAAM,eAAkB,GAAA,qBAAA;AAAA,QACtB,OAAQ,CAAA,GAAA;AAAA,QACR,OAAQ,CAAA,QAAA;AAAA,OACV,CAAA;AACA,MAAM,MAAA,IAAA,GAAO,eAAgB,CAAA,cAAA,CAAe,SAAS,CAAA,CAAA;AACrD,MAAA,MAAM,eAAkB,GAAA,iCAAA;AAAA,QACtB,IAAA;AAAA,QACA,OAAO,KAAM,CAAA,MAAA;AAAA,OACf,CAAA;AAEA,MAAG,EAAA,CAAA,OAAA,CAAQ,gBAAgB,KAAK,CAAA,CAAA;AAChC,MAAG,EAAA,CAAA,OAAA;AAAA,QACD,CAAA;AAAA,QACA,MAAA,CAAO,KAAM,CAAA,GAAA,CAAI,OAAQ,CAAA,IAAA;AAAA,QACzB,IAAI,KAAM,CAAA,QAAA,CAAS,KAAK,eAAe,CAAA,EAAG,GAAG,CAAC,CAAA;AAAA,OAChD,CAAA;AACA,MAAA,EAAA,CAAG,QAAQ,cAAgB,EAAA;AAAA,QACzB,QAAU,EAAA,IAAA;AAAA,QACV,YAAc,EAAA,IAAA;AAAA,OACf,CAAA,CAAA;AAED,MAAA,IAAI,GAAK,EAAA;AACP,QAAA,GAAA,CAAI,EAAK,GAAA,IAAA,CAAA;AAAA,OACX;AAEA,MAAA,OAAA,CAAQ,QAAW,GAAA,KAAA,CAAA,CAAA;AAEnB,MAAO,OAAA,EAAA,CAAA;AAAA,KACT;AAAA,GACF;AACA,EAAO,OAAA,IAAA,CAAA;AACT,CAAA;AAEa,MAAA,WAAA,GAAc,UAAU,MAGnC,CAAA;AAAA,EACA,IAAM,EAAA,cAAA;AAAA,EACN,UAAa,GAAA;AACX,IAAO,OAAA;AAAA,MACL,GAAK,EAAA,KAAA,CAAA;AAAA,MACL,GAAK,EAAA,KAAA,CAAA;AAAA,MAGL,uBAAA,EAAyB,MAAM,OAAA,CAAQ,MAAO,EAAA;AAAA,MAC9C,IAAM,EAAA,eAAA;AAAA,KACR,CAAA;AAAA,GACF;AAAA,EACA,UAAa,GAAA;AACX,IAAO,OAAA;AAAA,MACL,KAAO,EAAA,aAAA;AAAA,MACP,IAAA,EAAM,KAAK,OAAQ,CAAA,IAAA;AAAA,KACrB,CAAA;AAAA,GACF;AAAA,EACA,WAAc,GAAA;AACZ,IAAO,OAAA;AAAA,MACL,KAAA,EAAO,CAAC,MAAA,KAAW,MAAM;AACvB,QAAI,IAAA,OAAO,WAAW,QAAU,EAAA;AAC9B,UACE,IAAK,CAAA,MAAA,CAAO,QACZ,CAAA,uBAAA,CAAwB,MAAM,CAAA,CAAA;AAAA,SAC3B,MAAA;AACL,UACE,IAAA,CAAK,MAAO,CAAA,QAAA,CACZ,oBAAqB,EAAA,CAAA;AAAA,SACzB;AAEA,QAAO,OAAA,IAAA,CAAA;AAAA,OACT;AAAA,MAEA,0BACE,MACA,CAAC,EAAE,EAAA,EAAI,MAAyB,KAAA;AAC9B,QAAM,MAAA,YAAA,GAAe,KAAK,OAAQ,CAAA,KAAA,CAAA;AAGlC,QAAI,IAAA,YAAA,CAAa,UAAU,WAAa,EAAA;AACtC,UAAO,OAAA,KAAA,CAAA;AAAA,SACT;AAGA,QAAI,IAAA,8BAAA,CAA+B,YAAa,CAAA,QAAQ,CAAG,EAAA;AAEzD,UAAM,MAAA,OAAA,GAAU,aAAc,CAAA,IAAA,CAAK,MAAM,CAAA,CAAA;AACzC,UAAA,IAAI,CAAC,OAAS,EAAA;AACZ,YAAO,OAAA,KAAA,CAAA;AAAA,WACT;AAEA,UAAA,MAAM,eAAkB,GAAA,iCAAA;AAAA,YACtB,OAAQ,CAAA,IAAA;AAAA,YACR,IAAA,CAAK,OAAO,KAAM,CAAA,MAAA;AAAA,WACpB,CAAA;AACA,UAAG,EAAA,CAAA,OAAA,CAAQ,gBAAgB,KAAK,CAAA,CAAA;AAChC,UAAG,EAAA,CAAA,OAAA;AAAA,YACD,CAAA;AAAA,YACA,IAAK,CAAA,MAAA,CAAO,KAAM,CAAA,GAAA,CAAI,OAAQ,CAAA,IAAA;AAAA,YAC9B,IAAI,KAAM,CAAA,QAAA,CAAS,KAAK,eAAe,CAAA,EAAG,GAAG,CAAC,CAAA;AAAA,WAChD,CAAA;AACA,UAAA,EAAA,CAAG,QAAQ,cAAgB,EAAA;AAAA,YACzB,QAAU,EAAA,IAAA;AAAA,YACV,YAAc,EAAA,IAAA;AAAA,WACf,CAAA,CAAA;AAED,UAAA,IAAA,CAAK,QAAQ,QAAW,GAAA,KAAA,CAAA,CAAA;AAAA,SACnB,MAAA;AAGL,UAAA,MAAM,UAAa,GAAA,YAAA,CAAa,QAAS,CAAA,IAAA,CACtC,MAAM,IAAI,CAAA,CACV,GAAI,CAAA,CAAC,SAAc,KAAA,eAAA,CAAgB,IAAK,CAAA,MAAA,EAAQ,SAAS,CAAC,CAAA,CAAA;AAE7D,UAAG,EAAA,CAAA,MAAA,CAAO,KAAK,MAAO,CAAA,KAAA,CAAM,UAAU,GAAI,CAAA,GAAA,IAAO,UAAU,CAAA,CAAA;AAC3D,UAAG,EAAA,CAAA,OAAA,CAAQ,gBAAgB,IAAI,CAAA,CAAA;AAC/B,UAAA,IAAA,CAAK,SAAS,EAAE,CAAA,CAAA;AAEhB,UAAG,EAAA,CAAA,OAAA,CAAQ,mBAAmB,IAAI,CAAA,CAAA;AAAA,SACpC;AAGA,QAAyB,wBAAA,CAAA,IAAA,CAAK,MAAM,CAAA,EAAG,OAAQ,EAAA,CAAA;AAC/C,QAAK,IAAA,CAAA,MAAA,CAAO,YAAY,IAAI,CAAA,CAAA;AAG5B,QAAA,IAAA,CAAK,OAAQ,CAAA,KAAA,GAAQ,EAAE,KAAA,EAAO,QAAS,EAAA,CAAA;AAEvC,QAAO,OAAA,IAAA,CAAA;AAAA,OACT;AAAA,MAEF,iBACE,MACA,CAAC,EAAE,EAAA,EAAI,MAAyB,KAAA;AAC9B,QAAM,MAAA,YAAA,GAAe,KAAK,OAAQ,CAAA,KAAA,CAAA;AAGlC,QAAI,IAAA,YAAA,CAAa,UAAU,QAAU,EAAA;AACnC,UAAO,OAAA,KAAA,CAAA;AAAA,SACT;AAGA,QAAI,IAAA,YAAA,CAAa,UAAU,UAAY,EAAA;AACrC,UAAA,YAAA,CAAa,gBAAgB,KAAM,EAAA,CAAA;AAAA,SACrC;AAGA,QAAA,IACE,YAAa,CAAA,KAAA,KAAU,UACvB,IAAA,YAAA,CAAa,UAAU,WACvB,EAAA;AAEA,UAAA,MAAM,QAAW,GAAA,oBAAA;AAAA,YACf,EAAA;AAAA,YACA,IAAK,CAAA,MAAA;AAAA,YACL,IAAK,CAAA,OAAA;AAAA,YACL,KAAK,OAAQ,CAAA,GAAA;AAAA,WACf,CAAA;AACA,UAAA,IAAI,QAAU,EAAA;AACZ,YAAA,IAAA,CAAK,SAAS,QAAQ,CAAA,CAAA;AAEtB,YAAG,EAAA,CAAA,OAAA,CAAQ,mBAAmB,IAAI,CAAA,CAAA;AAAA,WACpC;AAAA,SACF;AAGA,QAAA,IAAA,CAAK,MAAO,CAAA,QAAA,CAAS,gBAAiB,CAAA,YAAA,CAAa,gBAAgB,CAAA,CAAA;AAGnE,QAAyB,wBAAA,CAAA,IAAA,CAAK,MAAM,CAAA,EAAG,OAAQ,EAAA,CAAA;AAC/C,QAAK,IAAA,CAAA,MAAA,CAAO,YAAY,IAAI,CAAA,CAAA;AAG5B,QAAA,IAAA,CAAK,OAAQ,CAAA,KAAA,GAAQ,EAAE,KAAA,EAAO,QAAS,EAAA,CAAA;AAEvC,QAAO,OAAA,IAAA,CAAA;AAAA,OACT;AAAA,MAEF,oBAAA,EAAsB,MAAM,MAAM;AAChC,QAAM,MAAA,YAAA,GAAe,KAAK,OAAQ,CAAA,KAAA,CAAA;AAGlC,QAAI,IAAA,YAAA,CAAa,UAAU,QAAU,EAAA;AACnC,UAAO,OAAA,KAAA,CAAA;AAAA,SACT;AAGA,QAAI,IAAA,IAAA,CAAK,OAAO,SAAW,EAAA;AACzB,UAAK,IAAA,CAAA,MAAA,CAAO,SAAS,IAAK,EAAA,CAAA;AAAA,SAC5B;AAGA,QAAA,IAAA,CAAK,QAAQ,KAAQ,GAAA;AAAA,UACnB,KAAO,EAAA,QAAA;AAAA,UAEP,gBAAkB,EAAA;AAAA,YAChB,IAAM,EAAA,IAAA,CAAK,MAAO,CAAA,KAAA,CAAM,SAAU,CAAA,IAAA;AAAA,YAClC,EAAI,EAAA,IAAA,CAAK,MAAO,CAAA,KAAA,CAAM,SAAU,CAAA,EAAA;AAAA,WAClC;AAAA,UAEA,YAAc,EAAA,EAAA;AAAA,SAChB,CAAA;AAEA,QAAO,OAAA,IAAA,CAAA;AAAA,OACT;AAAA,MAEA,uBAAA,EACE,CAAC,MAAgB,EAAA,oBAAA,KACjB,CAAC,EAAE,EAAA,EAAI,MAAyB,KAAA;AAC9B,QAAM,MAAA,YAAA,GAAe,KAAK,OAAQ,CAAA,KAAA,CAAA;AAGlC,QAAI,IAAA,YAAA,CAAa,UAAU,UAAY,EAAA;AACrC,UAAO,OAAA,KAAA,CAAA;AAAA,SACT;AAGA,QAAI,IAAA,IAAA,CAAK,OAAO,SAAW,EAAA;AACzB,UAAK,IAAA,CAAA,MAAA,CAAO,SAAS,IAAK,EAAA,CAAA;AAAA,SAC5B;AAEA,QAAM,MAAA,eAAA,GAAkB,IAAI,eAAgB,EAAA,CAAA;AAC5C,QAAM,MAAA,QAAA,GAAW,wBAAyB,CAAA,IAAA,CAAK,MAAM,CAAA,CAAA;AAGrD,QAAI,IAAA,YAAA,CAAa,UAAU,WAAa,EAAA;AAEtC,UAAA,MAAM,QAAW,GAAA,oBAAA;AAAA,YACf,EAAA;AAAA,YACA,IAAK,CAAA,MAAA;AAAA,YACL,IAAK,CAAA,OAAA;AAAA,YACL,KAAK,OAAQ,CAAA,GAAA;AAAA,WACf,CAAA;AACA,UAAA,IAAI,QAAU,EAAA;AAEZ,YAAA,IAAA,CAAK,SAAS,QAAQ,CAAA,CAAA;AAEtB,YAAG,EAAA,CAAA,OAAA,CAAQ,mBAAmB,IAAI,CAAA,CAAA;AAAA,WACpC;AAGA,UAAA,IAAA,CAAK,OAAO,QAAS,CAAA,gBAAA;AAAA,YACnB,YAAa,CAAA,gBAAA;AAAA,WACf,CAAA;AAAA,SACF;AAGA,QAAA,IAAA,CAAK,QAAQ,KAAQ,GAAA;AAAA,UACnB,KAAO,EAAA,UAAA;AAAA,UAEP,gBAAA,EAAkB,aAAa,gBAAoB,IAAA;AAAA,YACjD,IAAM,EAAA,IAAA,CAAK,MAAO,CAAA,KAAA,CAAM,SAAU,CAAA,IAAA;AAAA,YAClC,EAAI,EAAA,IAAA,CAAK,MAAO,CAAA,KAAA,CAAM,SAAU,CAAA,EAAA;AAAA,WAClC;AAAA,UAEA,YAAA,EAAc,aAAa,YAAgB,IAAA,EAAA;AAAA,UAC3C,MAAA;AAAA,UACA,eAAA;AAAA,UACA,kBAAkB,YAAa,CAAA,QAAA;AAAA,SACjC,CAAA;AAGA,QAAK,IAAA,CAAA,MAAA,CAAO,YAAY,KAAK,CAAA,CAAA;AAG7B,QAAA,SAAA;AAAA,UACE,YAAY;AACV,YAAA,MAAM,UAAU,KAAM,EAAA,CAAA;AAGtB,YAAA,MAAM,QAAY,GAAA,MAAM,IAAK,CAAA,OAAA,CAAQ,uBAAwB,CAAA;AAAA,cAC3D,MAAA;AAAA,cACA,OAAS,EAAA,0BAAA,CAA2B,IAAK,CAAA,MAAA,EAAQ,GAAK,CAAA;AAAA,cACtD,QAAQ,eAAgB,CAAA,MAAA;AAAA,cACxB,QACE,EAAA,oBAAA,IAAwB,YAAa,CAAA,KAAA,KAAU,WAC3C,GAAA;AAAA,gBACE,QAAQ,YAAa,CAAA,MAAA;AAAA,gBACrB,QAAU,EAAA;AAAA,kBACR,IAAA,EAAM,aAAa,QAAU,EAAA,IAAA;AAAA,kBAC7B,IAAA,EAAM,aAAa,QAAU,EAAA,IAAA;AAAA,iBAC/B;AAAA,eAEF,GAAA,KAAA,CAAA;AAAA,aACP,CAAA,CAAA;AAGD,YAAI,IAAA,iCAAA,CAAkC,QAAQ,CAAG,EAAA;AAC/C,cAAO,OAAA,QAAA,CAAA;AAAA,aACF,MAAA;AACL,cAAM,MAAA,IAAI,MAAM,8BAA8B,CAAA,CAAA;AAAA,aAChD;AAAA,WACF;AAAA,UACA,gCAAA;AAAA,UACA,8BAAA;AAAA,UAEA,CAAC,KAAU,KAAA;AAET,YACE,OAAA,eAAA,CAAgB,OAAO,OACtB,IAAA,KAAA,YAAiB,aAChB,KAAM,CAAA,MAAA,IAAU,GAChB,IAAA,KAAA,CAAM,MAAS,GAAA,GAAA,CAAA;AAAA,WAErB;AAAA,SACF,CACG,IAAK,CAAA,CAAC,QAAa,KAAA;AAClB,UAAI,IAAA,eAAA,CAAgB,OAAO,OAAS,EAAA;AAClC,YAAA,OAAA;AAAA,WACF;AAGA,UACE,IAAA,CAAK,MAAO,CAAA,QAAA,CACZ,+BAAgC,CAAA;AAAA,YAChC,MAAM,QAAS,CAAA,IAAA;AAAA,YACf,MAAM,QAAS,CAAA,IAAA;AAAA,WAChB,CAAA,CAAA;AAAA,SACF,CAAA,CACA,KAAM,CAAA,CAAC,KAAU,KAAA;AAChB,UAAI,IAAA,eAAA,CAAgB,OAAO,OAAS,EAAA;AAClC,YAAA,OAAA;AAAA,WACF;AAGA,UACE,IAAK,CAAA,MAAA,CAAO,QACZ,CAAA,6BAAA,CAA8B,KAAK,CAAA,CAAA;AAAA,SACtC,CAAA,CAAA;AAEH,QAAO,OAAA,IAAA,CAAA;AAAA,OACT;AAAA,MAEF,wBAAA,EAA0B,MAAM,MAAM;AACpC,QAAM,MAAA,YAAA,GAAe,KAAK,OAAQ,CAAA,KAAA,CAAA;AAGlC,QAAI,IAAA,YAAA,CAAa,UAAU,UAAY,EAAA;AACrC,UAAO,OAAA,KAAA,CAAA;AAAA,SACT;AAGA,QAAA,YAAA,CAAa,gBAAgB,KAAM,EAAA,CAAA;AAGnC,QAAK,IAAA,CAAA,MAAA,CAAO,YAAY,IAAI,CAAA,CAAA;AAG5B,QAAA,IAAA,CAAK,QAAQ,KAAQ,GAAA;AAAA,UACnB,KAAO,EAAA,QAAA;AAAA,UACP,kBAAkB,YAAa,CAAA,gBAAA;AAAA,UAE/B,cACE,YAAa,CAAA,MAAA,KAAW,YAAa,CAAA,YAAA,GACjC,aAAa,YACb,GAAA,EAAA;AAAA,SACR,CAAA;AAEA,QAAO,OAAA,IAAA,CAAA;AAAA,OACT;AAAA,MAEA,2BAAA,EAA6B,MAAM,MAAM;AAEvC,QAAA,IAAI,IAAK,CAAA,OAAA,CAAQ,KAAM,CAAA,KAAA,KAAU,WAAa,EAAA;AAC5C,UAAO,OAAA,KAAA,CAAA;AAAA,SACT;AAEA,QAAA,IAAI,CAAC,IAAK,CAAA,OAAA,CAAQ,OAAO,CAAC,IAAA,CAAK,QAAQ,QAAU,EAAA;AAC/C,UAAO,OAAA,KAAA,CAAA;AAAA,SACT;AAEA,QAAM,MAAA,gBAAA,GACJ,IAAK,CAAA,OAAA,CAAQ,QAAY,IAAA,aAAA,CAAA;AAC3B,QAAA,MAAM,eAAkB,GAAAA,QAAA,CAAa,IAAK,CAAA,OAAA,CAAQ,GAAG,CAAA,CAAA;AAErD,QAAI,IAAA,cAAA,CAAe,gBAAkB,EAAA,eAAe,CAAG,EAAA;AACrD,UAAO,OAAA,IAAA,CAAA;AAAA,SACT;AAEA,QAAc,aAAA,CAAA,IAAA,CAAK,MAAM,CAAG,EAAA,cAAA;AAAA,UAC1B,eAAA;AAAA,UACA,gBAAA;AAAA,SACF,CAAA;AAEA,QAAO,OAAA,IAAA,CAAA;AAAA,OACT;AAAA,MAEA,iCACE,CAAC,QAAA,KACD,CAAC,EAAE,IAAA,EAAM,IAAuB,KAAA;AAC9B,QAAM,MAAA,YAAA,GAAe,KAAK,OAAQ,CAAA,KAAA,CAAA;AAGlC,QAAI,IAAA,YAAA,CAAa,UAAU,UAAY,EAAA;AACrC,UAAO,OAAA,KAAA,CAAA;AAAA,SACT;AAGA,QAAI,IAAA,CAAC,8BAA+B,CAAA,QAAQ,CAAG,EAAA;AAC7C,UAAA,IAAA,CAAK,QAAQ,KAAQ,GAAA;AAAA,YACnB,KAAO,EAAA,WAAA;AAAA,YACP,kBAAkB,YAAa,CAAA,gBAAA;AAAA,YAC/B,YAAc,EAAA,EAAA;AAAA,YACd,QAAQ,YAAa,CAAA,MAAA;AAAA,YACrB,QAAA;AAAA,WACF,CAAA;AAEA,UAAO,OAAA,IAAA,CAAA;AAAA,SACT;AAEA,QAAI,IAAA,CAAC,IAAK,CAAA,OAAA,CAAQ,GAAK,EAAA;AACrB,UAAO,OAAA,KAAA,CAAA;AAAA,SACT;AAGA,QAAK,IAAA,CAAA,OAAA,CAAQ,IAAI,EAAK,GAAA,KAAA,CAAA;AACtB,QAAA,IAAA,CAAK,OAAQ,CAAA,QAAA,GAAWA,QAAa,CAAA,IAAA,CAAK,QAAQ,GAAG,CAAA,CAAA;AAGrD,QAAA,IAAA,CAAK,QAAQ,KAAQ,GAAA;AAAA,UACnB,KAAO,EAAA,WAAA;AAAA,UACP,kBAAkB,YAAa,CAAA,gBAAA;AAAA,UAC/B,YAAc,EAAA,EAAA;AAAA,UACd,QAAQ,YAAa,CAAA,MAAA;AAAA,UACrB,QAAA;AAAA,SACF,CAAA;AAGA,QAAA,MAAM,CAAC,cAAmB,EAAA,GAAA,eAAe,IACvC,QAAS,CAAA,IAAA,CAAK,MAAM,IAAI,CAAA,CAAA;AAE1B,QAAG,EAAA,CAAA,UAAA;AAAA,UACD,cAAA;AAAA,UACA,QAAA,CAAS,IAAS,KAAA,QAAA,GACd,IAAK,CAAA,MAAA,CAAO,KAAM,CAAA,SAAA,CAAU,EAC5B,GAAA,IAAA,CAAK,MAAO,CAAA,KAAA,CAAM,SAAU,CAAA,IAAA;AAAA,UAChC,IAAA,CAAK,MAAO,CAAA,KAAA,CAAM,SAAU,CAAA,EAAA;AAAA,SAC9B,CAAA;AAEA,QAAI,IAAA,eAAA,CAAgB,SAAS,CAAG,EAAA;AAC9B,UAAA,MAAM,aAAa,eAAgB,CAAA,GAAA;AAAA,YAAI,CAAC,SAAA,KACtC,eAAgB,CAAA,IAAA,CAAK,QAAQ,SAAS,CAAA;AAAA,WACxC,CAAA;AAEA,UAAA,EAAA,CAAG,MAAO,CAAA,EAAA,CAAG,SAAU,CAAA,GAAA,CAAI,KAAK,UAAU,CAAA,CAAA;AAAA,SAC5C;AAEA,QAAA,IAAA,CAAK,SAAS,EAAE,CAAA,CAAA;AAEhB,QAAG,EAAA,CAAA,OAAA,CAAQ,mBAAmB,IAAI,CAAA,CAAA;AAGlC,QACE,IAAA,CAAK,MAAO,CAAA,QAAA,CACZ,2BAA4B,EAAA,CAAA;AAI9B,QAAO,OAAA,IAAA,CAAA;AAAA,OACT;AAAA,MAEF,6BAAA,EAA+B,CAAC,KAAA,KAAmB,MAAM;AACvD,QAAM,MAAA,YAAA,GAAe,KAAK,OAAQ,CAAA,KAAA,CAAA;AAGlC,QAAI,IAAA,YAAA,CAAa,UAAU,UAAY,EAAA;AACrC,UAAO,OAAA,KAAA,CAAA;AAAA,SACT;AAGA,QAAK,IAAA,CAAA,MAAA,CAAO,YAAY,IAAI,CAAA,CAAA;AAG5B,QAAA,OAAA,CAAQ,MAAM,KAAK,CAAA,CAAA;AAGnB,QAAA,IAAA,CAAK,QAAQ,KAAQ,GAAA;AAAA,UACnB,KAAO,EAAA,QAAA;AAAA,UACP,kBAAkB,YAAa,CAAA,gBAAA;AAAA,UAE/B,cACE,YAAa,CAAA,MAAA,KAAW,YAAa,CAAA,YAAA,GACjC,aAAa,YACb,GAAA,EAAA;AAAA,UAEN,KACE,EAAA,KAAA,YAAiB,KACb,GAAA,KAAA,GACA,IAAI,KAAA,CAAM,MAAO,CAAA,KAAK,CAAG,EAAA,EAAE,KAAO,EAAA,KAAA,EAAO,CAAA;AAAA,SACjD,CAAA;AAEA,QAAO,OAAA,IAAA,CAAA;AAAA,OACT;AAAA,MAEA,4BAAA,EACE,CAAC,YAAA,KACD,MAAM;AACJ,QAAM,MAAA,YAAA,GAAe,KAAK,OAAQ,CAAA,KAAA,CAAA;AAGlC,QAAI,IAAA,OAAO,YAAa,CAAA,YAAA,KAAiB,QAAU,EAAA;AACjD,UAAO,OAAA,KAAA,CAAA;AAAA,SACT;AAGA,QAAK,IAAA,CAAA,OAAA,CAAQ,MAAM,YACjB,GAAA,OAAO,iBAAiB,UACpB,GAAA,YAAA,CAAa,YAAa,CAAA,YAAY,CACtC,GAAA,YAAA,CAAA;AAEN,QAAO,OAAA,IAAA,CAAA;AAAA,OACT;AAAA,KACJ,CAAA;AAAA,GACF;AAAA,EACA,qBAAwB,GAAA;AACtB,IAAO,OAAA;AAAA,MACL,IAAI,MAAO,CAAA;AAAA,QACT,GAAK,EAAA,2BAAA;AAAA,QACL,KAAO,EAAA;AAAA,UACL,WAAa,EAAA,CAAC,EAAE,GAAA,EAAK,WAAgB,KAAA;AAEnC,YAAA,IACE,IAAK,CAAA,OAAA,CAAQ,KAAM,CAAA,KAAA,KAAU,YAC5B,IAAK,CAAA,OAAA,CAAQ,KAAM,CAAA,KAAA,KAAU,eAC5B,8BAA+B,CAAA,IAAA,CAAK,OAAQ,CAAA,KAAA,CAAM,QAAQ,CAC5D,EAAA;AACA,cAAA,OAAO,aAAc,CAAA,MAAA,CAAO,GAAK,EAAA,EAAE,CAAA,CAAA;AAAA,aACrC;AAEA,YAAM,MAAA,EAAE,IAAM,EAAA,EAAA,EAAO,GAAA,SAAA,CAAA;AACrB,YAAA,MAAM,WAA4B,GAAA;AAAA,cAChC,UAAA,CAAW,MAAO,CAAA,IAAA,EAAM,EAAI,EAAA;AAAA,gBAC1B,KAAO,EAAA,iDAAA;AAAA,eACR,CAAA;AAAA,aACH,CAAA;AAEA,YAAO,OAAA,aAAA,CAAc,MAAO,CAAA,GAAA,EAAK,WAAW,CAAA,CAAA;AAAA,WAC9C;AAAA,SACF;AAAA,OACD,CAAA;AAAA,KACH,CAAA;AAAA,GACF;AACF,CAAC;;;;"}