tetrons 2.3.75 → 2.3.77

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,21 +1,143 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropNames = Object.getOwnPropertyNames;
3
+ var __esm = (fn, res) => function __init() {
4
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
5
+ };
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+
11
+ // src/components/tetrons/toolbar/MathModal.js
12
+ var MathModal_exports = {};
13
+ __export(MathModal_exports, {
14
+ default: () => MathModal
15
+ });
16
+ import { useEffect as useEffect7 } from "react";
17
+ import katex2 from "katex";
18
+ import "katex/dist/katex.min.css";
19
+ function MathModal({
20
+ isOpen,
21
+ onClose,
22
+ onSubmit,
23
+ value,
24
+ setValue
25
+ }) {
26
+ useEffect7(() => {
27
+ const onEsc = (e) => {
28
+ if (e.key === "Escape") onClose();
29
+ };
30
+ if (isOpen) {
31
+ window.addEventListener("keydown", onEsc);
32
+ }
33
+ return () => window.removeEventListener("keydown", onEsc);
34
+ }, [isOpen, onClose]);
35
+ if (!isOpen) return null;
36
+ return /* @__PURE__ */ React.createElement("div", { className: "ai-modal-backdrop" }, /* @__PURE__ */ React.createElement("div", { className: "ai-modal-content" }, /* @__PURE__ */ React.createElement("div", { className: "ai-modal-title" }, "Insert LaTeX Equation"), /* @__PURE__ */ React.createElement(
37
+ "textarea",
38
+ {
39
+ className: "ai-modal-textarea",
40
+ placeholder: "Enter LaTeX code here...",
41
+ value,
42
+ onChange: (e) => setValue(e.target.value)
43
+ }
44
+ ), /* @__PURE__ */ React.createElement("div", { className: "ai-modal-preview" }, /* @__PURE__ */ React.createElement("strong", null, "Preview:"), /* @__PURE__ */ React.createElement("div", { className: "ai-modal-preview-output" }, /* @__PURE__ */ React.createElement("span", { dangerouslySetInnerHTML: { __html: renderLatex(value) } }))), /* @__PURE__ */ React.createElement("div", { className: "ai-modal-actions" }, /* @__PURE__ */ React.createElement("button", { type: "button", className: "ai-cancel-btn", onClick: onClose }, "Cancel"), /* @__PURE__ */ React.createElement(
45
+ "button",
46
+ {
47
+ className: "ai-submit-btn",
48
+ onClick: () => onSubmit(value),
49
+ disabled: !value.trim()
50
+ },
51
+ "Insert"
52
+ ))));
53
+ }
54
+ function renderLatex(latex) {
55
+ try {
56
+ return katex2.renderToString(latex, {
57
+ throwOnError: false,
58
+ displayMode: false
59
+ });
60
+ } catch {
61
+ return `<span style="color: red;">Invalid LaTeX</span>`;
62
+ }
63
+ }
64
+ var init_MathModal = __esm({
65
+ "src/components/tetrons/toolbar/MathModal.js"() {
66
+ "use strict";
67
+ }
68
+ });
69
+
70
+ // src/components/tetrons/extensions/MathExtension.ts
71
+ import { Node, mergeAttributes } from "@tiptap/core";
72
+ import katex from "katex";
73
+ var MathInline = Node.create({
74
+ name: "mathInline",
75
+ inline: true,
76
+ group: "inline",
77
+ atom: true,
78
+ addAttributes() {
79
+ return {
80
+ formula: {
81
+ default: ""
82
+ }
83
+ };
84
+ },
85
+ parseHTML() {
86
+ return [{ tag: "span[data-math-inline]" }];
87
+ },
88
+ renderHTML({ HTMLAttributes }) {
89
+ return [
90
+ "span",
91
+ mergeAttributes(HTMLAttributes, {
92
+ "data-math-inline": "",
93
+ class: "math-inline"
94
+ }),
95
+ HTMLAttributes.formula
96
+ ];
97
+ },
98
+ addNodeView() {
99
+ return ({ node }) => {
100
+ const span = document.createElement("span");
101
+ try {
102
+ span.innerHTML = katex.renderToString(node.attrs.formula, {
103
+ throwOnError: false,
104
+ displayMode: false
105
+ });
106
+ } catch {
107
+ span.textContent = node.attrs.formula;
108
+ }
109
+ return {
110
+ dom: span
111
+ };
112
+ };
113
+ },
114
+ addCommands() {
115
+ return {
116
+ insertMathInline: (formula) => ({ commands }) => {
117
+ return commands.insertContent({
118
+ type: this.name,
119
+ attrs: { formula }
120
+ });
121
+ }
122
+ };
123
+ }
124
+ });
125
+
1
126
  // src/components/tetrons/EditorContent.tsx
2
- import React14, { useEffect as useEffect8, useRef as useRef7, useState as useState9 } from "react";
3
- import {
4
- useEditor,
5
- EditorContent as TiptapEditorContent
6
- } from "@tiptap/react";
127
+ import React16, { useEffect as useEffect9, useRef as useRef7, useState as useState10 } from "react";
128
+ import { useEditor, EditorContent as TiptapEditorContent } from "@tiptap/react";
7
129
 
8
130
  // node_modules/@tiptap/extension-document/dist/index.js
9
- import { Node } from "@tiptap/core";
10
- var Document = Node.create({
131
+ import { Node as Node2 } from "@tiptap/core";
132
+ var Document = Node2.create({
11
133
  name: "doc",
12
134
  topNode: true,
13
135
  content: "block+"
14
136
  });
15
137
 
16
138
  // node_modules/@tiptap/extension-paragraph/dist/index.js
17
- import { Node as Node2, mergeAttributes } from "@tiptap/core";
18
- var Paragraph = Node2.create({
139
+ import { Node as Node3, mergeAttributes as mergeAttributes2 } from "@tiptap/core";
140
+ var Paragraph = Node3.create({
19
141
  name: "paragraph",
20
142
  priority: 1e3,
21
143
  addOptions() {
@@ -31,7 +153,7 @@ var Paragraph = Node2.create({
31
153
  ];
32
154
  },
33
155
  renderHTML({ HTMLAttributes }) {
34
- return ["p", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
156
+ return ["p", mergeAttributes2(this.options.HTMLAttributes, HTMLAttributes), 0];
35
157
  },
36
158
  addCommands() {
37
159
  return {
@@ -48,8 +170,8 @@ var Paragraph = Node2.create({
48
170
  });
49
171
 
50
172
  // node_modules/@tiptap/extension-text/dist/index.js
51
- import { Node as Node3 } from "@tiptap/core";
52
- var Text = Node3.create({
173
+ import { Node as Node4 } from "@tiptap/core";
174
+ var Text = Node4.create({
53
175
  name: "text",
54
176
  group: "inline"
55
177
  });
@@ -1272,7 +1394,7 @@ var NodeRange = class {
1272
1394
  }
1273
1395
  };
1274
1396
  var emptyAttrs = /* @__PURE__ */ Object.create(null);
1275
- var Node4 = class _Node {
1397
+ var Node5 = class _Node {
1276
1398
  /**
1277
1399
  @internal
1278
1400
  */
@@ -1673,7 +1795,7 @@ var Node4 = class _Node {
1673
1795
  return node;
1674
1796
  }
1675
1797
  };
1676
- Node4.prototype.text = void 0;
1798
+ Node5.prototype.text = void 0;
1677
1799
  function wrapMarks(marks, str) {
1678
1800
  for (let i = marks.length - 1; i >= 0; i--)
1679
1801
  str = marks[i].type.name + "(" + str + ")";
@@ -5713,7 +5835,7 @@ var History = Extension.create({
5713
5835
  });
5714
5836
 
5715
5837
  // node_modules/@tiptap/extension-bold/dist/index.js
5716
- import { Mark as Mark2, mergeAttributes as mergeAttributes2, markInputRule, markPasteRule } from "@tiptap/core";
5838
+ import { Mark as Mark2, mergeAttributes as mergeAttributes3, markInputRule, markPasteRule } from "@tiptap/core";
5717
5839
  var starInputRegex = /(?:^|\s)(\*\*(?!\s+\*\*)((?:[^*]+))\*\*(?!\s+\*\*))$/;
5718
5840
  var starPasteRegex = /(?:^|\s)(\*\*(?!\s+\*\*)((?:[^*]+))\*\*(?!\s+\*\*))/g;
5719
5841
  var underscoreInputRegex = /(?:^|\s)(__(?!\s+__)((?:[^_]+))__(?!\s+__))$/;
@@ -5745,7 +5867,7 @@ var Bold = Mark2.create({
5745
5867
  ];
5746
5868
  },
5747
5869
  renderHTML({ HTMLAttributes }) {
5748
- return ["strong", mergeAttributes2(this.options.HTMLAttributes, HTMLAttributes), 0];
5870
+ return ["strong", mergeAttributes3(this.options.HTMLAttributes, HTMLAttributes), 0];
5749
5871
  },
5750
5872
  addCommands() {
5751
5873
  return {
@@ -5793,7 +5915,7 @@ var Bold = Mark2.create({
5793
5915
  });
5794
5916
 
5795
5917
  // node_modules/@tiptap/extension-italic/dist/index.js
5796
- import { Mark as Mark3, mergeAttributes as mergeAttributes3, markInputRule as markInputRule2, markPasteRule as markPasteRule2 } from "@tiptap/core";
5918
+ import { Mark as Mark3, mergeAttributes as mergeAttributes4, markInputRule as markInputRule2, markPasteRule as markPasteRule2 } from "@tiptap/core";
5797
5919
  var starInputRegex2 = /(?:^|\s)(\*(?!\s+\*)((?:[^*]+))\*(?!\s+\*))$/;
5798
5920
  var starPasteRegex2 = /(?:^|\s)(\*(?!\s+\*)((?:[^*]+))\*(?!\s+\*))/g;
5799
5921
  var underscoreInputRegex2 = /(?:^|\s)(_(?!\s+_)((?:[^_]+))_(?!\s+_))$/;
@@ -5824,7 +5946,7 @@ var Italic = Mark3.create({
5824
5946
  ];
5825
5947
  },
5826
5948
  renderHTML({ HTMLAttributes }) {
5827
- return ["em", mergeAttributes3(this.options.HTMLAttributes, HTMLAttributes), 0];
5949
+ return ["em", mergeAttributes4(this.options.HTMLAttributes, HTMLAttributes), 0];
5828
5950
  },
5829
5951
  addCommands() {
5830
5952
  return {
@@ -5875,7 +5997,7 @@ var Italic = Mark3.create({
5875
5997
  import Underline from "@tiptap/extension-underline";
5876
5998
 
5877
5999
  // node_modules/@tiptap/extension-strike/dist/index.js
5878
- import { Mark as Mark4, mergeAttributes as mergeAttributes4, markInputRule as markInputRule3, markPasteRule as markPasteRule3 } from "@tiptap/core";
6000
+ import { Mark as Mark4, mergeAttributes as mergeAttributes5, markInputRule as markInputRule3, markPasteRule as markPasteRule3 } from "@tiptap/core";
5879
6001
  var inputRegex = /(?:^|\s)(~~(?!\s+~~)((?:[^~]+))~~(?!\s+~~))$/;
5880
6002
  var pasteRegex = /(?:^|\s)(~~(?!\s+~~)((?:[^~]+))~~(?!\s+~~))/g;
5881
6003
  var Strike = Mark4.create({
@@ -5904,7 +6026,7 @@ var Strike = Mark4.create({
5904
6026
  ];
5905
6027
  },
5906
6028
  renderHTML({ HTMLAttributes }) {
5907
- return ["s", mergeAttributes4(this.options.HTMLAttributes, HTMLAttributes), 0];
6029
+ return ["s", mergeAttributes5(this.options.HTMLAttributes, HTMLAttributes), 0];
5908
6030
  },
5909
6031
  addCommands() {
5910
6032
  return {
@@ -5943,7 +6065,7 @@ var Strike = Mark4.create({
5943
6065
  });
5944
6066
 
5945
6067
  // node_modules/@tiptap/extension-code/dist/index.js
5946
- import { Mark as Mark5, mergeAttributes as mergeAttributes5, markInputRule as markInputRule4, markPasteRule as markPasteRule4 } from "@tiptap/core";
6068
+ import { Mark as Mark5, mergeAttributes as mergeAttributes6, markInputRule as markInputRule4, markPasteRule as markPasteRule4 } from "@tiptap/core";
5947
6069
  var inputRegex2 = /(^|[^`])`([^`]+)`(?!`)/;
5948
6070
  var pasteRegex2 = /(^|[^`])`([^`]+)`(?!`)/g;
5949
6071
  var Code = Mark5.create({
@@ -5962,7 +6084,7 @@ var Code = Mark5.create({
5962
6084
  ];
5963
6085
  },
5964
6086
  renderHTML({ HTMLAttributes }) {
5965
- return ["code", mergeAttributes5(this.options.HTMLAttributes, HTMLAttributes), 0];
6087
+ return ["code", mergeAttributes6(this.options.HTMLAttributes, HTMLAttributes), 0];
5966
6088
  },
5967
6089
  addCommands() {
5968
6090
  return {
@@ -6001,9 +6123,9 @@ var Code = Mark5.create({
6001
6123
  });
6002
6124
 
6003
6125
  // node_modules/@tiptap/extension-blockquote/dist/index.js
6004
- import { Node as Node5, mergeAttributes as mergeAttributes6, wrappingInputRule } from "@tiptap/core";
6126
+ import { Node as Node6, mergeAttributes as mergeAttributes7, wrappingInputRule } from "@tiptap/core";
6005
6127
  var inputRegex3 = /^\s*>\s$/;
6006
- var Blockquote = Node5.create({
6128
+ var Blockquote = Node6.create({
6007
6129
  name: "blockquote",
6008
6130
  addOptions() {
6009
6131
  return {
@@ -6019,7 +6141,7 @@ var Blockquote = Node5.create({
6019
6141
  ];
6020
6142
  },
6021
6143
  renderHTML({ HTMLAttributes }) {
6022
- return ["blockquote", mergeAttributes6(this.options.HTMLAttributes, HTMLAttributes), 0];
6144
+ return ["blockquote", mergeAttributes7(this.options.HTMLAttributes, HTMLAttributes), 0];
6023
6145
  },
6024
6146
  addCommands() {
6025
6147
  return {
@@ -6050,8 +6172,8 @@ var Blockquote = Node5.create({
6050
6172
  });
6051
6173
 
6052
6174
  // node_modules/@tiptap/extension-hard-break/dist/index.js
6053
- import { Node as Node6, mergeAttributes as mergeAttributes7 } from "@tiptap/core";
6054
- var HardBreak = Node6.create({
6175
+ import { Node as Node7, mergeAttributes as mergeAttributes8 } from "@tiptap/core";
6176
+ var HardBreak = Node7.create({
6055
6177
  name: "hardBreak",
6056
6178
  addOptions() {
6057
6179
  return {
@@ -6069,7 +6191,7 @@ var HardBreak = Node6.create({
6069
6191
  ];
6070
6192
  },
6071
6193
  renderHTML({ HTMLAttributes }) {
6072
- return ["br", mergeAttributes7(this.options.HTMLAttributes, HTMLAttributes)];
6194
+ return ["br", mergeAttributes8(this.options.HTMLAttributes, HTMLAttributes)];
6073
6195
  },
6074
6196
  renderText() {
6075
6197
  return "\n";
@@ -6108,8 +6230,8 @@ var HardBreak = Node6.create({
6108
6230
  });
6109
6231
 
6110
6232
  // node_modules/@tiptap/extension-heading/dist/index.js
6111
- import { Node as Node7, mergeAttributes as mergeAttributes8, textblockTypeInputRule } from "@tiptap/core";
6112
- var Heading = Node7.create({
6233
+ import { Node as Node8, mergeAttributes as mergeAttributes9, textblockTypeInputRule } from "@tiptap/core";
6234
+ var Heading = Node8.create({
6113
6235
  name: "heading",
6114
6236
  addOptions() {
6115
6237
  return {
@@ -6137,7 +6259,7 @@ var Heading = Node7.create({
6137
6259
  renderHTML({ node, HTMLAttributes }) {
6138
6260
  const hasLevel = this.options.levels.includes(node.attrs.level);
6139
6261
  const level = hasLevel ? node.attrs.level : this.options.levels[0];
6140
- return [`h${level}`, mergeAttributes8(this.options.HTMLAttributes, HTMLAttributes), 0];
6262
+ return [`h${level}`, mergeAttributes9(this.options.HTMLAttributes, HTMLAttributes), 0];
6141
6263
  },
6142
6264
  addCommands() {
6143
6265
  return {
@@ -6177,8 +6299,8 @@ var Heading = Node7.create({
6177
6299
  });
6178
6300
 
6179
6301
  // node_modules/@tiptap/extension-horizontal-rule/dist/index.js
6180
- import { Node as Node8, mergeAttributes as mergeAttributes9, canInsertNode, isNodeSelection, nodeInputRule } from "@tiptap/core";
6181
- var HorizontalRule = Node8.create({
6302
+ import { Node as Node9, mergeAttributes as mergeAttributes10, canInsertNode, isNodeSelection, nodeInputRule } from "@tiptap/core";
6303
+ var HorizontalRule = Node9.create({
6182
6304
  name: "horizontalRule",
6183
6305
  addOptions() {
6184
6306
  return {
@@ -6190,7 +6312,7 @@ var HorizontalRule = Node8.create({
6190
6312
  return [{ tag: "hr" }];
6191
6313
  },
6192
6314
  renderHTML({ HTMLAttributes }) {
6193
- return ["hr", mergeAttributes9(this.options.HTMLAttributes, HTMLAttributes)];
6315
+ return ["hr", mergeAttributes10(this.options.HTMLAttributes, HTMLAttributes)];
6194
6316
  },
6195
6317
  addCommands() {
6196
6318
  return {
@@ -6261,8 +6383,8 @@ import Link from "@tiptap/extension-link";
6261
6383
  import TextStyle from "@tiptap/extension-text-style";
6262
6384
 
6263
6385
  // node_modules/@tiptap/extension-list-item/dist/index.js
6264
- import { Node as Node9, mergeAttributes as mergeAttributes10 } from "@tiptap/core";
6265
- var ListItem = Node9.create({
6386
+ import { Node as Node10, mergeAttributes as mergeAttributes11 } from "@tiptap/core";
6387
+ var ListItem = Node10.create({
6266
6388
  name: "listItem",
6267
6389
  addOptions() {
6268
6390
  return {
@@ -6281,7 +6403,7 @@ var ListItem = Node9.create({
6281
6403
  ];
6282
6404
  },
6283
6405
  renderHTML({ HTMLAttributes }) {
6284
- return ["li", mergeAttributes10(this.options.HTMLAttributes, HTMLAttributes), 0];
6406
+ return ["li", mergeAttributes11(this.options.HTMLAttributes, HTMLAttributes), 0];
6285
6407
  },
6286
6408
  addKeyboardShortcuts() {
6287
6409
  return {
@@ -6293,11 +6415,11 @@ var ListItem = Node9.create({
6293
6415
  });
6294
6416
 
6295
6417
  // node_modules/@tiptap/extension-bullet-list/dist/index.js
6296
- import { Node as Node10, mergeAttributes as mergeAttributes11, wrappingInputRule as wrappingInputRule2 } from "@tiptap/core";
6418
+ import { Node as Node11, mergeAttributes as mergeAttributes12, wrappingInputRule as wrappingInputRule2 } from "@tiptap/core";
6297
6419
  var ListItemName = "listItem";
6298
6420
  var TextStyleName = "textStyle";
6299
6421
  var inputRegex4 = /^\s*([-+*])\s$/;
6300
- var BulletList = Node10.create({
6422
+ var BulletList = Node11.create({
6301
6423
  name: "bulletList",
6302
6424
  addOptions() {
6303
6425
  return {
@@ -6317,7 +6439,7 @@ var BulletList = Node10.create({
6317
6439
  ];
6318
6440
  },
6319
6441
  renderHTML({ HTMLAttributes }) {
6320
- return ["ul", mergeAttributes11(this.options.HTMLAttributes, HTMLAttributes), 0];
6442
+ return ["ul", mergeAttributes12(this.options.HTMLAttributes, HTMLAttributes), 0];
6321
6443
  },
6322
6444
  addCommands() {
6323
6445
  return {
@@ -6358,11 +6480,11 @@ var BulletList = Node10.create({
6358
6480
  });
6359
6481
 
6360
6482
  // node_modules/@tiptap/extension-ordered-list/dist/index.js
6361
- import { Node as Node11, mergeAttributes as mergeAttributes12, wrappingInputRule as wrappingInputRule3 } from "@tiptap/core";
6483
+ import { Node as Node12, mergeAttributes as mergeAttributes13, wrappingInputRule as wrappingInputRule3 } from "@tiptap/core";
6362
6484
  var ListItemName2 = "listItem";
6363
6485
  var TextStyleName2 = "textStyle";
6364
6486
  var inputRegex5 = /^(\d+)\.\s$/;
6365
- var OrderedList = Node11.create({
6487
+ var OrderedList = Node12.create({
6366
6488
  name: "orderedList",
6367
6489
  addOptions() {
6368
6490
  return {
@@ -6399,7 +6521,7 @@ var OrderedList = Node11.create({
6399
6521
  },
6400
6522
  renderHTML({ HTMLAttributes }) {
6401
6523
  const { start, ...attributesWithoutStart } = HTMLAttributes;
6402
- return start === 1 ? ["ol", mergeAttributes12(this.options.HTMLAttributes, attributesWithoutStart), 0] : ["ol", mergeAttributes12(this.options.HTMLAttributes, HTMLAttributes), 0];
6524
+ return start === 1 ? ["ol", mergeAttributes13(this.options.HTMLAttributes, attributesWithoutStart), 0] : ["ol", mergeAttributes13(this.options.HTMLAttributes, HTMLAttributes), 0];
6403
6525
  },
6404
6526
  addCommands() {
6405
6527
  return {
@@ -8025,7 +8147,7 @@ var Spellcheck = Mark6.create({
8025
8147
  });
8026
8148
 
8027
8149
  // src/components/tetrons/toolbar/extensions/Comment.ts
8028
- import { Mark as Mark7, mergeAttributes as mergeAttributes13 } from "@tiptap/core";
8150
+ import { Mark as Mark7, mergeAttributes as mergeAttributes14 } from "@tiptap/core";
8029
8151
  var Comment = Mark7.create({
8030
8152
  name: "comment",
8031
8153
  addOptions() {
@@ -8050,7 +8172,7 @@ var Comment = Mark7.create({
8050
8172
  renderHTML({ HTMLAttributes }) {
8051
8173
  return [
8052
8174
  "span",
8053
- mergeAttributes13(HTMLAttributes, {
8175
+ mergeAttributes14(HTMLAttributes, {
8054
8176
  "data-comment": HTMLAttributes.comment,
8055
8177
  class: "comment-highlight",
8056
8178
  title: HTMLAttributes.comment,
@@ -15210,8 +15332,8 @@ var ResizableTable = Table.extend({
15210
15332
  });
15211
15333
 
15212
15334
  // src/components/tetrons/toolbar/extensions/Embed.ts
15213
- import { Node as Node12, mergeAttributes as mergeAttributes14 } from "@tiptap/core";
15214
- var Embed = Node12.create({
15335
+ import { Node as Node13, mergeAttributes as mergeAttributes15 } from "@tiptap/core";
15336
+ var Embed = Node13.create({
15215
15337
  name: "embed",
15216
15338
  group: "block",
15217
15339
  atom: true,
@@ -15226,7 +15348,7 @@ var Embed = Node12.create({
15226
15348
  return [{ tag: "iframe[src]" }];
15227
15349
  },
15228
15350
  renderHTML({ HTMLAttributes }) {
15229
- return ["iframe", mergeAttributes14(HTMLAttributes)];
15351
+ return ["iframe", mergeAttributes15(HTMLAttributes)];
15230
15352
  },
15231
15353
  addCommands() {
15232
15354
  return {
@@ -15304,7 +15426,7 @@ var Embed = Node12.create({
15304
15426
  });
15305
15427
 
15306
15428
  // src/components/tetrons/toolbar/extensions/FontFamily.ts
15307
- import { Mark as Mark10, mergeAttributes as mergeAttributes15 } from "@tiptap/core";
15429
+ import { Mark as Mark10, mergeAttributes as mergeAttributes16 } from "@tiptap/core";
15308
15430
  var FontFamily = Mark10.create({
15309
15431
  name: "fontFamily",
15310
15432
  addAttributes() {
@@ -15323,7 +15445,7 @@ var FontFamily = Mark10.create({
15323
15445
  return [{ style: "font-family" }];
15324
15446
  },
15325
15447
  renderHTML({ HTMLAttributes }) {
15326
- return ["span", mergeAttributes15(HTMLAttributes), 0];
15448
+ return ["span", mergeAttributes16(HTMLAttributes), 0];
15327
15449
  },
15328
15450
  addCommands() {
15329
15451
  return {
@@ -15333,7 +15455,7 @@ var FontFamily = Mark10.create({
15333
15455
  });
15334
15456
 
15335
15457
  // src/components/tetrons/toolbar/extensions/FontSize.ts
15336
- import { Mark as Mark11, mergeAttributes as mergeAttributes16 } from "@tiptap/core";
15458
+ import { Mark as Mark11, mergeAttributes as mergeAttributes17 } from "@tiptap/core";
15337
15459
  var FontSize = Mark11.create({
15338
15460
  name: "fontSize",
15339
15461
  addAttributes() {
@@ -15352,7 +15474,7 @@ var FontSize = Mark11.create({
15352
15474
  return [{ style: "font-size" }];
15353
15475
  },
15354
15476
  renderHTML({ HTMLAttributes }) {
15355
- return ["span", mergeAttributes16(HTMLAttributes), 0];
15477
+ return ["span", mergeAttributes17(HTMLAttributes), 0];
15356
15478
  },
15357
15479
  addCommands() {
15358
15480
  return {
@@ -15366,7 +15488,7 @@ import Image from "@tiptap/extension-image";
15366
15488
  import { ReactNodeViewRenderer } from "@tiptap/react";
15367
15489
 
15368
15490
  // src/components/tetrons/ResizableImageComponent.tsx
15369
- import React, { useRef, useEffect as useEffect2, useState as useState2 } from "react";
15491
+ import React2, { useRef, useEffect as useEffect2, useState as useState2 } from "react";
15370
15492
  import { NodeViewWrapper } from "@tiptap/react";
15371
15493
  var ResizableImageComponent = ({
15372
15494
  node,
@@ -15404,7 +15526,7 @@ var ResizableImageComponent = ({
15404
15526
  window.removeEventListener("mouseup", handleMouseUp);
15405
15527
  };
15406
15528
  }, [isResizing, updateAttributes, aspectRatio]);
15407
- return /* @__PURE__ */ React.createElement(
15529
+ return /* @__PURE__ */ React2.createElement(
15408
15530
  NodeViewWrapper,
15409
15531
  {
15410
15532
  ref: wrapperRef,
@@ -15423,7 +15545,7 @@ var ResizableImageComponent = ({
15423
15545
  padding: 2
15424
15546
  }
15425
15547
  },
15426
- /* @__PURE__ */ React.createElement(
15548
+ /* @__PURE__ */ React2.createElement(
15427
15549
  "img",
15428
15550
  {
15429
15551
  src,
@@ -15441,7 +15563,7 @@ var ResizableImageComponent = ({
15441
15563
  draggable: false
15442
15564
  }
15443
15565
  ),
15444
- /* @__PURE__ */ React.createElement(
15566
+ /* @__PURE__ */ React2.createElement(
15445
15567
  "div",
15446
15568
  {
15447
15569
  onMouseDown: (e) => {
@@ -15494,11 +15616,11 @@ var ResizableImage = Image.extend({
15494
15616
  });
15495
15617
 
15496
15618
  // src/components/tetrons/ResizableVideo.ts
15497
- import { Node as Node13 } from "@tiptap/core";
15619
+ import { Node as Node14 } from "@tiptap/core";
15498
15620
  import { ReactNodeViewRenderer as ReactNodeViewRenderer2 } from "@tiptap/react";
15499
15621
 
15500
15622
  // src/components/tetrons/ResizableVideoComponent.tsx
15501
- import React2, { useRef as useRef2, useEffect as useEffect3 } from "react";
15623
+ import React3, { useRef as useRef2, useEffect as useEffect3 } from "react";
15502
15624
  import { NodeViewWrapper as NodeViewWrapper2 } from "@tiptap/react";
15503
15625
  var ResizableVideoComponent = ({
15504
15626
  node,
@@ -15519,7 +15641,7 @@ var ResizableVideoComponent = ({
15519
15641
  observer.observe(video);
15520
15642
  return () => observer.disconnect();
15521
15643
  }, [updateAttributes]);
15522
- return /* @__PURE__ */ React2.createElement(
15644
+ return /* @__PURE__ */ React3.createElement(
15523
15645
  NodeViewWrapper2,
15524
15646
  {
15525
15647
  ref: wrapperRef,
@@ -15533,7 +15655,7 @@ var ResizableVideoComponent = ({
15533
15655
  display: "inline-block"
15534
15656
  }
15535
15657
  },
15536
- /* @__PURE__ */ React2.createElement(
15658
+ /* @__PURE__ */ React3.createElement(
15537
15659
  "video",
15538
15660
  {
15539
15661
  ref: videoRef,
@@ -15550,7 +15672,7 @@ var ResizableVideoComponent = ({
15550
15672
  var ResizableVideoComponent_default = ResizableVideoComponent;
15551
15673
 
15552
15674
  // src/components/tetrons/ResizableVideo.ts
15553
- var ResizableVideo = Node13.create({
15675
+ var ResizableVideo = Node14.create({
15554
15676
  name: "video",
15555
15677
  group: "block",
15556
15678
  draggable: true,
@@ -15597,7 +15719,7 @@ var ResizableVideo = Node13.create({
15597
15719
  });
15598
15720
 
15599
15721
  // src/components/tetrons/toolbar/TableContextMenu.tsx
15600
- import React3, { useEffect as useEffect4, useState as useState3 } from "react";
15722
+ import React4, { useEffect as useEffect4, useState as useState3 } from "react";
15601
15723
  function TableContextMenu({ editor }) {
15602
15724
  const [menuPosition, setMenuPosition] = useState3(null);
15603
15725
  useEffect4(() => {
@@ -15625,13 +15747,13 @@ function TableContextMenu({ editor }) {
15625
15747
  const deleteRow = () => editor.chain().focus().deleteRow().run();
15626
15748
  const deleteCol = () => editor.chain().focus().deleteColumn().run();
15627
15749
  if (!menuPosition) return null;
15628
- return /* @__PURE__ */ React3.createElement(
15750
+ return /* @__PURE__ */ React4.createElement(
15629
15751
  "ul",
15630
15752
  {
15631
15753
  className: "absolute bg-white shadow border rounded text-sm z-50",
15632
15754
  style: { top: menuPosition.y, left: menuPosition.x }
15633
15755
  },
15634
- /* @__PURE__ */ React3.createElement(
15756
+ /* @__PURE__ */ React4.createElement(
15635
15757
  "li",
15636
15758
  {
15637
15759
  className: "px-3 py-1 hover:bg-gray-100 cursor-pointer",
@@ -15639,7 +15761,7 @@ function TableContextMenu({ editor }) {
15639
15761
  },
15640
15762
  "Insert Row Above"
15641
15763
  ),
15642
- /* @__PURE__ */ React3.createElement(
15764
+ /* @__PURE__ */ React4.createElement(
15643
15765
  "li",
15644
15766
  {
15645
15767
  className: "px-3 py-1 hover:bg-gray-100 cursor-pointer",
@@ -15647,7 +15769,7 @@ function TableContextMenu({ editor }) {
15647
15769
  },
15648
15770
  "Insert Row Below"
15649
15771
  ),
15650
- /* @__PURE__ */ React3.createElement(
15772
+ /* @__PURE__ */ React4.createElement(
15651
15773
  "li",
15652
15774
  {
15653
15775
  className: "px-3 py-1 hover:bg-gray-100 cursor-pointer",
@@ -15655,7 +15777,7 @@ function TableContextMenu({ editor }) {
15655
15777
  },
15656
15778
  "Insert Column Left"
15657
15779
  ),
15658
- /* @__PURE__ */ React3.createElement(
15780
+ /* @__PURE__ */ React4.createElement(
15659
15781
  "li",
15660
15782
  {
15661
15783
  className: "px-3 py-1 hover:bg-gray-100 cursor-pointer",
@@ -15663,7 +15785,7 @@ function TableContextMenu({ editor }) {
15663
15785
  },
15664
15786
  "Insert Column Right"
15665
15787
  ),
15666
- /* @__PURE__ */ React3.createElement(
15788
+ /* @__PURE__ */ React4.createElement(
15667
15789
  "li",
15668
15790
  {
15669
15791
  className: "px-3 py-1 hover:bg-red-100 cursor-pointer",
@@ -15671,7 +15793,7 @@ function TableContextMenu({ editor }) {
15671
15793
  },
15672
15794
  "Delete Row"
15673
15795
  ),
15674
- /* @__PURE__ */ React3.createElement(
15796
+ /* @__PURE__ */ React4.createElement(
15675
15797
  "li",
15676
15798
  {
15677
15799
  className: "px-3 py-1 hover:bg-red-100 cursor-pointer",
@@ -15683,10 +15805,10 @@ function TableContextMenu({ editor }) {
15683
15805
  }
15684
15806
 
15685
15807
  // src/components/tetrons/toolbar/TetronsToolbar.tsx
15686
- import React13, { useEffect as useEffect7, useState as useState8 } from "react";
15808
+ import React15, { useEffect as useEffect8, useState as useState9 } from "react";
15687
15809
 
15688
15810
  // src/components/tetrons/toolbar/ActionGroup.tsx
15689
- import React5, { useEffect as useEffect5, useRef as useRef3, useState as useState4 } from "react";
15811
+ import React6, { useEffect as useEffect5, useRef as useRef3, useState as useState4 } from "react";
15690
15812
  import {
15691
15813
  MdZoomIn,
15692
15814
  MdZoomOut,
@@ -15696,10 +15818,10 @@ import {
15696
15818
  } from "react-icons/md";
15697
15819
 
15698
15820
  // src/components/tetrons/toolbar/ToolbarButton.tsx
15699
- import React4 from "react";
15700
- var ToolbarButton = React4.forwardRef(
15821
+ import React5 from "react";
15822
+ var ToolbarButton = React5.forwardRef(
15701
15823
  ({ icon: Icon, onClick, disabled = false, title, label, isActive = false }, ref) => {
15702
- return /* @__PURE__ */ React4.createElement(
15824
+ return /* @__PURE__ */ React5.createElement(
15703
15825
  "button",
15704
15826
  {
15705
15827
  type: "button",
@@ -15710,7 +15832,7 @@ var ToolbarButton = React4.forwardRef(
15710
15832
  "aria-label": title ?? label,
15711
15833
  className: `toolbar-button ${isActive ? "active" : ""}`
15712
15834
  },
15713
- /* @__PURE__ */ React4.createElement(Icon, { size: 20 })
15835
+ /* @__PURE__ */ React5.createElement(Icon, { size: 20 })
15714
15836
  );
15715
15837
  }
15716
15838
  );
@@ -15844,7 +15966,7 @@ function ActionGroup({ editor }) {
15844
15966
  link.click();
15845
15967
  document.body.removeChild(link);
15846
15968
  };
15847
- return /* @__PURE__ */ React5.createElement("div", { className: "action-group", role: "group", "aria-label": "Editor actions" }, /* @__PURE__ */ React5.createElement(ToolbarButton_default, { icon: MdZoomIn, onClick: zoomIn, title: "Zoom In" }), /* @__PURE__ */ React5.createElement(ToolbarButton_default, { icon: MdZoomOut, onClick: zoomOut, title: "Zoom Out" }), /* @__PURE__ */ React5.createElement(ToolbarButton_default, { icon: MdPrint, onClick: handlePrint, title: "Print" }), /* @__PURE__ */ React5.createElement(ToolbarButton_default, { icon: MdSave, onClick: handleSave, title: "Save" }), /* @__PURE__ */ React5.createElement("div", { className: "relative", ref: dropdownRef }, /* @__PURE__ */ React5.createElement(
15969
+ return /* @__PURE__ */ React6.createElement("div", { className: "action-group", role: "group", "aria-label": "Editor actions" }, /* @__PURE__ */ React6.createElement(ToolbarButton_default, { icon: MdZoomIn, onClick: zoomIn, title: "Zoom In" }), /* @__PURE__ */ React6.createElement(ToolbarButton_default, { icon: MdZoomOut, onClick: zoomOut, title: "Zoom Out" }), /* @__PURE__ */ React6.createElement(ToolbarButton_default, { icon: MdPrint, onClick: handlePrint, title: "Print" }), /* @__PURE__ */ React6.createElement(ToolbarButton_default, { icon: MdSave, onClick: handleSave, title: "Save" }), /* @__PURE__ */ React6.createElement("div", { className: "relative", ref: dropdownRef }, /* @__PURE__ */ React6.createElement(
15848
15970
  "button",
15849
15971
  {
15850
15972
  type: "button",
@@ -15854,9 +15976,9 @@ function ActionGroup({ editor }) {
15854
15976
  className: "export-button",
15855
15977
  title: "Export"
15856
15978
  },
15857
- /* @__PURE__ */ React5.createElement(MdDownload, null),
15858
- /* @__PURE__ */ React5.createElement("span", { className: "text-sm" })
15859
- ), dropdownOpen && /* @__PURE__ */ React5.createElement("div", { className: "export-dropdown" }, /* @__PURE__ */ React5.createElement(
15979
+ /* @__PURE__ */ React6.createElement(MdDownload, null),
15980
+ /* @__PURE__ */ React6.createElement("span", { className: "text-sm" })
15981
+ ), dropdownOpen && /* @__PURE__ */ React6.createElement("div", { className: "export-dropdown" }, /* @__PURE__ */ React6.createElement(
15860
15982
  "button",
15861
15983
  {
15862
15984
  type: "button",
@@ -15866,7 +15988,7 @@ function ActionGroup({ editor }) {
15866
15988
  }
15867
15989
  },
15868
15990
  "Export as PDF"
15869
- ), /* @__PURE__ */ React5.createElement(
15991
+ ), /* @__PURE__ */ React6.createElement(
15870
15992
  "button",
15871
15993
  {
15872
15994
  type: "button",
@@ -15876,7 +15998,7 @@ function ActionGroup({ editor }) {
15876
15998
  }
15877
15999
  },
15878
16000
  "Export as HTML"
15879
- ), /* @__PURE__ */ React5.createElement(
16001
+ ), /* @__PURE__ */ React6.createElement(
15880
16002
  "button",
15881
16003
  {
15882
16004
  type: "button",
@@ -15896,9 +16018,9 @@ import {
15896
16018
  MdContentCopy,
15897
16019
  MdFormatPaint
15898
16020
  } from "react-icons/md";
15899
- import React6 from "react";
16021
+ import React7 from "react";
15900
16022
  function ClipboardGroup({ editor }) {
15901
- return /* @__PURE__ */ React6.createElement("div", { className: "clipboard-group" }, /* @__PURE__ */ React6.createElement(
16023
+ return /* @__PURE__ */ React7.createElement("div", { className: "clipboard-group" }, /* @__PURE__ */ React7.createElement(
15902
16024
  ToolbarButton_default,
15903
16025
  {
15904
16026
  icon: MdContentPaste,
@@ -15912,7 +16034,7 @@ function ClipboardGroup({ editor }) {
15912
16034
  }
15913
16035
  }
15914
16036
  }
15915
- ), /* @__PURE__ */ React6.createElement(
16037
+ ), /* @__PURE__ */ React7.createElement(
15916
16038
  ToolbarButton_default,
15917
16039
  {
15918
16040
  icon: MdContentCut,
@@ -15926,7 +16048,7 @@ function ClipboardGroup({ editor }) {
15926
16048
  });
15927
16049
  }
15928
16050
  }
15929
- ), /* @__PURE__ */ React6.createElement(
16051
+ ), /* @__PURE__ */ React7.createElement(
15930
16052
  ToolbarButton_default,
15931
16053
  {
15932
16054
  icon: MdContentCopy,
@@ -15938,7 +16060,7 @@ function ClipboardGroup({ editor }) {
15938
16060
  navigator.clipboard.writeText(selectedText);
15939
16061
  }
15940
16062
  }
15941
- ), /* @__PURE__ */ React6.createElement(
16063
+ ), /* @__PURE__ */ React7.createElement(
15942
16064
  ToolbarButton_default,
15943
16065
  {
15944
16066
  icon: MdFormatPaint,
@@ -15964,7 +16086,7 @@ import {
15964
16086
  } from "react-icons/md";
15965
16087
  import { ImTextColor } from "react-icons/im";
15966
16088
  import { BiSolidColorFill } from "react-icons/bi";
15967
- import React7, { useEffect as useEffect6, useState as useState5 } from "react";
16089
+ import React8, { useEffect as useEffect6, useState as useState5 } from "react";
15968
16090
  function FontStyleGroup({ editor }) {
15969
16091
  const [textColor, setTextColor] = useState5("#000000");
15970
16092
  const [highlightColor, setHighlightColor] = useState5("#ffff00");
@@ -15990,7 +16112,7 @@ function FontStyleGroup({ editor }) {
15990
16112
  editor.off("transaction", updateStates);
15991
16113
  };
15992
16114
  }, [editor]);
15993
- return /* @__PURE__ */ React7.createElement("div", { className: "font-style-group" }, /* @__PURE__ */ React7.createElement(
16115
+ return /* @__PURE__ */ React8.createElement("div", { className: "font-style-group" }, /* @__PURE__ */ React8.createElement(
15994
16116
  "select",
15995
16117
  {
15996
16118
  title: "Font Family",
@@ -16001,12 +16123,12 @@ function FontStyleGroup({ editor }) {
16001
16123
  editor.chain().focus().setFontFamily(value).run();
16002
16124
  }
16003
16125
  },
16004
- /* @__PURE__ */ React7.createElement("option", { value: "Arial" }, "Arial"),
16005
- /* @__PURE__ */ React7.createElement("option", { value: "Georgia" }, "Georgia"),
16006
- /* @__PURE__ */ React7.createElement("option", { value: "Times New Roman" }, "Times New Roman"),
16007
- /* @__PURE__ */ React7.createElement("option", { value: "Courier New" }, "Courier New"),
16008
- /* @__PURE__ */ React7.createElement("option", { value: "Verdana" }, "Verdana")
16009
- ), /* @__PURE__ */ React7.createElement(
16126
+ /* @__PURE__ */ React8.createElement("option", { value: "Arial" }, "Arial"),
16127
+ /* @__PURE__ */ React8.createElement("option", { value: "Georgia" }, "Georgia"),
16128
+ /* @__PURE__ */ React8.createElement("option", { value: "Times New Roman" }, "Times New Roman"),
16129
+ /* @__PURE__ */ React8.createElement("option", { value: "Courier New" }, "Courier New"),
16130
+ /* @__PURE__ */ React8.createElement("option", { value: "Verdana" }, "Verdana")
16131
+ ), /* @__PURE__ */ React8.createElement(
16010
16132
  "select",
16011
16133
  {
16012
16134
  title: "Font Size",
@@ -16017,16 +16139,16 @@ function FontStyleGroup({ editor }) {
16017
16139
  editor.chain().focus().setFontSize(value).run();
16018
16140
  }
16019
16141
  },
16020
- /* @__PURE__ */ React7.createElement("option", { value: "12px" }, "12"),
16021
- /* @__PURE__ */ React7.createElement("option", { value: "14px" }, "14"),
16022
- /* @__PURE__ */ React7.createElement("option", { value: "16px" }, "16"),
16023
- /* @__PURE__ */ React7.createElement("option", { value: "18px" }, "18"),
16024
- /* @__PURE__ */ React7.createElement("option", { value: "24px" }, "24"),
16025
- /* @__PURE__ */ React7.createElement("option", { value: "36px" }, "36"),
16026
- /* @__PURE__ */ React7.createElement("option", { value: "48px" }, "48"),
16027
- /* @__PURE__ */ React7.createElement("option", { value: "64px" }, "64"),
16028
- /* @__PURE__ */ React7.createElement("option", { value: "72px" }, "72")
16029
- ), /* @__PURE__ */ React7.createElement(
16142
+ /* @__PURE__ */ React8.createElement("option", { value: "12px" }, "12"),
16143
+ /* @__PURE__ */ React8.createElement("option", { value: "14px" }, "14"),
16144
+ /* @__PURE__ */ React8.createElement("option", { value: "16px" }, "16"),
16145
+ /* @__PURE__ */ React8.createElement("option", { value: "18px" }, "18"),
16146
+ /* @__PURE__ */ React8.createElement("option", { value: "24px" }, "24"),
16147
+ /* @__PURE__ */ React8.createElement("option", { value: "36px" }, "36"),
16148
+ /* @__PURE__ */ React8.createElement("option", { value: "48px" }, "48"),
16149
+ /* @__PURE__ */ React8.createElement("option", { value: "64px" }, "64"),
16150
+ /* @__PURE__ */ React8.createElement("option", { value: "72px" }, "72")
16151
+ ), /* @__PURE__ */ React8.createElement(
16030
16152
  ToolbarButton_default,
16031
16153
  {
16032
16154
  icon: MdFormatBold,
@@ -16034,7 +16156,7 @@ function FontStyleGroup({ editor }) {
16034
16156
  onClick: () => editor.chain().focus().toggleBold().run(),
16035
16157
  isActive: editor.isActive("bold")
16036
16158
  }
16037
- ), /* @__PURE__ */ React7.createElement(
16159
+ ), /* @__PURE__ */ React8.createElement(
16038
16160
  ToolbarButton_default,
16039
16161
  {
16040
16162
  icon: MdFormatItalic,
@@ -16042,7 +16164,7 @@ function FontStyleGroup({ editor }) {
16042
16164
  onClick: () => editor.chain().focus().toggleItalic().run(),
16043
16165
  isActive: editor.isActive("italic")
16044
16166
  }
16045
- ), /* @__PURE__ */ React7.createElement(
16167
+ ), /* @__PURE__ */ React8.createElement(
16046
16168
  ToolbarButton_default,
16047
16169
  {
16048
16170
  icon: MdFormatUnderlined,
@@ -16050,7 +16172,7 @@ function FontStyleGroup({ editor }) {
16050
16172
  onClick: () => editor.chain().focus().toggleUnderline().run(),
16051
16173
  isActive: editor.isActive("underline")
16052
16174
  }
16053
- ), /* @__PURE__ */ React7.createElement(
16175
+ ), /* @__PURE__ */ React8.createElement(
16054
16176
  ToolbarButton_default,
16055
16177
  {
16056
16178
  icon: MdStrikethroughS,
@@ -16058,7 +16180,7 @@ function FontStyleGroup({ editor }) {
16058
16180
  onClick: () => editor.chain().focus().toggleStrike().run(),
16059
16181
  isActive: editor.isActive("strike")
16060
16182
  }
16061
- ), /* @__PURE__ */ React7.createElement(
16183
+ ), /* @__PURE__ */ React8.createElement(
16062
16184
  ToolbarButton_default,
16063
16185
  {
16064
16186
  icon: MdSubscript,
@@ -16066,7 +16188,7 @@ function FontStyleGroup({ editor }) {
16066
16188
  onClick: () => editor.chain().focus().toggleSubscript().run(),
16067
16189
  isActive: editor.isActive("subscript")
16068
16190
  }
16069
- ), /* @__PURE__ */ React7.createElement(
16191
+ ), /* @__PURE__ */ React8.createElement(
16070
16192
  ToolbarButton_default,
16071
16193
  {
16072
16194
  icon: MdSuperscript,
@@ -16074,7 +16196,7 @@ function FontStyleGroup({ editor }) {
16074
16196
  onClick: () => editor.chain().focus().toggleSuperscript().run(),
16075
16197
  isActive: editor.isActive("superscript")
16076
16198
  }
16077
- ), /* @__PURE__ */ React7.createElement(
16199
+ ), /* @__PURE__ */ React8.createElement(
16078
16200
  "label",
16079
16201
  {
16080
16202
  title: "Font Color",
@@ -16082,9 +16204,9 @@ function FontStyleGroup({ editor }) {
16082
16204
  className: "color-label",
16083
16205
  style: { "--indicator-color": textColor }
16084
16206
  },
16085
- /* @__PURE__ */ React7.createElement(ImTextColor, { size: 20 }),
16086
- /* @__PURE__ */ React7.createElement("div", { className: "color-indicator" }),
16087
- /* @__PURE__ */ React7.createElement(
16207
+ /* @__PURE__ */ React8.createElement(ImTextColor, { size: 20 }),
16208
+ /* @__PURE__ */ React8.createElement("div", { className: "color-indicator" }),
16209
+ /* @__PURE__ */ React8.createElement(
16088
16210
  "input",
16089
16211
  {
16090
16212
  type: "color",
@@ -16096,7 +16218,7 @@ function FontStyleGroup({ editor }) {
16096
16218
  }
16097
16219
  }
16098
16220
  )
16099
- ), /* @__PURE__ */ React7.createElement(
16221
+ ), /* @__PURE__ */ React8.createElement(
16100
16222
  "label",
16101
16223
  {
16102
16224
  title: "Highlight Color",
@@ -16104,9 +16226,9 @@ function FontStyleGroup({ editor }) {
16104
16226
  className: "color-label",
16105
16227
  style: { "--indicator-color": highlightColor }
16106
16228
  },
16107
- /* @__PURE__ */ React7.createElement(BiSolidColorFill, { size: 20 }),
16108
- /* @__PURE__ */ React7.createElement("div", { className: "color-indicator" }),
16109
- /* @__PURE__ */ React7.createElement(
16229
+ /* @__PURE__ */ React8.createElement(BiSolidColorFill, { size: 20 }),
16230
+ /* @__PURE__ */ React8.createElement("div", { className: "color-indicator" }),
16231
+ /* @__PURE__ */ React8.createElement(
16110
16232
  "input",
16111
16233
  {
16112
16234
  type: "color",
@@ -16118,14 +16240,14 @@ function FontStyleGroup({ editor }) {
16118
16240
  }
16119
16241
  }
16120
16242
  )
16121
- ), /* @__PURE__ */ React7.createElement(
16243
+ ), /* @__PURE__ */ React8.createElement(
16122
16244
  ToolbarButton_default,
16123
16245
  {
16124
16246
  icon: MdFormatClear,
16125
16247
  label: "Clear Formatting",
16126
16248
  onClick: () => editor.chain().focus().unsetAllMarks().run()
16127
16249
  }
16128
- ), /* @__PURE__ */ React7.createElement(
16250
+ ), /* @__PURE__ */ React8.createElement(
16129
16251
  ToolbarButton_default,
16130
16252
  {
16131
16253
  icon: MdFormatPaint2,
@@ -16144,7 +16266,7 @@ function FontStyleGroup({ editor }) {
16144
16266
  }
16145
16267
 
16146
16268
  // src/components/tetrons/toolbar/InsertGroup.tsx
16147
- import React8, { useRef as useRef4, useState as useState6 } from "react";
16269
+ import React9, { useRef as useRef4, useState as useState6 } from "react";
16148
16270
  import {
16149
16271
  MdTableChart,
16150
16272
  MdInsertPhoto,
@@ -16231,7 +16353,7 @@ function InsertGroup({ editor }) {
16231
16353
  return url;
16232
16354
  }
16233
16355
  }
16234
- return /* @__PURE__ */ React8.createElement("div", { className: "insert-group" }, /* @__PURE__ */ React8.createElement(
16356
+ return /* @__PURE__ */ React9.createElement("div", { className: "insert-group" }, /* @__PURE__ */ React9.createElement(
16235
16357
  "input",
16236
16358
  {
16237
16359
  type: "file",
@@ -16242,7 +16364,7 @@ function InsertGroup({ editor }) {
16242
16364
  "aria-label": "Upload Image",
16243
16365
  title: "Upload Image"
16244
16366
  }
16245
- ), /* @__PURE__ */ React8.createElement(
16367
+ ), /* @__PURE__ */ React9.createElement(
16246
16368
  "input",
16247
16369
  {
16248
16370
  type: "file",
@@ -16253,23 +16375,23 @@ function InsertGroup({ editor }) {
16253
16375
  "aria-label": "Upload Video",
16254
16376
  title: "Upload Video"
16255
16377
  }
16256
- ), /* @__PURE__ */ React8.createElement(
16378
+ ), /* @__PURE__ */ React9.createElement(
16257
16379
  ToolbarButton_default,
16258
16380
  {
16259
16381
  icon: MdTableChart,
16260
16382
  label: "Insert Table",
16261
16383
  onClick: () => setShowTableGrid(!showTableGrid)
16262
16384
  }
16263
- ), showTableGrid && /* @__PURE__ */ React8.createElement(
16385
+ ), showTableGrid && /* @__PURE__ */ React9.createElement(
16264
16386
  "div",
16265
16387
  {
16266
16388
  className: "table-grid-popup",
16267
16389
  onMouseLeave: () => setShowTableGrid(false)
16268
16390
  },
16269
- /* @__PURE__ */ React8.createElement("div", { className: "table-grid" }, [...Array(10)].map(
16391
+ /* @__PURE__ */ React9.createElement("div", { className: "table-grid" }, [...Array(10)].map(
16270
16392
  (_, row) => [...Array(10)].map((_2, col) => {
16271
16393
  const isSelected = row < selectedRows && col < selectedCols;
16272
- return /* @__PURE__ */ React8.createElement(
16394
+ return /* @__PURE__ */ React9.createElement(
16273
16395
  "div",
16274
16396
  {
16275
16397
  key: `${row}-${col}`,
@@ -16280,22 +16402,22 @@ function InsertGroup({ editor }) {
16280
16402
  );
16281
16403
  })
16282
16404
  )),
16283
- /* @__PURE__ */ React8.createElement("div", { className: "table-grid-label" }, selectedRows, " x ", selectedCols)
16284
- ), /* @__PURE__ */ React8.createElement(
16405
+ /* @__PURE__ */ React9.createElement("div", { className: "table-grid-label" }, selectedRows, " x ", selectedCols)
16406
+ ), /* @__PURE__ */ React9.createElement(
16285
16407
  ToolbarButton_default,
16286
16408
  {
16287
16409
  icon: MdInsertPhoto,
16288
16410
  label: "Insert Image",
16289
16411
  onClick: () => imageInputRef.current?.click()
16290
16412
  }
16291
- ), /* @__PURE__ */ React8.createElement(
16413
+ ), /* @__PURE__ */ React9.createElement(
16292
16414
  ToolbarButton_default,
16293
16415
  {
16294
16416
  icon: MdVideoLibrary,
16295
16417
  label: "Insert Video",
16296
16418
  onClick: () => videoInputRef.current?.click()
16297
16419
  }
16298
- ), /* @__PURE__ */ React8.createElement(
16420
+ ), /* @__PURE__ */ React9.createElement(
16299
16421
  ToolbarButton_default,
16300
16422
  {
16301
16423
  icon: MdInsertLink,
@@ -16307,7 +16429,7 @@ function InsertGroup({ editor }) {
16307
16429
  }
16308
16430
  }
16309
16431
  }
16310
- ), /* @__PURE__ */ React8.createElement(
16432
+ ), /* @__PURE__ */ React9.createElement(
16311
16433
  ToolbarButton_default,
16312
16434
  {
16313
16435
  icon: MdInsertComment,
@@ -16321,14 +16443,14 @@ function InsertGroup({ editor }) {
16321
16443
  }
16322
16444
  }
16323
16445
  }
16324
- ), /* @__PURE__ */ React8.createElement("div", { className: "relative" }, /* @__PURE__ */ React8.createElement(
16446
+ ), /* @__PURE__ */ React9.createElement("div", { className: "relative" }, /* @__PURE__ */ React9.createElement(
16325
16447
  ToolbarButton_default,
16326
16448
  {
16327
16449
  icon: MdInsertEmoticon,
16328
16450
  label: "Emoji",
16329
16451
  onClick: () => setShowPicker(!showPicker)
16330
16452
  }
16331
- ), showPicker && /* @__PURE__ */ React8.createElement("div", { className: "emoji-picker" }, /* @__PURE__ */ React8.createElement(
16453
+ ), showPicker && /* @__PURE__ */ React9.createElement("div", { className: "emoji-picker" }, /* @__PURE__ */ React9.createElement(
16332
16454
  Picker,
16333
16455
  {
16334
16456
  onEmojiSelect: addEmoji,
@@ -16338,14 +16460,14 @@ function InsertGroup({ editor }) {
16338
16460
  showSkinTones: true,
16339
16461
  emojiTooltip: true
16340
16462
  }
16341
- ))), /* @__PURE__ */ React8.createElement(
16463
+ ))), /* @__PURE__ */ React9.createElement(
16342
16464
  ToolbarButton_default,
16343
16465
  {
16344
16466
  icon: MdHorizontalRule,
16345
16467
  label: "Horizontal Line",
16346
16468
  onClick: () => editor.chain().focus().setHorizontalRule().run()
16347
16469
  }
16348
- ), /* @__PURE__ */ React8.createElement(
16470
+ ), /* @__PURE__ */ React9.createElement(
16349
16471
  ToolbarButton_default,
16350
16472
  {
16351
16473
  icon: MdOutlineOndemandVideo,
@@ -16369,7 +16491,7 @@ function InsertGroup({ editor }) {
16369
16491
  }
16370
16492
 
16371
16493
  // src/components/tetrons/toolbar/ListAlignGroup.tsx
16372
- import React9 from "react";
16494
+ import React10 from "react";
16373
16495
  import {
16374
16496
  MdFormatListBulleted,
16375
16497
  MdFormatListNumbered,
@@ -16381,7 +16503,7 @@ import {
16381
16503
  MdFormatAlignJustify
16382
16504
  } from "react-icons/md";
16383
16505
  function ListAlignGroup({ editor }) {
16384
- return /* @__PURE__ */ React9.createElement("div", { className: "list-align-group" }, /* @__PURE__ */ React9.createElement(
16506
+ return /* @__PURE__ */ React10.createElement("div", { className: "list-align-group" }, /* @__PURE__ */ React10.createElement(
16385
16507
  ToolbarButton_default,
16386
16508
  {
16387
16509
  icon: MdFormatListBulleted,
@@ -16389,7 +16511,7 @@ function ListAlignGroup({ editor }) {
16389
16511
  onClick: () => editor.chain().focus().toggleBulletList().run(),
16390
16512
  disabled: !editor.can().toggleBulletList()
16391
16513
  }
16392
- ), /* @__PURE__ */ React9.createElement(
16514
+ ), /* @__PURE__ */ React10.createElement(
16393
16515
  ToolbarButton_default,
16394
16516
  {
16395
16517
  icon: MdFormatListNumbered,
@@ -16397,7 +16519,7 @@ function ListAlignGroup({ editor }) {
16397
16519
  onClick: () => editor.chain().focus().toggleOrderedList().run(),
16398
16520
  disabled: !editor.can().toggleOrderedList()
16399
16521
  }
16400
- ), /* @__PURE__ */ React9.createElement(
16522
+ ), /* @__PURE__ */ React10.createElement(
16401
16523
  ToolbarButton_default,
16402
16524
  {
16403
16525
  icon: MdFormatIndentIncrease,
@@ -16405,7 +16527,7 @@ function ListAlignGroup({ editor }) {
16405
16527
  onClick: () => editor.chain().focus().sinkListItem("listItem").run(),
16406
16528
  disabled: !editor.can().sinkListItem("listItem")
16407
16529
  }
16408
- ), /* @__PURE__ */ React9.createElement(
16530
+ ), /* @__PURE__ */ React10.createElement(
16409
16531
  ToolbarButton_default,
16410
16532
  {
16411
16533
  icon: MdFormatIndentDecrease,
@@ -16413,7 +16535,7 @@ function ListAlignGroup({ editor }) {
16413
16535
  onClick: () => editor.chain().focus().liftListItem("listItem").run(),
16414
16536
  disabled: !editor.can().liftListItem("listItem")
16415
16537
  }
16416
- ), /* @__PURE__ */ React9.createElement(
16538
+ ), /* @__PURE__ */ React10.createElement(
16417
16539
  ToolbarButton_default,
16418
16540
  {
16419
16541
  icon: MdFormatAlignLeft,
@@ -16421,7 +16543,7 @@ function ListAlignGroup({ editor }) {
16421
16543
  onClick: () => editor.chain().focus().setTextAlign("left").run(),
16422
16544
  disabled: !editor.can().setTextAlign("left")
16423
16545
  }
16424
- ), /* @__PURE__ */ React9.createElement(
16546
+ ), /* @__PURE__ */ React10.createElement(
16425
16547
  ToolbarButton_default,
16426
16548
  {
16427
16549
  icon: MdFormatAlignCenter,
@@ -16429,7 +16551,7 @@ function ListAlignGroup({ editor }) {
16429
16551
  onClick: () => editor.chain().focus().setTextAlign("center").run(),
16430
16552
  disabled: !editor.can().setTextAlign("center")
16431
16553
  }
16432
- ), /* @__PURE__ */ React9.createElement(
16554
+ ), /* @__PURE__ */ React10.createElement(
16433
16555
  ToolbarButton_default,
16434
16556
  {
16435
16557
  icon: MdFormatAlignRight,
@@ -16437,7 +16559,7 @@ function ListAlignGroup({ editor }) {
16437
16559
  onClick: () => editor.chain().focus().setTextAlign("right").run(),
16438
16560
  disabled: !editor.can().setTextAlign("right")
16439
16561
  }
16440
- ), /* @__PURE__ */ React9.createElement(
16562
+ ), /* @__PURE__ */ React10.createElement(
16441
16563
  ToolbarButton_default,
16442
16564
  {
16443
16565
  icon: MdFormatAlignJustify,
@@ -16449,7 +16571,7 @@ function ListAlignGroup({ editor }) {
16449
16571
  }
16450
16572
 
16451
16573
  // src/components/tetrons/toolbar/MiscGroup.tsx
16452
- import React10 from "react";
16574
+ import React11 from "react";
16453
16575
  import {
16454
16576
  MdUndo,
16455
16577
  MdRedo,
@@ -16522,7 +16644,7 @@ Reason: ${issue.message}
16522
16644
  alert("\u274C Failed to check grammar. Please try again later.");
16523
16645
  }
16524
16646
  };
16525
- return /* @__PURE__ */ React10.createElement("div", { className: "misc-group" }, /* @__PURE__ */ React10.createElement(
16647
+ return /* @__PURE__ */ React11.createElement("div", { className: "misc-group" }, /* @__PURE__ */ React11.createElement(
16526
16648
  ToolbarButton_default,
16527
16649
  {
16528
16650
  icon: MdUndo,
@@ -16530,7 +16652,7 @@ Reason: ${issue.message}
16530
16652
  onClick: () => editor.chain().focus().undo().run(),
16531
16653
  disabled: !editor.can().undo()
16532
16654
  }
16533
- ), /* @__PURE__ */ React10.createElement(
16655
+ ), /* @__PURE__ */ React11.createElement(
16534
16656
  ToolbarButton_default,
16535
16657
  {
16536
16658
  icon: MdRedo,
@@ -16538,14 +16660,14 @@ Reason: ${issue.message}
16538
16660
  onClick: () => editor.chain().focus().redo().run(),
16539
16661
  disabled: !editor.can().redo()
16540
16662
  }
16541
- ), /* @__PURE__ */ React10.createElement(
16663
+ ), /* @__PURE__ */ React11.createElement(
16542
16664
  ToolbarButton_default,
16543
16665
  {
16544
16666
  icon: MdRefresh,
16545
16667
  label: "Reset Formatting",
16546
16668
  onClick: () => editor.chain().focus().unsetAllMarks().clearNodes().run()
16547
16669
  }
16548
- ), /* @__PURE__ */ React10.createElement(
16670
+ ), /* @__PURE__ */ React11.createElement(
16549
16671
  ToolbarButton_default,
16550
16672
  {
16551
16673
  icon: MdCode,
@@ -16553,14 +16675,14 @@ Reason: ${issue.message}
16553
16675
  onClick: () => editor.chain().focus().toggleCodeBlock().run(),
16554
16676
  isActive: editor.isActive("codeBlock")
16555
16677
  }
16556
- ), /* @__PURE__ */ React10.createElement(
16678
+ ), /* @__PURE__ */ React11.createElement(
16557
16679
  ToolbarButton_default,
16558
16680
  {
16559
16681
  icon: MdVisibility,
16560
16682
  label: "Preview",
16561
16683
  onClick: handlePreview
16562
16684
  }
16563
- ), /* @__PURE__ */ React10.createElement(
16685
+ ), /* @__PURE__ */ React11.createElement(
16564
16686
  ToolbarButton_default,
16565
16687
  {
16566
16688
  icon: MdSpellcheck,
@@ -16573,7 +16695,7 @@ Reason: ${issue.message}
16573
16695
  // src/components/tetrons/toolbar/FileGroup.tsx
16574
16696
  import { FaRegFolderOpen } from "react-icons/fa";
16575
16697
  import { VscNewFile } from "react-icons/vsc";
16576
- import React11, { useRef as useRef5 } from "react";
16698
+ import React12, { useRef as useRef5 } from "react";
16577
16699
  function FileGroup({ editor }) {
16578
16700
  const fileInputRef = useRef5(null);
16579
16701
  const handleNew = () => {
@@ -16602,7 +16724,7 @@ function FileGroup({ editor }) {
16602
16724
  e.target.value = "";
16603
16725
  }
16604
16726
  };
16605
- return /* @__PURE__ */ React11.createElement("div", { className: "file-group", role: "group", "aria-label": "File actions" }, /* @__PURE__ */ React11.createElement(
16727
+ return /* @__PURE__ */ React12.createElement("div", { className: "file-group", role: "group", "aria-label": "File actions" }, /* @__PURE__ */ React12.createElement(
16606
16728
  "input",
16607
16729
  {
16608
16730
  type: "file",
@@ -16612,7 +16734,7 @@ function FileGroup({ editor }) {
16612
16734
  className: "hidden",
16613
16735
  "aria-label": "Open JSON file"
16614
16736
  }
16615
- ), /* @__PURE__ */ React11.createElement(ToolbarButton_default, { icon: VscNewFile, onClick: handleNew, title: "New" }), /* @__PURE__ */ React11.createElement(
16737
+ ), /* @__PURE__ */ React12.createElement(ToolbarButton_default, { icon: VscNewFile, onClick: handleNew, title: "New" }), /* @__PURE__ */ React12.createElement(
16616
16738
  ToolbarButton_default,
16617
16739
  {
16618
16740
  icon: FaRegFolderOpen,
@@ -16623,7 +16745,7 @@ function FileGroup({ editor }) {
16623
16745
  }
16624
16746
 
16625
16747
  // src/components/tetrons/toolbar/AIGroup.tsx
16626
- import React12, { useState as useState7, useRef as useRef6 } from "react";
16748
+ import React13, { useState as useState7, useRef as useRef6 } from "react";
16627
16749
  import { FaMicrophone, FaStop } from "react-icons/fa";
16628
16750
  import { Waveform } from "@uiball/loaders";
16629
16751
  import { motion, AnimatePresence } from "framer-motion";
@@ -16710,7 +16832,7 @@ function AiGroup({ editor }) {
16710
16832
  setIsLoadingAI(false);
16711
16833
  }
16712
16834
  };
16713
- return /* @__PURE__ */ React12.createElement("div", { className: "group relative space-y-3" }, /* @__PURE__ */ React12.createElement("div", { className: "flex gap-2 items-center" }, !isRecording ? /* @__PURE__ */ React12.createElement(
16835
+ return /* @__PURE__ */ React13.createElement("div", { className: "group relative space-y-3" }, /* @__PURE__ */ React13.createElement("div", { className: "flex gap-2 items-center" }, !isRecording ? /* @__PURE__ */ React13.createElement(
16714
16836
  "button",
16715
16837
  {
16716
16838
  type: "button",
@@ -16718,8 +16840,8 @@ function AiGroup({ editor }) {
16718
16840
  className: "icon-btn",
16719
16841
  title: "Start Voice Input"
16720
16842
  },
16721
- /* @__PURE__ */ React12.createElement(FaMicrophone, { size: 18 })
16722
- ) : /* @__PURE__ */ React12.createElement(
16843
+ /* @__PURE__ */ React13.createElement(FaMicrophone, { size: 18 })
16844
+ ) : /* @__PURE__ */ React13.createElement(
16723
16845
  "button",
16724
16846
  {
16725
16847
  type: "button",
@@ -16727,8 +16849,8 @@ function AiGroup({ editor }) {
16727
16849
  className: "icon-btn stop-btn",
16728
16850
  title: "Stop Recording"
16729
16851
  },
16730
- /* @__PURE__ */ React12.createElement(FaStop, { size: 18 })
16731
- ), /* @__PURE__ */ React12.createElement(
16852
+ /* @__PURE__ */ React13.createElement(FaStop, { size: 18 })
16853
+ ), /* @__PURE__ */ React13.createElement(
16732
16854
  "button",
16733
16855
  {
16734
16856
  type: "button",
@@ -16737,7 +16859,7 @@ function AiGroup({ editor }) {
16737
16859
  title: "AI Assist"
16738
16860
  },
16739
16861
  "AI"
16740
- )), isRecording && /* @__PURE__ */ React12.createElement("div", { className: "flex flex-col items-center" }, /* @__PURE__ */ React12.createElement(Waveform, { size: 30, lineWeight: 3.5, speed: 1, color: "#4F46E5" }), /* @__PURE__ */ React12.createElement("p", { className: "text-sm mt-1 text-gray-600" }, "Recording...")), isTranscribing && /* @__PURE__ */ React12.createElement("p", { className: "text-sm text-gray-500" }, "Transcribing..."), transcriptionError && /* @__PURE__ */ React12.createElement("p", { className: "text-sm text-red-600" }, transcriptionError), audioBlob && /* @__PURE__ */ React12.createElement("div", { className: "mt-2" }, /* @__PURE__ */ React12.createElement("audio", { controls: true, src: URL.createObjectURL(audioBlob) })), /* @__PURE__ */ React12.createElement(AnimatePresence, null, showPromptInput && /* @__PURE__ */ React12.createElement(
16862
+ )), isRecording && /* @__PURE__ */ React13.createElement("div", { className: "flex flex-col items-center" }, /* @__PURE__ */ React13.createElement(Waveform, { size: 30, lineWeight: 3.5, speed: 1, color: "#4F46E5" }), /* @__PURE__ */ React13.createElement("p", { className: "text-sm mt-1 text-gray-600" }, "Recording...")), isTranscribing && /* @__PURE__ */ React13.createElement("p", { className: "text-sm text-gray-500" }, "Transcribing..."), transcriptionError && /* @__PURE__ */ React13.createElement("p", { className: "text-sm text-red-600" }, transcriptionError), audioBlob && /* @__PURE__ */ React13.createElement("div", { className: "mt-2" }, /* @__PURE__ */ React13.createElement("audio", { controls: true, src: URL.createObjectURL(audioBlob) })), /* @__PURE__ */ React13.createElement(AnimatePresence, null, showPromptInput && /* @__PURE__ */ React13.createElement(
16741
16863
  motion.div,
16742
16864
  {
16743
16865
  className: "ai-modal-backdrop",
@@ -16745,7 +16867,7 @@ function AiGroup({ editor }) {
16745
16867
  animate: { opacity: 1 },
16746
16868
  exit: { opacity: 0 }
16747
16869
  },
16748
- /* @__PURE__ */ React12.createElement(
16870
+ /* @__PURE__ */ React13.createElement(
16749
16871
  motion.div,
16750
16872
  {
16751
16873
  className: "ai-modal-content",
@@ -16753,8 +16875,8 @@ function AiGroup({ editor }) {
16753
16875
  animate: { scale: 1, opacity: 1 },
16754
16876
  exit: { scale: 0.9, opacity: 0 }
16755
16877
  },
16756
- /* @__PURE__ */ React12.createElement("h2", { className: "ai-modal-title" }, "AI Prompt"),
16757
- /* @__PURE__ */ React12.createElement(
16878
+ /* @__PURE__ */ React13.createElement("h2", { className: "ai-modal-title" }, "AI Prompt"),
16879
+ /* @__PURE__ */ React13.createElement(
16758
16880
  "textarea",
16759
16881
  {
16760
16882
  className: "ai-modal-textarea",
@@ -16763,15 +16885,15 @@ function AiGroup({ editor }) {
16763
16885
  placeholder: "Enter your prompt here..."
16764
16886
  }
16765
16887
  ),
16766
- aiError && /* @__PURE__ */ React12.createElement("p", { className: "ai-modal-error" }, aiError),
16767
- /* @__PURE__ */ React12.createElement("div", { className: "ai-modal-actions" }, /* @__PURE__ */ React12.createElement(
16888
+ aiError && /* @__PURE__ */ React13.createElement("p", { className: "ai-modal-error" }, aiError),
16889
+ /* @__PURE__ */ React13.createElement("div", { className: "ai-modal-actions" }, /* @__PURE__ */ React13.createElement(
16768
16890
  "button",
16769
16891
  {
16770
16892
  onClick: () => setShowPromptInput(false),
16771
16893
  className: "ai-cancel-btn"
16772
16894
  },
16773
16895
  "Cancel"
16774
- ), /* @__PURE__ */ React12.createElement(
16896
+ ), /* @__PURE__ */ React13.createElement(
16775
16897
  "button",
16776
16898
  {
16777
16899
  onClick: handlePromptSubmit,
@@ -16784,13 +16906,66 @@ function AiGroup({ editor }) {
16784
16906
  )));
16785
16907
  }
16786
16908
 
16909
+ // src/components/tetrons/toolbar/AddOnGroup.tsx
16910
+ import React14, { useState as useState8 } from "react";
16911
+ import { FaCode, FaSuperscript } from "react-icons/fa";
16912
+ import dynamic from "next/dynamic";
16913
+ import "katex/dist/katex.min.css";
16914
+ var MathModal2 = dynamic(() => Promise.resolve().then(() => (init_MathModal(), MathModal_exports)), { ssr: false });
16915
+ var AddOnGroup = ({ editor }) => {
16916
+ const [isModalOpen, setModalOpen] = useState8(false);
16917
+ const [latexValue, setLatexValue] = useState8("");
16918
+ if (!editor) return null;
16919
+ const insertCodeBlock = () => {
16920
+ editor.chain().focus().toggleCodeBlock().run();
16921
+ };
16922
+ const handleMathInsert = (latex) => {
16923
+ editor.chain().focus().insertContent({
16924
+ type: "mathInline",
16925
+ attrs: { formula: latex }
16926
+ }).run();
16927
+ setModalOpen(false);
16928
+ setLatexValue("");
16929
+ };
16930
+ return /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement("div", { className: "group flex gap-2 items-center" }, /* @__PURE__ */ React14.createElement(
16931
+ "button",
16932
+ {
16933
+ type: "button",
16934
+ onClick: insertCodeBlock,
16935
+ className: "icon-btn",
16936
+ title: "Insert Code Block"
16937
+ },
16938
+ /* @__PURE__ */ React14.createElement(FaCode, { size: 18 })
16939
+ ), /* @__PURE__ */ React14.createElement(
16940
+ "button",
16941
+ {
16942
+ type: "button",
16943
+ onClick: () => setModalOpen(true),
16944
+ className: "icon-btn",
16945
+ title: "Insert Math Equation"
16946
+ },
16947
+ /* @__PURE__ */ React14.createElement(FaSuperscript, { size: 18 })
16948
+ )), /* @__PURE__ */ React14.createElement(
16949
+ MathModal2,
16950
+ {
16951
+ isOpen: isModalOpen,
16952
+ onClose: () => setModalOpen(false),
16953
+ onSubmit: handleMathInsert,
16954
+ value: latexValue,
16955
+ setValue: setLatexValue
16956
+ }
16957
+ ));
16958
+ };
16959
+ var AddOnGroup_default = AddOnGroup;
16960
+
16787
16961
  // src/components/tetrons/toolbar/TetronsToolbar.tsx
16788
16962
  function TetronsToolbar({
16789
16963
  editor,
16790
- version
16964
+ version,
16965
+ addOns = []
16791
16966
  }) {
16792
- const [autoSave, setAutoSave] = useState8(false);
16793
- useEffect7(() => {
16967
+ const [autoSave, setAutoSave] = useState9(false);
16968
+ useEffect8(() => {
16794
16969
  if (!editor) return;
16795
16970
  const handleUpdate = () => {
16796
16971
  if (!autoSave) return;
@@ -16806,7 +16981,7 @@ function TetronsToolbar({
16806
16981
  editor.off("update", handleUpdate);
16807
16982
  };
16808
16983
  }, [autoSave, editor]);
16809
- return /* @__PURE__ */ React13.createElement("div", { className: "tetrons-toolbar" }, version !== "free" && /* @__PURE__ */ React13.createElement("div", { className: "group" }, /* @__PURE__ */ React13.createElement(
16984
+ return /* @__PURE__ */ React15.createElement("div", { className: "tetrons-toolbar" }, version !== "free" && /* @__PURE__ */ React15.createElement("div", { className: "group" }, /* @__PURE__ */ React15.createElement(
16810
16985
  "input",
16811
16986
  {
16812
16987
  type: "checkbox",
@@ -16814,7 +16989,7 @@ function TetronsToolbar({
16814
16989
  checked: autoSave,
16815
16990
  onChange: (e) => setAutoSave(e.target.checked)
16816
16991
  }
16817
- ), /* @__PURE__ */ React13.createElement("label", { htmlFor: "autoSave" }, "Auto Save")), ["pro", "premium", "platinum"].includes(version) && /* @__PURE__ */ React13.createElement(FileGroup, { editor }), /* @__PURE__ */ React13.createElement(ClipboardGroup, { editor }), /* @__PURE__ */ React13.createElement(FontStyleGroup, { editor }), /* @__PURE__ */ React13.createElement(ListAlignGroup, { editor }), ["premium", "platinum"].includes(version) && /* @__PURE__ */ React13.createElement(React13.Fragment, null, /* @__PURE__ */ React13.createElement(InsertGroup, { editor }), /* @__PURE__ */ React13.createElement(ActionGroup, { editor })), version === "platinum" && /* @__PURE__ */ React13.createElement(React13.Fragment, null, /* @__PURE__ */ React13.createElement(MiscGroup, { editor }), /* @__PURE__ */ React13.createElement(AiGroup, { editor })));
16992
+ ), /* @__PURE__ */ React15.createElement("label", { htmlFor: "autoSave" }, "Auto Save")), ["pro", "premium", "platinum"].includes(version) && /* @__PURE__ */ React15.createElement(FileGroup, { editor }), /* @__PURE__ */ React15.createElement(ClipboardGroup, { editor }), /* @__PURE__ */ React15.createElement(FontStyleGroup, { editor }), /* @__PURE__ */ React15.createElement(ListAlignGroup, { editor }), ["premium", "platinum"].includes(version) && /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(InsertGroup, { editor }), /* @__PURE__ */ React15.createElement(ActionGroup, { editor })), version === "platinum" && /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(MiscGroup, { editor }), /* @__PURE__ */ React15.createElement(AiGroup, { editor })), addOns.length > 0 && /* @__PURE__ */ React15.createElement(AddOnGroup_default, { editor }));
16818
16993
  }
16819
16994
 
16820
16995
  // src/components/tetrons/EditorContent.tsx
@@ -16823,25 +16998,16 @@ lowlight.register("js", javascript);
16823
16998
  lowlight.register("ts", typescript);
16824
16999
  function EditorContent({ apiKey }) {
16825
17000
  const typo = useTypo();
16826
- const [isValid, setIsValid] = useState9(null);
16827
- const [error, setError] = useState9(null);
16828
- const [versions, setVersions] = useState9([]);
16829
- const [userVersion, setUserVersion] = useState9(null);
16830
- const [currentVersionIndex, setCurrentVersionIndex] = useState9(
17001
+ const [isValid, setIsValid] = useState10(null);
17002
+ const [error, setError] = useState10(null);
17003
+ const [versions, setVersions] = useState10([]);
17004
+ const [userVersion, setUserVersion] = useState10(null);
17005
+ const [currentVersionIndex, setCurrentVersionIndex] = useState10(
16831
17006
  null
16832
17007
  );
16833
17008
  const wrapperRef = useRef7(null);
16834
- function getApiBaseUrl() {
16835
- if (typeof import.meta !== "undefined" && import.meta.env?.VITE_TETRONS_API_URL) {
16836
- return import.meta.env.VITE_TETRONS_API_URL;
16837
- }
16838
- if (typeof process !== "undefined" && process.env?.NEXT_PUBLIC_TETRONS_API_URL) {
16839
- return process.env.NEXT_PUBLIC_TETRONS_API_URL;
16840
- }
16841
- return "https://staging.tetrons.com";
16842
- }
16843
- const API_BASE_URL = getApiBaseUrl();
16844
- useEffect8(() => {
17009
+ const API_BASE_URL = typeof process !== "undefined" && process.env?.NEXT_PUBLIC_TETRONS_API_URL ? process.env.NEXT_PUBLIC_TETRONS_API_URL : "https://staging.tetrons.com";
17010
+ useEffect9(() => {
16845
17011
  const validateKey = async () => {
16846
17012
  try {
16847
17013
  const res = await fetch(`${API_BASE_URL}/api/validate`, {
@@ -16912,7 +17078,8 @@ function EditorContent({ apiKey }) {
16912
17078
  Spellcheck.configure({
16913
17079
  spellcheckFn: (word) => typo.check(word)
16914
17080
  })
16915
- ] : []
17081
+ ] : [],
17082
+ MathInline
16916
17083
  ],
16917
17084
  content: "",
16918
17085
  editorProps: {
@@ -16923,7 +17090,7 @@ function EditorContent({ apiKey }) {
16923
17090
  },
16924
17091
  immediatelyRender: false
16925
17092
  });
16926
- useEffect8(() => {
17093
+ useEffect9(() => {
16927
17094
  return () => {
16928
17095
  editor?.destroy();
16929
17096
  };
@@ -16948,15 +17115,22 @@ function EditorContent({ apiKey }) {
16948
17115
  }
16949
17116
  };
16950
17117
  if (isValid === false) {
16951
- return /* @__PURE__ */ React14.createElement("div", { className: "editor-error" }, "\u26A0\uFE0F ", error);
17118
+ return /* @__PURE__ */ React16.createElement("div", { className: "editor-error" }, "\u26A0\uFE0F ", error);
16952
17119
  }
16953
17120
  if (isValid === null) {
16954
- return /* @__PURE__ */ React14.createElement("div", { className: "editor-loading" }, "\u{1F50D} Validating license...");
17121
+ return /* @__PURE__ */ React16.createElement("div", { className: "editor-loading" }, "\u{1F50D} Validating license...");
16955
17122
  }
16956
17123
  if (!typo) {
16957
- return /* @__PURE__ */ React14.createElement("div", { className: "editor-loading" }, "\u{1F4D6} Loading dictionary...");
17124
+ return /* @__PURE__ */ React16.createElement("div", { className: "editor-loading" }, "\u{1F4D6} Loading dictionary...");
16958
17125
  }
16959
- return /* @__PURE__ */ React14.createElement("div", { className: "editor-container" }, userVersion !== "free" && /* @__PURE__ */ React14.createElement("div", { className: "editor-toolbar" }, /* @__PURE__ */ React14.createElement(
17126
+ const versionAddOnsMap = {
17127
+ free: [],
17128
+ pro: ["code"],
17129
+ premium: ["code", "math"],
17130
+ platinum: ["code", "math"]
17131
+ };
17132
+ const enabledAddOns = userVersion ? versionAddOnsMap[userVersion] || [] : [];
17133
+ return /* @__PURE__ */ React16.createElement("div", { className: "editor-container" }, userVersion !== "free" && /* @__PURE__ */ React16.createElement("div", { className: "editor-toolbar" }, /* @__PURE__ */ React16.createElement(
16960
17134
  "button",
16961
17135
  {
16962
17136
  type: "button",
@@ -16965,7 +17139,7 @@ function EditorContent({ apiKey }) {
16965
17139
  className: "editor-save-btn"
16966
17140
  },
16967
17141
  "Save Version"
16968
- ), /* @__PURE__ */ React14.createElement("div", { className: "editor-versions-wrapper" }, versions.length === 0 ? /* @__PURE__ */ React14.createElement("span", { className: "editor-no-versions" }, "No saved versions") : versions.map((_, idx) => /* @__PURE__ */ React14.createElement(
17142
+ ), /* @__PURE__ */ React16.createElement("div", { className: "editor-versions-wrapper" }, versions.length === 0 ? /* @__PURE__ */ React16.createElement("span", { className: "editor-no-versions" }, "No saved versions") : versions.map((_, idx) => /* @__PURE__ */ React16.createElement(
16969
17143
  "button",
16970
17144
  {
16971
17145
  key: idx,
@@ -16975,17 +17149,53 @@ function EditorContent({ apiKey }) {
16975
17149
  title: `Restore Version ${idx + 1}`
16976
17150
  },
16977
17151
  `V${idx + 1}`
16978
- )))), editor && userVersion && /* @__PURE__ */ React14.createElement(TetronsToolbar, { editor, version: userVersion }), /* @__PURE__ */ React14.createElement(
17152
+ )))), editor && userVersion && /* @__PURE__ */ React16.createElement(
17153
+ TetronsToolbar,
17154
+ {
17155
+ editor,
17156
+ version: userVersion,
17157
+ addOns: enabledAddOns
17158
+ }
17159
+ ), /* @__PURE__ */ React16.createElement(
16979
17160
  "div",
16980
17161
  {
16981
17162
  ref: wrapperRef,
16982
17163
  className: "editor-content-wrapper",
16983
17164
  onClick: handleEditorClick
16984
17165
  },
16985
- editor ? /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(TiptapEditorContent, { editor }), /* @__PURE__ */ React14.createElement(TableContextMenu, { editor })) : /* @__PURE__ */ React14.createElement("div", { className: "editor-loading" }, "Loading editor...")
17166
+ editor ? /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(TiptapEditorContent, { editor }), /* @__PURE__ */ React16.createElement(TableContextMenu, { editor })) : /* @__PURE__ */ React16.createElement("div", { className: "editor-loading" }, "Loading editor...")
16986
17167
  ));
16987
17168
  }
16988
17169
 
17170
+ // src/utils/licenseTracker.ts
17171
+ var getLicenseKey = (plan) => `__tetrons_license_start_${plan}__`;
17172
+ var PLAN_DURATIONS = {
17173
+ free: 14,
17174
+ pro: 30,
17175
+ premium: 30,
17176
+ platinum: 30
17177
+ };
17178
+ function initLicenseTracking(plan) {
17179
+ if (typeof window === "undefined") return;
17180
+ const key = getLicenseKey(plan);
17181
+ const now = Date.now();
17182
+ const stored = localStorage.getItem(key);
17183
+ if (!stored) {
17184
+ localStorage.setItem(key, now.toString());
17185
+ }
17186
+ }
17187
+ function isLicenseValid(plan) {
17188
+ if (typeof window === "undefined") return true;
17189
+ const key = getLicenseKey(plan);
17190
+ const stored = localStorage.getItem(key);
17191
+ if (!stored) return false;
17192
+ const startedAt = parseInt(stored, 10);
17193
+ const now = Date.now();
17194
+ const diffDays = Math.floor((now - startedAt) / (1e3 * 60 * 60 * 24));
17195
+ const allowedDays = PLAN_DURATIONS[plan];
17196
+ return diffDays <= allowedDays;
17197
+ }
17198
+
16989
17199
  // src/index.ts
16990
17200
  var API_VALID = false;
16991
17201
  var API_VERSION = "";
@@ -17004,6 +17214,9 @@ async function initializeTetrons(apiKey) {
17004
17214
  const data = await res.json();
17005
17215
  API_VALID = data.valid;
17006
17216
  API_VERSION = data.version;
17217
+ if (API_VALID && typeof window !== "undefined") {
17218
+ initLicenseTracking(API_VERSION);
17219
+ }
17007
17220
  }
17008
17221
  function getTetronsVersion() {
17009
17222
  return API_VERSION;
@@ -17011,11 +17224,16 @@ function getTetronsVersion() {
17011
17224
  function isApiKeyValid() {
17012
17225
  return API_VALID;
17013
17226
  }
17227
+ function isTetronsLicenseValid() {
17228
+ if (!API_VALID || !API_VERSION) return false;
17229
+ return isLicenseValid(API_VERSION);
17230
+ }
17014
17231
  var index_default = EditorContent;
17015
17232
  export {
17016
17233
  EditorContent,
17017
17234
  index_default as default,
17018
17235
  getTetronsVersion,
17019
17236
  initializeTetrons,
17020
- isApiKeyValid
17237
+ isApiKeyValid,
17238
+ isTetronsLicenseValid
17021
17239
  };