@june-ai/june-ui 0.2.5 → 0.2.7

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.cjs CHANGED
@@ -145,6 +145,184 @@ var init_document_utils = __esm({
145
145
  }
146
146
  });
147
147
 
148
+ // src/components/document-editor/document-pagination.ts
149
+ function gapWidget(height) {
150
+ return () => {
151
+ const el = document.createElement("div");
152
+ el.className = "june-doc__page-gap";
153
+ el.contentEditable = "false";
154
+ el.setAttribute("aria-hidden", "true");
155
+ el.style.height = `${height}px`;
156
+ return el;
157
+ };
158
+ }
159
+ function build(doc, breaks) {
160
+ return import_view.DecorationSet.create(
161
+ doc,
162
+ breaks.map(
163
+ (b) => import_view.Decoration.widget(b.pos, gapWidget(b.height), {
164
+ side: -1,
165
+ ignoreSelection: true,
166
+ key: `jd-gap-${b.pos}-${Math.round(b.height)}`
167
+ })
168
+ )
169
+ );
170
+ }
171
+ function collectUnits(doc) {
172
+ const units = [];
173
+ const walk = (parent, start, inheritedBreak) => {
174
+ parent.forEach((child, offset, index) => {
175
+ const pos = start + offset;
176
+ const breakPos = index === 0 && inheritedBreak !== null ? inheritedBreak : pos;
177
+ if (SPLITTABLE.has(child.type.name) && child.childCount > 0) {
178
+ walk(child, pos + 1, breakPos);
179
+ } else {
180
+ units.push({ pos, breakPos, node: child });
181
+ }
182
+ });
183
+ };
184
+ walk(doc, 0, null);
185
+ return units;
186
+ }
187
+ function measure(view, cfg) {
188
+ const prose = view.dom;
189
+ const proseRect = prose.getBoundingClientRect();
190
+ const scale = prose.offsetWidth ? proseRect.width / prose.offsetWidth : 1;
191
+ if (!scale || !proseRect.width) return { breaks: [], pages: 1 };
192
+ const gaps = [...prose.querySelectorAll(".june-doc__page-gap")].map((g) => {
193
+ const r = g.getBoundingClientRect();
194
+ return { top: (r.top - proseRect.top) / scale, height: r.height / scale };
195
+ });
196
+ const gapsAbove = (y) => gaps.reduce((sum, g) => g.top <= y + 0.5 ? sum + g.height : sum, 0);
197
+ const contentH = Math.max(80, cfg.pageHeight - cfg.padTop - cfg.padBottom);
198
+ const stride = cfg.pageHeight + cfg.gap;
199
+ const breaks = /* @__PURE__ */ new Map();
200
+ let pageStart = 0;
201
+ let added = 0;
202
+ let force = false;
203
+ for (const unit of collectUnits(view.state.doc)) {
204
+ const el = view.nodeDOM(unit.pos);
205
+ if (!(el instanceof HTMLElement)) continue;
206
+ const r = el.getBoundingClientRect();
207
+ const rawTop = (r.top - proseRect.top) / scale;
208
+ const natural = rawTop - gapsAbove(rawTop);
209
+ const h = r.height / scale;
210
+ let top = natural + added;
211
+ let bottom = top + h;
212
+ const overflows = bottom > pageStart + contentH + 0.5 && top > pageStart + 1;
213
+ if (force || overflows) {
214
+ const target = pageStart + stride;
215
+ if (top < target) {
216
+ const spacer = target - top;
217
+ breaks.set(unit.breakPos, (breaks.get(unit.breakPos) ?? 0) + spacer);
218
+ added += spacer;
219
+ top = target;
220
+ bottom = top + h;
221
+ }
222
+ pageStart = target;
223
+ while (top >= pageStart + stride) pageStart += stride;
224
+ force = false;
225
+ }
226
+ while (bottom > pageStart + contentH + 0.5) pageStart += stride;
227
+ if (unit.node.type.name === "pageBreak") force = true;
228
+ }
229
+ const pages = Math.max(1, Math.round(pageStart / stride) + 1 + (force ? 1 : 0));
230
+ return {
231
+ breaks: [...breaks].map(([pos, height]) => ({ pos, height: Math.round(height * 10) / 10 })).sort((a, b) => a.pos - b.pos),
232
+ pages
233
+ };
234
+ }
235
+ function setPaginationConfig(editor, cfg) {
236
+ if (editor.isDestroyed) return;
237
+ const prev = configs.get(editor.view);
238
+ configs.set(editor.view, cfg);
239
+ if (!prev || prev.enabled !== cfg.enabled || prev.pageHeight !== cfg.pageHeight || prev.gap !== cfg.gap || prev.padTop !== cfg.padTop || prev.padBottom !== cfg.padBottom) {
240
+ remeasurePagination(editor);
241
+ }
242
+ }
243
+ function remeasurePagination(editor) {
244
+ if (editor.isDestroyed) return;
245
+ const s = paginationKey.getState(editor.state);
246
+ if (!s) return;
247
+ editor.view.dispatch(editor.state.tr.setMeta(paginationKey, { remeasure: true }).setMeta("addToHistory", false));
248
+ }
249
+ function getPageCount(editor) {
250
+ return editor && paginationKey.getState(editor.state)?.pages || 1;
251
+ }
252
+ var import_core, import_state, import_view, paginationKey, configs, SPLITTABLE, same2, DocumentPagination;
253
+ var init_document_pagination = __esm({
254
+ "src/components/document-editor/document-pagination.ts"() {
255
+ "use strict";
256
+ import_core = require("@tiptap/core");
257
+ import_state = require("@tiptap/pm/state");
258
+ import_view = require("@tiptap/pm/view");
259
+ paginationKey = new import_state.PluginKey("juneDocPagination");
260
+ configs = /* @__PURE__ */ new WeakMap();
261
+ SPLITTABLE = /* @__PURE__ */ new Set(["bulletList", "orderedList", "listItem", "blockquote"]);
262
+ same2 = (a, b) => a.length === b.length && a.every((x, i) => x.pos === b[i].pos && Math.abs(x.height - b[i].height) < 1);
263
+ DocumentPagination = import_core.Extension.create({
264
+ name: "juneDocPagination",
265
+ addProseMirrorPlugins() {
266
+ return [
267
+ new import_state.Plugin({
268
+ key: paginationKey,
269
+ state: {
270
+ init: () => ({ breaks: [], pages: 1, decorations: import_view.DecorationSet.empty, epoch: 0 }),
271
+ apply(tr, prev, _old, state) {
272
+ const meta = tr.getMeta(paginationKey);
273
+ if (meta?.remeasure) return { ...prev, epoch: prev.epoch + 1 };
274
+ if (meta?.breaks) {
275
+ return { ...prev, breaks: meta.breaks, pages: meta.pages ?? prev.pages, decorations: build(state.doc, meta.breaks) };
276
+ }
277
+ if (tr.docChanged) {
278
+ const breaks = prev.breaks.map((b) => ({ ...b, pos: tr.mapping.map(b.pos, -1) })).filter((b) => b.pos >= 0 && b.pos <= state.doc.content.size);
279
+ return { ...prev, breaks, decorations: prev.decorations.map(tr.mapping, tr.doc) };
280
+ }
281
+ return prev;
282
+ }
283
+ },
284
+ props: {
285
+ decorations: (state) => paginationKey.getState(state)?.decorations
286
+ },
287
+ view(view) {
288
+ let frame = null;
289
+ let rounds = 0;
290
+ const schedule = (reset) => {
291
+ if (reset) rounds = 0;
292
+ if (frame !== null || typeof window === "undefined") return;
293
+ const raf = window.requestAnimationFrame ?? ((cb) => window.setTimeout(() => cb(0), 16));
294
+ frame = raf(() => {
295
+ frame = null;
296
+ if (view.isDestroyed) return;
297
+ const cfg = configs.get(view);
298
+ const current = paginationKey.getState(view.state);
299
+ if (!current) return;
300
+ const next = cfg?.enabled ? measure(view, cfg) : { breaks: [], pages: 1 };
301
+ if (same2(next.breaks, current.breaks) && next.pages === current.pages) return;
302
+ if (++rounds > 4) return;
303
+ view.dispatch(view.state.tr.setMeta(paginationKey, next).setMeta("addToHistory", false));
304
+ });
305
+ };
306
+ schedule(true);
307
+ return {
308
+ update(v, prevState) {
309
+ const pg = paginationKey.getState(v.state);
310
+ const prevPg = paginationKey.getState(prevState);
311
+ if (v.state.doc !== prevState.doc || pg?.epoch !== prevPg?.epoch) schedule(true);
312
+ else if (pg !== prevPg) schedule(false);
313
+ },
314
+ destroy() {
315
+ frame = null;
316
+ }
317
+ };
318
+ }
319
+ })
320
+ ];
321
+ }
322
+ });
323
+ }
324
+ });
325
+
148
326
  // src/components/document-editor/document-search.ts
149
327
  function findMatches(doc, term, caseSensitive) {
150
328
  if (!term) return [];
@@ -174,13 +352,13 @@ function findMatches(doc, term, caseSensitive) {
174
352
  });
175
353
  return out;
176
354
  }
177
- function build(doc, term, caseSensitive, current) {
355
+ function build2(doc, term, caseSensitive, current) {
178
356
  const matches = findMatches(doc, term, caseSensitive);
179
357
  const active = matches.length ? Math.min(Math.max(current, 0), matches.length - 1) : -1;
180
- const decorations = import_view.DecorationSet.create(
358
+ const decorations = import_view2.DecorationSet.create(
181
359
  doc,
182
360
  matches.map(
183
- (m, i) => import_view.Decoration.inline(m.from, m.to, {
361
+ (m, i) => import_view2.Decoration.inline(m.from, m.to, {
184
362
  class: i === active ? "june-doc__match june-doc__match--active" : "june-doc__match"
185
363
  })
186
364
  )
@@ -226,27 +404,27 @@ function replaceAll(editor, replacement) {
226
404
  }).run();
227
405
  return matches.length;
228
406
  }
229
- var import_core, import_state, import_view, searchKey, DocumentSearch;
407
+ var import_core2, import_state2, import_view2, searchKey, DocumentSearch;
230
408
  var init_document_search = __esm({
231
409
  "src/components/document-editor/document-search.ts"() {
232
410
  "use strict";
233
- import_core = require("@tiptap/core");
234
- import_state = require("@tiptap/pm/state");
235
- import_view = require("@tiptap/pm/view");
236
- searchKey = new import_state.PluginKey("juneDocSearch");
237
- DocumentSearch = import_core.Extension.create({
411
+ import_core2 = require("@tiptap/core");
412
+ import_state2 = require("@tiptap/pm/state");
413
+ import_view2 = require("@tiptap/pm/view");
414
+ searchKey = new import_state2.PluginKey("juneDocSearch");
415
+ DocumentSearch = import_core2.Extension.create({
238
416
  name: "juneDocSearch",
239
417
  addProseMirrorPlugins() {
240
418
  return [
241
- new import_state.Plugin({
419
+ new import_state2.Plugin({
242
420
  key: searchKey,
243
421
  state: {
244
- init: () => ({ term: "", caseSensitive: false, current: -1, matches: [], decorations: import_view.DecorationSet.empty }),
422
+ init: () => ({ term: "", caseSensitive: false, current: -1, matches: [], decorations: import_view2.DecorationSet.empty }),
245
423
  apply(tr, prev, _old, state) {
246
424
  const meta = tr.getMeta(searchKey);
247
425
  if (!meta && !tr.docChanged) return prev;
248
426
  if (!meta && !prev.term) return prev;
249
- return build(
427
+ return build2(
250
428
  state.doc,
251
429
  meta?.term ?? prev.term,
252
430
  meta?.caseSensitive ?? prev.caseSensitive,
@@ -288,14 +466,16 @@ function createDocumentExtensions() {
288
466
  }),
289
467
  PageBreak,
290
468
  DocumentSearch,
469
+ DocumentPagination,
470
+ // inactive until the live editor sets a page geometry
291
471
  import_markdown.Markdown
292
472
  ];
293
473
  }
294
- var import_core2, import_extension_highlight, import_extension_image, import_extension_subscript, import_extension_superscript, import_extension_table, import_extension_text_align, import_extension_text_style, import_markdown, import_starter_kit, PageBreak;
474
+ var import_core3, import_extension_highlight, import_extension_image, import_extension_subscript, import_extension_superscript, import_extension_table, import_extension_text_align, import_extension_text_style, import_markdown, import_starter_kit, PageBreak;
295
475
  var init_document_extensions = __esm({
296
476
  "src/components/document-editor/document-extensions.ts"() {
297
477
  "use strict";
298
- import_core2 = require("@tiptap/core");
478
+ import_core3 = require("@tiptap/core");
299
479
  import_extension_highlight = __toESM(require("@tiptap/extension-highlight"), 1);
300
480
  import_extension_image = __toESM(require("@tiptap/extension-image"), 1);
301
481
  import_extension_subscript = __toESM(require("@tiptap/extension-subscript"), 1);
@@ -305,8 +485,9 @@ var init_document_extensions = __esm({
305
485
  import_extension_text_style = require("@tiptap/extension-text-style");
306
486
  import_markdown = require("@tiptap/markdown");
307
487
  import_starter_kit = __toESM(require("@tiptap/starter-kit"), 1);
488
+ init_document_pagination();
308
489
  init_document_search();
309
- PageBreak = import_core2.Node.create({
490
+ PageBreak = import_core3.Node.create({
310
491
  name: "pageBreak",
311
492
  group: "block",
312
493
  atom: true,
@@ -317,7 +498,7 @@ var init_document_extensions = __esm({
317
498
  renderHTML({ HTMLAttributes }) {
318
499
  return [
319
500
  "div",
320
- (0, import_core2.mergeAttributes)(HTMLAttributes, {
501
+ (0, import_core3.mergeAttributes)(HTMLAttributes, {
321
502
  "data-page-break": "true",
322
503
  class: "june-doc__page-break",
323
504
  style: "break-after: page; page-break-after: always;"
@@ -348,7 +529,7 @@ __export(document_engine_exports, {
348
529
  });
349
530
  function scratchEditor() {
350
531
  if (!scratch || scratch.isDestroyed) {
351
- scratch = new import_core3.Editor({ extensions: createDocumentExtensions(), content: "" });
532
+ scratch = new import_core4.Editor({ extensions: createDocumentExtensions(), content: "" });
352
533
  }
353
534
  return scratch;
354
535
  }
@@ -374,11 +555,11 @@ function load(doc) {
374
555
  editor.commands.setContent(doc, { emitUpdate: false });
375
556
  return editor;
376
557
  }
377
- var import_core3, scratch, docToHtml, docToMarkdown, docToText;
558
+ var import_core4, scratch, docToHtml, docToMarkdown, docToText;
378
559
  var init_document_engine = __esm({
379
560
  "src/components/document-editor/document-engine.ts"() {
380
561
  "use strict";
381
- import_core3 = require("@tiptap/core");
562
+ import_core4 = require("@tiptap/core");
382
563
  init_errors();
383
564
  init_document_extensions();
384
565
  init_document_utils();
@@ -418,17 +599,21 @@ __export(index_exports, {
418
599
  getDefaultDocumentStore: () => getDefaultDocumentStore,
419
600
  getDocumentEditorInstructions: () => getDocumentEditorInstructions,
420
601
  getDocumentEditorRules: () => getDocumentEditorRules,
602
+ isDocumentEcho: () => isDocumentEcho,
421
603
  isJuneError: () => isJuneError,
422
604
  jsonFieldExtractor: () => jsonFieldExtractor,
423
605
  juneLibrary: () => juneLibrary,
424
606
  lightTheme: () => lightTheme,
425
607
  listDocumentExporters: () => listDocumentExporters,
426
608
  mergeDocuments: () => mergeDocuments,
609
+ readDocumentFromProgram: () => readDocumentFromProgram,
427
610
  registerDocumentExporter: () => registerDocumentExporter,
611
+ rememberDocumentEcho: () => rememberDocumentEcho,
428
612
  runAction: () => runAction,
429
613
  serializeDocumentsForAgent: () => serializeDocumentsForAgent,
430
614
  sseToText: () => sseToText,
431
615
  toJuneError: () => toJuneError,
616
+ updateDocumentInProgram: () => updateDocumentInProgram,
432
617
  useDocumentOptions: () => useDocumentOptions,
433
618
  useJuneRuntime: () => useJuneRuntime,
434
619
  useJuneStream: () => useJuneStream,
@@ -438,6 +623,53 @@ __export(index_exports, {
438
623
  });
439
624
  module.exports = __toCommonJS(index_exports);
440
625
 
626
+ // src/openui/disable-devtools.tsx
627
+ var import_devtools = require("@openuidev/devtools");
628
+ var import_jsx_runtime = require("react/jsx-runtime");
629
+ var AUTO_MOUNT_FLAG = /* @__PURE__ */ Symbol.for("openui.devtools.autoMount");
630
+ var BLOCKED_BY_JUNE = /* @__PURE__ */ Symbol.for("openui.devtools.blockedByJune");
631
+ var flags = globalThis;
632
+ var scheduledByOpenUI = flags[AUTO_MOUNT_FLAG] === true && flags[BLOCKED_BY_JUNE] !== true;
633
+ flags[AUTO_MOUNT_FLAG] = true;
634
+ flags[BLOCKED_BY_JUNE] = true;
635
+ var DEVTOOLS_BUNDLE = "https://cdn.jsdelivr.net/npm/@openuidev/devtools@0/dist/devtools.browser.js";
636
+ var ALIAS_CACHE_MS = 5 * 60 * 1e3;
637
+ function claimDisabledDevtools() {
638
+ if (typeof document === "undefined") return () => {
639
+ };
640
+ const url = `${DEVTOOLS_BUNDLE}?t=${Math.floor(Date.now() / ALIAS_CACHE_MS)}`;
641
+ let cancelled = false;
642
+ let unmount = () => {
643
+ cancelled = true;
644
+ };
645
+ void Promise.all([
646
+ import(
647
+ /* @vite-ignore */
648
+ url
649
+ ),
650
+ import("react"),
651
+ import("react-dom"),
652
+ import("react-dom/client")
653
+ ]).then(([devtools, react, reactDom, reactDomClient]) => {
654
+ if (cancelled) return;
655
+ unmount = devtools.mountOpenUIDevtools({
656
+ React: react,
657
+ ReactDOM: reactDom,
658
+ ReactDOMClient: reactDomClient,
659
+ loadReactLang: () => import("@openuidev/react-lang"),
660
+ props: { enabled: false }
661
+ });
662
+ }).catch(() => {
663
+ });
664
+ return () => unmount();
665
+ }
666
+ if (scheduledByOpenUI && process.env.NODE_ENV === "development" && process.env.VITEST !== "true" && typeof document !== "undefined") {
667
+ claimDisabledDevtools();
668
+ }
669
+ function OpenUIDevtoolsGate() {
670
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_devtools.OpenUIDevtools, { enabled: false });
671
+ }
672
+
441
673
  // src/renderer/renderer.tsx
442
674
  var import_react_lang = require("@openuidev/react-lang");
443
675
  var import_react5 = require("react");
@@ -516,6 +748,318 @@ function useDocumentValue(store, id, selector) {
516
748
  return (0, import_react.useSyncExternalStore)(store.subscribe, read, read);
517
749
  }
518
750
 
751
+ // src/components/document-editor/document-merge.ts
752
+ init_document_utils();
753
+ var MAX_CELLS = 4e6;
754
+ function matchIndices(a, b) {
755
+ const n = a.length;
756
+ const m = b.length;
757
+ if (n * m > MAX_CELLS) return null;
758
+ const dp = Array.from({ length: n + 1 }, () => new Uint32Array(m + 1));
759
+ for (let i2 = n - 1; i2 >= 0; i2--) {
760
+ for (let j2 = m - 1; j2 >= 0; j2--) {
761
+ dp[i2][j2] = a[i2] === b[j2] ? dp[i2 + 1][j2 + 1] + 1 : Math.max(dp[i2 + 1][j2], dp[i2][j2 + 1]);
762
+ }
763
+ }
764
+ const matches = /* @__PURE__ */ new Map();
765
+ let i = 0;
766
+ let j = 0;
767
+ while (i < n && j < m) {
768
+ if (a[i] === b[j]) {
769
+ matches.set(i, j);
770
+ i++;
771
+ j++;
772
+ } else if (dp[i + 1][j] >= dp[i][j + 1]) i++;
773
+ else j++;
774
+ }
775
+ return matches;
776
+ }
777
+ var same = (x, y) => x.length === y.length && x.every((v, i) => v === y[i]);
778
+ function mergeBlocks(base, local, incoming) {
779
+ if (same(local, base)) return { blocks: incoming, conflicts: 0 };
780
+ if (same(incoming, base) || same(local, incoming)) return { blocks: local, conflicts: 0 };
781
+ const ml = matchIndices(base, local);
782
+ const mn = matchIndices(base, incoming);
783
+ if (!ml || !mn) return { blocks: null, conflicts: 1 };
784
+ const anchors = [...ml.keys()].filter((i) => mn.has(i)).sort((x, y) => x - y);
785
+ const out = [];
786
+ let conflicts = 0;
787
+ let pb = -1;
788
+ let pl = -1;
789
+ let pn = -1;
790
+ const region = (bEnd, lEnd, nEnd) => {
791
+ const B = base.slice(pb + 1, bEnd);
792
+ const L = local.slice(pl + 1, lEnd);
793
+ const N = incoming.slice(pn + 1, nEnd);
794
+ if (B.length === L.length && L.length === N.length) {
795
+ for (let k = 0; k < B.length; k++) {
796
+ if (L[k] === B[k]) out.push(N[k]);
797
+ else if (N[k] === B[k] || N[k] === L[k]) out.push(L[k]);
798
+ else {
799
+ conflicts++;
800
+ out.push(L[k]);
801
+ }
802
+ }
803
+ return;
804
+ }
805
+ if (same(L, B)) out.push(...N);
806
+ else if (same(N, B) || same(L, N)) out.push(...L);
807
+ else {
808
+ conflicts++;
809
+ out.push(...L);
810
+ }
811
+ };
812
+ for (const a of anchors) {
813
+ const la = ml.get(a);
814
+ const na = mn.get(a);
815
+ region(a, la, na);
816
+ out.push(local[la]);
817
+ pb = a;
818
+ pl = la;
819
+ pn = na;
820
+ }
821
+ region(base.length, local.length, incoming.length);
822
+ return { blocks: out, conflicts };
823
+ }
824
+ function mergeDocuments(base, local, incoming) {
825
+ const toBlocks = (d) => (d.content ?? []).map((node) => JSON.stringify(node));
826
+ const { blocks: blocks2, conflicts } = mergeBlocks(toBlocks(base), toBlocks(local), toBlocks(incoming));
827
+ if (!blocks2) return { doc: local, conflicts: Math.max(1, conflicts) };
828
+ if (blocks2.length === 0) return { doc: emptyDoc(), conflicts };
829
+ return { doc: { type: "doc", content: blocks2.map((b) => JSON.parse(b)) }, conflicts };
830
+ }
831
+
832
+ // src/components/document-editor/document-store.ts
833
+ init_document_utils();
834
+ var incomingKey = (doc) => JSON.stringify([doc.title, docKey(doc.json)]);
835
+ function createDocumentStore() {
836
+ const records = /* @__PURE__ */ new Map();
837
+ const listeners = /* @__PURE__ */ new Set();
838
+ const emit = () => listeners.forEach((listener) => listener());
839
+ const put = (record) => {
840
+ records.set(record.id, record);
841
+ emit();
842
+ };
843
+ const fresh2 = (doc) => ({
844
+ id: doc.id,
845
+ title: doc.title,
846
+ documentType: doc.documentType,
847
+ status: doc.status,
848
+ json: doc.json,
849
+ baseJson: doc.json,
850
+ baseTitle: doc.title,
851
+ lastIncomingKey: incomingKey(doc),
852
+ revision: 0,
853
+ origin: "external",
854
+ pending: null,
855
+ updatedAt: Date.now()
856
+ });
857
+ return {
858
+ get: (id) => records.get(id),
859
+ list: () => [...records.values()],
860
+ subscribe: (listener) => {
861
+ listeners.add(listener);
862
+ return () => {
863
+ listeners.delete(listener);
864
+ };
865
+ },
866
+ receive(incoming) {
867
+ const current = records.get(incoming.id);
868
+ if (!current) {
869
+ put(fresh2(incoming));
870
+ return "created";
871
+ }
872
+ const key = incomingKey(incoming);
873
+ if (current.lastIncomingKey === key) return "unchanged";
874
+ const userEditedBody = docKey(current.json) !== docKey(current.baseJson);
875
+ const userEditedTitle = current.title !== current.baseTitle;
876
+ const title = userEditedTitle ? current.title : incoming.title;
877
+ const meta = {
878
+ documentType: incoming.documentType ?? current.documentType,
879
+ status: incoming.status ?? current.status
880
+ };
881
+ if (!userEditedBody) {
882
+ put({
883
+ ...current,
884
+ ...meta,
885
+ title,
886
+ baseTitle: incoming.title,
887
+ json: incoming.json,
888
+ baseJson: incoming.json,
889
+ lastIncomingKey: key,
890
+ revision: current.revision + 1,
891
+ origin: "external",
892
+ pending: null,
893
+ updatedAt: Date.now()
894
+ });
895
+ return "applied";
896
+ }
897
+ const { doc, conflicts } = mergeDocuments(current.baseJson, current.json, incoming.json);
898
+ if (conflicts === 0) {
899
+ put({
900
+ ...current,
901
+ ...meta,
902
+ title,
903
+ baseTitle: incoming.title,
904
+ json: doc,
905
+ baseJson: incoming.json,
906
+ lastIncomingKey: key,
907
+ revision: current.revision + 1,
908
+ origin: "external",
909
+ pending: null,
910
+ updatedAt: Date.now()
911
+ });
912
+ return "merged";
913
+ }
914
+ put({
915
+ ...current,
916
+ ...meta,
917
+ lastIncomingKey: key,
918
+ pending: { json: incoming.json, title: incoming.title, merged: doc, conflicts }
919
+ });
920
+ return "conflict";
921
+ },
922
+ hydrate(doc) {
923
+ put(fresh2(doc));
924
+ },
925
+ edit(id, json, origin) {
926
+ const current = records.get(id);
927
+ if (!current || docKey(current.json) === docKey(json)) return;
928
+ put({ ...current, json, origin, revision: current.revision + 1, updatedAt: Date.now() });
929
+ },
930
+ setTitle(id, title) {
931
+ const current = records.get(id);
932
+ if (!current || current.title === title) return;
933
+ put({ ...current, title, updatedAt: Date.now() });
934
+ },
935
+ resolve(id, choice) {
936
+ const current = records.get(id);
937
+ const pending = current?.pending;
938
+ if (!current || !pending) return;
939
+ if (choice === "keep") {
940
+ put({ ...current, baseJson: pending.json, baseTitle: pending.title, pending: null });
941
+ return;
942
+ }
943
+ const json = choice === "merge" ? pending.merged : pending.json;
944
+ const title = choice === "merge" ? current.title : pending.title;
945
+ put({
946
+ ...current,
947
+ title,
948
+ json,
949
+ baseJson: pending.json,
950
+ baseTitle: pending.title,
951
+ revision: current.revision + 1,
952
+ origin: "external",
953
+ pending: null,
954
+ updatedAt: Date.now()
955
+ });
956
+ },
957
+ remove(id) {
958
+ if (records.delete(id)) emit();
959
+ }
960
+ };
961
+ }
962
+ var echoes = /* @__PURE__ */ new WeakMap();
963
+ var ECHO_MEMORY = 8;
964
+ function rememberDocumentEcho(store, id, content) {
965
+ let byId = echoes.get(store);
966
+ if (!byId) echoes.set(store, byId = /* @__PURE__ */ new Map());
967
+ const list2 = byId.get(id) ?? [];
968
+ list2.push(content);
969
+ if (list2.length > ECHO_MEMORY) list2.shift();
970
+ byId.set(id, list2);
971
+ }
972
+ function isDocumentEcho(store, id, content) {
973
+ return !!content && !!echoes.get(store)?.get(id)?.includes(content);
974
+ }
975
+ var defaultStore = null;
976
+ function getDefaultDocumentStore() {
977
+ if (!defaultStore) defaultStore = createDocumentStore();
978
+ return defaultStore;
979
+ }
980
+
981
+ // src/utils/update-document-program.ts
982
+ function readString(src, i) {
983
+ if (src[i] !== '"') return null;
984
+ let j = i + 1;
985
+ let value = "";
986
+ while (j < src.length) {
987
+ const ch = src[j];
988
+ if (ch === '"') return { start: i, end: j + 1, value };
989
+ if (ch === "\\") {
990
+ const next = src[j + 1];
991
+ if (next === void 0) return null;
992
+ if (next === "u" && /^[0-9a-fA-F]{4}$/.test(src.slice(j + 2, j + 6))) {
993
+ value += String.fromCharCode(parseInt(src.slice(j + 2, j + 6), 16));
994
+ j += 6;
995
+ continue;
996
+ }
997
+ value += next === "n" ? "\n" : next === "t" ? " " : next === "r" ? "\r" : next === "b" ? "\b" : next === "f" ? "\f" : next;
998
+ j += 2;
999
+ continue;
1000
+ }
1001
+ value += ch;
1002
+ j++;
1003
+ }
1004
+ return null;
1005
+ }
1006
+ var skipSpace = (src, i) => {
1007
+ while (i < src.length && /\s/.test(src[i])) i++;
1008
+ return i;
1009
+ };
1010
+ var toLangString = (value) => JSON.stringify(value);
1011
+ function updateDocumentInProgram(program, documentId, update, componentName = "DocumentEditor") {
1012
+ const re = new RegExp(`\\b${componentName}\\s*\\(`, "g");
1013
+ let match;
1014
+ while (match = re.exec(program)) {
1015
+ const args = [];
1016
+ let i = match.index + match[0].length;
1017
+ for (let n = 0; n < 3; n++) {
1018
+ i = skipSpace(program, i);
1019
+ const tok = readString(program, i);
1020
+ if (!tok) break;
1021
+ args.push(tok);
1022
+ i = skipSpace(program, tok.end);
1023
+ if (program[i] === ",") i++;
1024
+ else break;
1025
+ }
1026
+ if (args[0]?.value !== documentId) continue;
1027
+ const edits = [];
1028
+ if (update.title !== void 0 && args[1] && args[1].value !== update.title) {
1029
+ edits.push({ start: args[1].start, end: args[1].end, text: toLangString(update.title) });
1030
+ }
1031
+ if (update.content !== void 0 && args[2] && args[2].value !== update.content) {
1032
+ edits.push({ start: args[2].start, end: args[2].end, text: toLangString(update.content) });
1033
+ }
1034
+ if (!args[2] && update.content !== void 0) return null;
1035
+ let out = program;
1036
+ for (const e of edits.sort((a, b) => b.start - a.start)) {
1037
+ out = out.slice(0, e.start) + e.text + out.slice(e.end);
1038
+ }
1039
+ return out;
1040
+ }
1041
+ return null;
1042
+ }
1043
+ function readDocumentFromProgram(program, documentId, componentName = "DocumentEditor") {
1044
+ const re = new RegExp(`\\b${componentName}\\s*\\(`, "g");
1045
+ let match;
1046
+ while (match = re.exec(program)) {
1047
+ const args = [];
1048
+ let i = match.index + match[0].length;
1049
+ for (let n = 0; n < 3; n++) {
1050
+ i = skipSpace(program, i);
1051
+ const tok = readString(program, i);
1052
+ if (!tok) break;
1053
+ args.push(tok);
1054
+ i = skipSpace(program, tok.end);
1055
+ if (program[i] === ",") i++;
1056
+ else break;
1057
+ }
1058
+ if (args[0]?.value === documentId && args[1] && args[2]) return { title: args[1].value, content: args[2].value };
1059
+ }
1060
+ return null;
1061
+ }
1062
+
519
1063
  // src/core/context.ts
520
1064
  var import_react2 = require("react");
521
1065
  var JuneContext = (0, import_react2.createContext)({
@@ -555,7 +1099,7 @@ var lightTheme = {
555
1099
  };
556
1100
 
557
1101
  // src/themes/theme-provider.tsx
558
- var import_jsx_runtime = require("react/jsx-runtime");
1102
+ var import_jsx_runtime2 = require("react/jsx-runtime");
559
1103
  var QUERY = "(prefers-color-scheme: dark)";
560
1104
  function subscribe(onChange) {
561
1105
  if (typeof window === "undefined" || !window.matchMedia) return () => {
@@ -598,7 +1142,7 @@ function JuneThemeProvider({
598
1142
  () => ({ mode: mode ?? "system", theme: resolved }),
599
1143
  [mode, resolved]
600
1144
  );
601
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(JuneContext.Provider, { value: context, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1145
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(JuneContext.Provider, { value: context, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
602
1146
  "div",
603
1147
  {
604
1148
  className: className ? `june-ui-root ${className}` : "june-ui-root",
@@ -1020,7 +1564,7 @@ function splitResponse(source, options = {}) {
1020
1564
 
1021
1565
  // src/renderer/error-boundary.tsx
1022
1566
  var import_react4 = require("react");
1023
- var import_jsx_runtime2 = require("react/jsx-runtime");
1567
+ var import_jsx_runtime3 = require("react/jsx-runtime");
1024
1568
  function keysChanged(a = [], b = []) {
1025
1569
  return a.length !== b.length || a.some((v, i) => !Object.is(v, b[i]));
1026
1570
  }
@@ -1049,12 +1593,12 @@ var JuneErrorBoundary = class extends import_react4.Component {
1049
1593
  const { fallback } = this.props;
1050
1594
  if (typeof fallback === "function") return fallback({ error, reset: this.reset });
1051
1595
  if (fallback !== void 0) return fallback;
1052
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { role: "alert", "data-june-error": "", children: "Something went wrong while rendering this UI." });
1596
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { role: "alert", "data-june-error": "", children: "Something went wrong while rendering this UI." });
1053
1597
  }
1054
1598
  };
1055
1599
 
1056
1600
  // src/renderer/renderer.tsx
1057
- var import_jsx_runtime3 = require("react/jsx-runtime");
1601
+ var import_jsx_runtime4 = require("react/jsx-runtime");
1058
1602
  function JuneRenderer(props) {
1059
1603
  const {
1060
1604
  library,
@@ -1074,14 +1618,43 @@ function JuneRenderer(props) {
1074
1618
  onError,
1075
1619
  onJuneError,
1076
1620
  documents,
1621
+ onResponseChange,
1622
+ responseChangeDelay = 300,
1077
1623
  loadingFallback = null,
1078
1624
  emptyFallback = null,
1079
1625
  errorFallback,
1080
1626
  resetKeys,
1081
1627
  ...rendererProps
1082
1628
  } = props;
1083
- const latest = (0, import_react5.useRef)({ actions, confirmAction, parseActionEvent, onAction, onError, onJuneError });
1084
- latest.current = { actions, confirmAction, parseActionEvent, onAction, onError, onJuneError };
1629
+ const latest = (0, import_react5.useRef)({ actions, confirmAction, parseActionEvent, onAction, onError, onJuneError, onResponseChange, responseChangeDelay, response });
1630
+ latest.current = { actions, confirmAction, parseActionEvent, onAction, onError, onJuneError, onResponseChange, responseChangeDelay, response };
1631
+ const syncTimers = (0, import_react5.useRef)(/* @__PURE__ */ new Map());
1632
+ (0, import_react5.useEffect)(() => {
1633
+ const timers = syncTimers.current;
1634
+ return () => {
1635
+ timers.forEach(clearTimeout);
1636
+ timers.clear();
1637
+ };
1638
+ }, []);
1639
+ const syncProgram = (0, import_react5.useCallback)(async (change, store) => {
1640
+ const l = latest.current;
1641
+ if (!l.onResponseChange || typeof l.response !== "string") return;
1642
+ const record = store.get(change.documentId);
1643
+ const title = record?.title ?? change.title;
1644
+ const json = record?.json ?? change.json;
1645
+ try {
1646
+ const { docToMarkdown: docToMarkdown2 } = await Promise.resolve().then(() => (init_document_engine(), document_engine_exports));
1647
+ const markdown = docToMarkdown2(json);
1648
+ const program = latest.current.response;
1649
+ if (typeof program !== "string") return;
1650
+ const next = updateDocumentInProgram(program, change.documentId, { title, content: markdown });
1651
+ if (next === null || next === program) return;
1652
+ rememberDocumentEcho(store, change.documentId, markdown);
1653
+ latest.current.onResponseChange?.(next, { documentId: change.documentId, title, markdown, source: change.source });
1654
+ } catch (error) {
1655
+ latest.current.onJuneError?.(toJuneError(error, "DOCUMENT_ERROR", "Updating the program failed"));
1656
+ }
1657
+ }, []);
1085
1658
  const handleAction = (0, import_react5.useCallback)((event) => {
1086
1659
  const l = latest.current;
1087
1660
  l.onAction?.(event);
@@ -1120,12 +1693,27 @@ function JuneRenderer(props) {
1120
1693
  const documentOptions = (0, import_react5.useMemo)(
1121
1694
  () => ({
1122
1695
  ...documents,
1696
+ onDocumentChange: (change) => {
1697
+ documents?.onDocumentChange?.(change);
1698
+ if (!latest.current.onResponseChange || change.source === "ai") return;
1699
+ const store = documents?.store ?? getDefaultDocumentStore();
1700
+ const timers = syncTimers.current;
1701
+ const prev = timers.get(change.documentId);
1702
+ if (prev) clearTimeout(prev);
1703
+ timers.set(
1704
+ change.documentId,
1705
+ setTimeout(() => {
1706
+ timers.delete(change.documentId);
1707
+ void syncProgram(change, store);
1708
+ }, Math.max(0, latest.current.responseChangeDelay))
1709
+ );
1710
+ },
1123
1711
  onError: (error) => {
1124
1712
  documents?.onError?.(error);
1125
1713
  latest.current.onJuneError?.(error);
1126
1714
  }
1127
1715
  }),
1128
- [documents]
1716
+ [documents, syncProgram]
1129
1717
  );
1130
1718
  const parts = (0, import_react5.useMemo)(
1131
1719
  () => mixedContent && response ? splitResponse(response, { streaming: isStreaming }) : null,
@@ -1140,31 +1728,34 @@ function JuneRenderer(props) {
1140
1728
  const before = parts?.before ?? [];
1141
1729
  const after = parts?.after ?? [];
1142
1730
  const hasText = before.length + after.length > 0;
1143
- const text = (value, index, key) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react5.Fragment, { children: renderText ? renderText(value, index) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "june-text", children: value }) }, key);
1144
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(JuneThemeProvider, { mode: theme, vars: themeVars, className, style, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(JuneRuntimeContext.Provider, { value: runtime, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(JuneDocumentContext.Provider, { value: documentOptions, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1145
- JuneErrorBoundary,
1146
- {
1147
- fallback: errorFallback,
1148
- onError: handleBoundaryError,
1149
- resetKeys: resetKeys ?? [response],
1150
- children: [
1151
- before.map((t, i) => text(t, i, `b${i}`)),
1152
- hasUi && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1153
- import_react_lang.Renderer,
1154
- {
1155
- ...rendererProps,
1156
- library,
1157
- response: uiText,
1158
- isStreaming,
1159
- onAction: handleAction,
1160
- onError: handleParserErrors
1161
- }
1162
- ),
1163
- after.map((t, i) => text(t, before.length + i, `a${i}`)),
1164
- !hasUi && !hasText && (isStreaming ? loadingFallback : emptyFallback)
1165
- ]
1166
- }
1167
- ) }) }) });
1731
+ const text = (value, index, key) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react5.Fragment, { children: renderText ? renderText(value, index) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "june-text", children: value }) }, key);
1732
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(JuneThemeProvider, { mode: theme, vars: themeVars, className, style, children: [
1733
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(OpenUIDevtoolsGate, {}),
1734
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(JuneRuntimeContext.Provider, { value: runtime, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(JuneDocumentContext.Provider, { value: documentOptions, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1735
+ JuneErrorBoundary,
1736
+ {
1737
+ fallback: errorFallback,
1738
+ onError: handleBoundaryError,
1739
+ resetKeys: resetKeys ?? [response],
1740
+ children: [
1741
+ before.map((t, i) => text(t, i, `b${i}`)),
1742
+ hasUi && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1743
+ import_react_lang.Renderer,
1744
+ {
1745
+ ...rendererProps,
1746
+ library,
1747
+ response: uiText,
1748
+ isStreaming,
1749
+ onAction: handleAction,
1750
+ onError: handleParserErrors
1751
+ }
1752
+ ),
1753
+ after.map((t, i) => text(t, before.length + i, `a${i}`)),
1754
+ !hasUi && !hasText && (isStreaming ? loadingFallback : emptyFallback)
1755
+ ]
1756
+ }
1757
+ ) }) })
1758
+ ] });
1168
1759
  }
1169
1760
 
1170
1761
  // src/components/library.ts
@@ -1505,18 +2096,18 @@ var import_react_lang3 = require("@openuidev/react-lang");
1505
2096
  var import_v4 = require("zod/v4");
1506
2097
 
1507
2098
  // src/components/document-editor/document-draft.tsx
1508
- var import_jsx_runtime4 = require("react/jsx-runtime");
2099
+ var import_jsx_runtime5 = require("react/jsx-runtime");
1509
2100
  function DocumentDraft({ title, words, state }) {
1510
2101
  if (state === "empty") {
1511
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "june-doc june-doc--draft", role: "alert", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "june-doc__draft-text", children: "No document content was received." }) });
1512
- }
1513
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "june-doc june-doc--draft", role: "status", "aria-live": "polite", children: [
1514
- title ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "june-doc__draft-title", children: title }) : null,
1515
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "june-doc__draft-text", children: state === "drafting" ? `Drafting document\u2026${words ? ` ${words} words so far` : ""}` : "Loading editor\u2026" }),
1516
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "june-doc__pulse", "aria-hidden": "true", children: [
1517
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", {}),
1518
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", {}),
1519
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", {})
2102
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "june-doc june-doc--draft", role: "alert", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "june-doc__draft-text", children: "No document content was received." }) });
2103
+ }
2104
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "june-doc june-doc--draft", role: "status", "aria-live": "polite", children: [
2105
+ title ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "june-doc__draft-title", children: title }) : null,
2106
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "june-doc__draft-text", children: state === "drafting" ? `Drafting document\u2026${words ? ` ${words} words so far` : ""}` : "Loading editor\u2026" }),
2107
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "june-doc__pulse", "aria-hidden": "true", children: [
2108
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", {}),
2109
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", {}),
2110
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", {})
1520
2111
  ] })
1521
2112
  ] });
1522
2113
  }
@@ -1535,208 +2126,208 @@ var import_react8 = require("@tiptap/react");
1535
2126
  var import_react9 = require("react");
1536
2127
 
1537
2128
  // src/components/document-editor/document-icons.tsx
1538
- var import_jsx_runtime5 = require("react/jsx-runtime");
2129
+ var import_jsx_runtime6 = require("react/jsx-runtime");
1539
2130
  var PATHS = {
1540
- undo: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1541
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M9 14 4 9l5-5" }),
1542
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M4 9h10.5a5.5 5.5 0 0 1 0 11H11" })
2131
+ undo: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2132
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M9 14 4 9l5-5" }),
2133
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M4 9h10.5a5.5 5.5 0 0 1 0 11H11" })
1543
2134
  ] }),
1544
- redo: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1545
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m15 14 5-5-5-5" }),
1546
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M20 9H9.5a5.5 5.5 0 0 0 0 11H13" })
2135
+ redo: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2136
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m15 14 5-5-5-5" }),
2137
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M20 9H9.5a5.5 5.5 0 0 0 0 11H13" })
1547
2138
  ] }),
1548
- bold: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M6 12h9a4 4 0 0 1 0 8H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h7a4 4 0 0 1 0 8" }),
1549
- italic: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1550
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("line", { x1: "19", x2: "10", y1: "4", y2: "4" }),
1551
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("line", { x1: "14", x2: "5", y1: "20", y2: "20" }),
1552
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("line", { x1: "15", x2: "9", y1: "4", y2: "20" })
2139
+ bold: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M6 12h9a4 4 0 0 1 0 8H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h7a4 4 0 0 1 0 8" }),
2140
+ italic: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2141
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "19", x2: "10", y1: "4", y2: "4" }),
2142
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "14", x2: "5", y1: "20", y2: "20" }),
2143
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "15", x2: "9", y1: "4", y2: "20" })
1553
2144
  ] }),
1554
- underline: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1555
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M6 4v6a6 6 0 0 0 12 0V4" }),
1556
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("line", { x1: "4", x2: "20", y1: "20", y2: "20" })
2145
+ underline: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2146
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M6 4v6a6 6 0 0 0 12 0V4" }),
2147
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "4", x2: "20", y1: "20", y2: "20" })
1557
2148
  ] }),
1558
- strike: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1559
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M16 4H9a3 3 0 0 0-2.83 4" }),
1560
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M14 12a4 4 0 0 1 0 8H6" }),
1561
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("line", { x1: "4", x2: "20", y1: "12", y2: "12" })
2149
+ strike: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2150
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M16 4H9a3 3 0 0 0-2.83 4" }),
2151
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M14 12a4 4 0 0 1 0 8H6" }),
2152
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "4", x2: "20", y1: "12", y2: "12" })
1562
2153
  ] }),
1563
- code: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1564
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m16 18 6-6-6-6" }),
1565
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m8 6-6 6 6 6" })
2154
+ code: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2155
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m16 18 6-6-6-6" }),
2156
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m8 6-6 6 6 6" })
1566
2157
  ] }),
1567
- codeBlock: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1568
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }),
1569
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m10 9-3 3 3 3" }),
1570
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m14 15 3-3-3-3" })
2158
+ codeBlock: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2159
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }),
2160
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m10 9-3 3 3 3" }),
2161
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m14 15 3-3-3-3" })
1571
2162
  ] }),
1572
- superscript: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1573
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m4 19 8-8" }),
1574
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m12 19-8-8" }),
1575
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M20 12h-4c0-1.5.44-2 1.5-2.5S20 8.33 20 7c0-.47-.17-.93-.48-1.29a2.11 2.11 0 0 0-2.62-.44c-.42.24-.74.62-.9 1.07" })
2163
+ superscript: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2164
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m4 19 8-8" }),
2165
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m12 19-8-8" }),
2166
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M20 12h-4c0-1.5.44-2 1.5-2.5S20 8.33 20 7c0-.47-.17-.93-.48-1.29a2.11 2.11 0 0 0-2.62-.44c-.42.24-.74.62-.9 1.07" })
1576
2167
  ] }),
1577
- subscript: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1578
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m4 5 8 8" }),
1579
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m12 5-8 8" }),
1580
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M20 19h-4c0-1.5.44-2 1.5-2.5S20 15.33 20 14c0-.47-.17-.93-.48-1.29a2.11 2.11 0 0 0-2.62-.44c-.42.24-.74.62-.9 1.07" })
2168
+ subscript: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2169
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m4 5 8 8" }),
2170
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m12 5-8 8" }),
2171
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M20 19h-4c0-1.5.44-2 1.5-2.5S20 15.33 20 14c0-.47-.17-.93-.48-1.29a2.11 2.11 0 0 0-2.62-.44c-.42.24-.74.62-.9 1.07" })
1581
2172
  ] }),
1582
- alignLeft: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1583
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M15 12H3" }),
1584
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M17 18H3" }),
1585
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M21 6H3" })
2173
+ alignLeft: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2174
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M15 12H3" }),
2175
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M17 18H3" }),
2176
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M21 6H3" })
1586
2177
  ] }),
1587
- alignCenter: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1588
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M17 12H7" }),
1589
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M19 18H5" }),
1590
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M21 6H3" })
2178
+ alignCenter: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2179
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M17 12H7" }),
2180
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M19 18H5" }),
2181
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M21 6H3" })
1591
2182
  ] }),
1592
- alignRight: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1593
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M21 12H9" }),
1594
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M21 18H7" }),
1595
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M21 6H3" })
2183
+ alignRight: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2184
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M21 12H9" }),
2185
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M21 18H7" }),
2186
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M21 6H3" })
1596
2187
  ] }),
1597
- alignJustify: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1598
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M3 12h18" }),
1599
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M3 18h18" }),
1600
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M3 6h18" })
2188
+ alignJustify: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2189
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M3 12h18" }),
2190
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M3 18h18" }),
2191
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M3 6h18" })
1601
2192
  ] }),
1602
- list: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1603
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M3 12h.01" }),
1604
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M3 18h.01" }),
1605
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M3 6h.01" }),
1606
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M8 12h13" }),
1607
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M8 18h13" }),
1608
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M8 6h13" })
2193
+ list: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2194
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M3 12h.01" }),
2195
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M3 18h.01" }),
2196
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M3 6h.01" }),
2197
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M8 12h13" }),
2198
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M8 18h13" }),
2199
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M8 6h13" })
1609
2200
  ] }),
1610
- listOrdered: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1611
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M10 12h11" }),
1612
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M10 18h11" }),
1613
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M10 6h11" }),
1614
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M4 10h2" }),
1615
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M4 6h1v4" }),
1616
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M6 18H4c0-1 2-2 2-3s-1-1.5-2-1" })
2201
+ listOrdered: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2202
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M10 12h11" }),
2203
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M10 18h11" }),
2204
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M10 6h11" }),
2205
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M4 10h2" }),
2206
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M4 6h1v4" }),
2207
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M6 18H4c0-1 2-2 2-3s-1-1.5-2-1" })
1617
2208
  ] }),
1618
- outdent: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1619
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M21 12H11" }),
1620
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M21 18H11" }),
1621
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M21 6H11" }),
1622
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m7 8-4 4 4 4" })
2209
+ outdent: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2210
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M21 12H11" }),
2211
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M21 18H11" }),
2212
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M21 6H11" }),
2213
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m7 8-4 4 4 4" })
1623
2214
  ] }),
1624
- indent: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1625
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M21 12H11" }),
1626
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M21 18H11" }),
1627
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M21 6H11" }),
1628
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m3 8 4 4-4 4" })
2215
+ indent: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2216
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M21 12H11" }),
2217
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M21 18H11" }),
2218
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M21 6H11" }),
2219
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m3 8 4 4-4 4" })
1629
2220
  ] }),
1630
- quote: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1631
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M17 6H3" }),
1632
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M21 12H8" }),
1633
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M21 18H8" }),
1634
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M3 12v6" })
2221
+ quote: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2222
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M17 6H3" }),
2223
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M21 12H8" }),
2224
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M21 18H8" }),
2225
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M3 12v6" })
1635
2226
  ] }),
1636
- pilcrow: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1637
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M13 4v16" }),
1638
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M17 4v16" }),
1639
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M19 4H9.5a4.5 4.5 0 0 0 0 9H13" })
2227
+ pilcrow: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2228
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M13 4v16" }),
2229
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M17 4v16" }),
2230
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M19 4H9.5a4.5 4.5 0 0 0 0 9H13" })
1640
2231
  ] }),
1641
- pageBreak: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1642
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("line", { x1: "3", x2: "21", y1: "12", y2: "12" }),
1643
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("polyline", { points: "8 8 12 4 16 8" }),
1644
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("polyline", { points: "16 16 12 20 8 16" })
2232
+ pageBreak: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2233
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "3", x2: "21", y1: "12", y2: "12" }),
2234
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("polyline", { points: "8 8 12 4 16 8" }),
2235
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("polyline", { points: "16 16 12 20 8 16" })
1645
2236
  ] }),
1646
- divider: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1647
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M3 12h18" }),
1648
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M8 6h8", opacity: ".45" }),
1649
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M8 18h8", opacity: ".45" })
2237
+ divider: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2238
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M3 12h18" }),
2239
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M8 6h8", opacity: ".45" }),
2240
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M8 18h8", opacity: ".45" })
1650
2241
  ] }),
1651
- layout: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1652
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("rect", { width: "18", height: "7", x: "3", y: "3", rx: "1" }),
1653
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("rect", { width: "9", height: "7", x: "3", y: "14", rx: "1" }),
1654
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("rect", { width: "5", height: "7", x: "16", y: "14", rx: "1" })
2242
+ layout: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2243
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("rect", { width: "18", height: "7", x: "3", y: "3", rx: "1" }),
2244
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("rect", { width: "9", height: "7", x: "3", y: "14", rx: "1" }),
2245
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("rect", { width: "5", height: "7", x: "16", y: "14", rx: "1" })
1655
2246
  ] }),
1656
- search: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1657
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { cx: "11", cy: "11", r: "8" }),
1658
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m21 21-4.3-4.3" })
2247
+ search: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2248
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("circle", { cx: "11", cy: "11", r: "8" }),
2249
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m21 21-4.3-4.3" })
1659
2250
  ] }),
1660
- palette: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1661
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { cx: "13.5", cy: "6.5", r: ".5", fill: "currentColor" }),
1662
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { cx: "17.5", cy: "10.5", r: ".5", fill: "currentColor" }),
1663
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { cx: "8.5", cy: "7.5", r: ".5", fill: "currentColor" }),
1664
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { cx: "6.5", cy: "12.5", r: ".5", fill: "currentColor" }),
1665
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10c.93 0 1.65-.75 1.65-1.69 0-.44-.18-.84-.44-1.13-.29-.29-.44-.65-.44-1.13a1.64 1.64 0 0 1 1.67-1.67h2c3.05 0 5.55-2.5 5.55-5.55C21.97 6.01 17.46 2 12 2z" })
2251
+ palette: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2252
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("circle", { cx: "13.5", cy: "6.5", r: ".5", fill: "currentColor" }),
2253
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("circle", { cx: "17.5", cy: "10.5", r: ".5", fill: "currentColor" }),
2254
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("circle", { cx: "8.5", cy: "7.5", r: ".5", fill: "currentColor" }),
2255
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("circle", { cx: "6.5", cy: "12.5", r: ".5", fill: "currentColor" }),
2256
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10c.93 0 1.65-.75 1.65-1.69 0-.44-.18-.84-.44-1.13-.29-.29-.44-.65-.44-1.13a1.64 1.64 0 0 1 1.67-1.67h2c3.05 0 5.55-2.5 5.55-5.55C21.97 6.01 17.46 2 12 2z" })
1666
2257
  ] }),
1667
- highlighter: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1668
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m9 11-6 6v3h9l3-3" }),
1669
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m22 12-4.6 4.6a2 2 0 0 1-2.8 0l-5.2-5.2a2 2 0 0 1 0-2.8L14 4" })
2258
+ highlighter: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2259
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m9 11-6 6v3h9l3-3" }),
2260
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m22 12-4.6 4.6a2 2 0 0 1-2.8 0l-5.2-5.2a2 2 0 0 1 0-2.8L14 4" })
1670
2261
  ] }),
1671
- link: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1672
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" }),
1673
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" })
2262
+ link: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2263
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" }),
2264
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" })
1674
2265
  ] }),
1675
- image: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1676
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("rect", { width: "18", height: "18", x: "3", y: "3", rx: "2" }),
1677
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { cx: "9", cy: "9", r: "2" }),
1678
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m21 15-3.09-3.09a2 2 0 0 0-2.82 0L6 21" })
2266
+ image: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2267
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("rect", { width: "18", height: "18", x: "3", y: "3", rx: "2" }),
2268
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("circle", { cx: "9", cy: "9", r: "2" }),
2269
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m21 15-3.09-3.09a2 2 0 0 0-2.82 0L6 21" })
1679
2270
  ] }),
1680
- table: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1681
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M12 3v18" }),
1682
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("rect", { width: "18", height: "18", x: "3", y: "3", rx: "2" }),
1683
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M3 9h18" }),
1684
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M3 15h18" })
2271
+ table: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2272
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M12 3v18" }),
2273
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("rect", { width: "18", height: "18", x: "3", y: "3", rx: "2" }),
2274
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M3 9h18" }),
2275
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M3 15h18" })
1685
2276
  ] }),
1686
- eraser: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1687
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m7 21-4.3-4.3c-1-1-1-2.5 0-3.4l9.6-9.6c1-1 2.5-1 3.4 0l5.6 5.6c1 1 1 2.5 0 3.4L13 21" }),
1688
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M22 21H7" }),
1689
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m5 11 9 9" })
2277
+ eraser: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2278
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m7 21-4.3-4.3c-1-1-1-2.5 0-3.4l9.6-9.6c1-1 2.5-1 3.4 0l5.6 5.6c1 1 1 2.5 0 3.4L13 21" }),
2279
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M22 21H7" }),
2280
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m5 11 9 9" })
1690
2281
  ] }),
1691
- save: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1692
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z" }),
1693
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7" }),
1694
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M7 3v4a1 1 0 0 0 1 1h7" })
2282
+ save: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2283
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z" }),
2284
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7" }),
2285
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M7 3v4a1 1 0 0 0 1 1h7" })
1695
2286
  ] }),
1696
- download: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1697
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
1698
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("polyline", { points: "7 10 12 15 17 10" }),
1699
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("line", { x1: "12", x2: "12", y1: "15", y2: "3" })
2287
+ download: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2288
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
2289
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("polyline", { points: "7 10 12 15 17 10" }),
2290
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "12", x2: "12", y1: "15", y2: "3" })
1700
2291
  ] }),
1701
- chevronDown: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m6 9 6 6 6-6" }),
1702
- chevronUp: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m18 15-6-6-6 6" }),
1703
- close: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1704
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M18 6 6 18" }),
1705
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m6 6 12 12" })
2292
+ chevronDown: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m6 9 6 6 6-6" }),
2293
+ chevronUp: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m18 15-6-6-6 6" }),
2294
+ close: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2295
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M18 6 6 18" }),
2296
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m6 6 12 12" })
1706
2297
  ] }),
1707
- maximize: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1708
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M8 3H5a2 2 0 0 0-2 2v3" }),
1709
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M21 8V5a2 2 0 0 0-2-2h-3" }),
1710
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M3 16v3a2 2 0 0 0 2 2h3" }),
1711
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M16 21h3a2 2 0 0 0 2-2v-3" })
2298
+ maximize: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2299
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M8 3H5a2 2 0 0 0-2 2v3" }),
2300
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M21 8V5a2 2 0 0 0-2-2h-3" }),
2301
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M3 16v3a2 2 0 0 0 2 2h3" }),
2302
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M16 21h3a2 2 0 0 0 2-2v-3" })
1712
2303
  ] }),
1713
- copy: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1714
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("rect", { width: "14", height: "14", x: "8", y: "8", rx: "2" }),
1715
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" })
2304
+ copy: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2305
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("rect", { width: "14", height: "14", x: "8", y: "8", rx: "2" }),
2306
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" })
1716
2307
  ] }),
1717
- file: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1718
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
1719
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" })
2308
+ file: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2309
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
2310
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" })
1720
2311
  ] }),
1721
- plus: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1722
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M5 12h14" }),
1723
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M12 5v14" })
2312
+ plus: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2313
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M5 12h14" }),
2314
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M12 5v14" })
1724
2315
  ] }),
1725
- minus: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M5 12h14" }),
1726
- check: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M20 6 9 17l-5-5" }),
1727
- sparkles: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1728
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M9.94 14.06 8 20l-1.94-5.94L0 12l6.06-1.94L8 4l1.94 6.06L16 12z", transform: "translate(3 -1) scale(.85)" }),
1729
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M20 3v4" }),
1730
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M22 5h-4" })
2316
+ minus: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M5 12h14" }),
2317
+ check: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M20 6 9 17l-5-5" }),
2318
+ sparkles: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2319
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M9.94 14.06 8 20l-1.94-5.94L0 12l6.06-1.94L8 4l1.94 6.06L16 12z", transform: "translate(3 -1) scale(.85)" }),
2320
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M20 3v4" }),
2321
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M22 5h-4" })
1731
2322
  ] }),
1732
- upload: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1733
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
1734
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("polyline", { points: "17 8 12 3 7 8" }),
1735
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("line", { x1: "12", x2: "12", y1: "3", y2: "15" })
2323
+ upload: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2324
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
2325
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("polyline", { points: "17 8 12 3 7 8" }),
2326
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "12", x2: "12", y1: "3", y2: "15" })
1736
2327
  ] })
1737
2328
  };
1738
2329
  function Icon({ name, size = 16 }) {
1739
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2330
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1740
2331
  "svg",
1741
2332
  {
1742
2333
  className: "june-doc__icon",
@@ -1757,7 +2348,7 @@ function Icon({ name, size = 16 }) {
1757
2348
 
1758
2349
  // src/components/document-editor/document-popover.tsx
1759
2350
  var import_react7 = require("react");
1760
- var import_jsx_runtime6 = require("react/jsx-runtime");
2351
+ var import_jsx_runtime7 = require("react/jsx-runtime");
1761
2352
  function Dropdown({ trigger, children, align = "start", className, onOpen }) {
1762
2353
  const [open, setOpen] = (0, import_react7.useState)(false);
1763
2354
  const anchor = (0, import_react7.useRef)(null);
@@ -1774,7 +2365,7 @@ function Dropdown({ trigger, children, align = "start", className, onOpen }) {
1774
2365
  return !v;
1775
2366
  });
1776
2367
  const close = () => setOpen(false);
1777
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
2368
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1778
2369
  "div",
1779
2370
  {
1780
2371
  ref: anchor,
@@ -1787,7 +2378,7 @@ function Dropdown({ trigger, children, align = "start", className, onOpen }) {
1787
2378
  },
1788
2379
  children: [
1789
2380
  trigger({ open, toggle }),
1790
- open ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: `june-doc__pop june-doc__pop--${align}${className ? ` ${className}` : ""}`, children: children(close) }) : null
2381
+ open ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: `june-doc__pop june-doc__pop--${align}${className ? ` ${className}` : ""}`, children: children(close) }) : null
1791
2382
  ]
1792
2383
  }
1793
2384
  );
@@ -1795,7 +2386,7 @@ function Dropdown({ trigger, children, align = "start", className, onOpen }) {
1795
2386
 
1796
2387
  // src/components/document-editor/document-toolbar.tsx
1797
2388
  init_document_utils();
1798
- var import_jsx_runtime7 = require("react/jsx-runtime");
2389
+ var import_jsx_runtime8 = require("react/jsx-runtime");
1799
2390
  var FONT_FAMILIES = [
1800
2391
  { label: "Default", value: "" },
1801
2392
  { label: "Arial", value: "Arial, Helvetica, sans-serif" },
@@ -1842,7 +2433,7 @@ var HIGHLIGHT_COLORS = [
1842
2433
  ];
1843
2434
  var MAX_IMAGE_BYTES = 8 * 1024 * 1024;
1844
2435
  function Btn({ label, icon, active, disabled, toggle, onClick, children, className, text }) {
1845
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2436
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1846
2437
  "button",
1847
2438
  {
1848
2439
  type: "button",
@@ -1855,29 +2446,29 @@ function Btn({ label, icon, active, disabled, toggle, onClick, children, classNa
1855
2446
  onMouseDown: (e) => e.preventDefault(),
1856
2447
  onClick,
1857
2448
  children: [
1858
- icon ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Icon, { name: icon }) : null,
1859
- children ?? (text ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: label }) : null)
2449
+ icon ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Icon, { name: icon }) : null,
2450
+ children ?? (text ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: label }) : null)
1860
2451
  ]
1861
2452
  }
1862
2453
  );
1863
2454
  }
1864
2455
  function Group({ label, children }) {
1865
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "june-doc__group", role: "group", "aria-label": label, children: [
1866
- label ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "june-doc__group-label", "aria-hidden": "true", children: label }) : null,
2456
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "june-doc__group", role: "group", "aria-label": label, children: [
2457
+ label ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "june-doc__group-label", "aria-hidden": "true", children: label }) : null,
1867
2458
  children
1868
2459
  ] });
1869
2460
  }
1870
2461
  function Field({ label, children }) {
1871
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "june-doc__field", children: [
1872
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "june-doc__field-label", children: label }),
2462
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "june-doc__field", children: [
2463
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "june-doc__field-label", children: label }),
1873
2464
  children
1874
2465
  ] });
1875
2466
  }
1876
2467
  function ColorPicker({ label, icon, colors, current, disabled, resetLabel, onPick, onReset }) {
1877
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2468
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1878
2469
  Dropdown,
1879
2470
  {
1880
- trigger: ({ open, toggle }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2471
+ trigger: ({ open, toggle }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1881
2472
  "button",
1882
2473
  {
1883
2474
  type: "button",
@@ -1890,14 +2481,14 @@ function ColorPicker({ label, icon, colors, current, disabled, resetLabel, onPic
1890
2481
  onMouseDown: (e) => e.preventDefault(),
1891
2482
  onClick: toggle,
1892
2483
  children: [
1893
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Icon, { name: icon }),
1894
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "june-doc__color-bar", style: { background: current ?? "transparent" } })
2484
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Icon, { name: icon }),
2485
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "june-doc__color-bar", style: { background: current ?? "transparent" } })
1895
2486
  ]
1896
2487
  }
1897
2488
  ),
1898
- children: (close) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "june-doc__swatches-wrap", role: "dialog", "aria-label": label, children: [
1899
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "june-doc__pop-title", children: label }),
1900
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "june-doc__swatches", children: colors.map((c) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2489
+ children: (close) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "june-doc__swatches-wrap", role: "dialog", "aria-label": label, children: [
2490
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "june-doc__pop-title", children: label }),
2491
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "june-doc__swatches", children: colors.map((c) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1901
2492
  "button",
1902
2493
  {
1903
2494
  type: "button",
@@ -1914,8 +2505,8 @@ function ColorPicker({ label, icon, colors, current, disabled, resetLabel, onPic
1914
2505
  },
1915
2506
  c
1916
2507
  )) }),
1917
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "june-doc__pop-row", children: [
1918
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2508
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "june-doc__pop-row", children: [
2509
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1919
2510
  "button",
1920
2511
  {
1921
2512
  type: "button",
@@ -1928,9 +2519,9 @@ function ColorPicker({ label, icon, colors, current, disabled, resetLabel, onPic
1928
2519
  children: resetLabel
1929
2520
  }
1930
2521
  ),
1931
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "june-doc__custom-color", title: "Custom color", children: [
1932
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: "Custom" }),
1933
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2522
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "june-doc__custom-color", title: "Custom color", children: [
2523
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: "Custom" }),
2524
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1934
2525
  "input",
1935
2526
  {
1936
2527
  type: "color",
@@ -1961,9 +2552,9 @@ function LinkPanel({
1961
2552
  editor.chain().focus().extendMarkRange("link").unsetLink().run();
1962
2553
  close();
1963
2554
  };
1964
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "june-doc__form", role: "dialog", "aria-label": "Edit link", children: [
1965
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "june-doc__pop-title", children: "Link" }),
1966
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2555
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "june-doc__form", role: "dialog", "aria-label": "Edit link", children: [
2556
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "june-doc__pop-title", children: "Link" }),
2557
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1967
2558
  "input",
1968
2559
  {
1969
2560
  "aria-label": "Link address",
@@ -1980,10 +2571,10 @@ function LinkPanel({
1980
2571
  }
1981
2572
  }
1982
2573
  ),
1983
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "june-doc__pop-row june-doc__pop-row--end", children: [
1984
- isLink ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "june-doc__btn june-doc__btn--ghost", onClick: remove, children: "Remove" }) : null,
1985
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "june-doc__btn", onClick: close, children: "Cancel" }),
1986
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "june-doc__btn june-doc__btn--primary", onClick: apply, children: "Apply" })
2574
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "june-doc__pop-row june-doc__pop-row--end", children: [
2575
+ isLink ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", className: "june-doc__btn june-doc__btn--ghost", onClick: remove, children: "Remove" }) : null,
2576
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", className: "june-doc__btn", onClick: close, children: "Cancel" }),
2577
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", className: "june-doc__btn june-doc__btn--primary", onClick: apply, children: "Apply" })
1987
2578
  ] })
1988
2579
  ] });
1989
2580
  }
@@ -2012,9 +2603,9 @@ function ImagePanel({ editor, close, onNotice }) {
2012
2603
  reader.onerror = () => onNotice("The image could not be read");
2013
2604
  reader.readAsDataURL(f);
2014
2605
  };
2015
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "june-doc__form", role: "dialog", "aria-label": "Insert image", children: [
2016
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "june-doc__pop-title", children: "Image" }),
2017
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2606
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "june-doc__form", role: "dialog", "aria-label": "Insert image", children: [
2607
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "june-doc__pop-title", children: "Image" }),
2608
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2018
2609
  "button",
2019
2610
  {
2020
2611
  type: "button",
@@ -2026,12 +2617,12 @@ function ImagePanel({ editor, close, onNotice }) {
2026
2617
  fromFile(e.dataTransfer.files[0]);
2027
2618
  },
2028
2619
  children: [
2029
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Icon, { name: "upload", size: 18 }),
2030
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: "Upload or drop an image" })
2620
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Icon, { name: "upload", size: 18 }),
2621
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: "Upload or drop an image" })
2031
2622
  ]
2032
2623
  }
2033
2624
  ),
2034
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2625
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2035
2626
  "input",
2036
2627
  {
2037
2628
  ref: file,
@@ -2041,8 +2632,8 @@ function ImagePanel({ editor, close, onNotice }) {
2041
2632
  onChange: (e) => fromFile(e.target.files?.[0])
2042
2633
  }
2043
2634
  ),
2044
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "june-doc__or", children: "or" }),
2045
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2635
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "june-doc__or", children: "or" }),
2636
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2046
2637
  "input",
2047
2638
  {
2048
2639
  "aria-label": "Image address",
@@ -2053,7 +2644,7 @@ function ImagePanel({ editor, close, onNotice }) {
2053
2644
  onKeyDown: (e) => e.key === "Enter" && fromUrl()
2054
2645
  }
2055
2646
  ),
2056
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2647
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2057
2648
  "input",
2058
2649
  {
2059
2650
  "aria-label": "Alternative text",
@@ -2063,24 +2654,24 @@ function ImagePanel({ editor, close, onNotice }) {
2063
2654
  onChange: (e) => setAlt(e.target.value)
2064
2655
  }
2065
2656
  ),
2066
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "june-doc__pop-row june-doc__pop-row--end", children: [
2067
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "june-doc__btn", onClick: close, children: "Cancel" }),
2068
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "june-doc__btn june-doc__btn--primary", disabled: !url.trim(), onClick: fromUrl, children: "Insert" })
2657
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "june-doc__pop-row june-doc__pop-row--end", children: [
2658
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", className: "june-doc__btn", onClick: close, children: "Cancel" }),
2659
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", className: "june-doc__btn june-doc__btn--primary", disabled: !url.trim(), onClick: fromUrl, children: "Insert" })
2069
2660
  ] })
2070
2661
  ] });
2071
2662
  }
2072
2663
  function TablePanel({ editor, close }) {
2073
2664
  const [hover, setHover] = (0, import_react9.useState)([0, 0]);
2074
2665
  const N = 8;
2075
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "june-doc__form", role: "dialog", "aria-label": "Insert table", children: [
2076
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "june-doc__pop-title", children: [
2666
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "june-doc__form", role: "dialog", "aria-label": "Insert table", children: [
2667
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "june-doc__pop-title", children: [
2077
2668
  "Table ",
2078
2669
  hover[0] ? `${hover[0]} \xD7 ${hover[1]}` : ""
2079
2670
  ] }),
2080
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "june-doc__grid", onMouseLeave: () => setHover([0, 0]), children: Array.from({ length: N * N }, (_, i) => {
2671
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "june-doc__grid", onMouseLeave: () => setHover([0, 0]), children: Array.from({ length: N * N }, (_, i) => {
2081
2672
  const r = Math.floor(i / N) + 1;
2082
2673
  const c = i % N + 1;
2083
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2674
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2084
2675
  "button",
2085
2676
  {
2086
2677
  type: "button",
@@ -2162,34 +2753,34 @@ function DocumentToolbar(props) {
2162
2753
  const fontKnown = FONT_FAMILIES.some((f) => f.value === s?.fontFamily);
2163
2754
  const sizes = s?.fontSize && !FONT_SIZES.includes(Number(s.fontSize)) ? [...FONT_SIZES, Number(s.fontSize)].sort((a, b) => a - b) : FONT_SIZES;
2164
2755
  if (!editable) return null;
2165
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "june-doc__ribbon", role: "toolbar", "aria-label": "Document formatting", children: [
2166
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "june-doc__row", children: [
2167
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Group, { label: "History", children: [
2168
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { label: "Undo", icon: "undo", disabled: off || !s?.canUndo, onClick: () => run()?.undo().run() }),
2169
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { label: "Redo", icon: "redo", disabled: off || !s?.canRedo, onClick: () => run()?.redo().run() })
2756
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "june-doc__ribbon", role: "toolbar", "aria-label": "Document formatting", children: [
2757
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "june-doc__row", children: [
2758
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Group, { label: "History", children: [
2759
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Undo", icon: "undo", disabled: off || !s?.canUndo, onClick: () => run()?.undo().run() }),
2760
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Redo", icon: "redo", disabled: off || !s?.canRedo, onClick: () => run()?.redo().run() })
2170
2761
  ] }),
2171
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Group, { label: "Format", children: [
2172
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { label: "Bold", icon: "bold", toggle: true, active: s?.bold, disabled: off, onClick: () => run()?.toggleBold().run() }),
2173
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { label: "Italic", icon: "italic", toggle: true, active: s?.italic, disabled: off, onClick: () => run()?.toggleItalic().run() }),
2174
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { label: "Underline", icon: "underline", toggle: true, active: s?.underline, disabled: off, onClick: () => run()?.toggleUnderline().run() }),
2175
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { label: "Strikethrough", icon: "strike", toggle: true, active: s?.strike, disabled: off, onClick: () => run()?.toggleStrike().run() }),
2176
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { label: "Inline code", icon: "code", toggle: true, active: s?.code, disabled: off, onClick: () => run()?.toggleCode().run() }),
2177
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { label: "Superscript", icon: "superscript", toggle: true, active: s?.sup, disabled: off, onClick: () => run()?.toggleSuperscript().run() }),
2178
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { label: "Subscript", icon: "subscript", toggle: true, active: s?.sub, disabled: off, onClick: () => run()?.toggleSubscript().run() })
2762
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Group, { label: "Format", children: [
2763
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Bold", icon: "bold", toggle: true, active: s?.bold, disabled: off, onClick: () => run()?.toggleBold().run() }),
2764
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Italic", icon: "italic", toggle: true, active: s?.italic, disabled: off, onClick: () => run()?.toggleItalic().run() }),
2765
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Underline", icon: "underline", toggle: true, active: s?.underline, disabled: off, onClick: () => run()?.toggleUnderline().run() }),
2766
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Strikethrough", icon: "strike", toggle: true, active: s?.strike, disabled: off, onClick: () => run()?.toggleStrike().run() }),
2767
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Inline code", icon: "code", toggle: true, active: s?.code, disabled: off, onClick: () => run()?.toggleCode().run() }),
2768
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Superscript", icon: "superscript", toggle: true, active: s?.sup, disabled: off, onClick: () => run()?.toggleSuperscript().run() }),
2769
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Subscript", icon: "subscript", toggle: true, active: s?.sub, disabled: off, onClick: () => run()?.toggleSubscript().run() })
2179
2770
  ] }),
2180
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Group, { label: "Align", children: [
2181
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { label: "Align left", icon: "alignLeft", toggle: true, active: s?.left, disabled: off, onClick: () => run()?.setTextAlign("left").run() }),
2182
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { label: "Align center", icon: "alignCenter", toggle: true, active: s?.center, disabled: off, onClick: () => run()?.setTextAlign("center").run() }),
2183
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { label: "Align right", icon: "alignRight", toggle: true, active: s?.right, disabled: off, onClick: () => run()?.setTextAlign("right").run() }),
2184
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { label: "Justify", icon: "alignJustify", toggle: true, active: s?.justify, disabled: off, onClick: () => run()?.setTextAlign("justify").run() })
2771
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Group, { label: "Align", children: [
2772
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Align left", icon: "alignLeft", toggle: true, active: s?.left, disabled: off, onClick: () => run()?.setTextAlign("left").run() }),
2773
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Align center", icon: "alignCenter", toggle: true, active: s?.center, disabled: off, onClick: () => run()?.setTextAlign("center").run() }),
2774
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Align right", icon: "alignRight", toggle: true, active: s?.right, disabled: off, onClick: () => run()?.setTextAlign("right").run() }),
2775
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Justify", icon: "alignJustify", toggle: true, active: s?.justify, disabled: off, onClick: () => run()?.setTextAlign("justify").run() })
2185
2776
  ] }),
2186
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Group, { label: "Lists", children: [
2187
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { label: "Bullet list", icon: "list", toggle: true, active: s?.bullet, disabled: off, onClick: () => run()?.toggleBulletList().run() }),
2188
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { label: "Numbered list", icon: "listOrdered", toggle: true, active: s?.ordered, disabled: off, onClick: () => run()?.toggleOrderedList().run() }),
2189
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { label: "Decrease indent", icon: "outdent", disabled: off || !s?.canLift, onClick: () => run()?.liftListItem("listItem").run() }),
2190
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { label: "Increase indent", icon: "indent", disabled: off || !s?.canSink, onClick: () => run()?.sinkListItem("listItem").run() })
2777
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Group, { label: "Lists", children: [
2778
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Bullet list", icon: "list", toggle: true, active: s?.bullet, disabled: off, onClick: () => run()?.toggleBulletList().run() }),
2779
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Numbered list", icon: "listOrdered", toggle: true, active: s?.ordered, disabled: off, onClick: () => run()?.toggleOrderedList().run() }),
2780
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Decrease indent", icon: "outdent", disabled: off || !s?.canLift, onClick: () => run()?.liftListItem("listItem").run() }),
2781
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Increase indent", icon: "indent", disabled: off || !s?.canSink, onClick: () => run()?.sinkListItem("listItem").run() })
2191
2782
  ] }),
2192
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2783
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2193
2784
  "button",
2194
2785
  {
2195
2786
  type: "button",
@@ -2200,22 +2791,22 @@ function DocumentToolbar(props) {
2200
2791
  onClick: onToggleExpanded,
2201
2792
  children: [
2202
2793
  expanded ? "Less" : "More",
2203
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Icon, { name: expanded ? "chevronUp" : "chevronDown", size: 14 })
2794
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Icon, { name: expanded ? "chevronUp" : "chevronDown", size: 14 })
2204
2795
  ]
2205
2796
  }
2206
2797
  )
2207
2798
  ] }),
2208
- expanded ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "june-doc__row june-doc__row--secondary", children: [
2209
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Group, { label: "Style", children: [
2210
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Field, { label: "Style", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("select", { className: "june-doc__select", "aria-label": "Text style", disabled: off, value: style, onChange: (e) => setStyle(e.target.value), children: [
2211
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: "p", children: "Paragraph" }),
2212
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: "1", children: "Heading 1" }),
2213
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: "2", children: "Heading 2" }),
2214
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: "3", children: "Heading 3" }),
2215
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: "quote", children: "Quote" }),
2216
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: "code", children: "Code block" })
2799
+ expanded ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "june-doc__row june-doc__row--secondary", children: [
2800
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Group, { label: "Style", children: [
2801
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Field, { label: "Style", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("select", { className: "june-doc__select", "aria-label": "Text style", disabled: off, value: style, onChange: (e) => setStyle(e.target.value), children: [
2802
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "p", children: "Paragraph" }),
2803
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "1", children: "Heading 1" }),
2804
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "2", children: "Heading 2" }),
2805
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "3", children: "Heading 3" }),
2806
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "quote", children: "Quote" }),
2807
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "code", children: "Code block" })
2217
2808
  ] }) }),
2218
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Field, { label: "Font", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2809
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Field, { label: "Font", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2219
2810
  "select",
2220
2811
  {
2221
2812
  className: "june-doc__select june-doc__select--font",
@@ -2228,12 +2819,12 @@ function DocumentToolbar(props) {
2228
2819
  else run()?.unsetFontFamily().run();
2229
2820
  },
2230
2821
  children: [
2231
- FONT_FAMILIES.map((f) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: f.value, style: { fontFamily: f.value || void 0 }, children: f.label }, f.label)),
2232
- !fontKnown && s?.fontFamily ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: s.fontFamily, children: s.fontFamily.split(",")[0].replace(/['"]/g, "") }) : null
2822
+ FONT_FAMILIES.map((f) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: f.value, style: { fontFamily: f.value || void 0 }, children: f.label }, f.label)),
2823
+ !fontKnown && s?.fontFamily ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: s.fontFamily, children: s.fontFamily.split(",")[0].replace(/['"]/g, "") }) : null
2233
2824
  ]
2234
2825
  }
2235
2826
  ) }),
2236
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Field, { label: "Size", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2827
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Field, { label: "Size", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2237
2828
  "select",
2238
2829
  {
2239
2830
  className: "june-doc__select june-doc__select--size",
@@ -2246,21 +2837,21 @@ function DocumentToolbar(props) {
2246
2837
  else run()?.unsetFontSize().run();
2247
2838
  },
2248
2839
  children: [
2249
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: "", children: "Auto" }),
2250
- sizes.map((n) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: String(n), children: n }, n))
2840
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "", children: "Auto" }),
2841
+ sizes.map((n) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: String(n), children: n }, n))
2251
2842
  ]
2252
2843
  }
2253
2844
  ) })
2254
2845
  ] }),
2255
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { label: "Show formatting marks", icon: "pilcrow", toggle: true, active: showMarks, onClick: onToggleMarks, text: true, className: "june-doc__btn--marks", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: "Paragraph" }) }),
2256
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Group, { label: "Document", children: [
2257
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { label: "Insert page break", icon: "pageBreak", disabled: off, onClick: () => run()?.setPageBreak().run() }),
2258
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { label: "Insert divider", icon: "divider", disabled: off, onClick: () => run()?.setHorizontalRule().run() }),
2259
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { label: layout === "page" ? "Switch to full-width layout" : "Switch to page layout", icon: "layout", toggle: true, active: layout === "fluid", onClick: onToggleLayout }),
2260
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { label: "Find and replace", icon: "search", toggle: true, active: findOpen, onClick: onToggleFind })
2846
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Show formatting marks", icon: "pilcrow", toggle: true, active: showMarks, onClick: onToggleMarks, text: true, className: "june-doc__btn--marks", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: "Paragraph" }) }),
2847
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Group, { label: "Document", children: [
2848
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Insert page break", icon: "pageBreak", disabled: off, onClick: () => run()?.setPageBreak().run() }),
2849
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Insert divider", icon: "divider", disabled: off, onClick: () => run()?.setHorizontalRule().run() }),
2850
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: layout === "page" ? "Switch to full-width layout" : "Switch to page layout", icon: "layout", toggle: true, active: layout === "fluid", onClick: onToggleLayout }),
2851
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Find and replace", icon: "search", toggle: true, active: findOpen, onClick: onToggleFind })
2261
2852
  ] }),
2262
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Group, { label: "Color", children: [
2263
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2853
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Group, { label: "Color", children: [
2854
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2264
2855
  ColorPicker,
2265
2856
  {
2266
2857
  label: "Text color",
@@ -2273,7 +2864,7 @@ function DocumentToolbar(props) {
2273
2864
  onReset: () => run()?.unsetColor().run()
2274
2865
  }
2275
2866
  ),
2276
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2867
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2277
2868
  ColorPicker,
2278
2869
  {
2279
2870
  label: "Highlight",
@@ -2287,34 +2878,34 @@ function DocumentToolbar(props) {
2287
2878
  }
2288
2879
  )
2289
2880
  ] }),
2290
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Group, { label: "Insert", children: [
2291
- editor ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2881
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Group, { label: "Insert", children: [
2882
+ editor ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2292
2883
  Dropdown,
2293
2884
  {
2294
- trigger: ({ open, toggle }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { label: "Link", icon: "link", toggle: true, active: s?.link || open, disabled: off, onClick: toggle }),
2295
- children: (close) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(LinkPanel, { editor, href: s?.linkHref ?? "", isLink: !!s?.link, close })
2885
+ trigger: ({ open, toggle }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Link", icon: "link", toggle: true, active: s?.link || open, disabled: off, onClick: toggle }),
2886
+ children: (close) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(LinkPanel, { editor, href: s?.linkHref ?? "", isLink: !!s?.link, close })
2296
2887
  }
2297
2888
  ) : null,
2298
- editor ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Dropdown, { trigger: ({ open, toggle }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { label: "Insert image", icon: "image", active: open, disabled: off, onClick: toggle }), children: (close) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ImagePanel, { editor, close, onNotice }) }) : null,
2299
- editor ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Dropdown, { trigger: ({ open, toggle }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { label: "Insert table", icon: "table", active: open, disabled: off, onClick: toggle }), children: (close) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(TablePanel, { editor, close }) }) : null
2889
+ editor ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Dropdown, { trigger: ({ open, toggle }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Insert image", icon: "image", active: open, disabled: off, onClick: toggle }), children: (close) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ImagePanel, { editor, close, onNotice }) }) : null,
2890
+ editor ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Dropdown, { trigger: ({ open, toggle }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Insert table", icon: "table", active: open, disabled: off, onClick: toggle }), children: (close) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TablePanel, { editor, close }) }) : null
2300
2891
  ] }),
2301
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Group, { label: "Actions", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { label: "Clear formatting", icon: "eraser", disabled: off, onClick: () => run()?.unsetAllMarks().clearNodes().run() }) })
2892
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Group, { label: "Actions", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Clear formatting", icon: "eraser", disabled: off, onClick: () => run()?.unsetAllMarks().clearNodes().run() }) })
2302
2893
  ] }) : null,
2303
- s?.inTable ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "june-doc__row june-doc__row--context", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Group, { label: "Table", children: [
2304
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { label: "Add row below", disabled: off, onClick: () => run()?.addRowAfter().run(), children: "+ Row" }),
2305
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { label: "Add column right", disabled: off, onClick: () => run()?.addColumnAfter().run(), children: "+ Column" }),
2306
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { label: "Delete row", disabled: off, onClick: () => run()?.deleteRow().run(), children: "\u2212 Row" }),
2307
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { label: "Delete column", disabled: off, onClick: () => run()?.deleteColumn().run(), children: "\u2212 Column" }),
2308
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { label: "Merge cells", disabled: off || !s?.canMerge, onClick: () => run()?.mergeCells().run(), children: "Merge" }),
2309
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { label: "Split cell", disabled: off || !s?.canSplit, onClick: () => run()?.splitCell().run(), children: "Split" }),
2310
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { label: "Toggle header row", disabled: off, onClick: () => run()?.toggleHeaderRow().run(), children: "Header row" }),
2311
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { label: "Delete table", disabled: off, onClick: () => run()?.deleteTable().run(), className: "june-doc__btn--danger", children: "Delete table" })
2894
+ s?.inTable ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "june-doc__row june-doc__row--context", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Group, { label: "Table", children: [
2895
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Add row below", disabled: off, onClick: () => run()?.addRowAfter().run(), children: "+ Row" }),
2896
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Add column right", disabled: off, onClick: () => run()?.addColumnAfter().run(), children: "+ Column" }),
2897
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Delete row", disabled: off, onClick: () => run()?.deleteRow().run(), children: "\u2212 Row" }),
2898
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Delete column", disabled: off, onClick: () => run()?.deleteColumn().run(), children: "\u2212 Column" }),
2899
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Merge cells", disabled: off || !s?.canMerge, onClick: () => run()?.mergeCells().run(), children: "Merge" }),
2900
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Split cell", disabled: off || !s?.canSplit, onClick: () => run()?.splitCell().run(), children: "Split" }),
2901
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Toggle header row", disabled: off, onClick: () => run()?.toggleHeaderRow().run(), children: "Header row" }),
2902
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Delete table", disabled: off, onClick: () => run()?.deleteTable().run(), className: "june-doc__btn--danger", children: "Delete table" })
2312
2903
  ] }) }) : null
2313
2904
  ] });
2314
2905
  }
2315
2906
 
2316
2907
  // src/components/document-editor/document-bubble.tsx
2317
- var import_jsx_runtime8 = require("react/jsx-runtime");
2908
+ var import_jsx_runtime9 = require("react/jsx-runtime");
2318
2909
  function DocumentBubbleMenu({ editor }) {
2319
2910
  const s = (0, import_react10.useEditorState)({
2320
2911
  editor,
@@ -2330,7 +2921,7 @@ function DocumentBubbleMenu({ editor }) {
2330
2921
  })
2331
2922
  });
2332
2923
  const run = () => editor.chain().focus();
2333
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2924
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
2334
2925
  import_menus.BubbleMenu,
2335
2926
  {
2336
2927
  editor,
@@ -2343,13 +2934,13 @@ function DocumentBubbleMenu({ editor }) {
2343
2934
  return state.doc.textBetween(state.selection.from, state.selection.to).trim().length > 0;
2344
2935
  },
2345
2936
  children: [
2346
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Bold", icon: "bold", toggle: true, active: s.bold, onClick: () => run().toggleBold().run() }),
2347
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Italic", icon: "italic", toggle: true, active: s.italic, onClick: () => run().toggleItalic().run() }),
2348
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Underline", icon: "underline", toggle: true, active: s.underline, onClick: () => run().toggleUnderline().run() }),
2349
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Strikethrough", icon: "strike", toggle: true, active: s.strike, onClick: () => run().toggleStrike().run() }),
2350
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "june-doc__bubble-sep", "aria-hidden": "true" }),
2351
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Dropdown, { trigger: ({ open, toggle }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Link", icon: "link", toggle: true, active: s.link || open, onClick: toggle }), children: (close) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(LinkPanel, { editor, href: s.linkHref, isLink: s.link, close }) }),
2352
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2937
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Btn, { label: "Bold", icon: "bold", toggle: true, active: s.bold, onClick: () => run().toggleBold().run() }),
2938
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Btn, { label: "Italic", icon: "italic", toggle: true, active: s.italic, onClick: () => run().toggleItalic().run() }),
2939
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Btn, { label: "Underline", icon: "underline", toggle: true, active: s.underline, onClick: () => run().toggleUnderline().run() }),
2940
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Btn, { label: "Strikethrough", icon: "strike", toggle: true, active: s.strike, onClick: () => run().toggleStrike().run() }),
2941
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "june-doc__bubble-sep", "aria-hidden": "true" }),
2942
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Dropdown, { trigger: ({ open, toggle }) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Btn, { label: "Link", icon: "link", toggle: true, active: s.link || open, onClick: toggle }), children: (close) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(LinkPanel, { editor, href: s.linkHref, isLink: s.link, close }) }),
2943
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2353
2944
  ColorPicker,
2354
2945
  {
2355
2946
  label: "Text color",
@@ -2361,7 +2952,7 @@ function DocumentBubbleMenu({ editor }) {
2361
2952
  onReset: () => run().unsetColor().run()
2362
2953
  }
2363
2954
  ),
2364
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2955
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2365
2956
  ColorPicker,
2366
2957
  {
2367
2958
  label: "Highlight",
@@ -2373,8 +2964,8 @@ function DocumentBubbleMenu({ editor }) {
2373
2964
  onReset: () => run().unsetHighlight().run()
2374
2965
  }
2375
2966
  ),
2376
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "june-doc__bubble-sep", "aria-hidden": "true" }),
2377
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Clear formatting", icon: "eraser", onClick: () => run().unsetAllMarks().run() })
2967
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "june-doc__bubble-sep", "aria-hidden": "true" }),
2968
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Btn, { label: "Clear formatting", icon: "eraser", onClick: () => run().unsetAllMarks().run() })
2378
2969
  ]
2379
2970
  }
2380
2971
  );
@@ -2383,60 +2974,117 @@ function DocumentBubbleMenu({ editor }) {
2383
2974
  // src/components/document-editor/document-content.tsx
2384
2975
  var import_react11 = require("@tiptap/react");
2385
2976
  var import_react12 = require("react");
2386
- var import_jsx_runtime9 = require("react/jsx-runtime");
2977
+ init_document_pagination();
2978
+ var import_jsx_runtime10 = require("react/jsx-runtime");
2979
+ var PAGE_WIDTH = 794;
2387
2980
  var PAGE_HEIGHT = 1123;
2388
- var PAGE_PAD_Y = 96;
2981
+ var PAGE_GAP = 28;
2982
+ var CANVAS_PAD_X = 24;
2983
+ var useIsoLayoutEffect = typeof window === "undefined" ? import_react12.useEffect : import_react12.useLayoutEffect;
2984
+ function geometry(width) {
2985
+ const ratio = width / PAGE_WIDTH;
2986
+ const height = Math.round(PAGE_HEIGHT * ratio);
2987
+ const padX = Math.round(Math.min(96, Math.max(20, width * 0.12)));
2988
+ const padY = Math.round(Math.min(96, Math.max(36, 96 * ratio)));
2989
+ return { width, height, padX, padY };
2990
+ }
2389
2991
  function DocumentContent({ editor, layout = "page", zoom = 1, showMarks = false, onMetrics }) {
2390
2992
  const canvas = (0, import_react12.useRef)(null);
2391
2993
  const sheet = (0, import_react12.useRef)(null);
2994
+ const [avail, setAvail] = (0, import_react12.useState)(PAGE_WIDTH);
2995
+ const [sheetH, setSheetH] = (0, import_react12.useState)(0);
2392
2996
  const [pages, setPages] = (0, import_react12.useState)(1);
2393
2997
  const metricsRef = (0, import_react12.useRef)(onMetrics);
2394
2998
  metricsRef.current = onMetrics;
2395
2999
  const last = (0, import_react12.useRef)({ page: 0, pages: 0 });
3000
+ const paged = layout === "page";
3001
+ const width = paged ? Math.max(260, Math.min(PAGE_WIDTH, Math.floor(avail / zoom))) : Math.max(260, Math.floor(avail / zoom));
3002
+ const g = geometry(width);
3003
+ const stride = g.height + PAGE_GAP;
3004
+ useIsoLayoutEffect(() => {
3005
+ const c = canvas.current;
3006
+ if (!c) return;
3007
+ const read = () => {
3008
+ const cs = typeof getComputedStyle === "function" ? getComputedStyle(c) : null;
3009
+ const padX = cs ? (parseFloat(cs.paddingLeft) || 0) + (parseFloat(cs.paddingRight) || 0) : CANVAS_PAD_X * 2;
3010
+ const w = c.clientWidth - padX;
3011
+ if (w > 0) setAvail(w);
3012
+ };
3013
+ read();
3014
+ if (typeof ResizeObserver === "undefined") return;
3015
+ const ro = new ResizeObserver(read);
3016
+ ro.observe(c);
3017
+ return () => ro.disconnect();
3018
+ }, []);
3019
+ (0, import_react12.useEffect)(() => {
3020
+ if (!editor) return;
3021
+ setPaginationConfig(editor, {
3022
+ enabled: paged,
3023
+ pageHeight: g.height,
3024
+ gap: PAGE_GAP,
3025
+ padTop: g.padY,
3026
+ padBottom: g.padY
3027
+ });
3028
+ }, [editor, paged, g.height, g.padY, width]);
2396
3029
  (0, import_react12.useEffect)(() => {
2397
3030
  const c = canvas.current;
2398
- const p = sheet.current;
2399
- const prose = editor?.view.dom;
2400
- if (!c || !p || !prose) return;
2401
- const measure = () => {
2402
- const contentH = prose.getBoundingClientRect().height / zoom;
2403
- const total = layout === "page" ? Math.max(1, Math.ceil((contentH + PAGE_PAD_Y * 2) / PAGE_HEIGHT)) : 1;
2404
- const cRect = c.getBoundingClientRect();
2405
- const pRect = p.getBoundingClientRect();
2406
- const y = cRect.top + c.clientHeight * 0.35 - pRect.top;
2407
- const page = Math.min(total, Math.max(1, Math.floor(y / (PAGE_HEIGHT * zoom)) + 1));
3031
+ const s = sheet.current;
3032
+ if (!editor || !c || !s) return;
3033
+ const prose = editor.view.dom;
3034
+ const report = () => {
3035
+ const total = paged ? getPageCount(editor) : 1;
2408
3036
  setPages(total);
3037
+ setSheetH(s.offsetHeight);
3038
+ const cRect = c.getBoundingClientRect();
3039
+ const sRect = s.getBoundingClientRect();
3040
+ const y = (cRect.top + c.clientHeight * 0.35 - sRect.top) / zoom;
3041
+ const page = paged ? Math.min(total, Math.max(1, Math.floor(y / stride) + 1)) : 1;
2409
3042
  if (last.current.page !== page || last.current.pages !== total) {
2410
3043
  last.current = { page, pages: total };
2411
3044
  metricsRef.current?.({ page, pages: total });
2412
3045
  }
2413
3046
  };
2414
- measure();
2415
- c.addEventListener("scroll", measure, { passive: true });
2416
- const ro = typeof ResizeObserver !== "undefined" ? new ResizeObserver(measure) : null;
2417
- ro?.observe(prose);
2418
- ro?.observe(c);
2419
- editor?.on("update", measure);
3047
+ report();
3048
+ editor.on("transaction", report);
3049
+ c.addEventListener("scroll", report, { passive: true });
3050
+ const onLoad = () => remeasurePagination(editor);
3051
+ prose.addEventListener("load", onLoad, true);
3052
+ const ro = typeof ResizeObserver !== "undefined" ? new ResizeObserver(report) : null;
3053
+ ro?.observe(s);
2420
3054
  return () => {
2421
- c.removeEventListener("scroll", measure);
3055
+ editor.off("transaction", report);
3056
+ c.removeEventListener("scroll", report);
3057
+ prose.removeEventListener("load", onLoad, true);
2422
3058
  ro?.disconnect();
2423
- editor?.off("update", measure);
2424
3059
  };
2425
- }, [editor, layout, zoom]);
2426
- const sheetStyle = layout === "page" ? {
2427
- zoom,
2428
- minHeight: pages * PAGE_HEIGHT,
2429
- maxWidth: `calc(100% / ${zoom})`,
2430
- "--jd-page-h": `${PAGE_HEIGHT}px`
2431
- } : { zoom };
2432
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { ref: canvas, className: "june-doc__content june-doc__canvas", "data-layout": layout, "data-marks": showMarks || void 0, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { ref: sheet, className: "june-doc__sheet", style: sheetStyle, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react11.EditorContent, { editor }) }) });
3060
+ }, [editor, paged, zoom, stride]);
3061
+ const minHeight = paged ? pages * g.height + (pages - 1) * PAGE_GAP : void 0;
3062
+ const sheetStyle = {
3063
+ width,
3064
+ minHeight,
3065
+ transform: zoom === 1 ? void 0 : `scale(${zoom})`,
3066
+ "--jd-pad-x": `${g.padX}px`,
3067
+ "--jd-pad-y": `${g.padY}px`
3068
+ };
3069
+ const zoomerStyle = {
3070
+ width: width * zoom,
3071
+ height: zoom === 1 ? void 0 : Math.max(sheetH, minHeight ?? 0) * zoom
3072
+ };
3073
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { ref: canvas, className: "june-doc__content june-doc__canvas", "data-layout": layout, "data-marks": showMarks || void 0, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "june-doc__zoomer", style: zoomerStyle, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { ref: sheet, className: "june-doc__sheet", style: sheetStyle, children: [
3074
+ paged ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "june-doc__pages", "aria-hidden": "true", children: Array.from({ length: pages }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "june-doc__page", style: { top: i * stride, height: g.height }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "june-doc__page-num", children: [
3075
+ i + 1,
3076
+ " / ",
3077
+ pages
3078
+ ] }) }, i)) }) : null,
3079
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react11.EditorContent, { editor })
3080
+ ] }) }) });
2433
3081
  }
2434
3082
 
2435
3083
  // src/components/document-editor/document-findbar.tsx
2436
3084
  var import_react13 = require("@tiptap/react");
2437
3085
  var import_react14 = require("react");
2438
3086
  init_document_search();
2439
- var import_jsx_runtime10 = require("react/jsx-runtime");
3087
+ var import_jsx_runtime11 = require("react/jsx-runtime");
2440
3088
  function DocumentFindBar({ editor, editable, onClose, onNotice }) {
2441
3089
  const [term, setTerm] = (0, import_react14.useState)(() => {
2442
3090
  const { from, to, empty } = editor.state.selection;
@@ -2464,7 +3112,7 @@ function DocumentFindBar({ editor, editable, onClose, onNotice }) {
2464
3112
  }, [editor]);
2465
3113
  const count = info?.count ?? 0;
2466
3114
  const current = info?.current ?? -1;
2467
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
3115
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2468
3116
  "div",
2469
3117
  {
2470
3118
  className: "june-doc__findbar",
@@ -2477,9 +3125,9 @@ function DocumentFindBar({ editor, editable, onClose, onNotice }) {
2477
3125
  }
2478
3126
  },
2479
3127
  children: [
2480
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "june-doc__find-field", children: [
2481
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Icon, { name: "search", size: 14 }),
2482
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
3128
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "june-doc__find-field", children: [
3129
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Icon, { name: "search", size: 14 }),
3130
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2483
3131
  "input",
2484
3132
  {
2485
3133
  ref: input,
@@ -2496,11 +3144,11 @@ function DocumentFindBar({ editor, editable, onClose, onNotice }) {
2496
3144
  }
2497
3145
  }
2498
3146
  ),
2499
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "june-doc__find-count", "aria-live": "polite", children: term ? count ? `${current + 1} of ${count}` : "No results" : "" })
3147
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "june-doc__find-count", "aria-live": "polite", children: term ? count ? `${current + 1} of ${count}` : "No results" : "" })
2500
3148
  ] }),
2501
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: "june-doc__btn june-doc__btn--icon", "aria-label": "Previous match", title: "Previous (Shift+Enter)", disabled: !count, onClick: () => gotoMatch(editor, -1), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Icon, { name: "chevronUp" }) }),
2502
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: "june-doc__btn june-doc__btn--icon", "aria-label": "Next match", title: "Next (Enter)", disabled: !count, onClick: () => gotoMatch(editor, 1), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Icon, { name: "chevronDown" }) }),
2503
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
3149
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", className: "june-doc__btn june-doc__btn--icon", "aria-label": "Previous match", title: "Previous (Shift+Enter)", disabled: !count, onClick: () => gotoMatch(editor, -1), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Icon, { name: "chevronUp" }) }),
3150
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", className: "june-doc__btn june-doc__btn--icon", "aria-label": "Next match", title: "Next (Enter)", disabled: !count, onClick: () => gotoMatch(editor, 1), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Icon, { name: "chevronDown" }) }),
3151
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2504
3152
  "button",
2505
3153
  {
2506
3154
  type: "button",
@@ -2513,9 +3161,9 @@ function DocumentFindBar({ editor, editable, onClose, onNotice }) {
2513
3161
  children: "Aa"
2514
3162
  }
2515
3163
  ),
2516
- editable ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
2517
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "june-doc__find-sep", "aria-hidden": "true" }),
2518
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
3164
+ editable ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
3165
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "june-doc__find-sep", "aria-hidden": "true" }),
3166
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2519
3167
  "input",
2520
3168
  {
2521
3169
  className: "june-doc__input june-doc__replace-input",
@@ -2531,8 +3179,8 @@ function DocumentFindBar({ editor, editable, onClose, onNotice }) {
2531
3179
  }
2532
3180
  }
2533
3181
  ),
2534
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: "june-doc__btn", disabled: !count, onClick: () => replaceCurrent(editor, replacement), children: "Replace" }),
2535
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
3182
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", className: "june-doc__btn", disabled: !count, onClick: () => replaceCurrent(editor, replacement), children: "Replace" }),
3183
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2536
3184
  "button",
2537
3185
  {
2538
3186
  type: "button",
@@ -2546,16 +3194,16 @@ function DocumentFindBar({ editor, editable, onClose, onNotice }) {
2546
3194
  }
2547
3195
  )
2548
3196
  ] }) : null,
2549
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: "june-doc__btn june-doc__btn--icon june-doc__btn--ghost june-doc__find-close", "aria-label": "Close find", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Icon, { name: "close" }) })
3197
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", className: "june-doc__btn june-doc__btn--icon june-doc__btn--ghost june-doc__find-close", "aria-label": "Close find", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Icon, { name: "close" }) })
2550
3198
  ]
2551
3199
  }
2552
3200
  );
2553
3201
  }
2554
3202
 
2555
3203
  // src/components/document-editor/document-title.tsx
2556
- var import_jsx_runtime11 = require("react/jsx-runtime");
3204
+ var import_jsx_runtime12 = require("react/jsx-runtime");
2557
3205
  function DocumentTitle({ value, disabled, onChange }) {
2558
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
3206
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2559
3207
  "input",
2560
3208
  {
2561
3209
  className: "june-doc__title",
@@ -2569,7 +3217,7 @@ function DocumentTitle({ value, disabled, onChange }) {
2569
3217
  }
2570
3218
 
2571
3219
  // src/components/document-editor/document-header.tsx
2572
- var import_jsx_runtime12 = require("react/jsx-runtime");
3220
+ var import_jsx_runtime13 = require("react/jsx-runtime");
2573
3221
  var FORMATS = {
2574
3222
  docx: { label: "Word document", hint: ".docx", icon: "file" },
2575
3223
  pdf: { label: "PDF", hint: "Print / Save as PDF", icon: "file" },
@@ -2578,36 +3226,37 @@ var FORMATS = {
2578
3226
  txt: { label: "Plain text", hint: ".txt", icon: "file" }
2579
3227
  };
2580
3228
  function DocumentHeader(props) {
2581
- const { title, editable, isDraft, fullscreen, onToggleFullscreen, onTitle, exportFormats, canSave, saveState, onExport, onCopy, onSave } = props;
2582
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "june-doc__header", children: [
2583
- fullscreen ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", className: "june-doc__btn june-doc__btn--icon june-doc__btn--ghost", "aria-label": "Close full screen", title: "Close (Esc)", onClick: onToggleFullscreen, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Icon, { name: "close", size: 18 }) }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "june-doc__doc-icon", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Icon, { name: "file", size: 16 }) }),
2584
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(DocumentTitle, { value: title, disabled: !editable, onChange: onTitle }),
2585
- isDraft ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "june-doc__badge", children: [
2586
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Icon, { name: "sparkles", size: 12 }),
3229
+ const { title, editable, isDraft, fullscreen, onToggleFullscreen, onTitle, exportFormats, canSave, showSave = canSave, saveState, onExport, onCopy, onSave } = props;
3230
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "june-doc__header", children: [
3231
+ fullscreen ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", className: "june-doc__btn june-doc__btn--icon june-doc__btn--ghost", "aria-label": "Close full screen", title: "Close (Esc)", onClick: onToggleFullscreen, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { name: "close", size: 18 }) }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "june-doc__doc-icon", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { name: "file", size: 16 }) }),
3232
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DocumentTitle, { value: title, disabled: !editable, onChange: onTitle }),
3233
+ isDraft ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "june-doc__badge", children: [
3234
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { name: "sparkles", size: 12 }),
2587
3235
  "AI draft"
2588
3236
  ] }) : null,
2589
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "june-doc__header-actions", children: [
2590
- canSave ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
3237
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "june-doc__header-actions", children: [
3238
+ showSave ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2591
3239
  "button",
2592
3240
  {
2593
3241
  type: "button",
2594
- className: "june-doc__btn june-doc__btn--outline",
3242
+ className: "june-doc__btn june-doc__btn--outline june-doc__save",
3243
+ "data-state": saveState,
2595
3244
  "aria-label": "Save",
2596
3245
  title: "Save (Ctrl+S)",
2597
3246
  disabled: saveState === "saving" || saveState === "saved" || saveState === "idle",
2598
3247
  onClick: onSave,
2599
3248
  children: [
2600
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Icon, { name: saveState === "saved" ? "check" : "save" }),
2601
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: saveState === "saving" ? "Saving\u2026" : saveState === "saved" ? "Saved" : "Save" })
3249
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { name: saveState === "saved" ? "check" : "save" }),
3250
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: saveState === "saving" ? "Saving\u2026" : saveState === "saved" ? "Saved" : "Save" })
2602
3251
  ]
2603
3252
  }
2604
3253
  ) : null,
2605
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
3254
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2606
3255
  Dropdown,
2607
3256
  {
2608
3257
  align: "end",
2609
3258
  className: "june-doc__menu",
2610
- trigger: ({ open, toggle }) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
3259
+ trigger: ({ open, toggle }) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2611
3260
  "button",
2612
3261
  {
2613
3262
  type: "button",
@@ -2617,15 +3266,15 @@ function DocumentHeader(props) {
2617
3266
  "aria-expanded": open,
2618
3267
  onClick: toggle,
2619
3268
  children: [
2620
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: "Download" }),
2621
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Icon, { name: "chevronDown", size: 14 })
3269
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "Download" }),
3270
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { name: "chevronDown", size: 14 })
2622
3271
  ]
2623
3272
  }
2624
3273
  ),
2625
- children: (close) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { role: "menu", "aria-label": "Download options", children: [
3274
+ children: (close) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { role: "menu", "aria-label": "Download options", children: [
2626
3275
  exportFormats.map((f) => {
2627
3276
  const meta = FORMATS[f] ?? { label: f.toUpperCase(), hint: "", icon: "file" };
2628
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
3277
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2629
3278
  "button",
2630
3279
  {
2631
3280
  type: "button",
@@ -2636,16 +3285,16 @@ function DocumentHeader(props) {
2636
3285
  onExport(f);
2637
3286
  },
2638
3287
  children: [
2639
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Icon, { name: meta.icon }),
2640
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "june-doc__menu-label", children: meta.label }),
2641
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "june-doc__menu-hint", children: meta.hint })
3288
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { name: meta.icon }),
3289
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "june-doc__menu-label", children: meta.label }),
3290
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "june-doc__menu-hint", children: meta.hint })
2642
3291
  ]
2643
3292
  },
2644
3293
  f
2645
3294
  );
2646
3295
  }),
2647
- exportFormats.length ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "june-doc__menu-sep", role: "separator" }) : null,
2648
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
3296
+ exportFormats.length ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "june-doc__menu-sep", role: "separator" }) : null,
3297
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2649
3298
  "button",
2650
3299
  {
2651
3300
  type: "button",
@@ -2657,15 +3306,15 @@ function DocumentHeader(props) {
2657
3306
  onCopy();
2658
3307
  },
2659
3308
  children: [
2660
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Icon, { name: "copy" }),
2661
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "june-doc__menu-label", children: "Copy to clipboard" })
3309
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { name: "copy" }),
3310
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "june-doc__menu-label", children: "Copy to clipboard" })
2662
3311
  ]
2663
3312
  }
2664
3313
  )
2665
3314
  ] })
2666
3315
  }
2667
3316
  ),
2668
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
3317
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2669
3318
  "button",
2670
3319
  {
2671
3320
  type: "button",
@@ -2674,7 +3323,7 @@ function DocumentHeader(props) {
2674
3323
  title: fullscreen ? "Exit full screen" : "Open full screen",
2675
3324
  "aria-pressed": fullscreen,
2676
3325
  onClick: onToggleFullscreen,
2677
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Icon, { name: "maximize" })
3326
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { name: "maximize" })
2678
3327
  }
2679
3328
  )
2680
3329
  ] })
@@ -3105,223 +3754,6 @@ ${docToText2(doc.json)}`;
3105
3754
  // src/components/document-editor/document-editor.tsx
3106
3755
  init_document_extensions();
3107
3756
 
3108
- // src/components/document-editor/document-merge.ts
3109
- init_document_utils();
3110
- var MAX_CELLS = 4e6;
3111
- function matchIndices(a, b) {
3112
- const n = a.length;
3113
- const m = b.length;
3114
- if (n * m > MAX_CELLS) return null;
3115
- const dp = Array.from({ length: n + 1 }, () => new Uint32Array(m + 1));
3116
- for (let i2 = n - 1; i2 >= 0; i2--) {
3117
- for (let j2 = m - 1; j2 >= 0; j2--) {
3118
- dp[i2][j2] = a[i2] === b[j2] ? dp[i2 + 1][j2 + 1] + 1 : Math.max(dp[i2 + 1][j2], dp[i2][j2 + 1]);
3119
- }
3120
- }
3121
- const matches = /* @__PURE__ */ new Map();
3122
- let i = 0;
3123
- let j = 0;
3124
- while (i < n && j < m) {
3125
- if (a[i] === b[j]) {
3126
- matches.set(i, j);
3127
- i++;
3128
- j++;
3129
- } else if (dp[i + 1][j] >= dp[i][j + 1]) i++;
3130
- else j++;
3131
- }
3132
- return matches;
3133
- }
3134
- var same = (x, y) => x.length === y.length && x.every((v, i) => v === y[i]);
3135
- function mergeBlocks(base, local, incoming) {
3136
- if (same(local, base)) return { blocks: incoming, conflicts: 0 };
3137
- if (same(incoming, base) || same(local, incoming)) return { blocks: local, conflicts: 0 };
3138
- const ml = matchIndices(base, local);
3139
- const mn = matchIndices(base, incoming);
3140
- if (!ml || !mn) return { blocks: null, conflicts: 1 };
3141
- const anchors = [...ml.keys()].filter((i) => mn.has(i)).sort((x, y) => x - y);
3142
- const out = [];
3143
- let conflicts = 0;
3144
- let pb = -1;
3145
- let pl = -1;
3146
- let pn = -1;
3147
- const region = (bEnd, lEnd, nEnd) => {
3148
- const B = base.slice(pb + 1, bEnd);
3149
- const L = local.slice(pl + 1, lEnd);
3150
- const N = incoming.slice(pn + 1, nEnd);
3151
- if (B.length === L.length && L.length === N.length) {
3152
- for (let k = 0; k < B.length; k++) {
3153
- if (L[k] === B[k]) out.push(N[k]);
3154
- else if (N[k] === B[k] || N[k] === L[k]) out.push(L[k]);
3155
- else {
3156
- conflicts++;
3157
- out.push(L[k]);
3158
- }
3159
- }
3160
- return;
3161
- }
3162
- if (same(L, B)) out.push(...N);
3163
- else if (same(N, B) || same(L, N)) out.push(...L);
3164
- else {
3165
- conflicts++;
3166
- out.push(...L);
3167
- }
3168
- };
3169
- for (const a of anchors) {
3170
- const la = ml.get(a);
3171
- const na = mn.get(a);
3172
- region(a, la, na);
3173
- out.push(local[la]);
3174
- pb = a;
3175
- pl = la;
3176
- pn = na;
3177
- }
3178
- region(base.length, local.length, incoming.length);
3179
- return { blocks: out, conflicts };
3180
- }
3181
- function mergeDocuments(base, local, incoming) {
3182
- const toBlocks = (d) => (d.content ?? []).map((node) => JSON.stringify(node));
3183
- const { blocks: blocks2, conflicts } = mergeBlocks(toBlocks(base), toBlocks(local), toBlocks(incoming));
3184
- if (!blocks2) return { doc: local, conflicts: Math.max(1, conflicts) };
3185
- if (blocks2.length === 0) return { doc: emptyDoc(), conflicts };
3186
- return { doc: { type: "doc", content: blocks2.map((b) => JSON.parse(b)) }, conflicts };
3187
- }
3188
-
3189
- // src/components/document-editor/document-store.ts
3190
- init_document_utils();
3191
- var incomingKey = (doc) => JSON.stringify([doc.title, docKey(doc.json)]);
3192
- function createDocumentStore() {
3193
- const records = /* @__PURE__ */ new Map();
3194
- const listeners = /* @__PURE__ */ new Set();
3195
- const emit = () => listeners.forEach((listener) => listener());
3196
- const put = (record) => {
3197
- records.set(record.id, record);
3198
- emit();
3199
- };
3200
- const fresh2 = (doc) => ({
3201
- id: doc.id,
3202
- title: doc.title,
3203
- documentType: doc.documentType,
3204
- status: doc.status,
3205
- json: doc.json,
3206
- baseJson: doc.json,
3207
- baseTitle: doc.title,
3208
- lastIncomingKey: incomingKey(doc),
3209
- revision: 0,
3210
- origin: "external",
3211
- pending: null,
3212
- updatedAt: Date.now()
3213
- });
3214
- return {
3215
- get: (id) => records.get(id),
3216
- list: () => [...records.values()],
3217
- subscribe: (listener) => {
3218
- listeners.add(listener);
3219
- return () => {
3220
- listeners.delete(listener);
3221
- };
3222
- },
3223
- receive(incoming) {
3224
- const current = records.get(incoming.id);
3225
- if (!current) {
3226
- put(fresh2(incoming));
3227
- return "created";
3228
- }
3229
- const key = incomingKey(incoming);
3230
- if (current.lastIncomingKey === key) return "unchanged";
3231
- const userEditedBody = docKey(current.json) !== docKey(current.baseJson);
3232
- const userEditedTitle = current.title !== current.baseTitle;
3233
- const title = userEditedTitle ? current.title : incoming.title;
3234
- const meta = {
3235
- documentType: incoming.documentType ?? current.documentType,
3236
- status: incoming.status ?? current.status
3237
- };
3238
- if (!userEditedBody) {
3239
- put({
3240
- ...current,
3241
- ...meta,
3242
- title,
3243
- baseTitle: incoming.title,
3244
- json: incoming.json,
3245
- baseJson: incoming.json,
3246
- lastIncomingKey: key,
3247
- revision: current.revision + 1,
3248
- origin: "external",
3249
- pending: null,
3250
- updatedAt: Date.now()
3251
- });
3252
- return "applied";
3253
- }
3254
- const { doc, conflicts } = mergeDocuments(current.baseJson, current.json, incoming.json);
3255
- if (conflicts === 0) {
3256
- put({
3257
- ...current,
3258
- ...meta,
3259
- title,
3260
- baseTitle: incoming.title,
3261
- json: doc,
3262
- baseJson: incoming.json,
3263
- lastIncomingKey: key,
3264
- revision: current.revision + 1,
3265
- origin: "external",
3266
- pending: null,
3267
- updatedAt: Date.now()
3268
- });
3269
- return "merged";
3270
- }
3271
- put({
3272
- ...current,
3273
- ...meta,
3274
- lastIncomingKey: key,
3275
- pending: { json: incoming.json, title: incoming.title, merged: doc, conflicts }
3276
- });
3277
- return "conflict";
3278
- },
3279
- hydrate(doc) {
3280
- put(fresh2(doc));
3281
- },
3282
- edit(id, json, origin) {
3283
- const current = records.get(id);
3284
- if (!current || docKey(current.json) === docKey(json)) return;
3285
- put({ ...current, json, origin, revision: current.revision + 1, updatedAt: Date.now() });
3286
- },
3287
- setTitle(id, title) {
3288
- const current = records.get(id);
3289
- if (!current || current.title === title) return;
3290
- put({ ...current, title, updatedAt: Date.now() });
3291
- },
3292
- resolve(id, choice) {
3293
- const current = records.get(id);
3294
- const pending = current?.pending;
3295
- if (!current || !pending) return;
3296
- if (choice === "keep") {
3297
- put({ ...current, baseJson: pending.json, baseTitle: pending.title, pending: null });
3298
- return;
3299
- }
3300
- const json = choice === "merge" ? pending.merged : pending.json;
3301
- const title = choice === "merge" ? current.title : pending.title;
3302
- put({
3303
- ...current,
3304
- title,
3305
- json,
3306
- baseJson: pending.json,
3307
- baseTitle: pending.title,
3308
- revision: current.revision + 1,
3309
- origin: "external",
3310
- pending: null,
3311
- updatedAt: Date.now()
3312
- });
3313
- },
3314
- remove(id) {
3315
- if (records.delete(id)) emit();
3316
- }
3317
- };
3318
- }
3319
- var defaultStore = null;
3320
- function getDefaultDocumentStore() {
3321
- if (!defaultStore) defaultStore = createDocumentStore();
3322
- return defaultStore;
3323
- }
3324
-
3325
3757
  // src/components/document-editor/document-types.ts
3326
3758
  var ALL_EXPORT_FORMATS = [
3327
3759
  "html",
@@ -3333,7 +3765,7 @@ var ALL_EXPORT_FORMATS = [
3333
3765
 
3334
3766
  // src/components/document-editor/document-editor.tsx
3335
3767
  init_document_utils();
3336
- var import_jsx_runtime13 = require("react/jsx-runtime");
3768
+ var import_jsx_runtime14 = require("react/jsx-runtime");
3337
3769
  var snapshotOf = (r) => ({
3338
3770
  documentId: r.id,
3339
3771
  title: r.title,
@@ -3431,8 +3863,13 @@ function DocumentEditorImpl(props) {
3431
3863
  saveRef.current = async () => {
3432
3864
  const record = store.get(documentId);
3433
3865
  const onSave = optionsRef.current.onSave;
3434
- if (!record || !onSave) return;
3866
+ if (!record) return;
3435
3867
  const key = JSON.stringify([record.title, docKey(record.json)]);
3868
+ if (!onSave) {
3869
+ lastSavedKey.current = key;
3870
+ setSaveState("saved");
3871
+ return;
3872
+ }
3436
3873
  if (key === lastSavedKey.current) {
3437
3874
  setSaveState("saved");
3438
3875
  return;
@@ -3453,11 +3890,22 @@ function DocumentEditorImpl(props) {
3453
3890
  optionsRef.current.onError?.(toJuneError(error, "DOCUMENT_ERROR", "Saving the document failed"));
3454
3891
  }
3455
3892
  };
3456
- const markDirty = (0, import_react16.useCallback)(() => {
3457
- if (!optionsRef.current.onSave) return;
3458
- setSaveState("dirty");
3459
- autosave?.();
3460
- }, [autosave]);
3893
+ const markDirty = (0, import_react16.useCallback)(
3894
+ (userEdit = true) => {
3895
+ if (!optionsRef.current.onSave) {
3896
+ if (userEdit) setSaveState("dirty");
3897
+ return;
3898
+ }
3899
+ setSaveState("dirty");
3900
+ autosave?.();
3901
+ },
3902
+ [autosave]
3903
+ );
3904
+ (0, import_react16.useEffect)(() => {
3905
+ if (saveState !== "saved" || options.onSave) return;
3906
+ const t = setTimeout(() => setSaveState((s) => s === "saved" ? "idle" : s), 2500);
3907
+ return () => clearTimeout(t);
3908
+ }, [saveState, options.onSave]);
3461
3909
  const [initialJson] = (0, import_react16.useState)(() => store.get(documentId)?.json ?? parsed.json ?? emptyDoc());
3462
3910
  const extensions = (0, import_react16.useMemo)(() => createDocumentExtensions(), []);
3463
3911
  const onUpdateRef = (0, import_react16.useRef)(() => {
@@ -3483,10 +3931,12 @@ function DocumentEditorImpl(props) {
3483
3931
  onUpdate: ({ editor: ed }) => onUpdateRef.current(ed.getJSON())
3484
3932
  });
3485
3933
  (0, import_react16.useEffect)(() => {
3486
- editor?.setEditable(editable);
3934
+ if (!editor || editor.isEditable === editable) return;
3935
+ editor.setEditable(editable);
3487
3936
  }, [editor, editable]);
3488
3937
  (0, import_react16.useEffect)(() => {
3489
3938
  if (!parsed.json) return;
3939
+ if (isDocumentEcho(store, documentId, contentKey)) return;
3490
3940
  const outcome = store.receive({
3491
3941
  id: documentId,
3492
3942
  title: titleProp,
@@ -3496,7 +3946,7 @@ function DocumentEditorImpl(props) {
3496
3946
  });
3497
3947
  if (outcome === "applied" || outcome === "merged") {
3498
3948
  emitChange(outcome === "applied" ? "ai" : "merge");
3499
- markDirty();
3949
+ markDirty(false);
3500
3950
  } else if (outcome === "conflict") {
3501
3951
  const record = store.get(documentId);
3502
3952
  optionsRef.current.onConflict?.({
@@ -3567,18 +4017,18 @@ function DocumentEditorImpl(props) {
3567
4017
  };
3568
4018
  const formats = (exportFormats ?? [...ALL_EXPORT_FORMATS]).filter((f) => listDocumentExporters().includes(f));
3569
4019
  if (parsed.error && !store.get(documentId)) {
3570
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "june-doc june-doc--error", "data-theme": resolvedTheme, role: "alert", children: [
3571
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "june-doc__draft-text", children: "This document could not be displayed." }),
3572
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("details", { children: [
3573
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("summary", { children: "Show raw content" }),
3574
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("pre", { className: "june-doc__raw", children: contentKey })
4020
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "june-doc june-doc--error", "data-theme": resolvedTheme, role: "alert", children: [
4021
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "june-doc__draft-text", children: "This document could not be displayed." }),
4022
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("details", { children: [
4023
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("summary", { children: "Show raw content" }),
4024
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("pre", { className: "june-doc__raw", children: contentKey })
3575
4025
  ] })
3576
4026
  ] });
3577
4027
  }
3578
- if (!editor) return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DocumentDraft, { title, state: "loading" });
4028
+ if (!editor) return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(DocumentDraft, { title, state: "loading" });
3579
4029
  const isDraft = recordStatus === "draft";
3580
4030
  const classes = ["june-doc", fullscreen ? "june-doc--fullscreen" : "", className ?? ""].filter(Boolean).join(" ");
3581
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
4031
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
3582
4032
  "div",
3583
4033
  {
3584
4034
  className: classes,
@@ -3600,7 +4050,7 @@ function DocumentEditorImpl(props) {
3600
4050
  }
3601
4051
  },
3602
4052
  children: [
3603
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4053
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3604
4054
  DocumentHeader,
3605
4055
  {
3606
4056
  title,
@@ -3611,27 +4061,28 @@ function DocumentEditorImpl(props) {
3611
4061
  onTitle: handleTitle,
3612
4062
  exportFormats: formats,
3613
4063
  canSave: !!options.onSave,
4064
+ showSave: !!options.onSave || editable && saveState !== "idle",
3614
4065
  saveState,
3615
4066
  onExport: (f) => void handleExport(f),
3616
4067
  onCopy: () => void handleCopy(),
3617
4068
  onSave: () => void saveRef.current()
3618
4069
  }
3619
4070
  ),
3620
- pending ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "june-doc__banner", role: "status", children: [
3621
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { children: [
4071
+ pending ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "june-doc__banner", role: "status", children: [
4072
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { children: [
3622
4073
  "The assistant suggested changes that overlap your edits (",
3623
4074
  pending.conflicts,
3624
4075
  " ",
3625
4076
  pending.conflicts === 1 ? "section" : "sections",
3626
4077
  ")."
3627
4078
  ] }),
3628
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "june-doc__banner-actions", children: [
3629
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", className: "june-doc__btn", onClick: () => resolve("merge"), children: "Merge, keep my edits" }),
3630
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", className: "june-doc__btn", onClick: () => resolve("replace"), children: "Use AI version" }),
3631
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", className: "june-doc__btn", onClick: () => resolve("keep"), children: "Keep mine" })
4079
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "june-doc__banner-actions", children: [
4080
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: "june-doc__btn", onClick: () => resolve("merge"), children: "Merge, keep my edits" }),
4081
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: "june-doc__btn", onClick: () => resolve("replace"), children: "Use AI version" }),
4082
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: "june-doc__btn", onClick: () => resolve("keep"), children: "Keep mine" })
3632
4083
  ] })
3633
4084
  ] }) : null,
3634
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4085
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3635
4086
  DocumentToolbar,
3636
4087
  {
3637
4088
  editor,
@@ -3647,33 +4098,33 @@ function DocumentEditorImpl(props) {
3647
4098
  onNotice: flash
3648
4099
  }
3649
4100
  ),
3650
- findOpen ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DocumentFindBar, { editor, editable, onClose: () => setFindOpen(false), onNotice: flash }) : null,
3651
- editable ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DocumentBubbleMenu, { editor }) : null,
3652
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DocumentContent, { editor, layout, zoom, showMarks, onMetrics: setMetrics }),
3653
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "june-doc__footer", children: [
3654
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "june-doc__stats", children: [
3655
- layout === "page" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
3656
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { children: [
4101
+ findOpen ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(DocumentFindBar, { editor, editable, onClose: () => setFindOpen(false), onNotice: flash }) : null,
4102
+ editable ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(DocumentBubbleMenu, { editor }) : null,
4103
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(DocumentContent, { editor, layout, zoom, showMarks, onMetrics: setMetrics }),
4104
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "june-doc__footer", children: [
4105
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "june-doc__stats", children: [
4106
+ layout === "page" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
4107
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { children: [
3657
4108
  "Page ",
3658
4109
  metrics.page,
3659
4110
  " of ",
3660
4111
  metrics.pages
3661
4112
  ] }),
3662
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "june-doc__stats-sep", "aria-hidden": "true" })
4113
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "june-doc__stats-sep", "aria-hidden": "true" })
3663
4114
  ] }) : null,
3664
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { children: [
4115
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { children: [
3665
4116
  words,
3666
4117
  " words"
3667
4118
  ] })
3668
4119
  ] }),
3669
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "june-doc__status", "aria-live": "polite", "data-state": notice ? "notice" : saveState, children: notice ?? SAVE_LABEL[saveState] }),
3670
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "june-doc__zoom", role: "group", "aria-label": "Zoom", children: [
3671
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", className: "june-doc__btn june-doc__btn--icon june-doc__btn--ghost", "aria-label": "Zoom out", disabled: zoom <= ZOOM_STEPS[0], onClick: () => setZoom(stepZoom(zoom, -1)), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { name: "minus", size: 14 }) }),
3672
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("button", { type: "button", className: "june-doc__zoom-value", "aria-label": "Reset zoom", title: "Reset zoom", onClick: () => setZoom(1), children: [
4120
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "june-doc__status", "aria-live": "polite", "data-state": notice ? "notice" : saveState, children: notice ?? SAVE_LABEL[saveState] }),
4121
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "june-doc__zoom", role: "group", "aria-label": "Zoom", children: [
4122
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: "june-doc__btn june-doc__btn--icon june-doc__btn--ghost", "aria-label": "Zoom out", disabled: zoom <= ZOOM_STEPS[0], onClick: () => setZoom(stepZoom(zoom, -1)), children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Icon, { name: "minus", size: 14 }) }),
4123
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("button", { type: "button", className: "june-doc__zoom-value", "aria-label": "Reset zoom", title: "Reset zoom", onClick: () => setZoom(1), children: [
3673
4124
  Math.round(zoom * 100),
3674
4125
  "%"
3675
4126
  ] }),
3676
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", className: "june-doc__btn june-doc__btn--icon june-doc__btn--ghost", "aria-label": "Zoom in", disabled: zoom >= ZOOM_STEPS[ZOOM_STEPS.length - 1], onClick: () => setZoom(stepZoom(zoom, 1)), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { name: "plus", size: 14 }) })
4127
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: "june-doc__btn june-doc__btn--icon june-doc__btn--ghost", "aria-label": "Zoom in", disabled: zoom >= ZOOM_STEPS[ZOOM_STEPS.length - 1], onClick: () => setZoom(stepZoom(zoom, 1)), children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Icon, { name: "plus", size: 14 }) })
3677
4128
  ] })
3678
4129
  ] })
3679
4130
  ]
@@ -3682,7 +4133,7 @@ function DocumentEditorImpl(props) {
3682
4133
  }
3683
4134
 
3684
4135
  // src/components/document-editor/document-component.tsx
3685
- var import_jsx_runtime14 = require("react/jsx-runtime");
4136
+ var import_jsx_runtime15 = require("react/jsx-runtime");
3686
4137
  var DOCUMENT_COMPONENT_DESCRIPTION = 'Custom component. An editable document. DocumentEditor(documentId, title, content, documentType?, status?, editable?, exportFormats?). Place it in the root container (Card or Stack). "content" is the full document body as one Markdown string. Reuse documentId when revising the same document. Use it only when the user asks to create or revise a document.';
3687
4138
  var documentProps = import_v4.z.object({
3688
4139
  documentId: import_v4.z.string().describe("Stable id. Reuse it when revising the same document."),
@@ -3696,12 +4147,12 @@ var documentProps = import_v4.z.object({
3696
4147
  function DocumentEditor(props) {
3697
4148
  const { isStreaming } = useJuneRuntime();
3698
4149
  if (props.generating || isStreaming) {
3699
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(DocumentDraft, { title: props.title, state: "drafting" });
4150
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(DocumentDraft, { title: props.title, state: "drafting" });
3700
4151
  }
3701
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(DocumentEditorImpl, { ...props });
4152
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(DocumentEditorImpl, { ...props });
3702
4153
  }
3703
4154
  function OpenUIDocument({ props }) {
3704
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
4155
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3705
4156
  DocumentEditor,
3706
4157
  {
3707
4158
  documentId: props.documentId,
@@ -3789,9 +4240,9 @@ var import_react_ui = require("@openuidev/react-ui");
3789
4240
  var juneLibrary = withDocumentEditor(import_react_ui.openuiLibrary);
3790
4241
 
3791
4242
  // src/core/JuneUI.tsx
3792
- var import_jsx_runtime15 = require("react/jsx-runtime");
4243
+ var import_jsx_runtime16 = require("react/jsx-runtime");
3793
4244
  function JuneUI({ library = juneLibrary, ...props }) {
3794
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(JuneRenderer, { library, ...props });
4245
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(JuneRenderer, { library, ...props });
3795
4246
  }
3796
4247
  // Annotate the CommonJS export names for ESM import in node:
3797
4248
  0 && (module.exports = {
@@ -3821,17 +4272,21 @@ function JuneUI({ library = juneLibrary, ...props }) {
3821
4272
  getDefaultDocumentStore,
3822
4273
  getDocumentEditorInstructions,
3823
4274
  getDocumentEditorRules,
4275
+ isDocumentEcho,
3824
4276
  isJuneError,
3825
4277
  jsonFieldExtractor,
3826
4278
  juneLibrary,
3827
4279
  lightTheme,
3828
4280
  listDocumentExporters,
3829
4281
  mergeDocuments,
4282
+ readDocumentFromProgram,
3830
4283
  registerDocumentExporter,
4284
+ rememberDocumentEcho,
3831
4285
  runAction,
3832
4286
  serializeDocumentsForAgent,
3833
4287
  sseToText,
3834
4288
  toJuneError,
4289
+ updateDocumentInProgram,
3835
4290
  useDocumentOptions,
3836
4291
  useJuneRuntime,
3837
4292
  useJuneStream,