@bendyline/squisq-editor-react 2.13.14 → 2.13.15

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.
@@ -19,7 +19,7 @@ import {
19
19
  useDictationState,
20
20
  useEditorContext,
21
21
  useEditorContextOptional
22
- } from "./chunk-D2QFSFG2.js";
22
+ } from "./chunk-UQUYPT5P.js";
23
23
  import {
24
24
  monacoLanguageRequestKey,
25
25
  monacoLanguagesForDocument,
@@ -9741,10 +9741,24 @@ async function storeCopy(provider, path, file, clipboardImage) {
9741
9741
  mimeType: clipboardImage.type || "image/png"
9742
9742
  } : null);
9743
9743
  if (!copied) return null;
9744
- const existing = await readStoredFile(provider, path);
9745
- if (existing && await sameBytes(existing.data, copied.data)) return path;
9744
+ const stored = await storedCopyOf(provider, path, copied.data);
9745
+ if (stored) return stored;
9746
9746
  return provider.addMedia(await unusedName(provider, copied.name), copied.data, copied.mimeType);
9747
9747
  }
9748
+ async function storedCopyOf(provider, path, data) {
9749
+ let entries;
9750
+ try {
9751
+ entries = await provider.listMedia();
9752
+ } catch {
9753
+ return null;
9754
+ }
9755
+ const candidates = entries.filter((entry) => entry.size === data.size).sort((a, b) => Number(b.name === path) - Number(a.name === path));
9756
+ for (const { name } of candidates) {
9757
+ const existing = await readStoredFile(provider, name);
9758
+ if (existing && await sameBytes(existing.data, data)) return name;
9759
+ }
9760
+ return null;
9761
+ }
9748
9762
  async function sameBytes(a, b) {
9749
9763
  if (a.size !== b.size) return false;
9750
9764
  const [left, right] = await Promise.all([a.arrayBuffer(), b.arrayBuffer()]);
@@ -24645,10 +24659,38 @@ function renameNodeOp(diagram, nodeId, label) {
24645
24659
  if (!node2) return diagram;
24646
24660
  const clean = sanitizeAsciiLabel(label);
24647
24661
  if (clean.length === 0 || clean === node2.label) return diagram;
24648
- return {
24662
+ const renamed = {
24649
24663
  ...diagram,
24650
24664
  nodes: diagram.nodes.map((n) => n.id === nodeId ? { ...n, label: clean } : n)
24651
24665
  };
24666
+ const isContainer = diagram.nodes.some((n) => n.containerId === nodeId);
24667
+ const oldW = Math.max(node2.wCols, labelBoxWidth(node2.label, isContainer));
24668
+ const newW = Math.max(node2.wCols, labelBoxWidth(clean, isContainer));
24669
+ return makeRoomToTheRight(renamed, node2, oldW, newW);
24670
+ }
24671
+ var SIBLING_GAP = 1;
24672
+ function labelBoxWidth(label, isContainer) {
24673
+ const lines2 = label.split("\n");
24674
+ const widest = (ls) => ls.reduce((w, l2) => Math.max(w, Array.from(l2).length), 0);
24675
+ if (!isContainer) return widest(lines2) + 4;
24676
+ return Math.max(widest(lines2.slice(0, 1)) + 6, widest(lines2.slice(1)) + 4);
24677
+ }
24678
+ function makeRoomToTheRight(diagram, node2, oldW, newW) {
24679
+ if (newW <= oldW) return diagram;
24680
+ const drawnRight = node2.col + node2.wCols - 1;
24681
+ const newRight = node2.col + newW - 1;
24682
+ const r0 = node2.row - SIBLING_GAP;
24683
+ const r1 = node2.row + node2.hRows - 1 + SIBLING_GAP;
24684
+ let shift = 0;
24685
+ for (const n of diagram.nodes) {
24686
+ if (n.col <= drawnRight || n.row > r1 || n.row + n.hRows - 1 < r0) continue;
24687
+ shift = Math.max(shift, newRight + SIBLING_GAP + 1 - n.col);
24688
+ }
24689
+ if (shift === 0) return diagram;
24690
+ return {
24691
+ ...diagram,
24692
+ nodes: diagram.nodes.map((n) => n.col > drawnRight ? { ...n, col: n.col + shift } : n)
24693
+ };
24652
24694
  }
24653
24695
  function addNodeOp(diagram, opts) {
24654
24696
  let label = opts.label;
@@ -24695,7 +24737,7 @@ function removeNodeOp(diagram, nodeId) {
24695
24737
  }
24696
24738
 
24697
24739
  // src/asciiDiagram/asciiDiagramData.ts
24698
- import { useEffect as useEffect35, useMemo as useMemo29, useState as useState45 } from "react";
24740
+ import { useEffect as useEffect36, useMemo as useMemo29, useState as useState45 } from "react";
24699
24741
  import {
24700
24742
  asciiCellToCanvas,
24701
24743
  asciiDiagramToTemplateData,
@@ -24716,7 +24758,7 @@ import {
24716
24758
  } from "@bendyline/squisq/doc";
24717
24759
 
24718
24760
  // src/asciiDiagram/AsciiDiagramWidget.tsx
24719
- import { useCallback as useCallback35, useMemo as useMemo28, useRef as useRef39, useState as useState44 } from "react";
24761
+ import { useCallback as useCallback35, useEffect as useEffect35, useMemo as useMemo28, useRef as useRef39, useState as useState44 } from "react";
24720
24762
 
24721
24763
  // src/asciiDiagram/asciiDiagramCommands.ts
24722
24764
  import {
@@ -24901,7 +24943,7 @@ function applyRepairCommand(editor, blockId) {
24901
24943
  if (!repaired) return false;
24902
24944
  return replaceAsciiFenceText(editor, pos, repaired.art, "diagram");
24903
24945
  }
24904
- function applyOp(editor, blockId, op, diagramOffset) {
24946
+ function applyOp(editor, blockId, op, { diagramOffset, onRejected }) {
24905
24947
  const pos = findAsciiDiagramBlockPos(editor, blockId);
24906
24948
  if (pos === null) return false;
24907
24949
  const node2 = editor.state.doc.nodeAt(pos);
@@ -24913,12 +24955,15 @@ function applyOp(editor, blockId, op, diagramOffset) {
24913
24955
  if (next === diagram && diagram === sourceDiagram) return false;
24914
24956
  const rendered = renderAsciiDiagram(next);
24915
24957
  const verification = parseAsciiDiagram(rendered);
24916
- if (verification.nodes.length !== next.nodes.length) return false;
24958
+ if (verification.nodes.length !== next.nodes.length || verification.edges.length !== next.edges.length) {
24959
+ onRejected?.();
24960
+ return false;
24961
+ }
24917
24962
  return replaceAsciiFenceText(editor, pos, rendered, "diagram");
24918
24963
  }
24919
24964
  function applyAsciiDiagramCommand(editor, blockId, cmd, options = {}) {
24920
24965
  if (!editor.isEditable) return false;
24921
- const apply = (op) => applyOp(editor, blockId, op, options.diagramOffset);
24966
+ const apply = (op) => applyOp(editor, blockId, op, options);
24922
24967
  switch (cmd.kind) {
24923
24968
  case "moveNode": {
24924
24969
  const { col, row } = canvasToAsciiCell(cmd.x, cmd.y);
@@ -24960,6 +25005,8 @@ function applyAsciiDiagramCommand(editor, blockId, cmd, options = {}) {
24960
25005
  import { jsx as jsx54, jsxs as jsxs42 } from "react/jsx-runtime";
24961
25006
  var MIN_DIAGRAM_HEIGHT = 160;
24962
25007
  var DEFAULT_DIAGRAM_HEIGHT = 420;
25008
+ var REJECTED_NOTICE_MS = 6e3;
25009
+ var REJECTED_EDIT_MESSAGE = "That change wasn't applied: the diagram couldn't be redrawn without losing a box or connection. Try giving the boxes more room, or edit the ASCII source.";
24963
25010
  function AsciiDiagramWidget({
24964
25011
  editor,
24965
25012
  blockId,
@@ -24982,12 +25029,20 @@ function AsciiDiagramWidget({
24982
25029
  const offset = canvasOffsetRef.current ?? { col: 0, row: 0 };
24983
25030
  return asciiDiagramToCanvas(offsetAsciiDiagram(view.diagram, offset));
24984
25031
  }, [view, canvasOffsetVersion]);
25032
+ const [rejectedAt, setRejectedAt] = useState44(null);
25033
+ useEffect35(() => {
25034
+ if (rejectedAt === null) return;
25035
+ const timer = setTimeout(() => setRejectedAt(null), REJECTED_NOTICE_MS);
25036
+ return () => clearTimeout(timer);
25037
+ }, [rejectedAt]);
24985
25038
  const dispatch = useCallback35(
24986
25039
  (cmd) => {
24987
25040
  const offset = canvasOffsetRef.current ?? { col: 0, row: 0 };
24988
25041
  const applied = applyAsciiDiagramCommand(editor, blockId, cmd, {
24989
- diagramOffset: offset
25042
+ diagramOffset: offset,
25043
+ onRejected: () => setRejectedAt(Date.now())
24990
25044
  });
25045
+ if (applied) setRejectedAt(null);
24991
25046
  if (applied && (offset.col !== 0 || offset.row !== 0)) {
24992
25047
  canvasOffsetRef.current = { col: 0, row: 0 };
24993
25048
  setCanvasOffsetVersion((version) => version + 1);
@@ -25086,6 +25141,7 @@ function AsciiDiagramWidget({
25086
25141
  ] }),
25087
25142
  /* @__PURE__ */ jsx54("ul", { children: view.warnings.map((w, i) => /* @__PURE__ */ jsx54("li", { children: w }, i)) })
25088
25143
  ] }) : null;
25144
+ const notice = /* @__PURE__ */ jsx54("div", { className: "squisq-ascii-diagram-notice", role: "status", "aria-live": "polite", children: rejectedAt !== null && REJECTED_EDIT_MESSAGE });
25089
25145
  const canvas = /* @__PURE__ */ jsx54(
25090
25146
  DiagramCanvas,
25091
25147
  {
@@ -25109,7 +25165,8 @@ function AsciiDiagramWidget({
25109
25165
  style: effectiveHeight != null ? { height: effectiveHeight } : void 0,
25110
25166
  children: /* @__PURE__ */ jsx54(DiagramMaximizedOverlay, { host: host ?? null, onClose: () => setMaximized(false), children: /* @__PURE__ */ jsxs42("div", { className: "squisq-scene-block-max", children: [
25111
25167
  canvas,
25112
- /* @__PURE__ */ jsx54("div", { className: "squisq-scene-side-toolbar", children: toolbar })
25168
+ /* @__PURE__ */ jsx54("div", { className: "squisq-scene-side-toolbar", children: toolbar }),
25169
+ notice
25113
25170
  ] }) })
25114
25171
  }
25115
25172
  );
@@ -25139,6 +25196,7 @@ function AsciiDiagramWidget({
25139
25196
  ]
25140
25197
  }
25141
25198
  ),
25199
+ notice,
25142
25200
  warnings
25143
25201
  ] });
25144
25202
  }
@@ -25407,7 +25465,7 @@ function asciiDiagramToCanvas(diagram) {
25407
25465
  }
25408
25466
  function useAsciiDiagramData(editor, blockId) {
25409
25467
  const [version, setVersion] = useState45(0);
25410
- useEffect35(() => {
25468
+ useEffect36(() => {
25411
25469
  const onUpdate = () => setVersion((v2) => v2 + 1);
25412
25470
  editor.on("transaction", onUpdate);
25413
25471
  return () => {
@@ -27253,7 +27311,7 @@ function mermaidErrorMessage(error) {
27253
27311
  }
27254
27312
 
27255
27313
  // src/mermaid/mermaidSurfaceTheme.ts
27256
- import { useEffect as useEffect36, useMemo as useMemo30, useState as useState46 } from "react";
27314
+ import { useEffect as useEffect37, useMemo as useMemo30, useState as useState46 } from "react";
27257
27315
  import { relativeLuminance } from "@bendyline/squisq/schemas";
27258
27316
  var EDITOR_SURFACE = {
27259
27317
  light: {
@@ -27290,7 +27348,7 @@ function resolveMermaidSurfaceTheme(host, theme) {
27290
27348
  }
27291
27349
  function useMermaidSurfaceTheme(host, theme) {
27292
27350
  const [surface, setSurface] = useState46(() => readHostSurface(host));
27293
- useEffect36(() => {
27351
+ useEffect37(() => {
27294
27352
  const sync = () => setSurface((current) => {
27295
27353
  const next = readHostSurface(host);
27296
27354
  return current.scheme === next.scheme && current.inheritsThemeColors === next.inheritsThemeColors ? current : next;
@@ -27316,7 +27374,7 @@ function useMermaidSurfaceTheme(host, theme) {
27316
27374
  }
27317
27375
 
27318
27376
  // src/mermaid/MermaidDiagramCanvas.tsx
27319
- import { useCallback as useCallback36, useEffect as useEffect37, useId as useId12, useLayoutEffect as useLayoutEffect10, useRef as useRef40, useState as useState47 } from "react";
27377
+ import { useCallback as useCallback36, useEffect as useEffect38, useId as useId12, useLayoutEffect as useLayoutEffect10, useRef as useRef40, useState as useState47 } from "react";
27320
27378
  import { jsx as jsx55, jsxs as jsxs43 } from "react/jsx-runtime";
27321
27379
  var renderSequence = 0;
27322
27380
  function excludesCanvasPan(target, viewport) {
@@ -27393,7 +27451,7 @@ function MermaidDiagramCanvas({
27393
27451
  const [panning, setPanning] = useState47(false);
27394
27452
  const [selectionAnchor, setSelectionAnchor] = useState47(null);
27395
27453
  const [renameValue, setRenameValue] = useState47("");
27396
- useEffect37(() => {
27454
+ useEffect38(() => {
27397
27455
  if (!panning) return;
27398
27456
  const finish = () => {
27399
27457
  panDragRef.current = null;
@@ -27421,7 +27479,7 @@ function MermaidDiagramCanvas({
27421
27479
  window.removeEventListener("blur", finish);
27422
27480
  };
27423
27481
  }, [panning]);
27424
- useEffect37(() => {
27482
+ useEffect38(() => {
27425
27483
  let current = true;
27426
27484
  const id = `squisq-mermaid-svg-${++renderSequence}`;
27427
27485
  setRendering(true);
@@ -27692,7 +27750,7 @@ function MermaidDiagramCanvas({
27692
27750
  updateSelectionAnchor,
27693
27751
  zoom
27694
27752
  ]);
27695
- useEffect37(() => {
27753
+ useEffect38(() => {
27696
27754
  const scroll = scrollRef.current;
27697
27755
  if (!scroll) return;
27698
27756
  const update = () => updateSelectionAnchor();
@@ -28097,7 +28155,7 @@ function CanvasAction({
28097
28155
  }
28098
28156
 
28099
28157
  // src/mermaid/MermaidShapePalette.tsx
28100
- import { useEffect as useEffect38, useLayoutEffect as useLayoutEffect11, useMemo as useMemo31, useRef as useRef41, useState as useState48 } from "react";
28158
+ import { useEffect as useEffect39, useLayoutEffect as useLayoutEffect11, useMemo as useMemo31, useRef as useRef41, useState as useState48 } from "react";
28101
28159
  import { jsx as jsx56, jsxs as jsxs44 } from "react/jsx-runtime";
28102
28160
  var CATEGORIES = ["Basic", "Process", "Data", "Documents", "Symbols"];
28103
28161
  var PALETTE_WIDTH = 360;
@@ -28108,7 +28166,7 @@ function MermaidShapePalette({ selected, onPick, onClose }) {
28108
28166
  const [query, setQuery] = useState48("");
28109
28167
  const [position, setPosition] = useState48(null);
28110
28168
  const ref = useRef41(null);
28111
- useEffect38(() => {
28169
+ useEffect39(() => {
28112
28170
  const onPointerDown = (event) => {
28113
28171
  const target = event.target;
28114
28172
  if (target?.closest(".squisq-scene-block-toolbar")) return;
@@ -28279,7 +28337,7 @@ function MermaidShapeThumb({ shape }) {
28279
28337
  }
28280
28338
 
28281
28339
  // src/mermaid/mermaidData.ts
28282
- import { useEffect as useEffect40, useMemo as useMemo32, useState as useState50 } from "react";
28340
+ import { useEffect as useEffect41, useMemo as useMemo32, useState as useState50 } from "react";
28283
28341
 
28284
28342
  // src/mermaid/MermaidDiagramExtension.ts
28285
28343
  import { Extension as Extension7 } from "@tiptap/core";
@@ -28290,7 +28348,7 @@ import { createElement as createElement10 } from "react";
28290
28348
  // src/mermaid/MermaidDiagramWidget.tsx
28291
28349
  import {
28292
28350
  useCallback as useCallback37,
28293
- useEffect as useEffect39,
28351
+ useEffect as useEffect40,
28294
28352
  useLayoutEffect as useLayoutEffect12,
28295
28353
  useRef as useRef42,
28296
28354
  useState as useState49,
@@ -28930,7 +28988,7 @@ function MermaidDiagramWidget({
28930
28988
  },
28931
28989
  [effectiveHeight]
28932
28990
  );
28933
- useEffect39(() => {
28991
+ useEffect40(() => {
28934
28992
  if (!editNotice) return;
28935
28993
  const timeout = window.setTimeout(() => setEditNotice(""), 7e3);
28936
28994
  return () => window.clearTimeout(timeout);
@@ -29167,7 +29225,7 @@ function MermaidDiagramWidget({
29167
29225
  ] });
29168
29226
  }
29169
29227
  function useDismissibleMermaidPopover(ref, onClose) {
29170
- useEffect39(() => {
29228
+ useEffect40(() => {
29171
29229
  const onPointerDown = (event) => {
29172
29230
  const target = event.target;
29173
29231
  if (target?.closest(".squisq-scene-block-toolbar")) return;
@@ -29547,7 +29605,7 @@ var MermaidDiagramExtension = Extension7.create({
29547
29605
  // src/mermaid/mermaidData.ts
29548
29606
  function useMermaidDiagramData(editor, blockId) {
29549
29607
  const [version, setVersion] = useState50(0);
29550
- useEffect40(() => {
29608
+ useEffect41(() => {
29551
29609
  const onTransaction = () => setVersion((value) => value + 1);
29552
29610
  editor.on("transaction", onTransaction);
29553
29611
  return () => {
@@ -29572,7 +29630,7 @@ function describeSvgIslandRemovals(diagnostics) {
29572
29630
  }
29573
29631
 
29574
29632
  // src/svgIsland/SvgIslandWidget.tsx
29575
- import { useEffect as useEffect42, useMemo as useMemo33, useState as useState52 } from "react";
29633
+ import { useEffect as useEffect43, useMemo as useMemo33, useState as useState52 } from "react";
29576
29634
  import { parseSvgIsland } from "@bendyline/squisq/markdown";
29577
29635
  import { SvgIslandImage } from "@bendyline/squisq-react";
29578
29636
 
@@ -29628,7 +29686,7 @@ function FenceMonacoEditor({
29628
29686
  }
29629
29687
 
29630
29688
  // src/codeSnippet/fenceEditorHooks.ts
29631
- import { useEffect as useEffect41, useState as useState51 } from "react";
29689
+ import { useEffect as useEffect42, useState as useState51 } from "react";
29632
29690
  function schemeFromHost(host) {
29633
29691
  return host?.closest("[data-theme]")?.dataset.theme === "dark" ? "dark" : "light";
29634
29692
  }
@@ -29636,7 +29694,7 @@ function useHostColorScheme(host) {
29636
29694
  const [scheme, setScheme] = useState51(
29637
29695
  () => host != null && !host.isConnected ? null : schemeFromHost(host)
29638
29696
  );
29639
- useEffect41(() => {
29697
+ useEffect42(() => {
29640
29698
  if (host != null && !host.isConnected) {
29641
29699
  setScheme(null);
29642
29700
  const raf = requestAnimationFrame(() => {
@@ -29655,7 +29713,7 @@ function useHostColorScheme(host) {
29655
29713
  }
29656
29714
  function useEditorEditable(editor) {
29657
29715
  const [editable, setEditable] = useState51(editor.isEditable);
29658
- useEffect41(() => {
29716
+ useEffect42(() => {
29659
29717
  const sync = () => setEditable(editor.isEditable);
29660
29718
  editor.on("update", sync);
29661
29719
  editor.on("transaction", sync);
@@ -29818,7 +29876,7 @@ import { jsx as jsx59, jsxs as jsxs46 } from "react/jsx-runtime";
29818
29876
  var nextModelInstanceId = 0;
29819
29877
  function useSvgIslandView(editor, blockId) {
29820
29878
  const [version, setVersion] = useState52(0);
29821
- useEffect42(() => {
29879
+ useEffect43(() => {
29822
29880
  const onTransaction = () => setVersion((value) => value + 1);
29823
29881
  editor.on("transaction", onTransaction);
29824
29882
  return () => {
@@ -29920,13 +29978,13 @@ import { Decoration as Decoration8, DecorationSet as DecorationSet8 } from "@tip
29920
29978
  import { createElement as createElement12 } from "react";
29921
29979
 
29922
29980
  // src/codeSnippet/CodeSnippetWidget.tsx
29923
- import { useCallback as useCallback38, useEffect as useEffect44, useRef as useRef43, useState as useState54 } from "react";
29981
+ import { useCallback as useCallback38, useEffect as useEffect45, useRef as useRef43, useState as useState54 } from "react";
29924
29982
 
29925
29983
  // src/codeSnippet/codeSnippetData.ts
29926
- import { useEffect as useEffect43, useMemo as useMemo34, useState as useState53 } from "react";
29984
+ import { useEffect as useEffect44, useMemo as useMemo34, useState as useState53 } from "react";
29927
29985
  function useCodeSnippetData(editor, blockId) {
29928
29986
  const [version, setVersion] = useState53(0);
29929
- useEffect43(() => {
29987
+ useEffect44(() => {
29930
29988
  const onTransaction = () => setVersion((value) => value + 1);
29931
29989
  editor.on("transaction", onTransaction);
29932
29990
  return () => {
@@ -29993,7 +30051,7 @@ function CodeSnippetWidget({
29993
30051
  sourceRef.current = data?.source ?? "";
29994
30052
  const languageRef = useRef43("");
29995
30053
  languageRef.current = data?.fenceLanguage ?? "";
29996
- useEffect44(
30054
+ useEffect45(
29997
30055
  () => () => {
29998
30056
  if (copyResetTimer.current !== void 0) clearTimeout(copyResetTimer.current);
29999
30057
  },
@@ -30238,7 +30296,7 @@ import { Decoration as Decoration9, DecorationSet as DecorationSet9 } from "@tip
30238
30296
  import { createElement as createElement13 } from "react";
30239
30297
 
30240
30298
  // src/fenceWidgets/HostFenceWidget.tsx
30241
- import { Component as Component2, useEffect as useEffect45, useMemo as useMemo35, useState as useState55 } from "react";
30299
+ import { Component as Component2, useEffect as useEffect46, useMemo as useMemo35, useState as useState55 } from "react";
30242
30300
  import { jsx as jsx61 } from "react/jsx-runtime";
30243
30301
  var HostFenceErrorBoundary = class extends Component2 {
30244
30302
  constructor() {
@@ -30254,7 +30312,7 @@ var HostFenceErrorBoundary = class extends Component2 {
30254
30312
  };
30255
30313
  function HostFenceWidget({ editor, blockId, getRenderers, getTheme }) {
30256
30314
  const [version, setVersion] = useState55(0);
30257
- useEffect45(() => {
30315
+ useEffect46(() => {
30258
30316
  const onUpdate = () => setVersion((v2) => v2 + 1);
30259
30317
  editor.on("transaction", onUpdate);
30260
30318
  return () => {
@@ -30727,7 +30785,7 @@ import { createElement as createElement14 } from "react";
30727
30785
  import { isDataFilePath } from "@bendyline/squisq/doc";
30728
30786
 
30729
30787
  // src/dataCard/DataCardWidget.tsx
30730
- import { useCallback as useCallback39, useEffect as useEffect46, useMemo as useMemo36, useRef as useRef44, useState as useState56 } from "react";
30788
+ import { useCallback as useCallback39, useEffect as useEffect47, useMemo as useMemo36, useRef as useRef44, useState as useState56 } from "react";
30731
30789
  import { EMPTY_TABLE_VIEW_STATE } from "@bendyline/squisq/table";
30732
30790
 
30733
30791
  // src/dataCard/gridSave.ts
@@ -31131,7 +31189,7 @@ var XLSX_SESSION_LOCKED_REASON = "Date cells and shared-formula masters stay loc
31131
31189
  var pendingFormulas = /* @__PURE__ */ new WeakMap();
31132
31190
  function useCardLink(editor, blockId) {
31133
31191
  const [version, setVersion] = useState56(0);
31134
- useEffect46(() => {
31192
+ useEffect47(() => {
31135
31193
  const bump = () => setVersion((v2) => v2 + 1);
31136
31194
  editor.on("transaction", bump);
31137
31195
  return () => {
@@ -31151,7 +31209,7 @@ function useCardLink(editor, blockId) {
31151
31209
  }
31152
31210
  function useMediaRevision(getMediaRevision) {
31153
31211
  const [revision, setRevision] = useState56(() => getMediaRevision());
31154
- useEffect46(() => {
31212
+ useEffect47(() => {
31155
31213
  const timer = window.setInterval(() => {
31156
31214
  const next = getMediaRevision();
31157
31215
  setRevision((prev) => prev === next ? prev : next);
@@ -31195,7 +31253,7 @@ function DataCardWidget({
31195
31253
  regionParams.anchor,
31196
31254
  regionParams.headerRow
31197
31255
  ]);
31198
- useEffect46(() => {
31256
+ useEffect47(() => {
31199
31257
  if (!href || cardPos === null) return;
31200
31258
  const provider = activeProvider;
31201
31259
  if (!provider) {
@@ -31357,7 +31415,7 @@ function DataCardWidget({
31357
31415
  cancelled = true;
31358
31416
  };
31359
31417
  }, [href, revision, activeProvider, activeContainer, regionIdentity, editor]);
31360
- useEffect46(
31418
+ useEffect47(
31361
31419
  () => () => {
31362
31420
  gridRef.current?.formulaSession?.dispose();
31363
31421
  gridRef.current?.provider.dispose();
@@ -32094,7 +32152,7 @@ function pasteVideoEmbedCode(view, text) {
32094
32152
  }
32095
32153
 
32096
32154
  // src/treeview/treeViewData.ts
32097
- import { useEffect as useEffect47, useMemo as useMemo37, useState as useState58 } from "react";
32155
+ import { useEffect as useEffect48, useMemo as useMemo37, useState as useState58 } from "react";
32098
32156
 
32099
32157
  // src/treeview/TreeViewExtension.ts
32100
32158
  import { Extension as Extension15 } from "@tiptap/core";
@@ -32803,7 +32861,7 @@ var TreeViewExtension = Extension15.create({
32803
32861
  // src/treeview/treeViewData.ts
32804
32862
  function useTreeViewData(editor, blockId) {
32805
32863
  const [version, setVersion] = useState58(0);
32806
- useEffect47(() => {
32864
+ useEffect48(() => {
32807
32865
  const onUpdate = () => setVersion((v2) => v2 + 1);
32808
32866
  editor.on("transaction", onUpdate);
32809
32867
  return () => {
@@ -32829,7 +32887,7 @@ function shouldPasteAsTreeFence(text) {
32829
32887
  }
32830
32888
 
32831
32889
  // src/timeline/timelineData.ts
32832
- import { useEffect as useEffect49, useMemo as useMemo39, useRef as useRef47, useState as useState60 } from "react";
32890
+ import { useEffect as useEffect50, useMemo as useMemo39, useRef as useRef47, useState as useState60 } from "react";
32833
32891
 
32834
32892
  // src/timeline/TimelineViewExtension.ts
32835
32893
  import { Extension as Extension16 } from "@tiptap/core";
@@ -32843,7 +32901,7 @@ import {
32843
32901
  } from "@bendyline/squisq/doc";
32844
32902
 
32845
32903
  // src/timeline/TimelineEditorWidget.tsx
32846
- import { useCallback as useCallback41, useEffect as useEffect48, useMemo as useMemo38, useRef as useRef46, useState as useState59 } from "react";
32904
+ import { useCallback as useCallback41, useEffect as useEffect49, useMemo as useMemo38, useRef as useRef46, useState as useState59 } from "react";
32847
32905
  import {
32848
32906
  asciiTimelineToTemplateData
32849
32907
  } from "@bendyline/squisq/doc";
@@ -33394,7 +33452,7 @@ function TimelineEditorWidget({ editor, blockId }) {
33394
33452
  }
33395
33453
  return null;
33396
33454
  }, [selectedEventId, view]);
33397
- useEffect48(() => {
33455
+ useEffect49(() => {
33398
33456
  if (!view) return;
33399
33457
  const ids = new Set(
33400
33458
  view.timeline.tracks.flatMap((track) => track.events.map((event) => event.id))
@@ -33402,13 +33460,13 @@ function TimelineEditorWidget({ editor, blockId }) {
33402
33460
  if (selectedEventId && ids.has(selectedEventId)) return;
33403
33461
  setSelectedEventId(view.timeline.tracks[0]?.events[0]?.id ?? null);
33404
33462
  }, [selectedEventId, view]);
33405
- useEffect48(() => {
33463
+ useEffect49(() => {
33406
33464
  if (editable) return;
33407
33465
  setAddingTrackId(null);
33408
33466
  setEditingTrackId(null);
33409
33467
  setHover(null);
33410
33468
  }, [editable]);
33411
- useEffect48(() => {
33469
+ useEffect49(() => {
33412
33470
  if (!editingTrackId || view?.timeline.tracks.some((track) => track.id === editingTrackId)) {
33413
33471
  return;
33414
33472
  }
@@ -33815,7 +33873,7 @@ function InlineTrackLabel({
33815
33873
  onFinish
33816
33874
  }) {
33817
33875
  const [draft, setDraft] = useState59(label);
33818
- useEffect48(() => {
33876
+ useEffect49(() => {
33819
33877
  if (editing) setDraft(label);
33820
33878
  }, [editing, label]);
33821
33879
  const commitLabel = () => {
@@ -33874,8 +33932,8 @@ function EventInspector({
33874
33932
  const { event } = selected;
33875
33933
  const [label, setLabel] = useState59(event.label);
33876
33934
  const [description, setDescription] = useState59(event.description ?? "");
33877
- useEffect48(() => setLabel(event.label), [event.label]);
33878
- useEffect48(() => setDescription(event.description ?? ""), [event.description]);
33935
+ useEffect49(() => setLabel(event.label), [event.label]);
33936
+ useEffect49(() => setDescription(event.description ?? ""), [event.description]);
33879
33937
  const update = (patch) => dispatch(patch);
33880
33938
  const commitLabel = () => {
33881
33939
  const next = label.trim();
@@ -34185,7 +34243,7 @@ var TimelineViewExtension = Extension16.create({
34185
34243
  function useTimelineData(editor, blockId) {
34186
34244
  const [version, setVersion] = useState60(0);
34187
34245
  const dataCache = useRef47(null);
34188
- useEffect49(() => {
34246
+ useEffect50(() => {
34189
34247
  const onEditorChange = () => setVersion((value) => value + 1);
34190
34248
  editor.on("transaction", onEditorChange);
34191
34249
  editor.on("update", onEditorChange);
@@ -34220,7 +34278,7 @@ function shouldPasteAsTimelineFence(text) {
34220
34278
  }
34221
34279
 
34222
34280
  // src/BlockPropertiesPopover.tsx
34223
- import { useEffect as useEffect50, useId as useId13, useRef as useRef48, useState as useState61 } from "react";
34281
+ import { useEffect as useEffect51, useId as useId13, useRef as useRef48, useState as useState61 } from "react";
34224
34282
  import { createPortal as createPortal14 } from "react-dom";
34225
34283
  import { Fragment as Fragment22, jsx as jsx65, jsxs as jsxs51 } from "react/jsx-runtime";
34226
34284
  var TRANSITION_FLYOUT = ".squisq-transition-flyout";
@@ -34239,10 +34297,10 @@ function BlockPropertiesPopover({
34239
34297
  const [inner, setInner] = useState61(blockAttrs);
34240
34298
  const [templateInner, setTemplateInner] = useState61(templateParams);
34241
34299
  const [style, setStyle] = useState61(() => computeStyle3(anchorRect));
34242
- useEffect50(() => {
34300
+ useEffect51(() => {
34243
34301
  requestAnimationFrame(() => setStyle(computeStyle3(anchorRect, panelRef.current)));
34244
34302
  }, [anchorRect]);
34245
- useEffect50(() => {
34303
+ useEffect51(() => {
34246
34304
  const onKey = (e2) => {
34247
34305
  if (e2.key === "Escape") onClose();
34248
34306
  };
@@ -34493,7 +34551,7 @@ function persistFromWrite(bodyMd, state) {
34493
34551
  }
34494
34552
 
34495
34553
  // src/WysiwygEditor.tsx
34496
- import { useCallback as useCallback43, useEffect as useEffect55, useMemo as useMemo42, useRef as useRef51, useState as useState67 } from "react";
34554
+ import { useCallback as useCallback43, useEffect as useEffect56, useMemo as useMemo42, useRef as useRef51, useState as useState67 } from "react";
34497
34555
  import { useEditor as useEditor2, EditorContent as EditorContent2 } from "@tiptap/react";
34498
34556
  import { Selection as Selection2 } from "@tiptap/pm/state";
34499
34557
  import { Extension as Extension18, getHTMLFromFragment } from "@tiptap/core";
@@ -34538,7 +34596,7 @@ import Link2 from "@tiptap/extension-link";
34538
34596
  // src/WikiLink.tsx
34539
34597
  import { Node as Node2, InputRule } from "@tiptap/core";
34540
34598
  import { NodeViewWrapper, ReactNodeViewRenderer } from "@tiptap/react";
34541
- import { useEffect as useEffect51, useState as useState62 } from "react";
34599
+ import { useEffect as useEffect52, useState as useState62 } from "react";
34542
34600
  import { wikiLinkPath as wikiLinkPath3, parseWikiLink as parseWikiLink3 } from "@bendyline/squisq/markdown";
34543
34601
 
34544
34602
  // src/wikiSuggestionPlugin.ts
@@ -34711,7 +34769,7 @@ function WikiLinkView({ node: node2, editor }) {
34711
34769
  const [exists, setExists] = useState62(null);
34712
34770
  const [error, setError] = useState62("");
34713
34771
  const [busy, setBusy] = useState62(false);
34714
- useEffect51(() => {
34772
+ useEffect52(() => {
34715
34773
  let cancelled = false;
34716
34774
  setExists(null);
34717
34775
  setError("");
@@ -34906,7 +34964,7 @@ var InlineIcon = Node3.create({
34906
34964
  });
34907
34965
 
34908
34966
  // src/ImageNodeView.tsx
34909
- import { useEffect as useEffect52, useRef as useRef49, useState as useState63 } from "react";
34967
+ import { useEffect as useEffect53, useRef as useRef49, useState as useState63 } from "react";
34910
34968
  import { NodeViewWrapper as NodeViewWrapper2, ReactNodeViewRenderer as ReactNodeViewRenderer2 } from "@tiptap/react";
34911
34969
  import Image from "@tiptap/extension-image";
34912
34970
  import { mergeAttributes as mergeAttributes3 } from "@tiptap/core";
@@ -34940,7 +34998,7 @@ function ImageComponent({ node: node2, selected, editor, updateAttributes }) {
34940
34998
  const sanitizedSvg = useSanitizedSvgImage(loadedSrc, isSvg);
34941
34999
  const resolvedSrc = sanitizedSvg ?? "";
34942
35000
  const resolutionFailed = needsResolution && currentResolution?.url === null || sanitizedSvg === null;
34943
- useEffect52(() => {
35001
+ useEffect53(() => {
34944
35002
  if (isUploading || !mediaProvider || !resolveAs) return;
34945
35003
  setImageLoad(null);
34946
35004
  let cancelled = false;
@@ -35279,15 +35337,15 @@ function MediaEditButton({ src, kind, fx, className }) {
35279
35337
 
35280
35338
  // src/tiptap/TiptapVideo.tsx
35281
35339
  import { NodeViewWrapper as NodeViewWrapper3, ReactNodeViewRenderer as ReactNodeViewRenderer3 } from "@tiptap/react";
35282
- import { useEffect as useEffect54, useState as useState65 } from "react";
35340
+ import { useEffect as useEffect55, useState as useState65 } from "react";
35283
35341
 
35284
35342
  // src/tiptap/useResolvedMediaSrc.ts
35285
- import { useEffect as useEffect53, useState as useState64 } from "react";
35343
+ import { useEffect as useEffect54, useState as useState64 } from "react";
35286
35344
  function useResolvedMediaSrc(src) {
35287
35345
  const { mediaProvider, mediaRevision } = useEditorContext();
35288
35346
  const isRelative = !!src && !src.startsWith("blob:") && !src.startsWith("http:") && !src.startsWith("https:") && !src.startsWith("data:") && !src.startsWith("/");
35289
35347
  const [resolved, setResolved] = useState64(isRelative && mediaProvider ? "" : src);
35290
- useEffect53(() => {
35348
+ useEffect54(() => {
35291
35349
  if (!mediaProvider || !isRelative) {
35292
35350
  setResolved(src);
35293
35351
  return;
@@ -35346,7 +35404,7 @@ function VideoMedia({
35346
35404
  const resolvedSrc = useResolvedMediaSrc(src ?? "");
35347
35405
  const [audioOnly, setAudioOnly] = useState65(false);
35348
35406
  const resolvedPoster = useResolvedMediaSrc(poster ?? "");
35349
- useEffect54(() => {
35407
+ useEffect55(() => {
35350
35408
  setAudioOnly(false);
35351
35409
  }, [resolvedSrc]);
35352
35410
  const handleLoadedMetadata = (event) => {
@@ -36653,7 +36711,7 @@ function WysiwygEditor({
36653
36711
  mermaidThemeStoreRef.current = createMermaidThemeStore(activeTheme ?? DEFAULT_THEME4);
36654
36712
  }
36655
36713
  const mermaidThemeStore = mermaidThemeStoreRef.current;
36656
- useEffect55(() => {
36714
+ useEffect56(() => {
36657
36715
  mermaidThemeStore.setTheme(activeTheme ?? DEFAULT_THEME4);
36658
36716
  }, [activeTheme, mermaidThemeStore]);
36659
36717
  const { docTemplates, onDocTemplatesChange } = useDocCustomTemplates();
@@ -36673,19 +36731,19 @@ function WysiwygEditor({
36673
36731
  [docTemplates, onDocTemplatesChange]
36674
36732
  );
36675
36733
  const mentionProviderRef = useRef51(mentionProvider);
36676
- useEffect55(() => {
36734
+ useEffect56(() => {
36677
36735
  mentionProviderRef.current = mentionProvider;
36678
36736
  }, [mentionProvider]);
36679
36737
  const fenceRenderersRef = useRef51(fenceRenderers);
36680
- useEffect55(() => {
36738
+ useEffect56(() => {
36681
36739
  fenceRenderersRef.current = fenceRenderers;
36682
36740
  }, [fenceRenderers]);
36683
36741
  const onCopyCodeRef = useRef51(onCopyCode);
36684
- useEffect55(() => {
36742
+ useEffect56(() => {
36685
36743
  onCopyCodeRef.current = onCopyCode;
36686
36744
  }, [onCopyCode]);
36687
36745
  const activeThemeRef = useRef51(activeTheme);
36688
- useEffect55(() => {
36746
+ useEffect56(() => {
36689
36747
  activeThemeRef.current = activeTheme;
36690
36748
  }, [activeTheme]);
36691
36749
  const resolvedPlaceholder = useMemo42(() => placeholder ?? pickEmptyPrompt(), [placeholder]);
@@ -36696,30 +36754,30 @@ function WysiwygEditor({
36696
36754
  const pendingLocalSourcesRef = useRef51([]);
36697
36755
  const mediaProviderRef = useRef51(mediaProvider);
36698
36756
  const mediaRevisionRef = useRef51(mediaRevision);
36699
- useEffect55(() => {
36757
+ useEffect56(() => {
36700
36758
  mediaRevisionRef.current = mediaRevision;
36701
36759
  }, [mediaRevision]);
36702
36760
  const onOpenFilesPanelRef = useRef51(onOpenFilesPanel);
36703
- useEffect55(() => {
36761
+ useEffect56(() => {
36704
36762
  onOpenFilesPanelRef.current = onOpenFilesPanel;
36705
36763
  }, [onOpenFilesPanel]);
36706
36764
  const calcEngineFactoryRef = useRef51(calcEngineFactory);
36707
- useEffect55(() => {
36765
+ useEffect56(() => {
36708
36766
  calcEngineFactoryRef.current = calcEngineFactory;
36709
36767
  }, [calcEngineFactory]);
36710
36768
  const workspaceContainerRef = useRef51(workspaceContainer);
36711
- useEffect55(() => {
36769
+ useEffect56(() => {
36712
36770
  workspaceContainerRef.current = workspaceContainer;
36713
36771
  }, [workspaceContainer]);
36714
36772
  const bumpMediaRevisionRef = useRef51(bumpMediaRevision);
36715
- useEffect55(() => {
36773
+ useEffect56(() => {
36716
36774
  bumpMediaRevisionRef.current = bumpMediaRevision;
36717
36775
  }, [bumpMediaRevision]);
36718
- useEffect55(() => {
36776
+ useEffect56(() => {
36719
36777
  mediaProviderRef.current = mediaProvider;
36720
36778
  }, [mediaProvider]);
36721
36779
  const [accessoryPaths, setAccessoryPaths] = useState67(() => /* @__PURE__ */ new Set());
36722
- useEffect55(() => {
36780
+ useEffect56(() => {
36723
36781
  if (!mediaProvider) {
36724
36782
  setAccessoryPaths(/* @__PURE__ */ new Set());
36725
36783
  return;
@@ -36759,7 +36817,7 @@ function WysiwygEditor({
36759
36817
  initialContentRef.current = markdownToTiptap(initialDisplayBodyRef.current);
36760
36818
  }
36761
36819
  const submitOnEnterRef = useRef51(submitOnEnter);
36762
- useEffect55(() => {
36820
+ useEffect56(() => {
36763
36821
  submitOnEnterRef.current = submitOnEnter;
36764
36822
  }, [submitOnEnter]);
36765
36823
  const editor = useEditor2({
@@ -36991,7 +37049,7 @@ function WysiwygEditor({
36991
37049
  }
36992
37050
  }
36993
37051
  });
36994
- useEffect55(() => {
37052
+ useEffect56(() => {
36995
37053
  let cancelled = false;
36996
37054
  queueMicrotask(() => {
36997
37055
  if (!cancelled && editor && !editor.isDestroyed)
@@ -37001,13 +37059,13 @@ function WysiwygEditor({
37001
37059
  cancelled = true;
37002
37060
  };
37003
37061
  }, [editor, wikiLinks]);
37004
- useEffect55(() => {
37062
+ useEffect56(() => {
37005
37063
  if (editor) {
37006
37064
  setTiptapEditor(editor);
37007
37065
  }
37008
37066
  return () => setTiptapEditor(null);
37009
37067
  }, [editor, setTiptapEditor]);
37010
- useEffect55(() => {
37068
+ useEffect56(() => {
37011
37069
  if (!editor) return;
37012
37070
  const syncPlaceholders = () => {
37013
37071
  syncAccessoryFileLinkPlaceholders(editor.view.dom, accessoryPaths);
@@ -37018,7 +37076,7 @@ function WysiwygEditor({
37018
37076
  editor.off("update", syncPlaceholders);
37019
37077
  };
37020
37078
  }, [accessoryPaths, editor]);
37021
- useEffect55(() => {
37079
+ useEffect56(() => {
37022
37080
  if (editor) editor.setEditable(!readOnly);
37023
37081
  }, [editor, readOnly]);
37024
37082
  const containerRef = useRef51(null);
@@ -37030,7 +37088,7 @@ function WysiwygEditor({
37030
37088
  if (editor && !editor.isDestroyed) editor.commands.focus();
37031
37089
  });
37032
37090
  }, [editor]);
37033
- useEffect55(() => {
37091
+ useEffect56(() => {
37034
37092
  if (!editor) return;
37035
37093
  const root = containerRef.current;
37036
37094
  if (!root) return;
@@ -37086,7 +37144,7 @@ function WysiwygEditor({
37086
37144
  root.addEventListener("mousedown", onClick);
37087
37145
  return () => root.removeEventListener("mousedown", onClick);
37088
37146
  }, [editor]);
37089
- useEffect55(() => {
37147
+ useEffect56(() => {
37090
37148
  if (!editor) return;
37091
37149
  const previousLayout = sourceLayoutRef.current;
37092
37150
  const layoutChanged = previousLayout !== layoutMode;
@@ -37197,7 +37255,7 @@ function WysiwygEditor({
37197
37255
  }
37198
37256
  return out;
37199
37257
  }, [activeTheme, themeInheritance]);
37200
- useEffect55(() => {
37258
+ useEffect56(() => {
37201
37259
  if (!editor || editor.isDestroyed) return;
37202
37260
  editor.view.dispatch(editor.state.tr.setMeta(DOCUMENT_TRAY_KEY, layoutMode === "document"));
37203
37261
  }, [editor, layoutMode]);
@@ -37436,14 +37494,14 @@ import { VIEWPORT_PRESETS as VIEWPORT_PRESETS5 } from "@bendyline/squisq/schemas
37436
37494
  import { BlockRenderer as BlockRenderer3, MediaContext as MediaContext4 } from "@bendyline/squisq-react";
37437
37495
 
37438
37496
  // src/useHeadingLayout.ts
37439
- import { useCallback as useCallback44, useEffect as useEffect56, useMemo as useMemo43, useState as useState68 } from "react";
37497
+ import { useCallback as useCallback44, useEffect as useEffect57, useMemo as useMemo43, useState as useState68 } from "react";
37440
37498
  import { flattenBlocks as flattenBlocks3, hasTemplate } from "@bendyline/squisq/doc";
37441
37499
  function useHeadingLayout(refInsideWrapper) {
37442
37500
  const { doc, activeView, monacoEditor, tiptapEditor } = useEditorContext();
37443
37501
  const flatBlocks = useMemo43(() => doc ? flattenBlocks3(doc.blocks) : [], [doc]);
37444
37502
  const [entries, setEntries] = useState68([]);
37445
37503
  const [pageEdges, setPageEdges] = useState68(null);
37446
- useEffect56(() => {
37504
+ useEffect57(() => {
37447
37505
  if (activeView !== "wysiwyg") return;
37448
37506
  const node2 = refInsideWrapper.current;
37449
37507
  if (!node2) return;
@@ -37511,7 +37569,7 @@ function useHeadingLayout(refInsideWrapper) {
37511
37569
  window.removeEventListener("resize", recompute);
37512
37570
  };
37513
37571
  }, [activeView, flatBlocks, refInsideWrapper]);
37514
- useEffect56(() => {
37572
+ useEffect57(() => {
37515
37573
  if (activeView !== "raw") return;
37516
37574
  if (!monacoEditor) return;
37517
37575
  const node2 = refInsideWrapper.current;
@@ -37572,7 +37630,7 @@ function useHeadingLayout(refInsideWrapper) {
37572
37630
  window.removeEventListener("resize", recompute);
37573
37631
  };
37574
37632
  }, [activeView, monacoEditor, flatBlocks, refInsideWrapper]);
37575
- useEffect56(() => {
37633
+ useEffect57(() => {
37576
37634
  setEntries([]);
37577
37635
  setPageEdges(null);
37578
37636
  }, [activeView]);
@@ -37656,7 +37714,7 @@ import { flattenRenderableBlocks, DEFAULT_THEME as DEFAULT_THEME5 } from "@bendy
37656
37714
  import { extractPlainText as extractPlainText3 } from "@bendyline/squisq/markdown";
37657
37715
 
37658
37716
  // src/usePreviewProjection.ts
37659
- import { useEffect as useEffect57, useState as useState69 } from "react";
37717
+ import { useEffect as useEffect58, useState as useState69 } from "react";
37660
37718
  import {
37661
37719
  resolveAudioMapping,
37662
37720
  resolveDataReferences
@@ -37703,7 +37761,7 @@ function preserveEquivalentAudio(previous, next) {
37703
37761
  }
37704
37762
  function usePreviewProjection(doc, transformStyle, workspaceContainer, documentTitle2, mediaRevision) {
37705
37763
  const [projection, setProjection] = useState69(null);
37706
- useEffect57(() => {
37764
+ useEffect58(() => {
37707
37765
  if (!doc || !doc.blocks.length) {
37708
37766
  setProjection(null);
37709
37767
  return;
@@ -37982,7 +38040,7 @@ function InlinePreviewGutter({
37982
38040
  import {
37983
38041
  memo,
37984
38042
  useCallback as useCallback45,
37985
- useEffect as useEffect58,
38043
+ useEffect as useEffect59,
37986
38044
  useMemo as useMemo46,
37987
38045
  useRef as useRef53,
37988
38046
  useState as useState71
@@ -38455,10 +38513,10 @@ function useActiveOutlineBlockId() {
38455
38513
  flatBlocksRef.current = flatBlocks;
38456
38514
  const headingLocations = flatBlocks.map((block) => `${block.id}:${block.sourceHeading?.position?.start.line ?? ""}`).join("\0");
38457
38515
  const [activeId, setActiveId] = useState71(null);
38458
- useEffect58(() => {
38516
+ useEffect59(() => {
38459
38517
  setActiveId(null);
38460
38518
  }, [activeView]);
38461
- useEffect58(() => {
38519
+ useEffect59(() => {
38462
38520
  if (activeView !== "wysiwyg" || !tiptapEditor) return;
38463
38521
  const update = () => {
38464
38522
  const { from } = tiptapEditor.state.selection;
@@ -38480,7 +38538,7 @@ function useActiveOutlineBlockId() {
38480
38538
  tiptapEditor.off("update", update);
38481
38539
  };
38482
38540
  }, [activeView, tiptapEditor, headingLocations]);
38483
- useEffect58(() => {
38541
+ useEffect59(() => {
38484
38542
  if (activeView !== "raw" || !monacoEditor) return;
38485
38543
  const update = () => {
38486
38544
  const line = monacoEditor.getPosition()?.lineNumber;
@@ -38567,7 +38625,7 @@ function bumpHeadingLevelInSource(source, line, delta) {
38567
38625
  }
38568
38626
 
38569
38627
  // src/codeContext/CodeContextZones.tsx
38570
- import { useCallback as useCallback47, useEffect as useEffect60, useMemo as useMemo48, useRef as useRef55, useState as useState72 } from "react";
38628
+ import { useCallback as useCallback47, useEffect as useEffect61, useMemo as useMemo48, useRef as useRef55, useState as useState72 } from "react";
38571
38629
  import { createPortal as createPortal15 } from "react-dom";
38572
38630
 
38573
38631
  // src/codeContext/diffContextSections.ts
@@ -38691,7 +38749,7 @@ function setOrdinal(zone, ordinal) {
38691
38749
  // src/codeContext/CodeContextSectionView.tsx
38692
38750
  import { parseMarkdown as parseMarkdown8 } from "@bendyline/squisq/markdown";
38693
38751
  import { MarkdownRenderer } from "@bendyline/squisq-react";
38694
- import { useCallback as useCallback46, useEffect as useEffect59, useMemo as useMemo47, useRef as useRef54 } from "react";
38752
+ import { useCallback as useCallback46, useEffect as useEffect60, useMemo as useMemo47, useRef as useRef54 } from "react";
38695
38753
  import { jsx as jsx75, jsxs as jsxs61 } from "react/jsx-runtime";
38696
38754
  function CodeContextSectionView({
38697
38755
  section,
@@ -38711,7 +38769,7 @@ function CodeContextSectionView({
38711
38769
  () => expanded && section.markdown ? parseMarkdown8(section.markdown).children : null,
38712
38770
  [expanded, section.markdown]
38713
38771
  );
38714
- useEffect59(() => {
38772
+ useEffect60(() => {
38715
38773
  const el = rootRef.current;
38716
38774
  if (!el || typeof ResizeObserver === "undefined") return;
38717
38775
  const report = () => {
@@ -38787,7 +38845,7 @@ function CodeContextZones({ options }) {
38787
38845
  const [, setZonesVersion] = useState72(0);
38788
38846
  const [expandedById, setExpandedById] = useState72({});
38789
38847
  const seenIds = useRef55(/* @__PURE__ */ new Set());
38790
- useEffect60(() => {
38848
+ useEffect61(() => {
38791
38849
  if (!monacoEditor) return;
38792
38850
  const mgr = new CodeContextZoneManager(monacoEditor);
38793
38851
  const off = mgr.onDidChangeZones(() => setZonesVersion((v2) => v2 + 1));
@@ -38810,7 +38868,7 @@ function CodeContextZones({ options }) {
38810
38868
  });
38811
38869
  return out;
38812
38870
  }, [fileTop, sections]);
38813
- useEffect60(() => {
38871
+ useEffect61(() => {
38814
38872
  if (!manager) return;
38815
38873
  manager.sync(resolved.map((r) => r.spec));
38816
38874
  setExpandedById((prev) => {
@@ -39276,7 +39334,7 @@ function placeClipInBlock(source, fromLine, targetHeadingLine, spec, startAt) {
39276
39334
  }
39277
39335
 
39278
39336
  // src/TimelineTrack.tsx
39279
- import { useCallback as useCallback49, useEffect as useEffect63, useMemo as useMemo49, useRef as useRef58, useState as useState75 } from "react";
39337
+ import { useCallback as useCallback49, useEffect as useEffect64, useMemo as useMemo49, useRef as useRef58, useState as useState75 } from "react";
39280
39338
  import {
39281
39339
  resolveMediaSchedule as resolveMediaSchedule2,
39282
39340
  getDocPlaybackDuration,
@@ -39289,7 +39347,7 @@ import { useProcessedAudio as useProcessedAudio2 } from "@bendyline/squisq-video
39289
39347
  import { MediaClipLayer, MediaContext as MediaContext5 } from "@bendyline/squisq-react";
39290
39348
 
39291
39349
  // src/useTimelineClock.ts
39292
- import { useCallback as useCallback48, useEffect as useEffect61, useRef as useRef56, useState as useState73 } from "react";
39350
+ import { useCallback as useCallback48, useEffect as useEffect62, useRef as useRef56, useState as useState73 } from "react";
39293
39351
  function advanceTime(prev, dt, total) {
39294
39352
  if (total <= 0) return 0;
39295
39353
  return Math.min(total, Math.max(0, prev + dt));
@@ -39318,10 +39376,10 @@ function useTimelineClock(total) {
39318
39376
  const mediaHostRef = useRef56(null);
39319
39377
  currentTimeRef.current = currentTime;
39320
39378
  isPlayingRef.current = isPlaying;
39321
- useEffect61(() => {
39379
+ useEffect62(() => {
39322
39380
  setCurrentTime((t) => Math.min(t, Math.max(0, total)));
39323
39381
  }, [total]);
39324
- useEffect61(() => {
39382
+ useEffect62(() => {
39325
39383
  if (!isPlaying) return;
39326
39384
  lastRef.current = performance.now();
39327
39385
  const tick = (now) => {
@@ -39419,7 +39477,7 @@ function timelineBars(clips) {
39419
39477
  }
39420
39478
 
39421
39479
  // src/TimelineItemMenu.tsx
39422
- import { useEffect as useEffect62, useLayoutEffect as useLayoutEffect14, useRef as useRef57, useState as useState74 } from "react";
39480
+ import { useEffect as useEffect63, useLayoutEffect as useLayoutEffect14, useRef as useRef57, useState as useState74 } from "react";
39423
39481
  import { createPortal as createPortal16 } from "react-dom";
39424
39482
  import { Fragment as Fragment27, jsx as jsx78, jsxs as jsxs63 } from "react/jsx-runtime";
39425
39483
  function TimelineItemMenu({
@@ -39450,7 +39508,7 @@ function TimelineItemMenu({
39450
39508
  resizeObserver?.disconnect();
39451
39509
  };
39452
39510
  }, [anchor]);
39453
- useEffect62(() => {
39511
+ useEffect63(() => {
39454
39512
  const onKeyDown = (event) => {
39455
39513
  if (event.key !== "Escape") return;
39456
39514
  event.preventDefault();
@@ -39938,7 +39996,7 @@ function TimelineTrack({
39938
39996
  play();
39939
39997
  }, [play]);
39940
39998
  const [scrubbing, setScrubbing] = useState75(false);
39941
- useEffect63(() => {
39999
+ useEffect64(() => {
39942
40000
  if (!scrubbing) return;
39943
40001
  const onMove = (e2) => {
39944
40002
  const scroll = scrollRef.current;
@@ -39976,7 +40034,7 @@ function TimelineTrack({
39976
40034
  [blocks]
39977
40035
  );
39978
40036
  const followedBlockRef = useRef58(null);
39979
- useEffect63(() => {
40037
+ useEffect64(() => {
39980
40038
  if (!isPlaying) {
39981
40039
  followedBlockRef.current = null;
39982
40040
  return;
@@ -39987,7 +40045,7 @@ function TimelineTrack({
39987
40045
  const line = headingLine(block);
39988
40046
  if (line != null) goToBlockByLine(line);
39989
40047
  }, [isPlaying, currentTime, blockAtTime, goToBlockByLine]);
39990
- useEffect63(() => {
40048
+ useEffect64(() => {
39991
40049
  if (!isPlaying) return;
39992
40050
  const scroll = scrollRef.current;
39993
40051
  if (!scroll) return;
@@ -40036,7 +40094,7 @@ function TimelineTrack({
40036
40094
  const zoomIn = useCallback49(() => setPxPerSecond((s) => Math.min(ZOOM_MAX, s * ZOOM_FACTOR)), []);
40037
40095
  const zoomOut = useCallback49(() => setPxPerSecond((s) => Math.max(ZOOM_MIN, s / ZOOM_FACTOR)), []);
40038
40096
  const [viewportWidth, setViewportWidth] = useState75(0);
40039
- useEffect63(() => {
40097
+ useEffect64(() => {
40040
40098
  const el = scrollRef.current;
40041
40099
  if (!el || typeof ResizeObserver === "undefined") return;
40042
40100
  const update = () => setViewportWidth(el.clientWidth);
@@ -40050,7 +40108,7 @@ function TimelineTrack({
40050
40108
  const dragRef = useRef58(null);
40051
40109
  dragRef.current = drag;
40052
40110
  const isDragging = drag != null && !drag.committed;
40053
- useEffect63(() => {
40111
+ useEffect64(() => {
40054
40112
  if (!isDragging) return;
40055
40113
  const onMove = (e2) => {
40056
40114
  const d = dragRef.current;
@@ -40081,7 +40139,7 @@ function TimelineTrack({
40081
40139
  window.removeEventListener("pointerup", onUp);
40082
40140
  };
40083
40141
  }, [isDragging]);
40084
- useEffect63(() => {
40142
+ useEffect64(() => {
40085
40143
  if (dragRef.current?.committed) setDrag(null);
40086
40144
  }, [doc]);
40087
40145
  const beginDrag = useCallback49(
@@ -40943,7 +41001,7 @@ function TimelineToolbar({
40943
41001
  }
40944
41002
 
40945
41003
  // src/PlainHtmlPreview.tsx
40946
- import { useCallback as useCallback50, useEffect as useEffect64, useMemo as useMemo52, useRef as useRef59, useState as useState76 } from "react";
41004
+ import { useCallback as useCallback50, useEffect as useEffect65, useMemo as useMemo52, useRef as useRef59, useState as useState76 } from "react";
40947
41005
  import {
40948
41006
  isSvgImageSource as isSvgImageSource2,
40949
41007
  parseMarkdown as parseMarkdown9,
@@ -41053,7 +41111,7 @@ function PlainHtmlPreview({
41053
41111
  const parsedDoc = useMemo52(() => parseMarkdown9(markdown), [markdown]);
41054
41112
  const [wikiProjection, setWikiProjection] = useState76(null);
41055
41113
  const mdDoc = wikiProjection?.source === parsedDoc && wikiProjection.support === wikiLinks ? wikiProjection.doc : parsedDoc;
41056
- useEffect64(() => {
41114
+ useEffect65(() => {
41057
41115
  if (!wikiLinks) return;
41058
41116
  let cancelled = false;
41059
41117
  void resolveWikiLinks(
@@ -41072,7 +41130,7 @@ function PlainHtmlPreview({
41072
41130
  };
41073
41131
  }, [parsedDoc, wikiLinks]);
41074
41132
  const [resolvedImages, setResolvedImages] = useState76(null);
41075
- useEffect64(() => {
41133
+ useEffect65(() => {
41076
41134
  if (!mediaProvider) {
41077
41135
  setResolvedImages(null);
41078
41136
  return;
@@ -41109,7 +41167,7 @@ function PlainHtmlPreview({
41109
41167
  }, [resolvedImages, images]);
41110
41168
  const iconsCss = useMemo52(() => collectInlineFontAwesomeCss(), []);
41111
41169
  const [preparation, setPreparation] = useState76(null);
41112
- useEffect64(() => {
41170
+ useEffect65(() => {
41113
41171
  let cancelled = false;
41114
41172
  loadPreparation().then(
41115
41173
  (loaded) => {
@@ -41136,7 +41194,7 @@ function PlainHtmlPreview({
41136
41194
  );
41137
41195
  const [prepared, setPrepared] = useState76(null);
41138
41196
  const preparedOnceRef = useRef59(false);
41139
- useEffect64(() => {
41197
+ useEffect65(() => {
41140
41198
  if (!preparation || !needsPreparation) return;
41141
41199
  let cancelled = false;
41142
41200
  const prepare = () => {
@@ -41164,7 +41222,7 @@ function PlainHtmlPreview({
41164
41222
  }, [preparation, needsPreparation, mdDoc, container, dataTableCache]);
41165
41223
  const view = needsPreparation ? prepared : null;
41166
41224
  const [renderFn, setRenderFn] = useState76(() => cachedRender);
41167
- useEffect64(() => {
41225
+ useEffect65(() => {
41168
41226
  if (renderFn) return;
41169
41227
  let cancelled = false;
41170
41228
  loadRenderFn().then((fn) => {
@@ -41205,7 +41263,7 @@ function PlainHtmlPreview({
41205
41263
  frameDocument.addEventListener("click", handleClick, true);
41206
41264
  removeFrameLinkHandlerRef.current = () => frameDocument.removeEventListener("click", handleClick, true);
41207
41265
  }, [onLinkClick]);
41208
- useEffect64(() => {
41266
+ useEffect65(() => {
41209
41267
  installFrameLinkHandler();
41210
41268
  return () => removeFrameLinkHandlerRef.current();
41211
41269
  }, [html, installFrameLinkHandler]);
@@ -41301,11 +41359,11 @@ function PlainHtmlPreview({
41301
41359
  style2.remove();
41302
41360
  };
41303
41361
  }, [onCopyCode, showCodeCopyButton]);
41304
- useEffect64(() => {
41362
+ useEffect65(() => {
41305
41363
  installFrameCodeCopyControls();
41306
41364
  return () => removeFrameCodeCopyControlsRef.current();
41307
41365
  }, [html, installFrameCodeCopyControls]);
41308
- useEffect64(() => {
41366
+ useEffect65(() => {
41309
41367
  if (!globalKeyboardShortcuts) return;
41310
41368
  const handleKeyDown = (event) => {
41311
41369
  if (event.defaultPrevented || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey || event.key !== "ArrowDown" && event.key !== "ArrowUp") {
@@ -41390,7 +41448,7 @@ function collectImageRefs(doc) {
41390
41448
  }
41391
41449
 
41392
41450
  // src/PreviewPanel.tsx
41393
- import { useState as useState80, useEffect as useEffect69, useMemo as useMemo57, useCallback as useCallback54, useRef as useRef63 } from "react";
41451
+ import { useState as useState80, useEffect as useEffect70, useMemo as useMemo57, useCallback as useCallback54, useRef as useRef63 } from "react";
41394
41452
  import { createPortal as createPortal18 } from "react-dom";
41395
41453
  import {
41396
41454
  DashboardView,
@@ -41535,7 +41593,7 @@ import {
41535
41593
  createContext as createContext7,
41536
41594
  useCallback as useCallback51,
41537
41595
  useContext as useContext7,
41538
- useEffect as useEffect65,
41596
+ useEffect as useEffect66,
41539
41597
  useId as useId15,
41540
41598
  useLayoutEffect as useLayoutEffect15,
41541
41599
  useMemo as useMemo53,
@@ -41802,12 +41860,12 @@ function PresentationModeProvider({
41802
41860
  },
41803
41861
  [availableTargets, selectedTarget, stop]
41804
41862
  );
41805
- useEffect65(() => {
41863
+ useEffect66(() => {
41806
41864
  if (availableTargets.includes(selectedTarget)) return;
41807
41865
  setSelectedTarget("control");
41808
41866
  if (activeTargetRef.current !== null) void stop();
41809
41867
  }, [availableTargets, selectedTarget, stop]);
41810
- useEffect65(() => {
41868
+ useEffect66(() => {
41811
41869
  const root = rootRef.current;
41812
41870
  const ownerDocument = root?.ownerDocument;
41813
41871
  if (!root || !ownerDocument) return;
@@ -41819,7 +41877,7 @@ function PresentationModeProvider({
41819
41877
  ownerDocument.addEventListener("fullscreenchange", handleFullscreenChange);
41820
41878
  return () => ownerDocument.removeEventListener("fullscreenchange", handleFullscreenChange);
41821
41879
  }, [rootRef]);
41822
- useEffect65(() => {
41880
+ useEffect66(() => {
41823
41881
  const root = rootRef.current;
41824
41882
  if (!root) return;
41825
41883
  if (activeTarget) root.dataset.presentationMode = activeTarget;
@@ -41828,10 +41886,10 @@ function PresentationModeProvider({
41828
41886
  delete root.dataset.presentationMode;
41829
41887
  };
41830
41888
  }, [activeTarget, rootRef]);
41831
- useEffect65(() => {
41889
+ useEffect66(() => {
41832
41890
  if (activeView !== "preview" && activeTargetRef.current !== null) void stop();
41833
41891
  }, [activeView, stop]);
41834
- useEffect65(() => {
41892
+ useEffect66(() => {
41835
41893
  const previous = previousActiveTargetRef.current;
41836
41894
  previousActiveTargetRef.current = activeTarget;
41837
41895
  if (previous === null || activeTarget !== null) return;
@@ -41839,7 +41897,7 @@ function PresentationModeProvider({
41839
41897
  returnFocusRef.current = null;
41840
41898
  if (target?.isConnected) target.focus();
41841
41899
  }, [activeTarget]);
41842
- useEffect65(() => {
41900
+ useEffect66(() => {
41843
41901
  if (activeTarget !== "control") return;
41844
41902
  const ownerDocument = rootRef.current?.ownerDocument;
41845
41903
  if (!ownerDocument) return;
@@ -41851,7 +41909,7 @@ function PresentationModeProvider({
41851
41909
  ownerDocument.addEventListener("keydown", handleKeyDown);
41852
41910
  return () => ownerDocument.removeEventListener("keydown", handleKeyDown);
41853
41911
  }, [activeTarget, rootRef, stop]);
41854
- useEffect65(() => {
41912
+ useEffect66(() => {
41855
41913
  if (!error) return;
41856
41914
  const timer = window.setTimeout(() => setError(null), 6e3);
41857
41915
  return () => window.clearTimeout(timer);
@@ -41886,7 +41944,7 @@ function PresentationModeProvider({
41886
41944
  window.removeEventListener("resize", updatePosition);
41887
41945
  };
41888
41946
  }, [activeTarget, rootRef]);
41889
- useEffect65(
41947
+ useEffect66(
41890
41948
  () => () => {
41891
41949
  popupCleanupRef.current?.();
41892
41950
  const popup = popupRef.current;
@@ -42015,7 +42073,7 @@ function PresentationModeControl() {
42015
42073
  updatePosition();
42016
42074
  setOpen(true);
42017
42075
  }, [updatePosition]);
42018
- useEffect65(() => {
42076
+ useEffect66(() => {
42019
42077
  if (!open) return;
42020
42078
  const handlePointerDown = (event) => {
42021
42079
  const target = event.target;
@@ -42160,7 +42218,7 @@ import {
42160
42218
  createContext as createContext8,
42161
42219
  useCallback as useCallback52,
42162
42220
  useContext as useContext8,
42163
- useEffect as useEffect66,
42221
+ useEffect as useEffect67,
42164
42222
  useMemo as useMemo54,
42165
42223
  useRef as useRef61,
42166
42224
  useState as useState78
@@ -42230,7 +42288,7 @@ function PrintModeProvider({ rootRef, children }) {
42230
42288
  markPrinting();
42231
42289
  ownerWindow.print();
42232
42290
  }, [markPrinting, rootRef]);
42233
- useEffect66(() => {
42291
+ useEffect67(() => {
42234
42292
  const root = rootRef.current;
42235
42293
  if (!root) return;
42236
42294
  if (active) root.dataset.printPreview = "true";
@@ -42239,10 +42297,10 @@ function PrintModeProvider({ rootRef, children }) {
42239
42297
  delete root.dataset.printPreview;
42240
42298
  };
42241
42299
  }, [active, rootRef]);
42242
- useEffect66(() => {
42300
+ useEffect67(() => {
42243
42301
  if (activeView !== "preview" && active) close();
42244
42302
  }, [active, activeView, close]);
42245
- useEffect66(() => {
42303
+ useEffect67(() => {
42246
42304
  if (!active) return;
42247
42305
  const ownerWindow = rootRef.current?.ownerDocument.defaultView;
42248
42306
  const ownerDocument = rootRef.current?.ownerDocument;
@@ -42333,7 +42391,7 @@ function PrintPreviewToolbar() {
42333
42391
  }
42334
42392
 
42335
42393
  // src/print/PrintPreview.tsx
42336
- import { useCallback as useCallback53, useEffect as useEffect67, useMemo as useMemo55, useRef as useRef62 } from "react";
42394
+ import { useCallback as useCallback53, useEffect as useEffect68, useMemo as useMemo55, useRef as useRef62 } from "react";
42337
42395
  import {
42338
42396
  BlockRenderer as BlockRenderer4,
42339
42397
  FlashcardFaceView,
@@ -42390,7 +42448,7 @@ function PrintPreview({
42390
42448
  [contentDoc]
42391
42449
  );
42392
42450
  const isTextDocument = displayMode === "page" || displayMode === "narrate";
42393
- useEffect67(() => {
42451
+ useEffect68(() => {
42394
42452
  if (!isTextDocument) return registerPrintHandler(null);
42395
42453
  return registerPrintHandler(() => {
42396
42454
  const frameWindow = documentFrameRef.current?.contentWindow;
@@ -42529,7 +42587,7 @@ function PrintPreview({
42529
42587
  import {
42530
42588
  createContext as createContext9,
42531
42589
  useContext as useContext9,
42532
- useEffect as useEffect68,
42590
+ useEffect as useEffect69,
42533
42591
  useMemo as useMemo56,
42534
42592
  useState as useState79
42535
42593
  } from "react";
@@ -42636,7 +42694,7 @@ function SlideshowDataGridRenderer({
42636
42694
  const activeSourceKey = sourceKey(source);
42637
42695
  const [remote, setRemote] = useState79({ key: "", status: "idle" });
42638
42696
  const [gridModule, setGridModule] = useState79(null);
42639
- useEffect68(() => {
42697
+ useEffect69(() => {
42640
42698
  let active = true;
42641
42699
  void loadGridModule().then((module) => {
42642
42700
  if (active) setGridModule(module);
@@ -42645,7 +42703,7 @@ function SlideshowDataGridRenderer({
42645
42703
  active = false;
42646
42704
  };
42647
42705
  }, []);
42648
- useEffect68(() => {
42706
+ useEffect69(() => {
42649
42707
  if (!container || !source || !gridModule) {
42650
42708
  setRemote({ key: activeSourceKey, status: "idle" });
42651
42709
  return;
@@ -42696,13 +42754,13 @@ function SlideshowDataGridRenderer({
42696
42754
  () => useLocalGrid && gridModule ? new gridModule.TableStoreClient({ headers: previewHeaders, cells: previewRows }) : null,
42697
42755
  [previewHeaders, previewRows, useLocalGrid, gridModule]
42698
42756
  );
42699
- useEffect68(() => () => localProvider?.dispose(), [localProvider]);
42757
+ useEffect69(() => () => localProvider?.dispose(), [localProvider]);
42700
42758
  const ready = currentRemote?.status === "ready" ? currentRemote : void 0;
42701
42759
  const provider = ready?.provider ?? localProvider;
42702
42760
  const ingest = ready?.ingest ?? (localProvider ? { headers: previewHeaders, cells: previewRows } : void 0);
42703
42761
  const initialView = ready?.initialView ?? EMPTY_VIEW;
42704
42762
  const [view, setView] = useState79(initialView);
42705
- useEffect68(() => setView(initialView), [initialView, provider]);
42763
+ useEffect69(() => setView(initialView), [initialView, provider]);
42706
42764
  if (!provider || !ingest || !gridModule) return /* @__PURE__ */ jsx87(Fragment28, { children: fallback });
42707
42765
  const { style } = layer.content;
42708
42766
  const rowHeight = Math.max(32, style.fontSize * 2.1);
@@ -42839,11 +42897,11 @@ function PreviewPanel({
42839
42897
  const isNarrateMode = activeDisplayMode === "narrate";
42840
42898
  const isDashboardMode = activeDisplayMode === "dashboard";
42841
42899
  const isFlashcardsMode = activeDisplayMode === "flashcards";
42842
- useEffect69(() => {
42900
+ useEffect70(() => {
42843
42901
  if (presentation?.activeTarget === "window") return;
42844
42902
  setPlaybackState(null);
42845
42903
  }, [presentation?.activeTarget]);
42846
- useEffect69(() => {
42904
+ useEffect70(() => {
42847
42905
  if (presentation?.activeTarget !== "window" || !presentation.popupRoot) return;
42848
42906
  const mainRoot = mainSurfaceRef.current;
42849
42907
  const followerRoot = popupSurfaceRef.current;
@@ -43120,10 +43178,98 @@ function PreviewPanel({
43120
43178
  }
43121
43179
 
43122
43180
  // src/MediaBin.tsx
43123
- import { useState as useState81, useEffect as useEffect70, useRef as useRef64, useCallback as useCallback55 } from "react";
43181
+ import { useState as useState82, useEffect as useEffect72, useRef as useRef65, useCallback as useCallback55 } from "react";
43124
43182
  import { isSvgImageSource as isSvgImageSource3 } from "@bendyline/squisq/markdown";
43125
43183
  import { sanitizedSvgImageUrl as sanitizedSvgImageUrl2 } from "@bendyline/squisq-react";
43184
+
43185
+ // src/MediaPreviewDialog.tsx
43186
+ import { useEffect as useEffect71, useId as useId16, useRef as useRef64, useState as useState81 } from "react";
43126
43187
  import { jsx as jsx89, jsxs as jsxs72 } from "react/jsx-runtime";
43188
+ function MediaPreviewDialog({
43189
+ kind,
43190
+ name,
43191
+ detail,
43192
+ src,
43193
+ failed = false,
43194
+ isDark,
43195
+ onClose
43196
+ }) {
43197
+ const overlayRef = useRef64(null);
43198
+ const dialogRef = useRef64(null);
43199
+ const titleId = useId16();
43200
+ const [playbackFailed, setPlaybackFailed] = useState81(false);
43201
+ useModalDialog({ rootRef: overlayRef, dialogRef, onClose });
43202
+ useEffect71(() => setPlaybackFailed(false), [src]);
43203
+ let body;
43204
+ if (failed || playbackFailed || src === "") {
43205
+ body = /* @__PURE__ */ jsx89("div", { className: "squisq-media-preview-message", children: "This file can\u2019t be previewed." });
43206
+ } else if (src === null) {
43207
+ body = /* @__PURE__ */ jsx89("div", { className: "squisq-media-preview-message", children: "Loading\u2026" });
43208
+ } else if (kind === "image") {
43209
+ body = /* @__PURE__ */ jsx89(ImageViewer, { src, alt: name, theme: isDark ? "dark" : "light" });
43210
+ } else if (kind === "video") {
43211
+ body = /* @__PURE__ */ jsx89(
43212
+ "video",
43213
+ {
43214
+ className: "squisq-media-preview-video",
43215
+ src,
43216
+ controls: true,
43217
+ autoPlay: true,
43218
+ playsInline: true,
43219
+ onError: () => setPlaybackFailed(true)
43220
+ }
43221
+ );
43222
+ } else {
43223
+ body = /* @__PURE__ */ jsxs72("div", { className: "squisq-media-preview-audio", children: [
43224
+ /* @__PURE__ */ jsx89("span", { className: "squisq-media-preview-audio-icon", "aria-hidden": "true", children: "\u{1F50A}" }),
43225
+ /* @__PURE__ */ jsx89("audio", { src, controls: true, autoPlay: true, onError: () => setPlaybackFailed(true) })
43226
+ ] });
43227
+ }
43228
+ return /* @__PURE__ */ jsx89(
43229
+ "div",
43230
+ {
43231
+ ref: overlayRef,
43232
+ className: "squisq-media-preview",
43233
+ "data-theme": isDark ? "dark" : "light",
43234
+ onMouseDown: (event) => {
43235
+ if (event.target === event.currentTarget) onClose();
43236
+ },
43237
+ ...ownsContextMenuProps,
43238
+ children: /* @__PURE__ */ jsxs72(
43239
+ "div",
43240
+ {
43241
+ ref: dialogRef,
43242
+ className: `squisq-media-preview-surface squisq-media-preview-surface--${kind}`,
43243
+ role: "dialog",
43244
+ "aria-modal": "true",
43245
+ "aria-labelledby": titleId,
43246
+ tabIndex: -1,
43247
+ "data-testid": "media-preview-dialog",
43248
+ children: [
43249
+ /* @__PURE__ */ jsxs72("header", { className: "squisq-media-preview-header", children: [
43250
+ /* @__PURE__ */ jsx89("span", { id: titleId, className: "squisq-media-preview-title", title: name, children: name }),
43251
+ /* @__PURE__ */ jsx89("span", { className: "squisq-media-preview-detail", children: detail }),
43252
+ /* @__PURE__ */ jsx89(
43253
+ "button",
43254
+ {
43255
+ type: "button",
43256
+ className: "squisq-media-preview-close",
43257
+ onClick: onClose,
43258
+ "aria-label": "Close",
43259
+ children: "\xD7"
43260
+ }
43261
+ )
43262
+ ] }),
43263
+ /* @__PURE__ */ jsx89("div", { className: "squisq-media-preview-body", children: body })
43264
+ ]
43265
+ }
43266
+ )
43267
+ }
43268
+ );
43269
+ }
43270
+
43271
+ // src/MediaBin.tsx
43272
+ import { Fragment as Fragment29, jsx as jsx90, jsxs as jsxs73 } from "react/jsx-runtime";
43127
43273
  function formatSize(bytes) {
43128
43274
  if (bytes < 1024) return `${bytes} B`;
43129
43275
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
@@ -43195,23 +43341,24 @@ function MediaBin({
43195
43341
  allowBinaryDownloads = true,
43196
43342
  highlightPath = null
43197
43343
  }) {
43198
- const [entries, setEntries] = useState81([]);
43199
- const listRef = useRef64(null);
43200
- useEffect70(() => {
43344
+ const [entries, setEntries] = useState82([]);
43345
+ const listRef = useRef65(null);
43346
+ useEffect72(() => {
43201
43347
  if (!highlightPath || !listRef.current) return;
43202
43348
  const item = listRef.current.querySelector(`[data-media-path="${CSS.escape(highlightPath)}"]`);
43203
43349
  if (item instanceof HTMLElement) {
43204
43350
  item.scrollIntoView({ block: "nearest" });
43205
43351
  }
43206
43352
  }, [highlightPath, entries]);
43207
- const [thumbUrls, setThumbUrls] = useState81({});
43208
- const [loading, setLoading] = useState81(false);
43209
- const [isDropActive, setIsDropActive] = useState81(false);
43210
- const [downloadingPath, setDownloadingPath] = useState81(null);
43211
- const [contextMenu, setContextMenu] = useState81(null);
43212
- const fileInputRef = useRef64(null);
43213
- const contextMenuRef = useRef64(null);
43214
- const dropDepthRef = useRef64(0);
43353
+ const [thumbUrls, setThumbUrls] = useState82({});
43354
+ const [loading, setLoading] = useState82(false);
43355
+ const [isDropActive, setIsDropActive] = useState82(false);
43356
+ const [downloadingPath, setDownloadingPath] = useState82(null);
43357
+ const [contextMenu, setContextMenu] = useState82(null);
43358
+ const [preview, setPreview] = useState82(null);
43359
+ const fileInputRef = useRef65(null);
43360
+ const contextMenuRef = useRef65(null);
43361
+ const dropDepthRef = useRef65(0);
43215
43362
  const updateEntries = useCallback55(
43216
43363
  async (provider) => {
43217
43364
  const list = sortMediaEntries(filterVisibleMediaEntries(await provider.listMedia()));
@@ -43230,7 +43377,7 @@ function MediaBin({
43230
43377
  },
43231
43378
  [onCountChange]
43232
43379
  );
43233
- useEffect70(() => {
43380
+ useEffect72(() => {
43234
43381
  if (!contextMenu) return;
43235
43382
  const handlePointerDown = (event) => {
43236
43383
  if (contextMenuRef.current?.contains(event.target)) return;
@@ -43251,7 +43398,7 @@ function MediaBin({
43251
43398
  window.removeEventListener("resize", close);
43252
43399
  };
43253
43400
  }, [contextMenu]);
43254
- useEffect70(() => {
43401
+ useEffect72(() => {
43255
43402
  if (!mediaProvider) {
43256
43403
  setEntries([]);
43257
43404
  setThumbUrls({});
@@ -43408,6 +43555,27 @@ function MediaBin({
43408
43555
  const openContextMenu = useCallback55((entry, x, y) => {
43409
43556
  setContextMenu({ entry, x, y });
43410
43557
  }, []);
43558
+ useEffect72(() => {
43559
+ setPreview(null);
43560
+ }, [mediaProvider]);
43561
+ const openPreview = useCallback55(
43562
+ async (entry) => {
43563
+ if (!mediaProvider || squisqMediaKind(entry.mimeType) === "file") return;
43564
+ const thumb = thumbUrls[entry.name];
43565
+ setPreview({ entry, src: thumb ?? null, failed: false });
43566
+ if (thumb !== void 0) return;
43567
+ let src = null;
43568
+ try {
43569
+ src = isImageMime(entry.mimeType) ? await resolveThumbnailUrl(mediaProvider, entry.name) : await mediaProvider.resolveUrl(entry.name);
43570
+ } catch {
43571
+ }
43572
+ setPreview(
43573
+ (current) => current?.entry.name === entry.name ? { entry, src, failed: src === null } : current
43574
+ );
43575
+ },
43576
+ [mediaProvider, thumbUrls]
43577
+ );
43578
+ const closePreview = useCallback55(() => setPreview(null), []);
43411
43579
  const removeLabel = contextMenu ? isImageMime(contextMenu.entry.mimeType) ? "Remove image" : "Remove file" : "Remove file";
43412
43580
  const menuLeft = contextMenu ? Math.min(contextMenu.x, Math.max(8, window.innerWidth - 168)) : 0;
43413
43581
  const menuTop = contextMenu ? Math.min(contextMenu.y, Math.max(8, window.innerHeight - 48)) : 0;
@@ -43417,189 +43585,217 @@ function MediaBin({
43417
43585
  };
43418
43586
  const handleItemKeyDown = useCallback55(
43419
43587
  (entry, event) => {
43588
+ if (event.key === "Enter" || event.key === " ") {
43589
+ if (event.target !== event.currentTarget) return;
43590
+ if (squisqMediaKind(entry.mimeType) === "file") return;
43591
+ event.preventDefault();
43592
+ void openPreview(entry);
43593
+ return;
43594
+ }
43420
43595
  if (event.key !== "ContextMenu" && !(event.shiftKey && event.key === "F10")) return;
43421
43596
  event.preventDefault();
43422
43597
  const rect = event.currentTarget.getBoundingClientRect();
43423
43598
  openContextMenu(entry, rect.left + 16, rect.top + 16);
43424
43599
  },
43425
- [openContextMenu]
43600
+ [openContextMenu, openPreview]
43426
43601
  );
43427
- return /* @__PURE__ */ jsxs72(
43428
- "div",
43429
- {
43430
- className: [
43431
- "squisq-media-bin",
43432
- isDark ? "squisq-media-bin--dark" : "",
43433
- isDropActive ? "squisq-media-bin--drop-active" : ""
43434
- ].filter(Boolean).join(" "),
43435
- onDragEnter: handleDragEnter,
43436
- onDragOver: handleDragOver,
43437
- onDragLeave: handleDragLeave,
43438
- onDrop: handleDrop,
43439
- "aria-busy": loading,
43440
- ...ownsContextMenuProps,
43441
- children: [
43442
- /* @__PURE__ */ jsxs72("div", { className: "squisq-media-bin-header", children: [
43443
- /* @__PURE__ */ jsxs72("span", { className: "squisq-media-bin-title", children: [
43444
- "Attachments ",
43445
- entries.length > 0 && `(${entries.length})`
43446
- ] }),
43447
- /* @__PURE__ */ jsxs72("div", { className: "squisq-media-bin-actions", children: [
43448
- onRecord && /* @__PURE__ */ jsxs72(
43449
- "button",
43450
- {
43451
- type: "button",
43452
- className: "squisq-media-bin-record",
43453
- onClick: onRecord,
43454
- disabled: !mediaProvider,
43455
- title: mediaProvider ? "Record media" : "Load a content zip or select a storage slot first",
43456
- "aria-label": "Record media",
43457
- "aria-haspopup": "dialog",
43458
- "aria-expanded": isRecorderOpen,
43459
- children: [
43460
- /* @__PURE__ */ jsx89("span", { className: "squisq-media-bin-action-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx89("span", { className: "squisq-media-bin-record-dot" }) }),
43461
- /* @__PURE__ */ jsx89("span", { children: "Record" })
43462
- ]
43463
- }
43464
- ),
43465
- /* @__PURE__ */ jsxs72(
43466
- "button",
43467
- {
43468
- type: "button",
43469
- className: "squisq-media-bin-upload",
43470
- onClick: handleUploadClick,
43471
- disabled: !mediaProvider || loading,
43472
- title: mediaProvider ? "Upload files" : "Load a content zip or select a storage slot first",
43473
- children: [
43474
- /* @__PURE__ */ jsx89("span", { className: "squisq-media-bin-action-icon", children: "+" }),
43475
- /* @__PURE__ */ jsx89("span", { children: "Upload" })
43476
- ]
43477
- }
43478
- )
43479
- ] })
43480
- ] }),
43481
- /* @__PURE__ */ jsxs72("div", { className: "squisq-media-bin-list", ref: listRef, children: [
43482
- !mediaProvider && /* @__PURE__ */ jsxs72("div", { className: "squisq-media-bin-empty", children: [
43483
- "No media context.",
43484
- /* @__PURE__ */ jsx89("br", {}),
43485
- "Load a content zip or select a storage slot."
43602
+ const previewKind = preview ? squisqMediaKind(preview.entry.mimeType) : "file";
43603
+ return /* @__PURE__ */ jsxs73(Fragment29, { children: [
43604
+ /* @__PURE__ */ jsxs73(
43605
+ "div",
43606
+ {
43607
+ className: [
43608
+ "squisq-media-bin",
43609
+ isDark ? "squisq-media-bin--dark" : "",
43610
+ isDropActive ? "squisq-media-bin--drop-active" : ""
43611
+ ].filter(Boolean).join(" "),
43612
+ onDragEnter: handleDragEnter,
43613
+ onDragOver: handleDragOver,
43614
+ onDragLeave: handleDragLeave,
43615
+ onDrop: handleDrop,
43616
+ "aria-busy": loading,
43617
+ ...ownsContextMenuProps,
43618
+ children: [
43619
+ /* @__PURE__ */ jsxs73("div", { className: "squisq-media-bin-header", children: [
43620
+ /* @__PURE__ */ jsxs73("span", { className: "squisq-media-bin-title", children: [
43621
+ "Attachments ",
43622
+ entries.length > 0 && `(${entries.length})`
43623
+ ] }),
43624
+ /* @__PURE__ */ jsxs73("div", { className: "squisq-media-bin-actions", children: [
43625
+ onRecord && /* @__PURE__ */ jsxs73(
43626
+ "button",
43627
+ {
43628
+ type: "button",
43629
+ className: "squisq-media-bin-record",
43630
+ onClick: onRecord,
43631
+ disabled: !mediaProvider,
43632
+ title: mediaProvider ? "Record media" : "Load a content zip or select a storage slot first",
43633
+ "aria-label": "Record media",
43634
+ "aria-haspopup": "dialog",
43635
+ "aria-expanded": isRecorderOpen,
43636
+ children: [
43637
+ /* @__PURE__ */ jsx90("span", { className: "squisq-media-bin-action-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx90("span", { className: "squisq-media-bin-record-dot" }) }),
43638
+ /* @__PURE__ */ jsx90("span", { children: "Record" })
43639
+ ]
43640
+ }
43641
+ ),
43642
+ /* @__PURE__ */ jsxs73(
43643
+ "button",
43644
+ {
43645
+ type: "button",
43646
+ className: "squisq-media-bin-upload",
43647
+ onClick: handleUploadClick,
43648
+ disabled: !mediaProvider || loading,
43649
+ title: mediaProvider ? "Upload files" : "Load a content zip or select a storage slot first",
43650
+ children: [
43651
+ /* @__PURE__ */ jsx90("span", { className: "squisq-media-bin-action-icon", children: "+" }),
43652
+ /* @__PURE__ */ jsx90("span", { children: "Upload" })
43653
+ ]
43654
+ }
43655
+ )
43656
+ ] })
43486
43657
  ] }),
43487
- mediaProvider && entries.length === 0 && !loading && /* @__PURE__ */ jsx89("div", { className: "squisq-media-bin-empty", children: "No files yet." }),
43488
- entries.map((entry) => {
43489
- const thumb = thumbUrls[entry.name];
43490
- const basename = basenameForPath(entry.name);
43491
- const altText = basename.replace(/\.[^.]+$/, "").replace(/[-_]/g, " ");
43492
- const isUnused = !!usedMediaPaths && !usedMediaPaths.has(entry.name);
43493
- const handleDragStart = (e2) => {
43494
- const payload = {
43495
- name: entry.name,
43496
- mimeType: entry.mimeType,
43497
- alt: altText
43658
+ /* @__PURE__ */ jsxs73("div", { className: "squisq-media-bin-list", ref: listRef, children: [
43659
+ !mediaProvider && /* @__PURE__ */ jsxs73("div", { className: "squisq-media-bin-empty", children: [
43660
+ "No media context.",
43661
+ /* @__PURE__ */ jsx90("br", {}),
43662
+ "Load a content zip or select a storage slot."
43663
+ ] }),
43664
+ mediaProvider && entries.length === 0 && !loading && /* @__PURE__ */ jsx90("div", { className: "squisq-media-bin-empty", children: "No files yet." }),
43665
+ entries.map((entry) => {
43666
+ const thumb = thumbUrls[entry.name];
43667
+ const basename = basenameForPath(entry.name);
43668
+ const altText = basename.replace(/\.[^.]+$/, "").replace(/[-_]/g, " ");
43669
+ const isUnused = !!usedMediaPaths && !usedMediaPaths.has(entry.name);
43670
+ const isPreviewable = squisqMediaKind(entry.mimeType) !== "file";
43671
+ const handleDragStart = (e2) => {
43672
+ const payload = {
43673
+ name: entry.name,
43674
+ mimeType: entry.mimeType,
43675
+ alt: altText
43676
+ };
43677
+ e2.dataTransfer.setData(SQUISQ_MEDIA_MIME, JSON.stringify(payload));
43678
+ e2.dataTransfer.setData("text/plain", buildSquisqMediaReference(payload));
43679
+ e2.dataTransfer.effectAllowed = "copy";
43498
43680
  };
43499
- e2.dataTransfer.setData(SQUISQ_MEDIA_MIME, JSON.stringify(payload));
43500
- e2.dataTransfer.setData("text/plain", buildSquisqMediaReference(payload));
43501
- e2.dataTransfer.effectAllowed = "copy";
43502
- };
43503
- return /* @__PURE__ */ jsxs72(
43504
- "div",
43505
- {
43506
- "data-media-path": entry.name,
43507
- className: entry.name === highlightPath ? "squisq-media-bin-item squisq-media-bin-item--highlight" : "squisq-media-bin-item",
43508
- title: `${entry.name}
43681
+ return /* @__PURE__ */ jsxs73(
43682
+ "div",
43683
+ {
43684
+ "data-media-path": entry.name,
43685
+ className: [
43686
+ "squisq-media-bin-item",
43687
+ isPreviewable ? "squisq-media-bin-item--previewable" : "",
43688
+ entry.name === highlightPath ? "squisq-media-bin-item--highlight" : ""
43689
+ ].filter(Boolean).join(" "),
43690
+ title: `${entry.name}
43509
43691
  ${entry.mimeType}
43510
43692
  ${formatSize(entry.size)}`,
43511
- draggable: true,
43512
- tabIndex: 0,
43513
- onContextMenu: (e2) => {
43514
- e2.preventDefault();
43515
- openContextMenu(entry, e2.clientX, e2.clientY);
43693
+ draggable: true,
43694
+ tabIndex: 0,
43695
+ onClick: isPreviewable ? () => void openPreview(entry) : void 0,
43696
+ onContextMenu: (e2) => {
43697
+ e2.preventDefault();
43698
+ openContextMenu(entry, e2.clientX, e2.clientY);
43699
+ },
43700
+ onDragStart: handleDragStart,
43701
+ onKeyDown: (e2) => handleItemKeyDown(entry, e2),
43702
+ children: [
43703
+ thumb ? /* @__PURE__ */ jsx90(
43704
+ "img",
43705
+ {
43706
+ src: thumb,
43707
+ alt: basename,
43708
+ className: "squisq-media-bin-thumb",
43709
+ draggable: false
43710
+ }
43711
+ ) : /* @__PURE__ */ jsx90("span", { className: "squisq-media-bin-icon", children: iconForMime(entry.mimeType) }),
43712
+ /* @__PURE__ */ jsxs73("div", { className: "squisq-media-bin-meta", children: [
43713
+ /* @__PURE__ */ jsx90("div", { className: "squisq-media-bin-name", children: basename }),
43714
+ /* @__PURE__ */ jsxs73("div", { className: "squisq-media-bin-detail-row", children: [
43715
+ /* @__PURE__ */ jsx90("span", { className: "squisq-media-bin-size", children: formatSize(entry.size) }),
43716
+ isUnused && /* @__PURE__ */ jsx90("span", { className: "squisq-media-bin-unused-badge", title: "Not used in document", children: "Unused" })
43717
+ ] })
43718
+ ] }),
43719
+ allowBinaryDownloads && /* @__PURE__ */ jsx90(
43720
+ "button",
43721
+ {
43722
+ type: "button",
43723
+ className: "squisq-media-bin-download",
43724
+ title: `Download ${basename}`,
43725
+ "aria-label": `Download ${basename}`,
43726
+ disabled: !mediaProvider || downloadingPath !== null,
43727
+ draggable: false,
43728
+ onClick: (event) => {
43729
+ event.stopPropagation();
43730
+ void handleDownloadEntry(entry);
43731
+ },
43732
+ onDragStart: (event) => event.preventDefault(),
43733
+ children: /* @__PURE__ */ jsx90("span", { "aria-hidden": "true", children: downloadingPath === entry.name ? "\u2026" : "\u2193" })
43734
+ }
43735
+ )
43736
+ ]
43516
43737
  },
43517
- onDragStart: handleDragStart,
43518
- onKeyDown: (e2) => handleItemKeyDown(entry, e2),
43519
- children: [
43520
- thumb ? /* @__PURE__ */ jsx89(
43521
- "img",
43522
- {
43523
- src: thumb,
43524
- alt: basename,
43525
- className: "squisq-media-bin-thumb",
43526
- draggable: false
43527
- }
43528
- ) : /* @__PURE__ */ jsx89("span", { className: "squisq-media-bin-icon", children: iconForMime(entry.mimeType) }),
43529
- /* @__PURE__ */ jsxs72("div", { className: "squisq-media-bin-meta", children: [
43530
- /* @__PURE__ */ jsx89("div", { className: "squisq-media-bin-name", children: basename }),
43531
- /* @__PURE__ */ jsxs72("div", { className: "squisq-media-bin-detail-row", children: [
43532
- /* @__PURE__ */ jsx89("span", { className: "squisq-media-bin-size", children: formatSize(entry.size) }),
43533
- isUnused && /* @__PURE__ */ jsx89("span", { className: "squisq-media-bin-unused-badge", title: "Not used in document", children: "Unused" })
43534
- ] })
43535
- ] }),
43536
- allowBinaryDownloads && /* @__PURE__ */ jsx89(
43537
- "button",
43538
- {
43539
- type: "button",
43540
- className: "squisq-media-bin-download",
43541
- title: `Download ${basename}`,
43542
- "aria-label": `Download ${basename}`,
43543
- disabled: !mediaProvider || downloadingPath !== null,
43544
- draggable: false,
43545
- onClick: (event) => {
43546
- event.stopPropagation();
43547
- void handleDownloadEntry(entry);
43548
- },
43549
- onDragStart: (event) => event.preventDefault(),
43550
- children: /* @__PURE__ */ jsx89("span", { "aria-hidden": "true", children: downloadingPath === entry.name ? "\u2026" : "\u2193" })
43551
- }
43552
- )
43553
- ]
43554
- },
43555
- entry.name
43556
- );
43557
- })
43558
- ] }),
43559
- isDropActive && /* @__PURE__ */ jsxs72("div", { className: "squisq-media-bin-drop-target", "aria-hidden": "true", children: [
43560
- /* @__PURE__ */ jsx89("span", { className: "squisq-media-bin-drop-target-icon", children: "+" }),
43561
- /* @__PURE__ */ jsx89("strong", { children: "Drop media here" }),
43562
- /* @__PURE__ */ jsx89("span", { children: "Attach to this document" })
43563
- ] }),
43564
- contextMenu && /* @__PURE__ */ jsx89(
43565
- "div",
43566
- {
43567
- ref: contextMenuRef,
43568
- className: "squisq-media-bin-context-menu",
43569
- role: "menu",
43570
- "aria-label": `${contextMenu.entry.name} actions`,
43571
- style: contextMenuStyle,
43572
- children: /* @__PURE__ */ jsx89(
43573
- "button",
43574
- {
43575
- type: "button",
43576
- role: "menuitem",
43577
- className: "squisq-media-bin-context-menu-item squisq-media-bin-context-menu-item--danger",
43578
- onClick: () => handleRemoveEntry(contextMenu.entry),
43579
- disabled: !mediaProvider || loading,
43580
- children: removeLabel
43581
- }
43582
- )
43583
- }
43584
- ),
43585
- /* @__PURE__ */ jsx89(
43586
- "input",
43587
- {
43588
- ref: fileInputRef,
43589
- type: "file",
43590
- multiple: true,
43591
- style: { display: "none" },
43592
- onChange: handleFileChange
43593
- }
43594
- )
43595
- ]
43596
- }
43597
- );
43738
+ entry.name
43739
+ );
43740
+ })
43741
+ ] }),
43742
+ isDropActive && /* @__PURE__ */ jsxs73("div", { className: "squisq-media-bin-drop-target", "aria-hidden": "true", children: [
43743
+ /* @__PURE__ */ jsx90("span", { className: "squisq-media-bin-drop-target-icon", children: "+" }),
43744
+ /* @__PURE__ */ jsx90("strong", { children: "Drop media here" }),
43745
+ /* @__PURE__ */ jsx90("span", { children: "Attach to this document" })
43746
+ ] }),
43747
+ contextMenu && /* @__PURE__ */ jsx90(
43748
+ "div",
43749
+ {
43750
+ ref: contextMenuRef,
43751
+ className: "squisq-media-bin-context-menu",
43752
+ role: "menu",
43753
+ "aria-label": `${contextMenu.entry.name} actions`,
43754
+ style: contextMenuStyle,
43755
+ children: /* @__PURE__ */ jsx90(
43756
+ "button",
43757
+ {
43758
+ type: "button",
43759
+ role: "menuitem",
43760
+ className: "squisq-media-bin-context-menu-item squisq-media-bin-context-menu-item--danger",
43761
+ onClick: () => handleRemoveEntry(contextMenu.entry),
43762
+ disabled: !mediaProvider || loading,
43763
+ children: removeLabel
43764
+ }
43765
+ )
43766
+ }
43767
+ ),
43768
+ /* @__PURE__ */ jsx90(
43769
+ "input",
43770
+ {
43771
+ ref: fileInputRef,
43772
+ type: "file",
43773
+ multiple: true,
43774
+ style: { display: "none" },
43775
+ onChange: handleFileChange
43776
+ }
43777
+ )
43778
+ ]
43779
+ }
43780
+ ),
43781
+ preview && previewKind !== "file" && /* @__PURE__ */ jsx90(
43782
+ MediaPreviewDialog,
43783
+ {
43784
+ kind: previewKind,
43785
+ name: basenameForPath(preview.entry.name),
43786
+ detail: `${formatSize(preview.entry.size)} \xB7 ${preview.entry.mimeType}`,
43787
+ src: preview.src,
43788
+ failed: preview.failed,
43789
+ isDark,
43790
+ onClose: closePreview
43791
+ }
43792
+ )
43793
+ ] });
43598
43794
  }
43599
43795
 
43600
43796
  // src/DropZoneOverlay.tsx
43601
- import { useState as useState82 } from "react";
43602
- import { Fragment as Fragment29, jsx as jsx90, jsxs as jsxs73 } from "react/jsx-runtime";
43797
+ import { useState as useState83 } from "react";
43798
+ import { Fragment as Fragment30, jsx as jsx91, jsxs as jsxs74 } from "react/jsx-runtime";
43603
43799
  function DropZoneOverlay({
43604
43800
  dragContentType,
43605
43801
  zoneProps,
@@ -43607,8 +43803,8 @@ function DropZoneOverlay({
43607
43803
  }) {
43608
43804
  const showMedia = dragContentType === "media" || dragContentType === "mixed";
43609
43805
  const showText = dragContentType === "text" || dragContentType === "mixed";
43610
- return /* @__PURE__ */ jsx90("div", { className: "squisq-drop-overlay", children: /* @__PURE__ */ jsxs73("div", { className: "squisq-drop-overlay-inner", children: [
43611
- showMedia && /* @__PURE__ */ jsx90(
43806
+ return /* @__PURE__ */ jsx91("div", { className: "squisq-drop-overlay", children: /* @__PURE__ */ jsxs74("div", { className: "squisq-drop-overlay-inner", children: [
43807
+ showMedia && /* @__PURE__ */ jsx91(
43612
43808
  DropZone,
43613
43809
  {
43614
43810
  target: "media",
@@ -43620,8 +43816,8 @@ function DropZoneOverlay({
43620
43816
  variant: "media"
43621
43817
  }
43622
43818
  ),
43623
- showText && /* @__PURE__ */ jsxs73(Fragment29, { children: [
43624
- /* @__PURE__ */ jsx90(
43819
+ showText && /* @__PURE__ */ jsxs74(Fragment30, { children: [
43820
+ /* @__PURE__ */ jsx91(
43625
43821
  DropZone,
43626
43822
  {
43627
43823
  target: "insert",
@@ -43632,7 +43828,7 @@ function DropZoneOverlay({
43632
43828
  variant: "insert"
43633
43829
  }
43634
43830
  ),
43635
- /* @__PURE__ */ jsx90(
43831
+ /* @__PURE__ */ jsx91(
43636
43832
  DropZone,
43637
43833
  {
43638
43834
  target: "replace",
@@ -43655,9 +43851,9 @@ function DropZone({
43655
43851
  disabled,
43656
43852
  variant
43657
43853
  }) {
43658
- const [isHovering, setIsHovering] = useState82(false);
43854
+ const [isHovering, setIsHovering] = useState83(false);
43659
43855
  const props = zoneProps(target);
43660
- return /* @__PURE__ */ jsxs73(
43856
+ return /* @__PURE__ */ jsxs74(
43661
43857
  "div",
43662
43858
  {
43663
43859
  className: [
@@ -43690,16 +43886,16 @@ function DropZone({
43690
43886
  props.onDrop(e2);
43691
43887
  },
43692
43888
  children: [
43693
- /* @__PURE__ */ jsx90("span", { className: "squisq-drop-zone-icon", children: icon }),
43694
- /* @__PURE__ */ jsx90("span", { className: "squisq-drop-zone-label", children: label }),
43695
- /* @__PURE__ */ jsx90("span", { className: "squisq-drop-zone-desc", children: description })
43889
+ /* @__PURE__ */ jsx91("span", { className: "squisq-drop-zone-icon", children: icon }),
43890
+ /* @__PURE__ */ jsx91("span", { className: "squisq-drop-zone-label", children: label }),
43891
+ /* @__PURE__ */ jsx91("span", { className: "squisq-drop-zone-desc", children: description })
43696
43892
  ]
43697
43893
  }
43698
43894
  );
43699
43895
  }
43700
43896
 
43701
43897
  // src/Tooltip.tsx
43702
- import { useEffect as useEffect71, useLayoutEffect as useLayoutEffect16, useRef as useRef65, useState as useState83 } from "react";
43898
+ import { useEffect as useEffect73, useLayoutEffect as useLayoutEffect16, useRef as useRef66, useState as useState84 } from "react";
43703
43899
  import { createPortal as createPortal19 } from "react-dom";
43704
43900
 
43705
43901
  // src/tooltipPlacement.ts
@@ -43712,16 +43908,16 @@ function clampTooltipLeft(anchorX, tooltipWidth, viewportWidth, edgePadding = ED
43712
43908
  }
43713
43909
 
43714
43910
  // src/Tooltip.tsx
43715
- import { jsx as jsx91 } from "react/jsx-runtime";
43911
+ import { jsx as jsx92 } from "react/jsx-runtime";
43716
43912
  var SHOW_DELAY_MS = 180;
43717
43913
  function TooltipLayer() {
43718
- const [state, setState3] = useState83(null);
43719
- const tooltipRef = useRef65(null);
43720
- const timerRef = useRef65(null);
43721
- const currentTargetRef = useRef65(null);
43722
- const visibleRef = useRef65(false);
43723
- const pressedTargetRef = useRef65(null);
43724
- const lastPointerWasTouchRef = useRef65(false);
43914
+ const [state, setState3] = useState84(null);
43915
+ const tooltipRef = useRef66(null);
43916
+ const timerRef = useRef66(null);
43917
+ const currentTargetRef = useRef66(null);
43918
+ const visibleRef = useRef66(false);
43919
+ const pressedTargetRef = useRef66(null);
43920
+ const lastPointerWasTouchRef = useRef66(false);
43725
43921
  useLayoutEffect16(() => {
43726
43922
  if (!state) return;
43727
43923
  const node2 = tooltipRef.current;
@@ -43733,7 +43929,7 @@ function TooltipLayer() {
43733
43929
  node2.style.left = `${left}px`;
43734
43930
  node2.style.visibility = "visible";
43735
43931
  }, [state]);
43736
- useEffect71(() => {
43932
+ useEffect73(() => {
43737
43933
  const clearTimer = () => {
43738
43934
  if (timerRef.current) {
43739
43935
  clearTimeout(timerRef.current);
@@ -43815,7 +44011,7 @@ function TooltipLayer() {
43815
44011
  }, []);
43816
44012
  if (!state) return null;
43817
44013
  return createPortal19(
43818
- /* @__PURE__ */ jsx91(
44014
+ /* @__PURE__ */ jsx92(
43819
44015
  "div",
43820
44016
  {
43821
44017
  role: "tooltip",
@@ -43835,13 +44031,13 @@ function TooltipLayer() {
43835
44031
  }
43836
44032
 
43837
44033
  // src/EditorShell.tsx
43838
- import { useEffect as useEffect78, useRef as useRef74, useState as useState90, useCallback as useCallback63, useMemo as useMemo62 } from "react";
44034
+ import { useEffect as useEffect80, useRef as useRef75, useState as useState91, useCallback as useCallback63, useMemo as useMemo62 } from "react";
43839
44035
 
43840
44036
  // src/BlockPreviewPanel.tsx
43841
44037
  import { useMemo as useMemo58 } from "react";
43842
44038
  import { VIEWPORT_PRESETS as VIEWPORT_PRESETS7 } from "@bendyline/squisq/schemas";
43843
44039
  import { flattenBlocks as flattenBlocks6, DEFAULT_THEME as DEFAULT_THEME7 } from "@bendyline/squisq/doc";
43844
- import { jsx as jsx92 } from "react/jsx-runtime";
44040
+ import { jsx as jsx93 } from "react/jsx-runtime";
43845
44041
  function BlockPreviewPanel({ basePath = "/" }) {
43846
44042
  const { doc, activeBlockStartLine, mediaProvider, workspaceContainer, fileName, mediaRevision } = useEditorContext();
43847
44043
  const previewSettings = usePreviewSettingsOptional();
@@ -43860,12 +44056,12 @@ function BlockPreviewPanel({ basePath = "/" }) {
43860
44056
  [previewDoc, block, theme, viewport]
43861
44057
  );
43862
44058
  if (!visual) return null;
43863
- return /* @__PURE__ */ jsx92("div", { className: "squisq-block-preview-panel", "data-testid": "block-preview-panel", "aria-hidden": true, children: /* @__PURE__ */ jsx92(
44059
+ return /* @__PURE__ */ jsx93("div", { className: "squisq-block-preview-panel", "data-testid": "block-preview-panel", "aria-hidden": true, children: /* @__PURE__ */ jsx93(
43864
44060
  "div",
43865
44061
  {
43866
44062
  className: "squisq-block-preview-frame",
43867
44063
  style: { aspectRatio: `${viewport.width} / ${viewport.height}` },
43868
- children: /* @__PURE__ */ jsx92(
44064
+ children: /* @__PURE__ */ jsx93(
43869
44065
  BlockThumbnail,
43870
44066
  {
43871
44067
  visual,
@@ -43879,14 +44075,14 @@ function BlockPreviewPanel({ basePath = "/" }) {
43879
44075
  }
43880
44076
 
43881
44077
  // src/NavigationSheet.tsx
43882
- import { useCallback as useCallback57, useEffect as useEffect73, useId as useId16, useRef as useRef68, useState as useState84 } from "react";
44078
+ import { useCallback as useCallback57, useEffect as useEffect75, useId as useId17, useRef as useRef69, useState as useState85 } from "react";
43883
44079
 
43884
44080
  // src/BlockPreviewList.tsx
43885
- import { useCallback as useCallback56, useRef as useRef66 } from "react";
44081
+ import { useCallback as useCallback56, useRef as useRef67 } from "react";
43886
44082
  import { VIEWPORT_PRESETS as VIEWPORT_PRESETS8 } from "@bendyline/squisq/schemas";
43887
44083
  import { flattenBlocks as flattenBlocks7 } from "@bendyline/squisq/doc";
43888
44084
  import { BlockRenderer as BlockRenderer5, MediaContext as MediaContext6 } from "@bendyline/squisq-react";
43889
- import { Fragment as Fragment30, jsx as jsx93, jsxs as jsxs74 } from "react/jsx-runtime";
44085
+ import { Fragment as Fragment31, jsx as jsx94, jsxs as jsxs75 } from "react/jsx-runtime";
43890
44086
  function BlockPreviewList({
43891
44087
  basePath = "/",
43892
44088
  viewport = VIEWPORT_PRESETS8.landscape,
@@ -43895,7 +44091,7 @@ function BlockPreviewList({
43895
44091
  }) {
43896
44092
  const { doc, activeView, layoutMode, goToBlockByLine, monacoEditor } = useEditorContext();
43897
44093
  const items = useBlockPreviewItems(viewport);
43898
- const listRef = useRef66(null);
44094
+ const listRef = useRef67(null);
43899
44095
  const handleSelect = useCallback56(
43900
44096
  (item) => {
43901
44097
  const line = blockStartLine(item.sourceBlock);
@@ -43922,9 +44118,9 @@ function BlockPreviewList({
43922
44118
  [activeView, doc, goToBlockByLine, layoutMode, monacoEditor, onNavigate]
43923
44119
  );
43924
44120
  if (items.length === 0) {
43925
- return /* @__PURE__ */ jsx93("div", { className: "squisq-preview-list-empty", children: /* @__PURE__ */ jsx93("p", { children: "Add some content to see block previews." }) });
44121
+ return /* @__PURE__ */ jsx94("div", { className: "squisq-preview-list-empty", children: /* @__PURE__ */ jsx94("p", { children: "Add some content to see block previews." }) });
43926
44122
  }
43927
- return /* @__PURE__ */ jsx93(MediaContext6.Provider, { value: mediaProvider, children: /* @__PURE__ */ jsx93("ul", { ref: listRef, className: "squisq-preview-list", "aria-label": "Block previews", children: items.map((item) => /* @__PURE__ */ jsx93("li", { children: /* @__PURE__ */ jsxs74(
44123
+ return /* @__PURE__ */ jsx94(MediaContext6.Provider, { value: mediaProvider, children: /* @__PURE__ */ jsx94("ul", { ref: listRef, className: "squisq-preview-list", "aria-label": "Block previews", children: items.map((item) => /* @__PURE__ */ jsx94("li", { children: /* @__PURE__ */ jsxs75(
43928
44124
  "button",
43929
44125
  {
43930
44126
  type: "button",
@@ -43932,20 +44128,20 @@ function BlockPreviewList({
43932
44128
  "data-template": item.template,
43933
44129
  onClick: () => handleSelect(item),
43934
44130
  children: [
43935
- /* @__PURE__ */ jsxs74("span", { className: "squisq-inline-preview-card-label", children: [
43936
- /* @__PURE__ */ jsx93("span", { className: "squisq-inline-preview-card-template", children: templateLabel(item.template) }),
43937
- item.headingText && /* @__PURE__ */ jsxs74(Fragment30, { children: [
43938
- /* @__PURE__ */ jsx93("span", { className: "squisq-inline-preview-card-sep", "aria-hidden": "true", children: "\u2014" }),
43939
- /* @__PURE__ */ jsx93("span", { className: "squisq-inline-preview-card-title", children: item.headingText })
44131
+ /* @__PURE__ */ jsxs75("span", { className: "squisq-inline-preview-card-label", children: [
44132
+ /* @__PURE__ */ jsx94("span", { className: "squisq-inline-preview-card-template", children: templateLabel(item.template) }),
44133
+ item.headingText && /* @__PURE__ */ jsxs75(Fragment31, { children: [
44134
+ /* @__PURE__ */ jsx94("span", { className: "squisq-inline-preview-card-sep", "aria-hidden": "true", children: "\u2014" }),
44135
+ /* @__PURE__ */ jsx94("span", { className: "squisq-inline-preview-card-title", children: item.headingText })
43940
44136
  ] })
43941
44137
  ] }),
43942
- /* @__PURE__ */ jsx93(
44138
+ /* @__PURE__ */ jsx94(
43943
44139
  "span",
43944
44140
  {
43945
44141
  className: "squisq-inline-preview-card-svg",
43946
44142
  "aria-hidden": "true",
43947
44143
  style: { aspectRatio: `${viewport.width} / ${viewport.height}` },
43948
- children: /* @__PURE__ */ jsx93(
44144
+ children: /* @__PURE__ */ jsx94(
43949
44145
  BlockRenderer5,
43950
44146
  {
43951
44147
  block: item.block,
@@ -43963,7 +44159,7 @@ function BlockPreviewList({
43963
44159
  }
43964
44160
 
43965
44161
  // src/useNavigationSheetSwipe.ts
43966
- import { useEffect as useEffect72, useRef as useRef67 } from "react";
44162
+ import { useEffect as useEffect74, useRef as useRef68 } from "react";
43967
44163
  var NAVIGATION_SHEET_MAX_BODY_WIDTH = 720;
43968
44164
  var EDGE_ZONE_PX = 24;
43969
44165
  var AXIS_LOCK_PX = 10;
@@ -43978,9 +44174,9 @@ function useNavigationSheetSwipe({
43978
44174
  onOpen,
43979
44175
  onClose
43980
44176
  }) {
43981
- const callbacksRef = useRef67({ onDragStart, onOpen, onClose });
44177
+ const callbacksRef = useRef68({ onDragStart, onOpen, onClose });
43982
44178
  callbacksRef.current = { onDragStart, onOpen, onClose };
43983
- useEffect72(() => {
44179
+ useEffect74(() => {
43984
44180
  const sheet = sheetRef.current;
43985
44181
  const surface = sheet?.parentElement;
43986
44182
  if (!sheet || !surface) return;
@@ -44086,7 +44282,7 @@ function useNavigationSheetSwipe({
44086
44282
  }
44087
44283
 
44088
44284
  // src/NavigationSheet.tsx
44089
- import { Fragment as Fragment31, jsx as jsx94, jsxs as jsxs75 } from "react/jsx-runtime";
44285
+ import { Fragment as Fragment32, jsx as jsx95, jsxs as jsxs76 } from "react/jsx-runtime";
44090
44286
  var PANEL_LABELS = {
44091
44287
  outline: "Outline",
44092
44288
  previews: "Block previews"
@@ -44104,17 +44300,17 @@ function NavigationSheet({
44104
44300
  basePath,
44105
44301
  mediaProvider
44106
44302
  }) {
44107
- const sheetRef = useRef68(null);
44108
- const panelRef = useRef68(null);
44109
- const scrimRef = useRef68(null);
44110
- const tabIdPrefix = useId16();
44111
- const [dragPanel, setDragPanel] = useState84(null);
44303
+ const sheetRef = useRef69(null);
44304
+ const panelRef = useRef69(null);
44305
+ const scrimRef = useRef69(null);
44306
+ const tabIdPrefix = useId17();
44307
+ const [dragPanel, setDragPanel] = useState85(null);
44112
44308
  const open = panel !== null;
44113
44309
  const shown = panel ?? dragPanel;
44114
- const [lastShown, setLastShown] = useState84(shown);
44310
+ const [lastShown, setLastShown] = useState85(shown);
44115
44311
  if (shown && shown !== lastShown) setLastShown(shown);
44116
44312
  const content = shown ?? lastShown;
44117
- useEffect73(() => {
44313
+ useEffect75(() => {
44118
44314
  if (shown || !lastShown) return;
44119
44315
  const timer = setTimeout(() => setLastShown(null), CLOSE_LINGER_MS);
44120
44316
  return () => clearTimeout(timer);
@@ -44139,14 +44335,14 @@ function NavigationSheet({
44139
44335
  onClose: close
44140
44336
  });
44141
44337
  useEscapeDismissal(open, close);
44142
- useEffect73(() => {
44338
+ useEffect75(() => {
44143
44339
  const scrim = scrimRef.current;
44144
44340
  if (!scrim) return;
44145
44341
  const stop = (event) => event.stopPropagation();
44146
44342
  scrim.addEventListener("pointerdown", stop);
44147
44343
  return () => scrim.removeEventListener("pointerdown", stop);
44148
44344
  }, []);
44149
- useEffect73(() => {
44345
+ useEffect75(() => {
44150
44346
  const sheet = sheetRef.current;
44151
44347
  const surface = sheet?.parentElement;
44152
44348
  if (!open || !sheet || !surface) return;
@@ -44159,7 +44355,7 @@ function NavigationSheet({
44159
44355
  for (const sibling of siblings) sibling.inert = false;
44160
44356
  };
44161
44357
  }, [open]);
44162
- return /* @__PURE__ */ jsxs75(
44358
+ return /* @__PURE__ */ jsxs76(
44163
44359
  "div",
44164
44360
  {
44165
44361
  ref: sheetRef,
@@ -44167,8 +44363,8 @@ function NavigationSheet({
44167
44363
  "data-state": open ? "open" : dragPanel ? "dragging" : "closed",
44168
44364
  "data-testid": "navigation-sheet",
44169
44365
  children: [
44170
- /* @__PURE__ */ jsx94("div", { ref: scrimRef, className: "squisq-navigation-sheet-scrim", onClick: close }),
44171
- /* @__PURE__ */ jsx94(
44366
+ /* @__PURE__ */ jsx95("div", { ref: scrimRef, className: "squisq-navigation-sheet-scrim", onClick: close }),
44367
+ /* @__PURE__ */ jsx95(
44172
44368
  "div",
44173
44369
  {
44174
44370
  ref: panelRef,
@@ -44176,9 +44372,9 @@ function NavigationSheet({
44176
44372
  role: "dialog",
44177
44373
  "aria-label": content ? PANEL_LABELS[content] : "Document navigation",
44178
44374
  tabIndex: -1,
44179
- children: content && /* @__PURE__ */ jsxs75(Fragment31, { children: [
44180
- /* @__PURE__ */ jsxs75("div", { className: "squisq-navigation-sheet-header", children: [
44181
- /* @__PURE__ */ jsx94("div", { className: "squisq-navigation-sheet-tabs", role: "tablist", children: PANELS.map((option) => /* @__PURE__ */ jsx94(
44375
+ children: content && /* @__PURE__ */ jsxs76(Fragment32, { children: [
44376
+ /* @__PURE__ */ jsxs76("div", { className: "squisq-navigation-sheet-header", children: [
44377
+ /* @__PURE__ */ jsx95("div", { className: "squisq-navigation-sheet-tabs", role: "tablist", children: PANELS.map((option) => /* @__PURE__ */ jsx95(
44182
44378
  "button",
44183
44379
  {
44184
44380
  type: "button",
@@ -44192,25 +44388,25 @@ function NavigationSheet({
44192
44388
  },
44193
44389
  option
44194
44390
  )) }),
44195
- /* @__PURE__ */ jsx94(
44391
+ /* @__PURE__ */ jsx95(
44196
44392
  "button",
44197
44393
  {
44198
44394
  type: "button",
44199
44395
  className: "squisq-navigation-sheet-close",
44200
44396
  "aria-label": "Close",
44201
44397
  onClick: close,
44202
- children: /* @__PURE__ */ jsx94(Icon, { icon: "xmark" })
44398
+ children: /* @__PURE__ */ jsx95(Icon, { icon: "xmark" })
44203
44399
  }
44204
44400
  )
44205
44401
  ] }),
44206
- /* @__PURE__ */ jsx94(
44402
+ /* @__PURE__ */ jsx95(
44207
44403
  "div",
44208
44404
  {
44209
44405
  id: `${tabIdPrefix}-body`,
44210
44406
  className: "squisq-navigation-sheet-body",
44211
44407
  role: "tabpanel",
44212
44408
  "aria-labelledby": `${tabIdPrefix}-${content}`,
44213
- children: content === "outline" ? /* @__PURE__ */ jsx94(OutlinePanel, { presentation: "sheet", readOnly, onNavigate: close }) : /* @__PURE__ */ jsx94(
44409
+ children: content === "outline" ? /* @__PURE__ */ jsx95(OutlinePanel, { presentation: "sheet", readOnly, onNavigate: close }) : /* @__PURE__ */ jsx95(
44214
44410
  BlockPreviewList,
44215
44411
  {
44216
44412
  basePath,
@@ -44229,7 +44425,7 @@ function NavigationSheet({
44229
44425
  }
44230
44426
 
44231
44427
  // src/proofing/ProofingPanel.tsx
44232
- import { jsx as jsx95, jsxs as jsxs76 } from "react/jsx-runtime";
44428
+ import { jsx as jsx96, jsxs as jsxs77 } from "react/jsx-runtime";
44233
44429
  var CATEGORY_LABELS = {
44234
44430
  spelling: "Spelling",
44235
44431
  grammar: "Grammar",
@@ -44239,14 +44435,14 @@ function ProofingPanel() {
44239
44435
  const state = useProofingState();
44240
44436
  if (!state || !state.panelVisible || !state.enabled) return null;
44241
44437
  const { findings, activeFindingId } = state;
44242
- return /* @__PURE__ */ jsxs76("aside", { className: "squisq-proof-panel", "aria-label": "Proofing findings", children: [
44243
- /* @__PURE__ */ jsxs76("div", { className: "squisq-proof-panel-header", children: [
44244
- /* @__PURE__ */ jsxs76("span", { className: "squisq-proof-panel-title", children: [
44438
+ return /* @__PURE__ */ jsxs77("aside", { className: "squisq-proof-panel", "aria-label": "Proofing findings", children: [
44439
+ /* @__PURE__ */ jsxs77("div", { className: "squisq-proof-panel-header", children: [
44440
+ /* @__PURE__ */ jsxs77("span", { className: "squisq-proof-panel-title", children: [
44245
44441
  "Proofing",
44246
- /* @__PURE__ */ jsx95("span", { className: "squisq-proof-panel-count", children: findings.length })
44442
+ /* @__PURE__ */ jsx96("span", { className: "squisq-proof-panel-count", children: findings.length })
44247
44443
  ] }),
44248
- /* @__PURE__ */ jsxs76("span", { className: "squisq-proof-panel-actions", children: [
44249
- /* @__PURE__ */ jsx95(
44444
+ /* @__PURE__ */ jsxs77("span", { className: "squisq-proof-panel-actions", children: [
44445
+ /* @__PURE__ */ jsx96(
44250
44446
  "button",
44251
44447
  {
44252
44448
  type: "button",
@@ -44258,7 +44454,7 @@ function ProofingPanel() {
44258
44454
  children: "\u2191"
44259
44455
  }
44260
44456
  ),
44261
- /* @__PURE__ */ jsx95(
44457
+ /* @__PURE__ */ jsx96(
44262
44458
  "button",
44263
44459
  {
44264
44460
  type: "button",
@@ -44270,7 +44466,7 @@ function ProofingPanel() {
44270
44466
  children: "\u2193"
44271
44467
  }
44272
44468
  ),
44273
- /* @__PURE__ */ jsx95(
44469
+ /* @__PURE__ */ jsx96(
44274
44470
  "button",
44275
44471
  {
44276
44472
  type: "button",
@@ -44283,20 +44479,20 @@ function ProofingPanel() {
44283
44479
  )
44284
44480
  ] })
44285
44481
  ] }),
44286
- state.status === "loading" && /* @__PURE__ */ jsx95("div", { className: "squisq-proof-panel-empty", children: "Loading proofing engine\u2026" }),
44287
- state.status === "error" && /* @__PURE__ */ jsxs76("div", { className: "squisq-proof-panel-empty", children: [
44482
+ state.status === "loading" && /* @__PURE__ */ jsx96("div", { className: "squisq-proof-panel-empty", children: "Loading proofing engine\u2026" }),
44483
+ state.status === "error" && /* @__PURE__ */ jsxs77("div", { className: "squisq-proof-panel-empty", children: [
44288
44484
  "Proofing failed to load.",
44289
- /* @__PURE__ */ jsx95("button", { type: "button", className: "squisq-proof-panel-retry", onClick: state.retrySetup, children: "Retry" })
44485
+ /* @__PURE__ */ jsx96("button", { type: "button", className: "squisq-proof-panel-retry", onClick: state.retrySetup, children: "Retry" })
44290
44486
  ] }),
44291
- state.status === "ready" && findings.length === 0 && /* @__PURE__ */ jsx95("div", { className: "squisq-proof-panel-empty", children: "No issues found." }),
44292
- /* @__PURE__ */ jsx95("ul", { className: "squisq-proof-panel-list", children: findings.map((finding) => /* @__PURE__ */ jsx95("li", { children: /* @__PURE__ */ jsxs76(
44487
+ state.status === "ready" && findings.length === 0 && /* @__PURE__ */ jsx96("div", { className: "squisq-proof-panel-empty", children: "No issues found." }),
44488
+ /* @__PURE__ */ jsx96("ul", { className: "squisq-proof-panel-list", children: findings.map((finding) => /* @__PURE__ */ jsx96("li", { children: /* @__PURE__ */ jsxs77(
44293
44489
  "button",
44294
44490
  {
44295
44491
  type: "button",
44296
44492
  className: finding.id === activeFindingId ? "squisq-proof-panel-row squisq-proof-panel-row--active" : "squisq-proof-panel-row",
44297
44493
  onClick: () => state.selectFinding(finding.id),
44298
44494
  children: [
44299
- /* @__PURE__ */ jsx95(
44495
+ /* @__PURE__ */ jsx96(
44300
44496
  "span",
44301
44497
  {
44302
44498
  className: `squisq-proof-dot squisq-proof-dot--${finding.category}`,
@@ -44304,9 +44500,9 @@ function ProofingPanel() {
44304
44500
  "aria-hidden": true
44305
44501
  }
44306
44502
  ),
44307
- /* @__PURE__ */ jsxs76("span", { className: "squisq-proof-panel-row-body", children: [
44308
- /* @__PURE__ */ jsx95("span", { className: "squisq-proof-panel-excerpt", children: finding.originalText }),
44309
- /* @__PURE__ */ jsx95("span", { className: "squisq-proof-panel-message", children: proofMessageText(finding) })
44503
+ /* @__PURE__ */ jsxs77("span", { className: "squisq-proof-panel-row-body", children: [
44504
+ /* @__PURE__ */ jsx96("span", { className: "squisq-proof-panel-excerpt", children: finding.originalText }),
44505
+ /* @__PURE__ */ jsx96("span", { className: "squisq-proof-panel-message", children: proofMessageText(finding) })
44310
44506
  ] })
44311
44507
  ]
44312
44508
  }
@@ -44315,13 +44511,13 @@ function ProofingPanel() {
44315
44511
  }
44316
44512
 
44317
44513
  // src/imageEditor/ImageEditModal.tsx
44318
- import { useCallback as useCallback58, useEffect as useEffect74, useMemo as useMemo59, useRef as useRef69, useState as useState85 } from "react";
44514
+ import { useCallback as useCallback58, useEffect as useEffect76, useMemo as useMemo59, useRef as useRef70, useState as useState86 } from "react";
44319
44515
  import { DARK_SURFACE, LIGHT_SURFACE } from "@bendyline/squisq/schemas";
44320
44516
  import {
44321
44517
  MemoryContentContainer,
44322
44518
  scopeContainer
44323
44519
  } from "@bendyline/squisq/storage";
44324
- import { jsx as jsx96, jsxs as jsxs77 } from "react/jsx-runtime";
44520
+ import { jsx as jsx97, jsxs as jsxs78 } from "react/jsx-runtime";
44325
44521
  function ImageEditModal({
44326
44522
  relativePath,
44327
44523
  container,
@@ -44332,8 +44528,8 @@ function ImageEditModal({
44332
44528
  versioningAutoSaveIdleMs,
44333
44529
  shellTheme
44334
44530
  }) {
44335
- const modalRef = useRef69(null);
44336
- const surfaceRef = useRef69(null);
44531
+ const modalRef = useRef70(null);
44532
+ const surfaceRef = useRef70(null);
44337
44533
  useModalDialog({ rootRef: modalRef, dialogRef: surfaceRef, onClose });
44338
44534
  const extension = relativePath.split(/[?#]/, 1)[0]?.split(".").pop()?.toLowerCase();
44339
44535
  const saveFormat = extension === "png" ? "png" : extension === "jpg" || extension === "jpeg" ? "jpeg" : extension === "webp" ? "webp" : null;
@@ -44348,9 +44544,9 @@ function ImageEditModal({
44348
44544
  const parent = container ?? new MemoryContentContainer();
44349
44545
  return scopeContainer(parent, `.imageEdits/${scopedName}`);
44350
44546
  }, [container, relativePath]);
44351
- const [initialSrc, setInitialSrc] = useState85(null);
44352
- const [resolveError, setResolveError] = useState85(null);
44353
- useEffect74(() => {
44547
+ const [initialSrc, setInitialSrc] = useState86(null);
44548
+ const [resolveError, setResolveError] = useState86(null);
44549
+ useEffect76(() => {
44354
44550
  let cancelled = false;
44355
44551
  setInitialSrc(null);
44356
44552
  setResolveError(null);
@@ -44380,7 +44576,7 @@ function ImageEditModal({
44380
44576
  },
44381
44577
  [mediaProvider, relativePath, onSaved]
44382
44578
  );
44383
- return /* @__PURE__ */ jsx96(
44579
+ return /* @__PURE__ */ jsx97(
44384
44580
  "div",
44385
44581
  {
44386
44582
  ref: modalRef,
@@ -44392,11 +44588,11 @@ function ImageEditModal({
44392
44588
  onClick: (e2) => {
44393
44589
  if (e2.target === e2.currentTarget) onClose();
44394
44590
  },
44395
- children: /* @__PURE__ */ jsxs77("div", { ref: surfaceRef, className: "squisq-image-edit-modal__surface", children: [
44396
- /* @__PURE__ */ jsxs77("header", { className: "squisq-image-edit-modal__header", children: [
44397
- /* @__PURE__ */ jsx96("span", { className: "squisq-image-edit-modal__title", children: "Edit image" }),
44398
- /* @__PURE__ */ jsx96("span", { className: "squisq-image-edit-modal__path", children: relativePath }),
44399
- /* @__PURE__ */ jsx96(
44591
+ children: /* @__PURE__ */ jsxs78("div", { ref: surfaceRef, className: "squisq-image-edit-modal__surface", children: [
44592
+ /* @__PURE__ */ jsxs78("header", { className: "squisq-image-edit-modal__header", children: [
44593
+ /* @__PURE__ */ jsx97("span", { className: "squisq-image-edit-modal__title", children: "Edit image" }),
44594
+ /* @__PURE__ */ jsx97("span", { className: "squisq-image-edit-modal__path", children: relativePath }),
44595
+ /* @__PURE__ */ jsx97(
44400
44596
  "button",
44401
44597
  {
44402
44598
  type: "button",
@@ -44408,10 +44604,10 @@ function ImageEditModal({
44408
44604
  }
44409
44605
  )
44410
44606
  ] }),
44411
- /* @__PURE__ */ jsx96("div", { className: "squisq-image-edit-modal__body", children: resolveError ? /* @__PURE__ */ jsxs77("div", { className: "squisq-image-edit-modal__error", children: [
44607
+ /* @__PURE__ */ jsx97("div", { className: "squisq-image-edit-modal__body", children: resolveError ? /* @__PURE__ */ jsxs78("div", { className: "squisq-image-edit-modal__error", children: [
44412
44608
  "Failed to load image: ",
44413
44609
  resolveError
44414
- ] }) : !saveFormat ? /* @__PURE__ */ jsx96("div", { className: "squisq-image-edit-modal__error", children: "Editing supports PNG, JPEG, and WebP images without changing the asset type." }) : !initialSrc ? /* @__PURE__ */ jsx96("div", { className: "squisq-image-edit-modal__loading", children: "Loading image\u2026" }) : /* @__PURE__ */ jsx96(
44610
+ ] }) : !saveFormat ? /* @__PURE__ */ jsx97("div", { className: "squisq-image-edit-modal__error", children: "Editing supports PNG, JPEG, and WebP images without changing the asset type." }) : !initialSrc ? /* @__PURE__ */ jsx97("div", { className: "squisq-image-edit-modal__loading", children: "Loading image\u2026" }) : /* @__PURE__ */ jsx97(
44415
44611
  ImageEditor,
44416
44612
  {
44417
44613
  filesContainer: sidecar,
@@ -44472,18 +44668,18 @@ function MediaEditContextMenuItems() {
44472
44668
  // src/mediaEdit/MediaEditModal.tsx
44473
44669
  import {
44474
44670
  useCallback as useCallback62,
44475
- useEffect as useEffect77,
44476
- useId as useId17,
44671
+ useEffect as useEffect79,
44672
+ useId as useId18,
44477
44673
  useMemo as useMemo61,
44478
- useRef as useRef73,
44479
- useState as useState89
44674
+ useRef as useRef74,
44675
+ useState as useState90
44480
44676
  } from "react";
44481
44677
  import {
44482
44678
  useMediaEditStatus as useMediaEditStatus2
44483
44679
  } from "@bendyline/squisq-video-react/media-edit";
44484
44680
 
44485
44681
  // src/mediaEdit/MediaEditAudioSection.tsx
44486
- import { useCallback as useCallback59, useEffect as useEffect75, useRef as useRef70, useState as useState86 } from "react";
44682
+ import { useCallback as useCallback59, useEffect as useEffect77, useRef as useRef71, useState as useState87 } from "react";
44487
44683
  import { MEDIA_FX_SPECS as MEDIA_FX_SPECS2, serializeMediaFx } from "@bendyline/squisq/mediaEdit";
44488
44684
 
44489
44685
  // src/mediaEdit/mediaEditDraft.ts
@@ -44582,7 +44778,7 @@ function centeredCrop(ratio, frameWidth, frameHeight) {
44582
44778
  }
44583
44779
 
44584
44780
  // src/mediaEdit/MediaEditAudioSection.tsx
44585
- import { Fragment as Fragment32, jsx as jsx97, jsxs as jsxs78 } from "react/jsx-runtime";
44781
+ import { Fragment as Fragment33, jsx as jsx98, jsxs as jsxs79 } from "react/jsx-runtime";
44586
44782
  var STAGES = [
44587
44783
  {
44588
44784
  id: "highpass",
@@ -44636,8 +44832,8 @@ var LOUDNESS_PRESETS = [
44636
44832
  ];
44637
44833
  var PREVIEW_SECONDS = 10;
44638
44834
  function useMediaDuration(url) {
44639
- const [duration, setDuration] = useState86(null);
44640
- useEffect75(() => {
44835
+ const [duration, setDuration] = useState87(null);
44836
+ useEffect77(() => {
44641
44837
  setDuration(null);
44642
44838
  if (!url || typeof Audio === "undefined") return;
44643
44839
  const probe = new Audio();
@@ -44654,12 +44850,12 @@ function useMediaDuration(url) {
44654
44850
  return duration;
44655
44851
  }
44656
44852
  function usePreviewPlayer(preview) {
44657
- const ctxRef = useRef70(null);
44658
- const sourceRef = useRef70(null);
44659
- const startedRef = useRef70(null);
44660
- const [playing, setPlaying] = useState86(null);
44661
- const cueRef = useRef70(0);
44662
- const [position, setPosition] = useState86(0);
44853
+ const ctxRef = useRef71(null);
44854
+ const sourceRef = useRef71(null);
44855
+ const startedRef = useRef71(null);
44856
+ const [playing, setPlaying] = useState87(null);
44857
+ const cueRef = useRef71(0);
44858
+ const [position, setPosition] = useState87(0);
44663
44859
  const frames = preview?.original[0]?.length ?? 0;
44664
44860
  const duration = preview && frames > 0 ? frames / preview.sampleRate : 0;
44665
44861
  const currentOffset = useCallback59(() => {
@@ -44677,8 +44873,8 @@ function usePreviewPlayer(preview) {
44677
44873
  setPosition(0);
44678
44874
  setPlaying(null);
44679
44875
  }, []);
44680
- useEffect75(() => stop, [preview, stop]);
44681
- useEffect75(
44876
+ useEffect77(() => stop, [preview, stop]);
44877
+ useEffect77(
44682
44878
  () => () => {
44683
44879
  void ctxRef.current?.close();
44684
44880
  ctxRef.current = null;
@@ -44717,7 +44913,7 @@ function usePreviewPlayer(preview) {
44717
44913
  },
44718
44914
  [duration, playing, play]
44719
44915
  );
44720
- useEffect75(() => {
44916
+ useEffect77(() => {
44721
44917
  if (!playing) return;
44722
44918
  let frame = requestAnimationFrame(function tick() {
44723
44919
  setPosition(currentOffset());
@@ -44728,26 +44924,26 @@ function usePreviewPlayer(preview) {
44728
44924
  return { playing, play, stop, seek, position, duration };
44729
44925
  }
44730
44926
  function PlayIcon() {
44731
- return /* @__PURE__ */ jsx97(
44927
+ return /* @__PURE__ */ jsx98(
44732
44928
  "svg",
44733
44929
  {
44734
44930
  className: "squisq-media-edit-icon",
44735
44931
  viewBox: "0 0 10 10",
44736
44932
  "aria-hidden": "true",
44737
44933
  focusable: "false",
44738
- children: /* @__PURE__ */ jsx97("path", { d: "M2 1 9 5 2 9Z" })
44934
+ children: /* @__PURE__ */ jsx98("path", { d: "M2 1 9 5 2 9Z" })
44739
44935
  }
44740
44936
  );
44741
44937
  }
44742
44938
  function StopIcon() {
44743
- return /* @__PURE__ */ jsx97(
44939
+ return /* @__PURE__ */ jsx98(
44744
44940
  "svg",
44745
44941
  {
44746
44942
  className: "squisq-media-edit-icon",
44747
44943
  viewBox: "0 0 10 10",
44748
44944
  "aria-hidden": "true",
44749
44945
  focusable: "false",
44750
- children: /* @__PURE__ */ jsx97("rect", { x: "1.5", y: "1.5", width: "7", height: "7", rx: "1" })
44946
+ children: /* @__PURE__ */ jsx98("rect", { x: "1.5", y: "1.5", width: "7", height: "7", rx: "1" })
44751
44947
  }
44752
44948
  );
44753
44949
  }
@@ -44765,14 +44961,14 @@ function MediaEditAudioSection({
44765
44961
  const duration = useMediaDuration(resolvedSrc);
44766
44962
  const windowMin = item.clipStart ?? 0;
44767
44963
  const windowMax = Math.max(windowMin, (item.clipEnd ?? duration ?? windowMin) - 1);
44768
- const [previewFrom, setPreviewFrom] = useState86(windowMin);
44769
- const [preview, setPreview] = useState86(null);
44770
- const [previewedFx, setPreviewedFx] = useState86(null);
44771
- const [previewing, setPreviewing] = useState86(false);
44772
- const [previewError, setPreviewError] = useState86(null);
44773
- const previewAbort = useRef70(null);
44964
+ const [previewFrom, setPreviewFrom] = useState87(windowMin);
44965
+ const [preview, setPreview] = useState87(null);
44966
+ const [previewedFx, setPreviewedFx] = useState87(null);
44967
+ const [previewing, setPreviewing] = useState87(false);
44968
+ const [previewError, setPreviewError] = useState87(null);
44969
+ const previewAbort = useRef71(null);
44774
44970
  const player = usePreviewPlayer(preview);
44775
- useEffect75(() => () => previewAbort.current?.abort(), []);
44971
+ useEffect77(() => () => previewAbort.current?.abort(), []);
44776
44972
  const runPreview = useCallback59(async () => {
44777
44973
  if (draftFx.ops.length === 0) return;
44778
44974
  previewAbort.current?.abort();
@@ -44797,23 +44993,23 @@ function MediaEditAudioSection({
44797
44993
  setPreviewing(false);
44798
44994
  }
44799
44995
  }, [draftFx.ops.length, manager, item.src, knownFx, previewFrom]);
44800
- return /* @__PURE__ */ jsxs78("div", { className: "squisq-media-edit-section", children: [
44801
- /* @__PURE__ */ jsxs78("div", { className: "squisq-media-edit-presets", role: "group", "aria-label": "Presets", children: [
44802
- /* @__PURE__ */ jsx97("button", { type: "button", onClick: () => onChange({ ...draft, fx: presetFx("voice") }), children: "Clean up voice" }),
44803
- /* @__PURE__ */ jsx97("button", { type: "button", onClick: () => onChange({ ...draft, fx: presetFx("levels") }), children: "Levels only" }),
44804
- /* @__PURE__ */ jsx97("button", { type: "button", onClick: () => onChange({ ...draft, fx: presetFx("none") }), children: "None" })
44996
+ return /* @__PURE__ */ jsxs79("div", { className: "squisq-media-edit-section", children: [
44997
+ /* @__PURE__ */ jsxs79("div", { className: "squisq-media-edit-presets", role: "group", "aria-label": "Presets", children: [
44998
+ /* @__PURE__ */ jsx98("button", { type: "button", onClick: () => onChange({ ...draft, fx: presetFx("voice") }), children: "Clean up voice" }),
44999
+ /* @__PURE__ */ jsx98("button", { type: "button", onClick: () => onChange({ ...draft, fx: presetFx("levels") }), children: "Levels only" }),
45000
+ /* @__PURE__ */ jsx98("button", { type: "button", onClick: () => onChange({ ...draft, fx: presetFx("none") }), children: "None" })
44805
45001
  ] }),
44806
- /* @__PURE__ */ jsx97("ul", { className: "squisq-media-edit-stages", children: STAGES.map((stage) => {
45002
+ /* @__PURE__ */ jsx98("ul", { className: "squisq-media-edit-stages", children: STAGES.map((stage) => {
44807
45003
  const s = draft.fx[stage.id];
44808
45004
  const inputId = `${idPrefix}-${stage.id}`;
44809
- return /* @__PURE__ */ jsxs78(
45005
+ return /* @__PURE__ */ jsxs79(
44810
45006
  "li",
44811
45007
  {
44812
45008
  className: "squisq-media-edit-stage",
44813
45009
  "data-enabled": s.enabled ? "true" : "false",
44814
45010
  children: [
44815
- /* @__PURE__ */ jsxs78("label", { className: "squisq-media-edit-stage__toggle", children: [
44816
- /* @__PURE__ */ jsx97(
45011
+ /* @__PURE__ */ jsxs79("label", { className: "squisq-media-edit-stage__toggle", children: [
45012
+ /* @__PURE__ */ jsx98(
44817
45013
  "input",
44818
45014
  {
44819
45015
  type: "checkbox",
@@ -44821,9 +45017,9 @@ function MediaEditAudioSection({
44821
45017
  onChange: (e2) => setStage(stage.id, { enabled: e2.target.checked })
44822
45018
  }
44823
45019
  ),
44824
- /* @__PURE__ */ jsx97("span", { className: "squisq-media-edit-stage__label", children: stage.label })
45020
+ /* @__PURE__ */ jsx98("span", { className: "squisq-media-edit-stage__label", children: stage.label })
44825
45021
  ] }),
44826
- /* @__PURE__ */ jsx97(
45022
+ /* @__PURE__ */ jsx98(
44827
45023
  "input",
44828
45024
  {
44829
45025
  id: inputId,
@@ -44839,9 +45035,9 @@ function MediaEditAudioSection({
44839
45035
  onChange: (e2) => setStage(stage.id, { value: stage.toValue(Number(e2.target.value)) })
44840
45036
  }
44841
45037
  ),
44842
- /* @__PURE__ */ jsx97("output", { className: "squisq-media-edit-stage__value", htmlFor: inputId, children: stage.format(s.value) }),
44843
- /* @__PURE__ */ jsx97("p", { className: "squisq-media-edit-stage__hint", children: stage.hint }),
44844
- stage.id === "loudness" && s.enabled && /* @__PURE__ */ jsx97("div", { className: "squisq-media-edit-chips", role: "group", "aria-label": "Targets", children: LOUDNESS_PRESETS.map((preset) => /* @__PURE__ */ jsxs78(
45038
+ /* @__PURE__ */ jsx98("output", { className: "squisq-media-edit-stage__value", htmlFor: inputId, children: stage.format(s.value) }),
45039
+ /* @__PURE__ */ jsx98("p", { className: "squisq-media-edit-stage__hint", children: stage.hint }),
45040
+ stage.id === "loudness" && s.enabled && /* @__PURE__ */ jsx98("div", { className: "squisq-media-edit-chips", role: "group", "aria-label": "Targets", children: LOUDNESS_PRESETS.map((preset) => /* @__PURE__ */ jsxs79(
44845
45041
  "button",
44846
45042
  {
44847
45043
  type: "button",
@@ -44861,14 +45057,14 @@ function MediaEditAudioSection({
44861
45057
  stage.id
44862
45058
  );
44863
45059
  }) }),
44864
- /* @__PURE__ */ jsxs78("div", { className: "squisq-media-edit-preview", "aria-label": "Preview", children: [
44865
- duration != null && windowMax > windowMin && /* @__PURE__ */ jsxs78("label", { className: "squisq-media-edit-preview__from", children: [
44866
- /* @__PURE__ */ jsxs78("span", { children: [
45060
+ /* @__PURE__ */ jsxs79("div", { className: "squisq-media-edit-preview", "aria-label": "Preview", children: [
45061
+ duration != null && windowMax > windowMin && /* @__PURE__ */ jsxs79("label", { className: "squisq-media-edit-preview__from", children: [
45062
+ /* @__PURE__ */ jsxs79("span", { children: [
44867
45063
  "Preview from ",
44868
45064
  previewFrom.toFixed(0),
44869
45065
  " s"
44870
45066
  ] }),
44871
- /* @__PURE__ */ jsx97(
45067
+ /* @__PURE__ */ jsx98(
44872
45068
  "input",
44873
45069
  {
44874
45070
  type: "range",
@@ -44880,7 +45076,7 @@ function MediaEditAudioSection({
44880
45076
  }
44881
45077
  )
44882
45078
  ] }),
44883
- /* @__PURE__ */ jsx97("div", { className: "squisq-media-edit-preview__actions", children: /* @__PURE__ */ jsx97(
45079
+ /* @__PURE__ */ jsx98("div", { className: "squisq-media-edit-preview__actions", children: /* @__PURE__ */ jsx98(
44884
45080
  "button",
44885
45081
  {
44886
45082
  type: "button",
@@ -44889,10 +45085,10 @@ function MediaEditAudioSection({
44889
45085
  children: previewing ? "Rendering preview\u2026" : preview ? "Update preview" : "Create preview"
44890
45086
  }
44891
45087
  ) }),
44892
- preview != null && player.duration > 0 && /* @__PURE__ */ jsxs78(Fragment32, { children: [
44893
- /* @__PURE__ */ jsxs78("div", { className: "squisq-media-edit-playback", "data-playing": player.playing ?? void 0, children: [
44894
- /* @__PURE__ */ jsx97("span", { className: "squisq-media-edit-playback__label", children: player.playing ? `${player.playing === "original" ? "Original" : "Processed"} from ${Math.round(preview.startSec)} s` : "Stopped" }),
44895
- /* @__PURE__ */ jsx97(
45088
+ preview != null && player.duration > 0 && /* @__PURE__ */ jsxs79(Fragment33, { children: [
45089
+ /* @__PURE__ */ jsxs79("div", { className: "squisq-media-edit-playback", "data-playing": player.playing ?? void 0, children: [
45090
+ /* @__PURE__ */ jsx98("span", { className: "squisq-media-edit-playback__label", children: player.playing ? `${player.playing === "original" ? "Original" : "Processed"} from ${Math.round(preview.startSec)} s` : "Stopped" }),
45091
+ /* @__PURE__ */ jsx98(
44896
45092
  "input",
44897
45093
  {
44898
45094
  type: "range",
@@ -44906,14 +45102,14 @@ function MediaEditAudioSection({
44906
45102
  onChange: (e2) => player.seek(Number(e2.target.value))
44907
45103
  }
44908
45104
  ),
44909
- /* @__PURE__ */ jsxs78("span", { className: "squisq-media-edit-playback__time", children: [
45105
+ /* @__PURE__ */ jsxs79("span", { className: "squisq-media-edit-playback__time", children: [
44910
45106
  formatClock6(player.position),
44911
45107
  " / ",
44912
45108
  formatClock6(player.duration)
44913
45109
  ] })
44914
45110
  ] }),
44915
- /* @__PURE__ */ jsxs78("div", { className: "squisq-media-edit-preview__actions", children: [
44916
- /* @__PURE__ */ jsxs78(
45111
+ /* @__PURE__ */ jsxs79("div", { className: "squisq-media-edit-preview__actions", children: [
45112
+ /* @__PURE__ */ jsxs79(
44917
45113
  "button",
44918
45114
  {
44919
45115
  type: "button",
@@ -44921,12 +45117,12 @@ function MediaEditAudioSection({
44921
45117
  disabled: previewing,
44922
45118
  onClick: () => player.play("original"),
44923
45119
  children: [
44924
- /* @__PURE__ */ jsx97(PlayIcon, {}),
45120
+ /* @__PURE__ */ jsx98(PlayIcon, {}),
44925
45121
  "Original"
44926
45122
  ]
44927
45123
  }
44928
45124
  ),
44929
- /* @__PURE__ */ jsxs78(
45125
+ /* @__PURE__ */ jsxs79(
44930
45126
  "button",
44931
45127
  {
44932
45128
  type: "button",
@@ -44934,26 +45130,26 @@ function MediaEditAudioSection({
44934
45130
  disabled: previewing,
44935
45131
  onClick: () => player.play("processed"),
44936
45132
  children: [
44937
- /* @__PURE__ */ jsx97(PlayIcon, {}),
45133
+ /* @__PURE__ */ jsx98(PlayIcon, {}),
44938
45134
  "Processed"
44939
45135
  ]
44940
45136
  }
44941
45137
  ),
44942
- /* @__PURE__ */ jsxs78("button", { type: "button", disabled: !player.playing, onClick: player.stop, children: [
44943
- /* @__PURE__ */ jsx97(StopIcon, {}),
45138
+ /* @__PURE__ */ jsxs79("button", { type: "button", disabled: !player.playing, onClick: player.stop, children: [
45139
+ /* @__PURE__ */ jsx98(StopIcon, {}),
44944
45140
  "Stop"
44945
45141
  ] })
44946
45142
  ] })
44947
45143
  ] }),
44948
- preview != null && previewedFx !== knownFx && /* @__PURE__ */ jsx97("p", { className: "squisq-media-edit-note", children: "Settings changed \u2014 update the preview to hear them." }),
44949
- previewError && /* @__PURE__ */ jsx97("p", { className: "squisq-media-edit-note squisq-media-edit-note--error", role: "alert", children: previewError })
45144
+ preview != null && previewedFx !== knownFx && /* @__PURE__ */ jsx98("p", { className: "squisq-media-edit-note", children: "Settings changed \u2014 update the preview to hear them." }),
45145
+ previewError && /* @__PURE__ */ jsx98("p", { className: "squisq-media-edit-note squisq-media-edit-note--error", role: "alert", children: previewError })
44950
45146
  ] })
44951
45147
  ] });
44952
45148
  }
44953
45149
 
44954
45150
  // src/mediaEdit/MediaEditTimingSection.tsx
44955
- import { useCallback as useCallback60, useEffect as useEffect76, useRef as useRef71, useState as useState87 } from "react";
44956
- import { jsx as jsx98, jsxs as jsxs79 } from "react/jsx-runtime";
45151
+ import { useCallback as useCallback60, useEffect as useEffect78, useRef as useRef72, useState as useState88 } from "react";
45152
+ import { jsx as jsx99, jsxs as jsxs80 } from "react/jsx-runtime";
44957
45153
  var DEFAULT_MAX_PAUSE = 0.8;
44958
45154
  function formatDb(value) {
44959
45155
  if (value === 0) return "0 dB";
@@ -44966,11 +45162,11 @@ function MediaEditTimingSection({
44966
45162
  manager,
44967
45163
  idPrefix
44968
45164
  }) {
44969
- const [maxPause, setMaxPause] = useState87(DEFAULT_MAX_PAUSE);
44970
- const [finding, setFinding] = useState87(false);
44971
- const [error, setError] = useState87(null);
44972
- const abortRef = useRef71(null);
44973
- useEffect76(() => () => abortRef.current?.abort(), []);
45165
+ const [maxPause, setMaxPause] = useState88(DEFAULT_MAX_PAUSE);
45166
+ const [finding, setFinding] = useState88(false);
45167
+ const [error, setError] = useState88(null);
45168
+ const abortRef = useRef72(null);
45169
+ useEffect78(() => () => abortRef.current?.abort(), []);
44974
45170
  const findPauses = useCallback60(async () => {
44975
45171
  abortRef.current?.abort();
44976
45172
  const controller = new AbortController();
@@ -44994,10 +45190,10 @@ function MediaEditTimingSection({
44994
45190
  }
44995
45191
  }, [manager, item.src, maxPause, draft, onChange]);
44996
45192
  const saved = cutSeconds(draft.cuts);
44997
- return /* @__PURE__ */ jsxs79("div", { className: "squisq-media-edit-section", children: [
44998
- /* @__PURE__ */ jsxs79("div", { className: "squisq-media-edit-row", children: [
44999
- /* @__PURE__ */ jsx98("label", { className: "squisq-media-edit-row__label", htmlFor: `${idPrefix}-pause`, children: "Shorten pauses longer than" }),
45000
- /* @__PURE__ */ jsx98(
45193
+ return /* @__PURE__ */ jsxs80("div", { className: "squisq-media-edit-section", children: [
45194
+ /* @__PURE__ */ jsxs80("div", { className: "squisq-media-edit-row", children: [
45195
+ /* @__PURE__ */ jsx99("label", { className: "squisq-media-edit-row__label", htmlFor: `${idPrefix}-pause`, children: "Shorten pauses longer than" }),
45196
+ /* @__PURE__ */ jsx99(
45001
45197
  "input",
45002
45198
  {
45003
45199
  id: `${idPrefix}-pause`,
@@ -45010,14 +45206,14 @@ function MediaEditTimingSection({
45010
45206
  onChange: (e2) => setMaxPause(Number(e2.target.value))
45011
45207
  }
45012
45208
  ),
45013
- /* @__PURE__ */ jsxs79("output", { htmlFor: `${idPrefix}-pause`, children: [
45209
+ /* @__PURE__ */ jsxs80("output", { htmlFor: `${idPrefix}-pause`, children: [
45014
45210
  maxPause.toFixed(1),
45015
45211
  " s"
45016
45212
  ] })
45017
45213
  ] }),
45018
- /* @__PURE__ */ jsxs79("div", { className: "squisq-media-edit-preview__actions", children: [
45019
- /* @__PURE__ */ jsx98("button", { type: "button", onClick: findPauses, disabled: finding, children: finding ? "Finding pauses\u2026" : "Find pauses" }),
45020
- /* @__PURE__ */ jsx98(
45214
+ /* @__PURE__ */ jsxs80("div", { className: "squisq-media-edit-preview__actions", children: [
45215
+ /* @__PURE__ */ jsx99("button", { type: "button", onClick: findPauses, disabled: finding, children: finding ? "Finding pauses\u2026" : "Find pauses" }),
45216
+ /* @__PURE__ */ jsx99(
45021
45217
  "button",
45022
45218
  {
45023
45219
  type: "button",
@@ -45027,11 +45223,11 @@ function MediaEditTimingSection({
45027
45223
  }
45028
45224
  )
45029
45225
  ] }),
45030
- /* @__PURE__ */ jsx98("p", { className: "squisq-media-edit-note", role: "status", "aria-live": "polite", children: draft.cuts.length === 0 ? "No pauses shortened." : `${draft.cuts.length} ${draft.cuts.length === 1 ? "pause" : "pauses"} shortened, saving ${formatClock6(saved)}.` }),
45031
- error && /* @__PURE__ */ jsx98("p", { className: "squisq-media-edit-note squisq-media-edit-note--error", role: "alert", children: error }),
45032
- /* @__PURE__ */ jsxs79("div", { className: "squisq-media-edit-row", children: [
45033
- /* @__PURE__ */ jsx98("label", { className: "squisq-media-edit-row__label", htmlFor: `${idPrefix}-gain`, children: "Volume" }),
45034
- /* @__PURE__ */ jsx98(
45226
+ /* @__PURE__ */ jsx99("p", { className: "squisq-media-edit-note", role: "status", "aria-live": "polite", children: draft.cuts.length === 0 ? "No pauses shortened." : `${draft.cuts.length} ${draft.cuts.length === 1 ? "pause" : "pauses"} shortened, saving ${formatClock6(saved)}.` }),
45227
+ error && /* @__PURE__ */ jsx99("p", { className: "squisq-media-edit-note squisq-media-edit-note--error", role: "alert", children: error }),
45228
+ /* @__PURE__ */ jsxs80("div", { className: "squisq-media-edit-row", children: [
45229
+ /* @__PURE__ */ jsx99("label", { className: "squisq-media-edit-row__label", htmlFor: `${idPrefix}-gain`, children: "Volume" }),
45230
+ /* @__PURE__ */ jsx99(
45035
45231
  "input",
45036
45232
  {
45037
45233
  id: `${idPrefix}-gain`,
@@ -45044,11 +45240,11 @@ function MediaEditTimingSection({
45044
45240
  onChange: (e2) => onChange({ ...draft, gain: Number(e2.target.value) })
45045
45241
  }
45046
45242
  ),
45047
- /* @__PURE__ */ jsx98("output", { htmlFor: `${idPrefix}-gain`, children: formatDb(draft.gain) })
45243
+ /* @__PURE__ */ jsx99("output", { htmlFor: `${idPrefix}-gain`, children: formatDb(draft.gain) })
45048
45244
  ] }),
45049
- ["fadeIn", "fadeOut"].map((key) => /* @__PURE__ */ jsxs79("div", { className: "squisq-media-edit-row", children: [
45050
- /* @__PURE__ */ jsx98("label", { className: "squisq-media-edit-row__label", htmlFor: `${idPrefix}-${key}`, children: key === "fadeIn" ? "Fade in" : "Fade out" }),
45051
- /* @__PURE__ */ jsx98(
45245
+ ["fadeIn", "fadeOut"].map((key) => /* @__PURE__ */ jsxs80("div", { className: "squisq-media-edit-row", children: [
45246
+ /* @__PURE__ */ jsx99("label", { className: "squisq-media-edit-row__label", htmlFor: `${idPrefix}-${key}`, children: key === "fadeIn" ? "Fade in" : "Fade out" }),
45247
+ /* @__PURE__ */ jsx99(
45052
45248
  "input",
45053
45249
  {
45054
45250
  id: `${idPrefix}-${key}`,
@@ -45061,7 +45257,7 @@ function MediaEditTimingSection({
45061
45257
  onChange: (e2) => onChange({ ...draft, [key]: Number(e2.target.value) })
45062
45258
  }
45063
45259
  ),
45064
- /* @__PURE__ */ jsx98("output", { htmlFor: `${idPrefix}-${key}`, children: draft[key] === 0 ? "Off" : `${draft[key].toFixed(1)} s` })
45260
+ /* @__PURE__ */ jsx99("output", { htmlFor: `${idPrefix}-${key}`, children: draft[key] === 0 ? "Off" : `${draft[key].toFixed(1)} s` })
45065
45261
  ] }, key))
45066
45262
  ] });
45067
45263
  }
@@ -45069,11 +45265,11 @@ function MediaEditTimingSection({
45069
45265
  // src/mediaEdit/MediaEditFrameSection.tsx
45070
45266
  import {
45071
45267
  useCallback as useCallback61,
45072
- useRef as useRef72,
45073
- useState as useState88
45268
+ useRef as useRef73,
45269
+ useState as useState89
45074
45270
  } from "react";
45075
45271
  import { normalizeMediaCrop } from "@bendyline/squisq/mediaEdit";
45076
- import { jsx as jsx99, jsxs as jsxs80 } from "react/jsx-runtime";
45272
+ import { jsx as jsx100, jsxs as jsxs81 } from "react/jsx-runtime";
45077
45273
  var FULL = { x: 0, y: 0, w: 1, h: 1 };
45078
45274
  var MIN_EDGE = 0.05;
45079
45275
  var NUDGE = 0.01;
@@ -45096,9 +45292,9 @@ function clampCrop(crop) {
45096
45292
  }
45097
45293
  function MediaEditFrameSection({ item, draft, onChange }) {
45098
45294
  const src = useResolvedMediaSrc(item.src);
45099
- const [frame, setFrame] = useState88(null);
45100
- const [aspect, setAspect] = useState88(null);
45101
- const stageRef = useRef72(null);
45295
+ const [frame, setFrame] = useState89(null);
45296
+ const [aspect, setAspect] = useState89(null);
45297
+ const stageRef = useRef73(null);
45102
45298
  const crop = draft.crop ?? FULL;
45103
45299
  const setCrop = useCallback61(
45104
45300
  (next) => onChange({ ...draft, crop: normalizeMediaCrop(clampCrop(next)) }),
@@ -45153,9 +45349,9 @@ function MediaEditFrameSection({ item, draft, onChange }) {
45153
45349
  );
45154
45350
  };
45155
45351
  const pct = (n) => `${(n * 100).toFixed(2)}%`;
45156
- return /* @__PURE__ */ jsxs80("div", { className: "squisq-media-edit-section", children: [
45157
- /* @__PURE__ */ jsxs80("div", { className: "squisq-media-edit-chips", role: "group", "aria-label": "Crop aspect", children: [
45158
- ASPECTS.map((option) => /* @__PURE__ */ jsx99(
45352
+ return /* @__PURE__ */ jsxs81("div", { className: "squisq-media-edit-section", children: [
45353
+ /* @__PURE__ */ jsxs81("div", { className: "squisq-media-edit-chips", role: "group", "aria-label": "Crop aspect", children: [
45354
+ ASPECTS.map((option) => /* @__PURE__ */ jsx100(
45159
45355
  "button",
45160
45356
  {
45161
45357
  type: "button",
@@ -45170,7 +45366,7 @@ function MediaEditFrameSection({ item, draft, onChange }) {
45170
45366
  },
45171
45367
  option.label
45172
45368
  )),
45173
- /* @__PURE__ */ jsx99(
45369
+ /* @__PURE__ */ jsx100(
45174
45370
  "button",
45175
45371
  {
45176
45372
  type: "button",
@@ -45183,14 +45379,14 @@ function MediaEditFrameSection({ item, draft, onChange }) {
45183
45379
  }
45184
45380
  )
45185
45381
  ] }),
45186
- /* @__PURE__ */ jsxs80(
45382
+ /* @__PURE__ */ jsxs81(
45187
45383
  "div",
45188
45384
  {
45189
45385
  ref: stageRef,
45190
45386
  className: "squisq-media-edit-crop",
45191
45387
  style: frame ? { aspectRatio: `${frame.w} / ${frame.h}` } : void 0,
45192
45388
  children: [
45193
- src && /* @__PURE__ */ jsx99(
45389
+ src && /* @__PURE__ */ jsx100(
45194
45390
  "video",
45195
45391
  {
45196
45392
  src,
@@ -45206,7 +45402,7 @@ function MediaEditFrameSection({ item, draft, onChange }) {
45206
45402
  }
45207
45403
  }
45208
45404
  ),
45209
- /* @__PURE__ */ jsx99(
45405
+ /* @__PURE__ */ jsx100(
45210
45406
  "div",
45211
45407
  {
45212
45408
  className: "squisq-media-edit-crop__rect",
@@ -45217,7 +45413,7 @@ function MediaEditFrameSection({ item, draft, onChange }) {
45217
45413
  style: { left: pct(crop.x), top: pct(crop.y), width: pct(crop.w), height: pct(crop.h) },
45218
45414
  onPointerDown: startDrag("move"),
45219
45415
  onKeyDown,
45220
- children: ["nw", "ne", "sw", "se"].map((handle) => /* @__PURE__ */ jsx99(
45416
+ children: ["nw", "ne", "sw", "se"].map((handle) => /* @__PURE__ */ jsx100(
45221
45417
  "span",
45222
45418
  {
45223
45419
  className: `squisq-media-edit-crop__handle squisq-media-edit-crop__handle--${handle}`,
@@ -45230,12 +45426,12 @@ function MediaEditFrameSection({ item, draft, onChange }) {
45230
45426
  ]
45231
45427
  }
45232
45428
  ),
45233
- /* @__PURE__ */ jsx99("p", { className: "squisq-media-edit-note", children: draft.crop ? "Only the framed area is shown and exported." : "Drag the corners or pick an aspect to crop." })
45429
+ /* @__PURE__ */ jsx100("p", { className: "squisq-media-edit-note", children: draft.crop ? "Only the framed area is shown and exported." : "Drag the corners or pick an aspect to crop." })
45234
45430
  ] });
45235
45431
  }
45236
45432
 
45237
45433
  // src/mediaEdit/MediaEditModal.tsx
45238
- import { Fragment as Fragment33, jsx as jsx100, jsxs as jsxs81 } from "react/jsx-runtime";
45434
+ import { Fragment as Fragment34, jsx as jsx101, jsxs as jsxs82 } from "react/jsx-runtime";
45239
45435
  var TABS = [
45240
45436
  { id: "audio", label: "Audio cleanup" },
45241
45437
  { id: "timing", label: "Timing" },
@@ -45257,7 +45453,7 @@ function useRenderStatus(item, manager) {
45257
45453
  }
45258
45454
  var percent = (status) => `${Math.round((status.progress ?? 0) * 100)}%`;
45259
45455
  function RenderStatusBadge({ status }) {
45260
- return /* @__PURE__ */ jsxs81("span", { className: "squisq-media-edit-badge", "data-state": status.state, children: [
45456
+ return /* @__PURE__ */ jsxs82("span", { className: "squisq-media-edit-badge", "data-state": status.state, children: [
45261
45457
  status.state === "ready" && "Processed",
45262
45458
  status.state === "queued" && "Queued",
45263
45459
  status.state === "rendering" && `Processing ${percent(status)}`,
@@ -45270,43 +45466,43 @@ function RenderStatusText({
45270
45466
  }) {
45271
45467
  switch (status.state) {
45272
45468
  case "ready":
45273
- return /* @__PURE__ */ jsx100(Fragment33, { children: "Processed audio is in use." });
45469
+ return /* @__PURE__ */ jsx101(Fragment34, { children: "Processed audio is in use." });
45274
45470
  case "queued":
45275
- return /* @__PURE__ */ jsx100(Fragment33, { children: "Waiting to process\u2026" });
45471
+ return /* @__PURE__ */ jsx101(Fragment34, { children: "Waiting to process\u2026" });
45276
45472
  case "rendering":
45277
- return /* @__PURE__ */ jsxs81(Fragment33, { children: [
45473
+ return /* @__PURE__ */ jsxs82(Fragment34, { children: [
45278
45474
  "Processing\u2026 ",
45279
45475
  percent(status)
45280
45476
  ] });
45281
45477
  case "failed":
45282
- return /* @__PURE__ */ jsxs81(Fragment33, { children: [
45478
+ return /* @__PURE__ */ jsxs82(Fragment34, { children: [
45283
45479
  "Processing failed: ",
45284
45480
  status.error,
45285
45481
  " ",
45286
- /* @__PURE__ */ jsx100("button", { type: "button", onClick: onRetry, children: "Retry" })
45482
+ /* @__PURE__ */ jsx101("button", { type: "button", onClick: onRetry, children: "Retry" })
45287
45483
  ] });
45288
45484
  }
45289
45485
  }
45290
45486
  function MediaEditModal({ target, onClose }) {
45291
45487
  const { doc, markdownSource, setMarkdownSource, mediaEditRenders } = useEditorContext();
45292
- const modalRef = useRef73(null);
45293
- const surfaceRef = useRef73(null);
45294
- const titleId = useId17();
45488
+ const modalRef = useRef74(null);
45489
+ const surfaceRef = useRef74(null);
45490
+ const titleId = useId18();
45295
45491
  useModalDialog({ rootRef: modalRef, dialogRef: surfaceRef, onClose });
45296
45492
  const item = useMemo61(() => doc ? findEditableMedia(doc, target) : null, [doc, target]);
45297
45493
  const companions = useMemo61(() => doc && item ? groupCompanions(doc, item) : [], [doc, item]);
45298
45494
  const renderStatus = useRenderStatus(item, mediaEditRenders);
45299
- const [draft, setDraft] = useState89(() => draftFromEdits(item?.edits));
45495
+ const [draft, setDraft] = useState90(() => draftFromEdits(item?.edits));
45300
45496
  const seedKey = item ? `${item.sourceLine}|${editsSignature(item.edits)}` : null;
45301
- const seededRef = useRef73(null);
45302
- useEffect77(() => {
45497
+ const seededRef = useRef74(null);
45498
+ useEffect79(() => {
45303
45499
  if (seedKey === null || seededRef.current === seedKey) return;
45304
45500
  seededRef.current = seedKey;
45305
45501
  setDraft(draftFromEdits(item?.edits));
45306
45502
  }, [seedKey]);
45307
45503
  const tabs = TABS.filter((t) => t.id !== "frame" || item?.kind === "video");
45308
- const [activeTab, setActiveTab] = useState89("audio");
45309
- const tabRefs = useRef73(/* @__PURE__ */ new Map());
45504
+ const [activeTab, setActiveTab] = useState90("audio");
45505
+ const tabRefs = useRef74(/* @__PURE__ */ new Map());
45310
45506
  const onTabKeyDown = (event, index2) => {
45311
45507
  const next = event.key === "ArrowRight" ? (index2 + 1) % tabs.length : event.key === "ArrowLeft" ? (index2 - 1 + tabs.length) % tabs.length : event.key === "Home" ? 0 : event.key === "End" ? tabs.length - 1 : null;
45312
45508
  if (next == null) return;
@@ -45334,7 +45530,7 @@ function MediaEditModal({ target, onClose }) {
45334
45530
  const tabbed = item != null && mediaEditRenders != null;
45335
45531
  const tabId = (tab) => `${titleId}-tab-${tab}`;
45336
45532
  const panelId = (tab) => `${titleId}-panel-${tab}`;
45337
- return /* @__PURE__ */ jsx100(
45533
+ return /* @__PURE__ */ jsx101(
45338
45534
  "div",
45339
45535
  {
45340
45536
  ref: modalRef,
@@ -45343,7 +45539,7 @@ function MediaEditModal({ target, onClose }) {
45343
45539
  onClick: (e2) => {
45344
45540
  if (e2.target === e2.currentTarget) onClose();
45345
45541
  },
45346
- children: /* @__PURE__ */ jsxs81(
45542
+ children: /* @__PURE__ */ jsxs82(
45347
45543
  "div",
45348
45544
  {
45349
45545
  ref: surfaceRef,
@@ -45352,11 +45548,11 @@ function MediaEditModal({ target, onClose }) {
45352
45548
  "aria-modal": "true",
45353
45549
  "aria-labelledby": titleId,
45354
45550
  children: [
45355
- /* @__PURE__ */ jsxs81("header", { className: "squisq-media-edit-modal__header", children: [
45356
- /* @__PURE__ */ jsx100("span", { id: titleId, className: "squisq-media-edit-modal__title", children: title }),
45357
- /* @__PURE__ */ jsx100("span", { className: "squisq-media-edit-modal__path", children: target.src }),
45358
- renderStatus && /* @__PURE__ */ jsx100(RenderStatusBadge, { status: renderStatus }),
45359
- /* @__PURE__ */ jsx100(
45551
+ /* @__PURE__ */ jsxs82("header", { className: "squisq-media-edit-modal__header", children: [
45552
+ /* @__PURE__ */ jsx101("span", { id: titleId, className: "squisq-media-edit-modal__title", children: title }),
45553
+ /* @__PURE__ */ jsx101("span", { className: "squisq-media-edit-modal__path", children: target.src }),
45554
+ renderStatus && /* @__PURE__ */ jsx101(RenderStatusBadge, { status: renderStatus }),
45555
+ /* @__PURE__ */ jsx101(
45360
45556
  "button",
45361
45557
  {
45362
45558
  type: "button",
@@ -45367,11 +45563,11 @@ function MediaEditModal({ target, onClose }) {
45367
45563
  }
45368
45564
  )
45369
45565
  ] }),
45370
- !item ? /* @__PURE__ */ jsx100("p", { className: "squisq-media-edit-modal__empty", children: "This clip is no longer in the document." }) : !mediaEditRenders ? /* @__PURE__ */ jsx100("p", { className: "squisq-media-edit-modal__empty", children: "Media editing needs a media folder for this document." }) : /* @__PURE__ */ jsxs81(Fragment33, { children: [
45371
- /* @__PURE__ */ jsx100("div", { className: "squisq-media-edit-tabs", role: "tablist", "aria-label": "Edit sections", children: tabs.map((tab, index2) => {
45566
+ !item ? /* @__PURE__ */ jsx101("p", { className: "squisq-media-edit-modal__empty", children: "This clip is no longer in the document." }) : !mediaEditRenders ? /* @__PURE__ */ jsx101("p", { className: "squisq-media-edit-modal__empty", children: "Media editing needs a media folder for this document." }) : /* @__PURE__ */ jsxs82(Fragment34, { children: [
45567
+ /* @__PURE__ */ jsx101("div", { className: "squisq-media-edit-tabs", role: "tablist", "aria-label": "Edit sections", children: tabs.map((tab, index2) => {
45372
45568
  const selected = tab.id === activeTab;
45373
45569
  const edited = tabHasEdits(tab.id, draft);
45374
- return /* @__PURE__ */ jsxs81(
45570
+ return /* @__PURE__ */ jsxs82(
45375
45571
  "button",
45376
45572
  {
45377
45573
  ref: (el) => {
@@ -45390,21 +45586,21 @@ function MediaEditModal({ target, onClose }) {
45390
45586
  onKeyDown: (e2) => onTabKeyDown(e2, index2),
45391
45587
  children: [
45392
45588
  tab.label,
45393
- edited && /* @__PURE__ */ jsx100("span", { className: "squisq-sr-only", children: " (edited)" })
45589
+ edited && /* @__PURE__ */ jsx101("span", { className: "squisq-sr-only", children: " (edited)" })
45394
45590
  ]
45395
45591
  },
45396
45592
  tab.id
45397
45593
  );
45398
45594
  }) }),
45399
- /* @__PURE__ */ jsxs81("div", { className: "squisq-media-edit-modal__body", children: [
45400
- /* @__PURE__ */ jsx100(
45595
+ /* @__PURE__ */ jsxs82("div", { className: "squisq-media-edit-modal__body", children: [
45596
+ /* @__PURE__ */ jsx101(
45401
45597
  "div",
45402
45598
  {
45403
45599
  role: "tabpanel",
45404
45600
  id: panelId("audio"),
45405
45601
  "aria-labelledby": tabId("audio"),
45406
45602
  hidden: activeTab !== "audio",
45407
- children: /* @__PURE__ */ jsx100(
45603
+ children: /* @__PURE__ */ jsx101(
45408
45604
  MediaEditAudioSection,
45409
45605
  {
45410
45606
  item,
@@ -45416,14 +45612,14 @@ function MediaEditModal({ target, onClose }) {
45416
45612
  )
45417
45613
  }
45418
45614
  ),
45419
- /* @__PURE__ */ jsx100(
45615
+ /* @__PURE__ */ jsx101(
45420
45616
  "div",
45421
45617
  {
45422
45618
  role: "tabpanel",
45423
45619
  id: panelId("timing"),
45424
45620
  "aria-labelledby": tabId("timing"),
45425
45621
  hidden: activeTab !== "timing",
45426
- children: /* @__PURE__ */ jsx100(
45622
+ children: /* @__PURE__ */ jsx101(
45427
45623
  MediaEditTimingSection,
45428
45624
  {
45429
45625
  item,
@@ -45435,17 +45631,17 @@ function MediaEditModal({ target, onClose }) {
45435
45631
  )
45436
45632
  }
45437
45633
  ),
45438
- item.kind === "video" && /* @__PURE__ */ jsx100(
45634
+ item.kind === "video" && /* @__PURE__ */ jsx101(
45439
45635
  "div",
45440
45636
  {
45441
45637
  role: "tabpanel",
45442
45638
  id: panelId("frame"),
45443
45639
  "aria-labelledby": tabId("frame"),
45444
45640
  hidden: activeTab !== "frame",
45445
- children: /* @__PURE__ */ jsx100(MediaEditFrameSection, { item, draft, onChange: setDraft })
45641
+ children: /* @__PURE__ */ jsx101(MediaEditFrameSection, { item, draft, onChange: setDraft })
45446
45642
  }
45447
45643
  ),
45448
- companions.length > 0 && /* @__PURE__ */ jsxs81("p", { className: "squisq-media-edit-note", children: [
45644
+ companions.length > 0 && /* @__PURE__ */ jsxs82("p", { className: "squisq-media-edit-note", children: [
45449
45645
  "Cleanup and pause cuts also apply to ",
45450
45646
  companions.length,
45451
45647
  " linked",
@@ -45455,16 +45651,16 @@ function MediaEditModal({ target, onClose }) {
45455
45651
  ] })
45456
45652
  ] })
45457
45653
  ] }),
45458
- /* @__PURE__ */ jsxs81("footer", { className: "squisq-media-edit-modal__footer", children: [
45459
- /* @__PURE__ */ jsx100("p", { className: "squisq-media-edit-status", role: "status", "data-state": renderStatus?.state, children: renderStatus && item && mediaEditRenders && /* @__PURE__ */ jsx100(
45654
+ /* @__PURE__ */ jsxs82("footer", { className: "squisq-media-edit-modal__footer", children: [
45655
+ /* @__PURE__ */ jsx101("p", { className: "squisq-media-edit-status", role: "status", "data-state": renderStatus?.state, children: renderStatus && item && mediaEditRenders && /* @__PURE__ */ jsx101(
45460
45656
  RenderStatusText,
45461
45657
  {
45462
45658
  status: renderStatus,
45463
45659
  onRetry: () => mediaEditRenders.retry(item.clip)
45464
45660
  }
45465
45661
  ) }),
45466
- /* @__PURE__ */ jsx100("button", { type: "button", onClick: onClose, children: "Cancel" }),
45467
- /* @__PURE__ */ jsx100(
45662
+ /* @__PURE__ */ jsx101("button", { type: "button", onClick: onClose, children: "Cancel" }),
45663
+ /* @__PURE__ */ jsx101(
45468
45664
  "button",
45469
45665
  {
45470
45666
  type: "button",
@@ -45729,7 +45925,7 @@ import {
45729
45925
  createMediaEditRenderManager,
45730
45926
  useProcessedAudio as useProcessedAudio4
45731
45927
  } from "@bendyline/squisq-video-react/media-edit";
45732
- import { Fragment as Fragment34, jsx as jsx101, jsxs as jsxs82 } from "react/jsx-runtime";
45928
+ import { Fragment as Fragment35, jsx as jsx102, jsxs as jsxs83 } from "react/jsx-runtime";
45733
45929
  function EditorShell({
45734
45930
  ariaLabel,
45735
45931
  initialMarkdown = "",
@@ -45835,11 +46031,11 @@ function EditorShell({
45835
46031
  () => mediaEditRenders === void 0 && effectiveMediaProvider ? createMediaEditRenderManager({ mediaProvider: effectiveMediaProvider }) : null,
45836
46032
  [mediaEditRenders, effectiveMediaProvider]
45837
46033
  );
45838
- useEffect78(() => () => ownedMediaEditRenders?.dispose(), [ownedMediaEditRenders]);
46034
+ useEffect80(() => () => ownedMediaEditRenders?.dispose(), [ownedMediaEditRenders]);
45839
46035
  const effectiveMediaEditRenders = mediaEditRenders === void 0 ? ownedMediaEditRenders : mediaEditRenders;
45840
46036
  const filesToggleEnabled = showFilesToggle ?? effectiveMediaProvider !== void 0;
45841
46037
  const effectiveInitialView = hostMode === "chat" || !showPlayTab && initialView === "preview" ? "wysiwyg" : initialView;
45842
- return /* @__PURE__ */ jsx101(MediaContext7.Provider, { value: effectiveMediaProvider ?? null, children: /* @__PURE__ */ jsx101(
46038
+ return /* @__PURE__ */ jsx102(MediaContext7.Provider, { value: effectiveMediaProvider ?? null, children: /* @__PURE__ */ jsx102(
45843
46039
  EditorProvider,
45844
46040
  {
45845
46041
  initialMarkdown,
@@ -45885,7 +46081,7 @@ function EditorShell({
45885
46081
  themeInheritance,
45886
46082
  viewPreferences,
45887
46083
  onViewPreferencesChange,
45888
- children: /* @__PURE__ */ jsx101(ProofingRoot, { children: /* @__PURE__ */ jsx101(ReviewRoot, { providers: reviewProviders, children: /* @__PURE__ */ jsx101(PageTemplateContext.Provider, { value: pageTemplates, children: /* @__PURE__ */ jsx101(
46084
+ children: /* @__PURE__ */ jsx102(ProofingRoot, { children: /* @__PURE__ */ jsx102(ReviewRoot, { providers: reviewProviders, children: /* @__PURE__ */ jsx102(PageTemplateContext.Provider, { value: pageTemplates, children: /* @__PURE__ */ jsx102(
45889
46085
  EditorShellInner,
45890
46086
  {
45891
46087
  ariaLabel: ariaLabel ?? (hostMode === "chat" ? "Message" : fileName ? `Edit ${fileName}` : "Document editor"),
@@ -45951,11 +46147,11 @@ function UseModeToolbarControls({
45951
46147
  summarizationDesigner
45952
46148
  }) {
45953
46149
  const printMode = usePrintMode();
45954
- if (printMode.active) return /* @__PURE__ */ jsx101(PrintPreviewToolbar, {});
45955
- return /* @__PURE__ */ jsxs82(Fragment34, { children: [
45956
- /* @__PURE__ */ jsx101(PreviewToolbarControls, { summarizationDesigner }),
45957
- /* @__PURE__ */ jsx101(PresentationModeControl, {}),
45958
- allowPrint && /* @__PURE__ */ jsx101(PrintModeControl, {})
46150
+ if (printMode.active) return /* @__PURE__ */ jsx102(PrintPreviewToolbar, {});
46151
+ return /* @__PURE__ */ jsxs83(Fragment35, { children: [
46152
+ /* @__PURE__ */ jsx102(PreviewToolbarControls, { summarizationDesigner }),
46153
+ /* @__PURE__ */ jsx102(PresentationModeControl, {}),
46154
+ allowPrint && /* @__PURE__ */ jsx102(PrintModeControl, {})
45959
46155
  ] });
45960
46156
  }
45961
46157
  function UseModeProviders({
@@ -45964,13 +46160,13 @@ function UseModeProviders({
45964
46160
  allowPresentationWindow,
45965
46161
  allowPresentationFullscreen
45966
46162
  }) {
45967
- return /* @__PURE__ */ jsx101(
46163
+ return /* @__PURE__ */ jsx102(
45968
46164
  PresentationModeProvider,
45969
46165
  {
45970
46166
  rootRef,
45971
46167
  allowWindow: allowPresentationWindow,
45972
46168
  allowFullscreen: allowPresentationFullscreen,
45973
- children: /* @__PURE__ */ jsx101(PrintModeProvider, { rootRef, children })
46169
+ children: /* @__PURE__ */ jsx102(PrintModeProvider, { rootRef, children })
45974
46170
  }
45975
46171
  );
45976
46172
  }
@@ -46029,8 +46225,8 @@ function EditorShellInner({
46029
46225
  defaultThemeId,
46030
46226
  defaultThemeLabel
46031
46227
  }) {
46032
- const shellRef = useRef74(null);
46033
- const [uncontrolledNavigationSheet, setUncontrolledNavigationSheet] = useState90(null);
46228
+ const shellRef = useRef75(null);
46229
+ const [uncontrolledNavigationSheet, setUncontrolledNavigationSheet] = useState91(null);
46034
46230
  const navigationSheetPanel = navigationSheet === void 0 ? uncontrolledNavigationSheet : navigationSheet;
46035
46231
  const handleNavigationSheetChange = useCallback63(
46036
46232
  (panel) => {
@@ -46069,8 +46265,8 @@ function EditorShellInner({
46069
46265
  } = useEditorContext();
46070
46266
  const processedAudio = useProcessedAudio4(mediaEditRenders);
46071
46267
  const { docThemes, onDocThemesChange } = useDocCustomThemes();
46072
- const lastEditingView = useRef74(activeView === "raw" ? "raw" : "wysiwyg");
46073
- useEffect78(() => {
46268
+ const lastEditingView = useRef75(activeView === "raw" ? "raw" : "wysiwyg");
46269
+ useEffect80(() => {
46074
46270
  if (activeView !== "preview") lastEditingView.current = activeView;
46075
46271
  }, [activeView]);
46076
46272
  const editingView = activeView === "preview" ? lastEditingView.current : activeView;
@@ -46117,32 +46313,32 @@ function EditorShellInner({
46117
46313
  );
46118
46314
  const timelineClock = useTimelineClock(isTimelineMode ? timelineDuration : 0);
46119
46315
  const hasTimelineVideo = timelineVideoSchedule.length > 0;
46120
- const [timelineVideoVisible, setTimelineVideoVisible] = useState90(false);
46121
- const [timelineCompositionVisible, setTimelineCompositionVisible] = useState90(false);
46316
+ const [timelineVideoVisible, setTimelineVideoVisible] = useState91(false);
46317
+ const [timelineCompositionVisible, setTimelineCompositionVisible] = useState91(false);
46122
46318
  const timelinePreviewCount = Number(timelineVideoVisible) + Number(timelineCompositionVisible);
46123
- const [showFiles, setShowFiles] = useState90(false);
46124
- const [filesFocusPath, setFilesFocusPath] = useState90(null);
46125
- const [mediaRefreshKey, setMediaRefreshKey] = useState90(0);
46126
- const [mediaCount, setMediaCount] = useState90(0);
46127
- const [mediaBinRecorderOpen, setMediaBinRecorderOpen] = useState90(false);
46319
+ const [showFiles, setShowFiles] = useState91(false);
46320
+ const [filesFocusPath, setFilesFocusPath] = useState91(null);
46321
+ const [mediaRefreshKey, setMediaRefreshKey] = useState91(0);
46322
+ const [mediaCount, setMediaCount] = useState91(0);
46323
+ const [mediaBinRecorderOpen, setMediaBinRecorderOpen] = useState91(false);
46128
46324
  const mediaListRefreshKey = mediaRefreshKey + mediaRevision;
46129
46325
  const usedMediaPaths = useMemo62(
46130
46326
  () => collectMediaReferencesFromMarkdown(markdownSource),
46131
46327
  [markdownSource]
46132
46328
  );
46133
- const imageEditFallbackContainerRef = useRef74(null);
46329
+ const imageEditFallbackContainerRef = useRef75(null);
46134
46330
  if (imageEditFallbackContainerRef.current === null) {
46135
46331
  imageEditFallbackContainerRef.current = new MemoryContentContainer2();
46136
46332
  }
46137
46333
  const imageEditFallbackContainer = imageEditFallbackContainerRef.current;
46138
46334
  const isDark = colorScheme === "dark";
46139
- useEffect78(() => {
46335
+ useEffect80(() => {
46140
46336
  if (!isTimelineMode || !hasTimelineVideo) setTimelineVideoVisible(false);
46141
46337
  }, [isTimelineMode, hasTimelineVideo]);
46142
- useEffect78(() => {
46338
+ useEffect80(() => {
46143
46339
  if (!isTimelineMode || !doc?.blocks.length) setTimelineCompositionVisible(false);
46144
46340
  }, [isTimelineMode, doc]);
46145
- useEffect78(() => {
46341
+ useEffect80(() => {
46146
46342
  if (!mediaProvider) {
46147
46343
  setMediaCount(0);
46148
46344
  return;
@@ -46166,7 +46362,7 @@ function EditorShellInner({
46166
46362
  cancelled = true;
46167
46363
  };
46168
46364
  }, [mediaProvider, mediaListRefreshKey]);
46169
- useEffect78(() => {
46365
+ useEffect80(() => {
46170
46366
  if (showFilesWhenNotEmpty && mediaCount > 0) setShowFiles(true);
46171
46367
  }, [mediaCount, showFilesWhenNotEmpty]);
46172
46368
  const handleToggleFiles = useCallback63(() => {
@@ -46185,8 +46381,8 @@ function EditorShellInner({
46185
46381
  },
46186
46382
  [insertionTarget]
46187
46383
  );
46188
- const docBasenameRef = useRef74("document");
46189
- useEffect78(() => {
46384
+ const docBasenameRef = useRef75("document");
46385
+ useEffect80(() => {
46190
46386
  let cancelled = false;
46191
46387
  docBasenameRef.current = "document";
46192
46388
  void resolveDocBasename(workspaceContainer).then((base) => {
@@ -46269,7 +46465,7 @@ function EditorShellInner({
46269
46465
  onDrop: handleFileDrop,
46270
46466
  enabled: !readOnly
46271
46467
  });
46272
- useEffect78(() => {
46468
+ useEffect80(() => {
46273
46469
  onChange?.(markdownSource);
46274
46470
  }, [markdownSource, onChange]);
46275
46471
  const handleShellKeyDown = useCallback63((e2) => {
@@ -46325,7 +46521,7 @@ function EditorShellInner({
46325
46521
  anchor.removeAttribute("data-squisq-link-title");
46326
46522
  }, []);
46327
46523
  const autoGrow = minHeight !== void 0 || maxHeight !== void 0;
46328
- const shell = /* @__PURE__ */ jsxs82(
46524
+ const shell = /* @__PURE__ */ jsxs83(
46329
46525
  "div",
46330
46526
  {
46331
46527
  ref: shellRef,
@@ -46364,7 +46560,7 @@ function EditorShellInner({
46364
46560
  },
46365
46561
  ...containerProps,
46366
46562
  children: [
46367
- /* @__PURE__ */ jsx101(CustomThemeProvider, { docThemes, onDocThemesChange, children: /* @__PURE__ */ jsx101(
46563
+ /* @__PURE__ */ jsx102(CustomThemeProvider, { docThemes, onDocThemesChange, children: /* @__PURE__ */ jsx102(
46368
46564
  PreviewSettingsProvider,
46369
46565
  {
46370
46566
  doc,
@@ -46372,25 +46568,25 @@ function EditorShellInner({
46372
46568
  themeOverride,
46373
46569
  defaultThemeId,
46374
46570
  defaultThemeLabel,
46375
- children: /* @__PURE__ */ jsxs82(
46571
+ children: /* @__PURE__ */ jsxs83(
46376
46572
  UseModeProviders,
46377
46573
  {
46378
46574
  rootRef: shellRef,
46379
46575
  allowPresentationWindow,
46380
46576
  allowPresentationFullscreen,
46381
46577
  children: [
46382
- isImageMode ? (toolbarSlotLeft || toolbarSlotRight) && /* @__PURE__ */ jsxs82("div", { className: "squisq-editor-header squisq-editor-header--image", children: [
46578
+ isImageMode ? (toolbarSlotLeft || toolbarSlotRight) && /* @__PURE__ */ jsxs83("div", { className: "squisq-editor-header squisq-editor-header--image", children: [
46383
46579
  toolbarSlotLeft,
46384
- /* @__PURE__ */ jsx101("div", { style: { flex: 1 } }),
46580
+ /* @__PURE__ */ jsx102("div", { style: { flex: 1 } }),
46385
46581
  toolbarSlotRight
46386
- ] }) : /* @__PURE__ */ jsx101("div", { className: "squisq-editor-header", children: /* @__PURE__ */ jsx101(
46582
+ ] }) : /* @__PURE__ */ jsx102("div", { className: "squisq-editor-header", children: /* @__PURE__ */ jsx102(
46387
46583
  Toolbar,
46388
46584
  {
46389
46585
  showFiles,
46390
46586
  fileCount: mediaCount,
46391
46587
  onToggleFiles: !isCodeMode && filesToggleEnabled ? handleToggleFiles : void 0,
46392
46588
  slotLeft: toolbarSlotLeft,
46393
- slotAfterTabs: !isCodeMode && isPreview && /* @__PURE__ */ jsx101(
46589
+ slotAfterTabs: !isCodeMode && isPreview && /* @__PURE__ */ jsx102(
46394
46590
  UseModeToolbarControls,
46395
46591
  {
46396
46592
  allowPrint,
@@ -46407,7 +46603,7 @@ function EditorShellInner({
46407
46603
  findShortcut
46408
46604
  }
46409
46605
  ) }),
46410
- /* @__PURE__ */ jsxs82(
46606
+ /* @__PURE__ */ jsxs83(
46411
46607
  "div",
46412
46608
  {
46413
46609
  className: "squisq-editor-content",
@@ -46421,7 +46617,7 @@ function EditorShellInner({
46421
46617
  display: "flex"
46422
46618
  },
46423
46619
  children: [
46424
- /* @__PURE__ */ jsxs82(
46620
+ /* @__PURE__ */ jsxs83(
46425
46621
  "div",
46426
46622
  {
46427
46623
  className: "squisq-editor-primary",
@@ -46432,7 +46628,7 @@ function EditorShellInner({
46432
46628
  position: "relative"
46433
46629
  },
46434
46630
  children: [
46435
- isImageMode && imageSrc && (imageMode === "edit" && imageEditorContainer ? /* @__PURE__ */ jsx101(
46631
+ isImageMode && imageSrc && (imageMode === "edit" && imageEditorContainer ? /* @__PURE__ */ jsx102(
46436
46632
  ImageEditor,
46437
46633
  {
46438
46634
  filesContainer: imageEditorContainer,
@@ -46442,16 +46638,16 @@ function EditorShellInner({
46442
46638
  onExport: onImageExport,
46443
46639
  surface: colorScheme === "dark" ? DARK_SURFACE2 : LIGHT_SURFACE2
46444
46640
  }
46445
- ) : /* @__PURE__ */ jsx101(ImageViewer, { src: imageSrc, alt: imageAlt, theme: colorScheme })),
46446
- !isImageMode && editingView === "raw" && /* @__PURE__ */ jsxs82(
46641
+ ) : /* @__PURE__ */ jsx102(ImageViewer, { src: imageSrc, alt: imageAlt, theme: colorScheme })),
46642
+ !isImageMode && editingView === "raw" && /* @__PURE__ */ jsxs83(
46447
46643
  "div",
46448
46644
  {
46449
46645
  className: "squisq-editor-with-gutter",
46450
46646
  hidden: isPreview,
46451
46647
  style: isPreview ? { display: "none" } : void 0,
46452
46648
  children: [
46453
- isMarkdownMode && outlineVisible && /* @__PURE__ */ jsx101(OutlinePanel, { width: outlineWidth, readOnly }, "outline"),
46454
- /* @__PURE__ */ jsx101(
46649
+ isMarkdownMode && outlineVisible && /* @__PURE__ */ jsx102(OutlinePanel, { width: outlineWidth, readOnly }, "outline"),
46650
+ /* @__PURE__ */ jsx102(
46455
46651
  BlockCardView,
46456
46652
  {
46457
46653
  active: isCardMode,
@@ -46460,7 +46656,7 @@ function EditorShellInner({
46460
46656
  onPrev: prevBlock,
46461
46657
  onNext: nextBlock,
46462
46658
  onAdd: addBlock,
46463
- children: /* @__PURE__ */ jsx101("div", { className: "squisq-raw-editor-container", children: /* @__PURE__ */ jsx101(
46659
+ children: /* @__PURE__ */ jsx102("div", { className: "squisq-raw-editor-container", children: /* @__PURE__ */ jsx102(
46464
46660
  RawEditor,
46465
46661
  {
46466
46662
  ariaLabel: `${ariaLabel} \u2014 source`,
@@ -46472,9 +46668,9 @@ function EditorShellInner({
46472
46668
  },
46473
46669
  "raw-frame"
46474
46670
  ),
46475
- isCodeMode && codeContext && /* @__PURE__ */ jsx101(CodeContextZones, { options: codeContext }, "code-context"),
46476
- isMarkdownMode && isCardMode && inlinePreviewVisible && /* @__PURE__ */ jsx101(BlockPreviewPanel, { basePath }, "block-preview"),
46477
- isMarkdownMode && !isCardMode && inlinePreviewVisible && /* @__PURE__ */ jsx101(
46671
+ isCodeMode && codeContext && /* @__PURE__ */ jsx102(CodeContextZones, { options: codeContext }, "code-context"),
46672
+ isMarkdownMode && isCardMode && inlinePreviewVisible && /* @__PURE__ */ jsx102(BlockPreviewPanel, { basePath }, "block-preview"),
46673
+ isMarkdownMode && !isCardMode && inlinePreviewVisible && /* @__PURE__ */ jsx102(
46478
46674
  InlinePreviewGutter,
46479
46675
  {
46480
46676
  width: inlinePreviewWidth,
@@ -46483,7 +46679,7 @@ function EditorShellInner({
46483
46679
  },
46484
46680
  "inline"
46485
46681
  ),
46486
- isMarkdownMode && /* @__PURE__ */ jsx101(
46682
+ isMarkdownMode && /* @__PURE__ */ jsx102(
46487
46683
  NavigationSheet,
46488
46684
  {
46489
46685
  panel: navigationSheetPanel,
@@ -46498,15 +46694,15 @@ function EditorShellInner({
46498
46694
  },
46499
46695
  "raw-shell"
46500
46696
  ),
46501
- isMarkdownMode && editingView === "wysiwyg" && /* @__PURE__ */ jsxs82(
46697
+ isMarkdownMode && editingView === "wysiwyg" && /* @__PURE__ */ jsxs83(
46502
46698
  "div",
46503
46699
  {
46504
46700
  className: "squisq-editor-with-gutter",
46505
46701
  hidden: isPreview,
46506
46702
  style: isPreview ? { display: "none" } : void 0,
46507
46703
  children: [
46508
- outlineVisible && /* @__PURE__ */ jsx101(OutlinePanel, { width: outlineWidth, readOnly }, "outline"),
46509
- /* @__PURE__ */ jsx101(
46704
+ outlineVisible && /* @__PURE__ */ jsx102(OutlinePanel, { width: outlineWidth, readOnly }, "outline"),
46705
+ /* @__PURE__ */ jsx102(
46510
46706
  BlockCardView,
46511
46707
  {
46512
46708
  active: isCardMode,
@@ -46515,7 +46711,7 @@ function EditorShellInner({
46515
46711
  onPrev: prevBlock,
46516
46712
  onNext: nextBlock,
46517
46713
  onAdd: addBlock,
46518
- children: /* @__PURE__ */ jsx101(
46714
+ children: /* @__PURE__ */ jsx102(
46519
46715
  WysiwygEditor,
46520
46716
  {
46521
46717
  ariaLabel,
@@ -46533,8 +46729,8 @@ function EditorShellInner({
46533
46729
  },
46534
46730
  "wysiwyg-frame"
46535
46731
  ),
46536
- isCardMode && inlinePreviewVisible && /* @__PURE__ */ jsx101(BlockPreviewPanel, { basePath }, "block-preview"),
46537
- !isCardMode && inlinePreviewVisible && /* @__PURE__ */ jsx101(
46732
+ isCardMode && inlinePreviewVisible && /* @__PURE__ */ jsx102(BlockPreviewPanel, { basePath }, "block-preview"),
46733
+ !isCardMode && inlinePreviewVisible && /* @__PURE__ */ jsx102(
46538
46734
  InlinePreviewGutter,
46539
46735
  {
46540
46736
  width: inlinePreviewWidth,
@@ -46543,7 +46739,7 @@ function EditorShellInner({
46543
46739
  },
46544
46740
  "inline"
46545
46741
  ),
46546
- /* @__PURE__ */ jsx101(
46742
+ /* @__PURE__ */ jsx102(
46547
46743
  NavigationSheet,
46548
46744
  {
46549
46745
  panel: navigationSheetPanel,
@@ -46558,7 +46754,7 @@ function EditorShellInner({
46558
46754
  },
46559
46755
  "wysiwyg-shell"
46560
46756
  ),
46561
- isMarkdownMode && isPreview && /* @__PURE__ */ jsx101(
46757
+ isMarkdownMode && isPreview && /* @__PURE__ */ jsx102(
46562
46758
  PreviewPanel,
46563
46759
  {
46564
46760
  basePath,
@@ -46571,7 +46767,7 @@ function EditorShellInner({
46571
46767
  ]
46572
46768
  }
46573
46769
  ),
46574
- isTimelineMode && timelineVideoVisible && /* @__PURE__ */ jsx101(
46770
+ isTimelineMode && timelineVideoVisible && /* @__PURE__ */ jsx102(
46575
46771
  TimelineVideoPanel,
46576
46772
  {
46577
46773
  schedule: timelineVideoSchedule,
@@ -46581,7 +46777,7 @@ function EditorShellInner({
46581
46777
  onClose: () => setTimelineVideoVisible(false)
46582
46778
  }
46583
46779
  ),
46584
- isTimelineMode && timelineCompositionVisible && /* @__PURE__ */ jsx101(
46780
+ isTimelineMode && timelineCompositionVisible && /* @__PURE__ */ jsx102(
46585
46781
  TimelineCompositionPanel,
46586
46782
  {
46587
46783
  doc,
@@ -46591,7 +46787,7 @@ function EditorShellInner({
46591
46787
  onClose: () => setTimelineCompositionVisible(false)
46592
46788
  }
46593
46789
  ),
46594
- isMarkdownMode && showFiles && /* @__PURE__ */ jsx101(
46790
+ isMarkdownMode && showFiles && /* @__PURE__ */ jsx102(
46595
46791
  MediaBin,
46596
46792
  {
46597
46793
  mediaProvider,
@@ -46607,11 +46803,11 @@ function EditorShellInner({
46607
46803
  highlightPath: filesFocusPath
46608
46804
  }
46609
46805
  ),
46610
- isMarkdownMode && /* @__PURE__ */ jsx101(ProofingPanel, {}),
46611
- isMarkdownMode && /* @__PURE__ */ jsx101(ReviewPanel, {}),
46806
+ isMarkdownMode && /* @__PURE__ */ jsx102(ProofingPanel, {}),
46807
+ isMarkdownMode && /* @__PURE__ */ jsx102(ReviewPanel, {}),
46612
46808
  isMarkdownMode && sidePanelSlot,
46613
- isMarkdownMode && /* @__PURE__ */ jsx101(ThemeDesignerDock, {}),
46614
- isMarkdownMode && isDragging && !(activeView === "wysiwyg" && dragContentType === "media") && /* @__PURE__ */ jsx101(
46809
+ isMarkdownMode && /* @__PURE__ */ jsx102(ThemeDesignerDock, {}),
46810
+ isMarkdownMode && isDragging && !(activeView === "wysiwyg" && dragContentType === "media") && /* @__PURE__ */ jsx102(
46615
46811
  DropZoneOverlay,
46616
46812
  {
46617
46813
  dragContentType,
@@ -46622,7 +46818,7 @@ function EditorShellInner({
46622
46818
  ]
46623
46819
  }
46624
46820
  ),
46625
- isTimelineMode && /* @__PURE__ */ jsx101(
46821
+ isTimelineMode && /* @__PURE__ */ jsx102(
46626
46822
  TimelineToolbar,
46627
46823
  {
46628
46824
  literalVideoVisible: timelineVideoVisible,
@@ -46633,7 +46829,7 @@ function EditorShellInner({
46633
46829
  onToggleComposition: () => setTimelineCompositionVisible((visible) => !visible)
46634
46830
  }
46635
46831
  ),
46636
- isTimelineMode && /* @__PURE__ */ jsx101(
46832
+ isTimelineMode && /* @__PURE__ */ jsx102(
46637
46833
  TimelineTrack,
46638
46834
  {
46639
46835
  doc: timelineDoc,
@@ -46642,8 +46838,8 @@ function EditorShellInner({
46642
46838
  basePath
46643
46839
  }
46644
46840
  ),
46645
- statusBarVisible && !isImageMode && /* @__PURE__ */ jsx101(StatusBar, { slotRight: statusBarSlotRight }),
46646
- isMarkdownMode && allowRecording && mediaProvider && /* @__PURE__ */ jsx101(
46841
+ statusBarVisible && !isImageMode && /* @__PURE__ */ jsx102(StatusBar, { slotRight: statusBarSlotRight }),
46842
+ isMarkdownMode && allowRecording && mediaProvider && /* @__PURE__ */ jsx102(
46647
46843
  RecorderEntry,
46648
46844
  {
46649
46845
  open: mediaBinRecorderOpen,
@@ -46656,8 +46852,8 @@ function EditorShellInner({
46656
46852
  )
46657
46853
  }
46658
46854
  ) }),
46659
- /* @__PURE__ */ jsx101(TooltipLayer, {}),
46660
- imageEditTarget !== null && mediaProvider && /* @__PURE__ */ jsx101(
46855
+ /* @__PURE__ */ jsx102(TooltipLayer, {}),
46856
+ imageEditTarget !== null && mediaProvider && /* @__PURE__ */ jsx102(
46661
46857
  ImageEditModal,
46662
46858
  {
46663
46859
  relativePath: imageEditTarget,
@@ -46673,12 +46869,12 @@ function EditorShellInner({
46673
46869
  shellTheme: colorScheme
46674
46870
  }
46675
46871
  ),
46676
- mediaEditTarget !== null && /* @__PURE__ */ jsx101(MediaEditModal, { target: mediaEditTarget, onClose: closeMediaEdit })
46872
+ mediaEditTarget !== null && /* @__PURE__ */ jsx102(MediaEditModal, { target: mediaEditTarget, onClose: closeMediaEdit })
46677
46873
  ]
46678
46874
  }
46679
46875
  );
46680
- return /* @__PURE__ */ jsxs82(EditorContextMenuProvider, { rootRef: shellRef, readOnly, children: [
46681
- /* @__PURE__ */ jsx101(MediaEditContextMenuItems, {}),
46876
+ return /* @__PURE__ */ jsxs83(EditorContextMenuProvider, { rootRef: shellRef, readOnly, children: [
46877
+ /* @__PURE__ */ jsx102(MediaEditContextMenuItems, {}),
46682
46878
  shell
46683
46879
  ] });
46684
46880
  }