superdoc 2.29.0-next.9 → 2.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/dist/chunks/{FindReplaceSurface-BKVHzhQ4.es.js → FindReplaceSurface-B_5ggdWg.es.js} +1 -1
  2. package/dist/chunks/{FindReplaceSurface-BNDrJ6VS.cjs → FindReplaceSurface-fVHxPXtn.cjs} +1 -1
  3. package/dist/chunks/{PasswordPromptSurface-6mF6Azda.es.js → PasswordPromptSurface-CZqhDQQ1.es.js} +1 -1
  4. package/dist/chunks/{PasswordPromptSurface-BNkaztaP.cjs → PasswordPromptSurface-x8GNmMJT.cjs} +1 -1
  5. package/dist/chunks/{PdfViewer-aOWhUVI7.es.js → PdfViewer-CW09MNrB.es.js} +4 -10
  6. package/dist/chunks/{PdfViewer-DmSkZehl.cjs → PdfViewer-CkrAHpC-.cjs} +4 -10
  7. package/dist/chunks/{_plugin-vue_export-helper-6MBoygIY.cjs → _plugin-vue_export-helper-BkbCxNeT.cjs} +31 -7
  8. package/dist/chunks/{_plugin-vue_export-helper-CsJQtMvr.es.js → _plugin-vue_export-helper-DRPRMkeA.es.js} +20 -8
  9. package/dist/chunks/{create-super-doc-ui-Bm5kmx0W.es.js → create-super-doc-ui-Dc8dQAMc.es.js} +83 -114
  10. package/dist/chunks/{create-super-doc-ui-DN70aatf.cjs → create-super-doc-ui-L60GhVAX.cjs} +199 -236
  11. package/dist/collaboration-upgrade-engine.cjs +1 -1
  12. package/dist/collaboration-upgrade-engine.es.js +1 -1
  13. package/dist/document-api/src/contract/command-catalog.d.ts +1 -1
  14. package/dist/public/ui-react.cjs +1 -1
  15. package/dist/public/ui-react.es.js +1 -1
  16. package/dist/public/ui-vue.cjs +1 -1
  17. package/dist/public/ui-vue.es.js +1 -1
  18. package/dist/public/ui.cjs +1 -1
  19. package/dist/public/ui.es.js +1 -1
  20. package/dist/style.css +1 -1
  21. package/dist/style.layered.css +1 -1
  22. package/dist/superdoc/src/components/CommentsLayer/collect-removed-comment-ids.d.ts +11 -1
  23. package/dist/superdoc/src/components/CommentsLayer/collect-tracked-change-thread.d.ts +19 -2
  24. package/dist/superdoc/src/components/CommentsLayer/comment-urls.d.ts +1 -1
  25. package/dist/superdoc/src/components/CommentsLayer/commentsList/super-comments-list.d.ts +23 -20
  26. package/dist/superdoc/src/components/CommentsLayer/helpers.d.ts +1 -4
  27. package/dist/superdoc/src/components/CommentsLayer/tracked-change-threading.d.ts +16 -1
  28. package/dist/superdoc/src/components/Whiteboard/WhiteboardLayer.vue.d.ts +4 -5
  29. package/dist/superdoc/src/components/Whiteboard/WhiteboardPage.vue.d.ts +3 -4
  30. package/dist/superdoc/src/components/Whiteboard/whiteboard-types.d.ts +2 -0
  31. package/dist/superdoc/src/components/surfaces/watermark-surface-runtime.d.ts +7 -7
  32. package/dist/superdoc/src/composables/use-comment-small-screen.d.ts +11 -7
  33. package/dist/superdoc/src/composables/use-compact-comment-popover.d.ts +44 -18
  34. package/dist/superdoc/src/composables/use-find-replace.d.ts +13 -3
  35. package/dist/superdoc/src/composables/use-password-prompt.d.ts +1 -1
  36. package/dist/superdoc/src/composables/use-viewport-fit.d.ts +62 -26
  37. package/dist/superdoc/src/core/SuperDoc.d.ts +3 -3
  38. package/dist/superdoc/src/core/pdf/pdf-adapter.d.ts +6 -2
  39. package/dist/superdoc/src/core/types/index.d.ts +37 -4
  40. package/dist/superdoc/src/core/v2-integration/browser-peer-runtime.d.ts +5 -3
  41. package/dist/superdoc/src/core/v2-integration/cdn-engine-loader.d.ts +3 -13
  42. package/dist/superdoc/src/core/v2-integration/internal-vue-runtime.d.ts +64 -59
  43. package/dist/superdoc/src/helpers/object-guards.d.ts +1 -0
  44. package/dist/superdoc/src/helpers/v2-author-required-rejection.d.ts +8 -11
  45. package/dist/superdoc/src/helpers/v2-bulk-decision-event.d.ts +9 -7
  46. package/dist/superdoc/src/helpers/v2-keyboard-edit-rejection.d.ts +8 -7
  47. package/dist/superdoc/src/helpers/v2-mutation-exception.d.ts +12 -8
  48. package/dist/superdoc/src/helpers/v2-review-target.d.ts +11 -1
  49. package/dist/superdoc/src/helpers/v2-selection-sync.d.ts +40 -14
  50. package/dist/superdoc/src/helpers/v2-typing-mutation-event.d.ts +14 -5
  51. package/dist/superdoc/src/icons.d.ts +11 -19
  52. package/dist/superdoc/src/internal/diagnostics/translate-diagnostic.d.ts +6 -4
  53. package/dist/superdoc/src/internal/toolbar/built-in/PageNumberMenu.vue.d.ts +25 -15
  54. package/dist/superdoc/src/internal/toolbar/built-in/constants.d.ts +3 -1
  55. package/dist/superdoc/src/internal/toolbar/built-in/font-options.d.ts +15 -1
  56. package/dist/superdoc/src/internal/toolbar/built-in/font-typeahead.d.ts +37 -7
  57. package/dist/superdoc/src/internal/toolbar/built-in/format-negation.d.ts +10 -4
  58. package/dist/superdoc/src/internal/toolbar/built-in/general.d.ts +12 -1
  59. package/dist/superdoc/src/internal/toolbar/built-in/helpers.d.ts +9 -4
  60. package/dist/superdoc/src/internal/toolbar/built-in/list-style-buttons.d.ts +2 -2
  61. package/dist/superdoc/src/internal/toolbar/built-in/page-number-feedback.d.ts +4 -5
  62. package/dist/superdoc/src/internal/toolbar/built-in/scroll-helpers.d.ts +3 -4
  63. package/dist/superdoc/src/internal/toolbar/built-in/toolbarIcons.d.ts +78 -145
  64. package/dist/superdoc/src/internal/toolbar/built-in/url-safety.d.ts +11 -3
  65. package/dist/superdoc/src/internal/toolbar/built-in-toolbar.d.ts +4 -3
  66. package/dist/superdoc/src/internal/toolbar/image-upload.d.ts +29 -39
  67. package/dist/superdoc/src/public/ui/format-painter-helpers.d.ts +2 -8
  68. package/dist/superdoc/src/stores/comments-store.d.ts +7 -7
  69. package/dist/superdoc/src/stores/helpers/comment-document-scope.d.ts +22 -0
  70. package/dist/superdoc/src/stores/helpers/pending-selection-snapshot.d.ts +17 -0
  71. package/dist/superdoc/src/stores/helpers/tracked-change-compaction.d.ts +16 -0
  72. package/dist/superdoc/src/stores/helpers/tracked-change-decision.d.ts +45 -0
  73. package/dist/superdoc/src/stores/superdoc-store.d.ts +21 -21
  74. package/dist/superdoc.cjs +423 -464
  75. package/dist/superdoc.es.js +335 -376
  76. package/dist-cdn/style.layered.css +1 -1
  77. package/dist-cdn/superdoc.min.css +1 -1
  78. package/dist-cdn/superdoc.min.js +41 -41
  79. package/package.json +3 -2
  80. package/dist/superdoc/src/main.d.ts +0 -1
@@ -1,20 +1,20 @@
1
1
  import { i as __toESM$2 } from "./chunks/rolldown-runtime-0pSA04fp.es.js";
2
+ import { $ as vModelSelect, A as onActivated, B as renderList, C as isRef$1, D as normalizeClass, E as nextTick, F as openBlock, G as toDisplayString, H as resolveDirective, I as provide$1, J as toRefs, K as toRaw$2, L as reactive, M as onDeactivated, N as onMounted, O as normalizeProps, P as onScopeDispose$1, Q as vModelCheckbox, R as readonly, S as isReactive$1, T as mergeProps, U as resolveDynamicComponent, V as renderSlot, W as shallowRef$1, X as useAttrs, Y as unref, Z as useSlots, _ as getCurrentInstance, a as computed$1, at as withModifiers, b as hasInjectionContext, c as createCommentVNode, d as createStaticVNode, et as vModelText, f as createTextVNode, g as effectScope, h as defineComponent, i as Transition, it as withKeys, j as onBeforeUnmount, k as normalizeStyle, l as createElementBlock, m as defineAsyncComponent, n as Fragment, nt as withCtx, o as createApp, ot as isPlainObject$1, p as createVNode, q as toRef, r as Teleport, rt as withDirectives, s as createBlock, st as isThenable$1, t as _plugin_vue_export_helper_default, tt as watch$1, u as createElementVNode, v as getCurrentScope, w as markRaw, x as inject$1, y as h, z as ref } from "./chunks/_plugin-vue_export-helper-DRPRMkeA.es.js";
2
3
  import { t as blank_default } from "./chunks/blank-docx-DzQccOlW.es.js";
3
- import { C as createInteractionHistory, E as recordInteraction, S as closeInteractionHistory, T as isWorkflowRecordingEnabled, _ as createTrackedChangePermissionResolver, a as registerFirstPartyCommandMutation, b as isPlainObject$1, c as getCommandDescriptor, d as mutationCommittedEventChangedDocument, f as createImageFilePicker, g as PERMISSIONS, h as BUILT_IN_PERMISSION_METHOD, i as readFirstPartyPageNumbers, l as applyV2CommentInvalidationFromMutation, n as executeFirstPartyCommandAsync, o as isRecord, p as resolveImageSrc, r as executeFirstPartyShortcutAsync, t as createSuperDocUI, u as getV2TrackedChangeMutationImpact, v as isAllowed, w as getWorkflowRecording, x as DOM_CLASS_NAMES, y as isSyntheticTrackedChangeCommentLaneItem } from "./chunks/create-super-doc-ui-Bm5kmx0W.es.js";
4
+ import { C as getWorkflowRecording, S as createInteractionHistory, T as recordInteraction, _ as createTrackedChangePermissionResolver, a as registerFirstPartyCommandMutation, b as DOM_CLASS_NAMES, c as getCommandDescriptor, d as mutationCommittedEventChangedDocument, f as createImageFilePicker, g as PERMISSIONS, h as BUILT_IN_PERMISSION_METHOD, i as readFirstPartyPageNumbers, l as applyV2CommentInvalidationFromMutation, n as executeFirstPartyCommandAsync, o as isRecord, p as resolveImageSrc, r as executeFirstPartyShortcutAsync, t as createSuperDocUI, u as getV2TrackedChangeMutationImpact, v as isAllowed, w as isWorkflowRecordingEnabled, x as closeInteractionHistory, y as isSyntheticTrackedChangeCommentLaneItem } from "./chunks/create-super-doc-ui-Dc8dQAMc.es.js";
4
5
  import { t as import_eventemitter3 } from "./chunks/eventemitter3-DEIiXiH2.es.js";
5
6
  import { t as v4 } from "./chunks/uuid-H0Xcmmhy.es.js";
6
- import { $ as vModelSelect, A as onActivated, B as renderList, C as isRef$1, D as normalizeClass, E as nextTick, F as openBlock, G as toDisplayString, H as resolveDirective, I as provide$1, J as toRefs, K as toRaw$2, L as reactive, M as onDeactivated, N as onMounted, O as normalizeProps, P as onScopeDispose$1, Q as vModelCheckbox, R as readonly, S as isReactive$1, T as mergeProps, U as resolveDynamicComponent, V as renderSlot, W as shallowRef$1, X as useAttrs, Y as unref, Z as useSlots, _ as getCurrentInstance, a as computed$1, at as withModifiers, b as hasInjectionContext, c as createCommentVNode, d as createStaticVNode, et as vModelText, f as createTextVNode, g as effectScope, h as defineComponent, i as Transition, it as withKeys, j as onBeforeUnmount, k as normalizeStyle, l as createElementBlock, m as defineAsyncComponent, n as Fragment, nt as withCtx, o as createApp, p as createVNode, q as toRef, r as Teleport, rt as withDirectives, s as createBlock, t as _plugin_vue_export_helper_default, tt as watch$1, u as createElementVNode, v as getCurrentScope, w as markRaw, x as inject$1, y as h, z as ref } from "./chunks/_plugin-vue_export-helper-CsJQtMvr.es.js";
7
7
  import { a as init_dist$1, i as global, n as init_dist$2, o as Buffer, r as process$1, s as init_dist, t as require_jszip_min } from "./chunks/jszip-BzJ3CyxR.es.js";
8
8
  import { t as isFiniteNumber } from "./chunks/is-finite-number-BpL4F38c.es.js";
9
9
  import { t as PDF_TO_CSS_UNITS } from "./chunks/constants-BvNs_ybI.es.js";
10
10
  import * as Vue from "vue";
11
11
  import { Map as Map$1 } from "yjs";
12
12
  import Konva from "konva";
13
- //#region src/core/v2-integration/browser-peer-runtime.js
13
+ //#region src/core/v2-integration/browser-peer-runtime.ts
14
14
  var SUPERDOC_V2_BROWSER_RUNTIME_GLOBAL_KEY = "__SUPERDOC_V2_BROWSER_RUNTIME__";
15
15
  function readInstalledRuntime(globalObject = globalThis) {
16
- const installed = globalObject[SUPERDOC_V2_BROWSER_RUNTIME_GLOBAL_KEY];
17
- return installed && typeof installed === "object" ? installed : null;
16
+ const installed = Reflect.get(globalObject, SUPERDOC_V2_BROWSER_RUNTIME_GLOBAL_KEY);
17
+ return isPlainObject$1(installed) ? installed : null;
18
18
  }
19
19
  function installSuperDocV2BrowserRuntime(runtime = {}, globalObject = globalThis) {
20
20
  const installed = readInstalledRuntime(globalObject) ?? {};
@@ -23,7 +23,7 @@ function installSuperDocV2BrowserRuntime(runtime = {}, globalObject = globalThis
23
23
  ...runtime,
24
24
  vue: runtime.vue ?? installed.vue ?? Vue
25
25
  };
26
- globalObject[SUPERDOC_V2_BROWSER_RUNTIME_GLOBAL_KEY] = nextRuntime;
26
+ Reflect.set(globalObject, SUPERDOC_V2_BROWSER_RUNTIME_GLOBAL_KEY, nextRuntime);
27
27
  return nextRuntime;
28
28
  }
29
29
  installSuperDocV2BrowserRuntime();
@@ -258,7 +258,7 @@ var v_click_outside_default = {
258
258
  var DEFAULT_ENDPOINT = "https://ingest.superdoc.dev/v1/collect";
259
259
  function getSuperdocVersion() {
260
260
  try {
261
- return "2.29.0-next.9";
261
+ return "2.29.0";
262
262
  } catch {
263
263
  return "unknown";
264
264
  }
@@ -5874,7 +5874,7 @@ var getCommentIndex = (yArray, comment) => {
5874
5874
  //#endregion
5875
5875
  //#region src/core/collaboration/helpers.ts
5876
5876
  var isPropertyBag = (value) => typeof value === "object" && value !== null || typeof value === "function";
5877
- var readCommentsStore = (superdoc) => superdoc["commentsStore"];
5877
+ var readCommentsStore$1 = (superdoc) => superdoc["commentsStore"];
5878
5878
  var isV2ReviewRuntimeActive = (superdoc) => superdoc.activeEditor?.editorVersion === 2 || superdoc.editorVersion === 2;
5879
5879
  var commentKey = (comment) => {
5880
5880
  const key = comment.commentId ?? comment.importedId;
@@ -5893,7 +5893,7 @@ var preserveLocalV2TrackedChangeRows = (superdoc, commentsStore, incomingComment
5893
5893
  };
5894
5894
  var loadCommentsFromYdoc = (superdoc) => {
5895
5895
  if (!superdoc?.ydoc) return false;
5896
- const commentsStore = readCommentsStore(superdoc);
5896
+ const commentsStore = readCommentsStore$1(superdoc);
5897
5897
  if (!commentsStore) return false;
5898
5898
  const comments = superdoc.ydoc.getArray("comments").toJSON();
5899
5899
  const seenCommentIdByKey = /* @__PURE__ */ new Map();
@@ -5939,7 +5939,7 @@ var initCollaborationComments = (superdoc) => {
5939
5939
  const updateCommentsStore = () => loadCommentsFromYdoc(superdoc);
5940
5940
  const onSuperDocYdocSynced = () => {
5941
5941
  if (!updateCommentsStore()) setTimeout(updateCommentsStore, 0);
5942
- const commentsStore = readCommentsStore(superdoc);
5942
+ const commentsStore = readCommentsStore$1(superdoc);
5943
5943
  if (commentsStore) commentsStore.hasSyncedCollaborationComments = true;
5944
5944
  const currentProvider = superdoc.provider;
5945
5945
  if (!currentProvider) throw new TypeError("initCollaborationComments requires superdoc.provider");
@@ -5951,7 +5951,7 @@ var initCollaborationComments = (superdoc) => {
5951
5951
  provider.on("synced", onSuperDocYdocSynced);
5952
5952
  if (!updateCommentsStore()) setTimeout(updateCommentsStore, 0);
5953
5953
  commentsArray.observe((event) => {
5954
- if (!readCommentsStore(superdoc)) return;
5954
+ if (!readCommentsStore$1(superdoc)) return;
5955
5955
  const currentUser = superdoc.config.user;
5956
5956
  const origin = event?.transaction?.origin;
5957
5957
  const originUser = isPropertyBag(origin) ? origin.user : null;
@@ -6890,23 +6890,76 @@ var buildFloatingCommentInstances = ({ comment, positionKey, positionEntry, fall
6890
6890
  })];
6891
6891
  };
6892
6892
  //#endregion
6893
- //#region src/components/CommentsLayer/tracked-change-threading.js
6893
+ //#region src/stores/helpers/comment-document-scope.ts
6894
+ var getCommentDocumentId = (comment) => {
6895
+ if (!comment) return null;
6896
+ if (comment.fileId != null) return String(comment.fileId);
6897
+ if (comment.documentId != null) return String(comment.documentId);
6898
+ if (comment.selection?.documentId != null) return String(comment.selection.documentId);
6899
+ return null;
6900
+ };
6901
+ var createCommentDocumentScope = (readOpenDocuments) => {
6902
+ const getOpenDocuments = () => {
6903
+ const source = readOpenDocuments();
6904
+ const docs = Array.isArray(source) ? source : source?.value;
6905
+ return Array.isArray(docs) ? docs : [];
6906
+ };
6907
+ const getSingleOpenDocumentId = () => {
6908
+ const docs = getOpenDocuments();
6909
+ if (docs.length !== 1) return null;
6910
+ return docs[0]?.id != null ? String(docs[0].id) : null;
6911
+ };
6912
+ const belongsToDocument = (comment, activeDocumentId, options = {}) => {
6913
+ const { allowSingleDocumentMismatch = false } = options;
6914
+ if (!activeDocumentId) return false;
6915
+ const commentDocumentId = getCommentDocumentId(comment);
6916
+ if (commentDocumentId) {
6917
+ if (commentDocumentId === activeDocumentId) return true;
6918
+ const singleOpenDocumentId = getSingleOpenDocumentId();
6919
+ return allowSingleDocumentMismatch && singleOpenDocumentId === activeDocumentId;
6920
+ }
6921
+ return getSingleOpenDocumentId() === activeDocumentId;
6922
+ };
6923
+ const belongsToTrackedChangeSyncDocument = (comment, activeDocumentId) => belongsToDocument(comment, activeDocumentId, { allowSingleDocumentMismatch: true });
6924
+ return {
6925
+ belongsToDocument,
6926
+ belongsToTrackedChangeSyncDocument
6927
+ };
6928
+ };
6929
+ //#endregion
6930
+ //#region src/stores/helpers/pending-selection-snapshot.ts
6931
+ var isThenable = (value) => (typeof value === "object" || typeof value === "function") && value !== null && "then" in value && typeof value.then === "function";
6932
+ var getPendingSelectionSnapshot = (superdoc, activeSelection) => {
6933
+ if (activeSelection?.source !== "document-editor") return null;
6934
+ const selectionDocumentId = activeSelection?.documentId ?? null;
6935
+ const editorDocumentId = superdoc?.activeEditor?.options?.documentId ?? null;
6936
+ if (!selectionDocumentId || !editorDocumentId || selectionDocumentId !== editorDocumentId) return null;
6937
+ let currentSelection;
6938
+ try {
6939
+ currentSelection = superdoc?.activeEditor?.doc?.selection?.current;
6940
+ } catch {
6941
+ return null;
6942
+ }
6943
+ if (typeof currentSelection !== "function") return null;
6944
+ try {
6945
+ const snapshot = currentSelection();
6946
+ return isThenable(snapshot) ? Promise.resolve(snapshot).catch(() => null) : snapshot;
6947
+ } catch {
6948
+ return null;
6949
+ }
6950
+ };
6951
+ //#endregion
6952
+ //#region src/components/CommentsLayer/tracked-change-threading.ts
6894
6953
  /**
6895
6954
  * Legacy comment payloads predate explicit tracked-change thread provenance.
6896
6955
  * These fields distinguish a true legacy review child from a v2 comment whose
6897
6956
  * anchor merely overlaps tracked content.
6898
- *
6899
- * @param {Record<string, any> | null | undefined} comment
6900
- * @returns {boolean}
6901
6957
  */
6902
6958
  var hasLegacyTrackedChangeThreadSignal = (comment) => Boolean(comment?.trackedChangeLink) || Boolean(comment?.trackedChangeType) || Boolean(comment?.trackedChangeDisplayType) || Boolean(comment?.trackedChangeText) || Boolean(comment?.deletedText) || comment?.trackedChange === true;
6903
6959
  /**
6904
6960
  * Resolve explicit thread provenance first, then the guarded legacy fallback.
6905
6961
  * Spatial-only v2 comments carry neither the explicit field nor a legacy
6906
6962
  * review signal and therefore remain standalone.
6907
- *
6908
- * @param {Record<string, any> | null | undefined} comment
6909
- * @returns {string | number | null}
6910
6963
  */
6911
6964
  var trackedChangeThreadParentIdForComment$1 = (comment) => {
6912
6965
  if (comment?.trackedChangeThreadParentId != null) return comment.trackedChangeThreadParentId;
@@ -7185,7 +7238,6 @@ function createDefaultV2Integration() {
7185
7238
  //#region src/helpers/interaction-trace.ts
7186
7239
  var isStartSpan = (value) => typeof value === "function";
7187
7240
  var isEndSpan = (value) => typeof value === "function";
7188
- var isThenable$3 = (value) => (typeof value === "object" || typeof value === "function") && value !== null && "then" in value && typeof value.then === "function";
7189
7241
  function safeTraceCollector() {
7190
7242
  try {
7191
7243
  const collector = Reflect.get(globalThis, "__superdocInteractionTrace");
@@ -7216,7 +7268,7 @@ function withInteractionSpan(stage, branch, meta, fn) {
7216
7268
  if (!span) return fn();
7217
7269
  try {
7218
7270
  const result = fn();
7219
- if (isThenable$3(result)) return result.then((value) => {
7271
+ if (isThenable$1(result)) return result.then((value) => {
7220
7272
  endInteractionSpan(span);
7221
7273
  return value;
7222
7274
  }, (error) => {
@@ -7231,6 +7283,81 @@ function withInteractionSpan(stage, branch, meta, fn) {
7231
7283
  }
7232
7284
  }
7233
7285
  //#endregion
7286
+ //#region src/stores/helpers/tracked-change-decision.ts
7287
+ var normalizeTrackedChangeDecisionType = (value) => {
7288
+ const lower = typeof value === "string" ? value.toLowerCase() : "";
7289
+ if (!lower) return null;
7290
+ if (lower === "insert" || lower === "insertion" || lower === "trackinsert" || lower === "tableinsert" || lower === "paragraphsplit") return "insertion";
7291
+ if (lower === "delete" || lower === "deletion" || lower === "trackdelete" || lower === "tabledelete") return "deletion";
7292
+ return lower;
7293
+ };
7294
+ var trackedChangeDecisionKeepsCommentAnchor = ({ comment, decision } = {}) => {
7295
+ const normalizedDecision = decision === "accept" || decision === "reject" ? decision : null;
7296
+ if (!normalizedDecision) return false;
7297
+ const type = normalizeTrackedChangeDecisionType(comment?.trackedChangeDisplayType) ?? normalizeTrackedChangeDecisionType(comment?.trackedChangeType);
7298
+ return normalizedDecision === "accept" && type === "insertion" || normalizedDecision === "reject" && type === "deletion";
7299
+ };
7300
+ var collectTrackedChangeDecisionIdsWithAliases = (comment, aliasIds) => {
7301
+ const trackedChangeIds = new Set(aliasIds);
7302
+ if (comment?.trackedChangeCanonicalId != null) trackedChangeIds.add(String(comment.trackedChangeCanonicalId));
7303
+ const anchorKey = comment?.trackedChangeAnchorKey != null ? String(comment.trackedChangeAnchorKey) : null;
7304
+ if (anchorKey) {
7305
+ trackedChangeIds.add(anchorKey);
7306
+ if (anchorKey.startsWith("tc::")) {
7307
+ const rawId = anchorKey.slice(anchorKey.lastIndexOf("::") + 2);
7308
+ if (rawId) trackedChangeIds.add(rawId);
7309
+ }
7310
+ }
7311
+ return trackedChangeIds;
7312
+ };
7313
+ var collectTrackedChangeEntityIdsFromReceipt = (receipt) => {
7314
+ const record = receipt && typeof receipt === "object" ? receipt : null;
7315
+ if (!record?.success) return /* @__PURE__ */ new Set();
7316
+ const ids = /* @__PURE__ */ new Set();
7317
+ const collect = (entry) => {
7318
+ const ref = entry && typeof entry === "object" ? entry : null;
7319
+ if (ref?.kind !== "entity" || ref.entityType !== "trackedChange") return;
7320
+ if (ref.entityId != null && String(ref.entityId).length > 0) ids.add(String(ref.entityId));
7321
+ };
7322
+ if (Array.isArray(record.removed)) record.removed.forEach(collect);
7323
+ if (Array.isArray(record.invalidatedRefs)) record.invalidatedRefs.forEach(collect);
7324
+ return ids;
7325
+ };
7326
+ var collectReliableDecidedTrackedChangeIds = (outcome) => {
7327
+ const ids = /* @__PURE__ */ new Set();
7328
+ if (outcome?.decidedId != null && String(outcome.decidedId).length > 0) ids.add(String(outcome.decidedId));
7329
+ if (Array.isArray(outcome?.decidedIds)) outcome.decidedIds.forEach((id) => {
7330
+ if (id != null && String(id).length > 0) ids.add(String(id));
7331
+ });
7332
+ collectTrackedChangeEntityIdsFromReceipt(outcome?.receipt).forEach((id) => ids.add(id));
7333
+ return ids;
7334
+ };
7335
+ var clearV2ActiveTrackedChangeTarget = (adapter, decidedId) => {
7336
+ if (!decidedId || typeof adapter?.clearActiveTrackedChangeTargetIfMatches !== "function") return;
7337
+ try {
7338
+ adapter.clearActiveTrackedChangeTargetIfMatches(decidedId);
7339
+ } catch {}
7340
+ };
7341
+ var waitForTrackedDecisionCanonicalPaint = async ({ superdoc, receipt } = {}) => {
7342
+ const readiness = superdoc?.activeEditor?.documentMutationReadiness;
7343
+ if (receipt?.success !== true || typeof receipt?.txId !== "string" || !receipt.txId || typeof readiness?.whenPainted !== "function") return;
7344
+ try {
7345
+ await readiness.whenPainted(receipt);
7346
+ const requestFrame = globalThis.requestAnimationFrame;
7347
+ if (typeof requestFrame === "function") await new Promise((resolve) => {
7348
+ let settled = false;
7349
+ const finish = () => {
7350
+ if (settled) return;
7351
+ settled = true;
7352
+ clearTimeout(fallback);
7353
+ resolve();
7354
+ };
7355
+ const fallback = setTimeout(finish, 250);
7356
+ requestFrame(() => requestFrame(() => setTimeout(finish, 0)));
7357
+ });
7358
+ } catch {}
7359
+ };
7360
+ //#endregion
7234
7361
  //#region src/stores/helpers/comment-draft-text.ts
7235
7362
  var COMMENT_DRAFT_BR_TAG = /<br(?:\s[^>]*)?\s*\/?>/gi;
7236
7363
  var COMMENT_DRAFT_BLOCK_BOUNDARY = /(?:<\/(?:p|div|li|blockquote|pre|h[1-6])\s*>\s*)+(?:<(?:p|div|li|blockquote|pre|h[1-6])(?:\s[^>]*)?\s*\/?>)+/gi;
@@ -7603,6 +7730,82 @@ var cloneV2TrackedChangeStory = (story) => {
7603
7730
  };
7604
7731
  };
7605
7732
  //#endregion
7733
+ //#region src/stores/helpers/tracked-change-compaction.ts
7734
+ var isPresentId = (id) => Boolean(id);
7735
+ var getBodyTrackedChangeIdentityIds = (comment) => {
7736
+ return [normalizeCommentId(comment.commentId), ...!normalizeCommentId(comment.trackedChangeCanonicalId) ? [
7737
+ comment.importedId,
7738
+ comment.trackedChangeAnchorKey,
7739
+ ...normalizeTrackedChangePositionAliases(comment.trackedChangePositionAliases)
7740
+ ] : []].map((id) => normalizeCommentId(id)).filter(isPresentId);
7741
+ };
7742
+ var groupBodyTrackedChangeCommentsByIdentity = (comments) => {
7743
+ const parents = comments.map((_, index) => index);
7744
+ const findRoot = (index) => {
7745
+ let root = index;
7746
+ while (parents[root] !== root) root = parents[root];
7747
+ while (parents[index] !== index) {
7748
+ const next = parents[index];
7749
+ parents[index] = root;
7750
+ index = next;
7751
+ }
7752
+ return root;
7753
+ };
7754
+ const join = (left, right) => {
7755
+ const leftRoot = findRoot(left);
7756
+ const rightRoot = findRoot(right);
7757
+ if (leftRoot === rightRoot) return;
7758
+ parents[Math.max(leftRoot, rightRoot)] = Math.min(leftRoot, rightRoot);
7759
+ };
7760
+ const identityOwner = /* @__PURE__ */ new Map();
7761
+ comments.forEach((comment, index) => {
7762
+ getBodyTrackedChangeIdentityIds(comment).forEach((identityId) => {
7763
+ const owner = identityOwner.get(identityId);
7764
+ if (owner === void 0) identityOwner.set(identityId, index);
7765
+ else join(index, owner);
7766
+ });
7767
+ });
7768
+ const groups = /* @__PURE__ */ new Map();
7769
+ comments.forEach((comment, index) => {
7770
+ const root = findRoot(index);
7771
+ const group = groups.get(root) ?? [];
7772
+ group.push(comment);
7773
+ groups.set(root, group);
7774
+ });
7775
+ return groups;
7776
+ };
7777
+ var mergeDuplicateBodyTrackedChangeComments = (groups) => {
7778
+ const duplicates = /* @__PURE__ */ new Map();
7779
+ groups.forEach(([survivor, ...duplicateRows]) => {
7780
+ if (!survivor || duplicateRows.length === 0) return;
7781
+ const resolvedDuplicate = duplicateRows.find((comment) => comment.resolvedTime != null);
7782
+ if (survivor.resolvedTime == null && resolvedDuplicate) {
7783
+ survivor.resolvedTime = resolvedDuplicate.resolvedTime;
7784
+ survivor.resolvedById = resolvedDuplicate.resolvedById;
7785
+ survivor.resolvedByEmail = resolvedDuplicate.resolvedByEmail;
7786
+ survivor.resolvedByName = resolvedDuplicate.resolvedByName;
7787
+ survivor.trackedChangeDecision = resolvedDuplicate.trackedChangeDecision;
7788
+ }
7789
+ survivor.trackedChangePositionAliases = normalizeTrackedChangePositionAliases([...normalizeTrackedChangePositionAliases(survivor.trackedChangePositionAliases), ...duplicateRows.flatMap((comment) => [
7790
+ comment.commentId,
7791
+ comment.importedId,
7792
+ comment.trackedChangeCanonicalId,
7793
+ ...normalizeTrackedChangePositionAliases(comment.trackedChangePositionAliases)
7794
+ ])]);
7795
+ duplicateRows.forEach((comment) => duplicates.set(comment, survivor));
7796
+ });
7797
+ return duplicates;
7798
+ };
7799
+ var createDroppedCommentIdMap = (duplicates) => {
7800
+ const droppedCommentIds = /* @__PURE__ */ new Map();
7801
+ duplicates.forEach((survivor, duplicate) => {
7802
+ const fromId = normalizeCommentId(duplicate.commentId);
7803
+ const toId = normalizeCommentId(survivor.commentId);
7804
+ if (fromId && toId) droppedCommentIds.set(fromId, toId);
7805
+ });
7806
+ return droppedCommentIds;
7807
+ };
7808
+ //#endregion
7606
7809
  //#region src/stores/comments-store.js
7607
7810
  var useCommentsStore = defineStore("comments", () => {
7608
7811
  const superdocStore = useSuperdocStore();
@@ -8081,25 +8284,6 @@ var useCommentsStore = defineStore("comments", () => {
8081
8284
  delete debounceTimers[commentId];
8082
8285
  }, delay);
8083
8286
  };
8084
- const getPendingSelectionSnapshot = (superdoc, activeSelection) => {
8085
- if (activeSelection?.source !== "document-editor") return null;
8086
- const selectionDocumentId = activeSelection?.documentId ?? null;
8087
- const editorDocumentId = superdoc?.activeEditor?.options?.documentId ?? null;
8088
- if (!selectionDocumentId || !editorDocumentId || selectionDocumentId !== editorDocumentId) return null;
8089
- let currentSelection;
8090
- try {
8091
- currentSelection = superdoc?.activeEditor?.doc?.selection?.current;
8092
- } catch {
8093
- return null;
8094
- }
8095
- if (typeof currentSelection !== "function") return null;
8096
- try {
8097
- const snapshot = currentSelection();
8098
- return typeof snapshot?.then === "function" ? Promise.resolve(snapshot).catch(() => null) : snapshot;
8099
- } catch {
8100
- return null;
8101
- }
8102
- };
8103
8287
  const showAddComment = (superdoc, targetClientY = null) => {
8104
8288
  const request = ++pendingCommentRequest;
8105
8289
  const editor = superdoc?.activeEditor;
@@ -9623,122 +9807,7 @@ var useCommentsStore = defineStore("comments", () => {
9623
9807
  const activeCommentId = activeComment.value != null ? String(activeComment.value) : null;
9624
9808
  if (activeCommentId && removedAliasIds.has(activeCommentId)) clearActiveCommentSelection();
9625
9809
  }
9626
- const getCommentDocumentId = (comment) => {
9627
- if (!comment) return null;
9628
- if (comment.fileId != null) return String(comment.fileId);
9629
- if (comment.documentId != null) return String(comment.documentId);
9630
- if (comment.selection?.documentId != null) return String(comment.selection.documentId);
9631
- return null;
9632
- };
9633
- const getOpenDocuments = () => {
9634
- const docs = Array.isArray(superdocStore.documents) ? superdocStore.documents : superdocStore.documents?.value;
9635
- return Array.isArray(docs) ? docs : [];
9636
- };
9637
- const getSingleOpenDocumentId = () => {
9638
- const docs = getOpenDocuments();
9639
- if (docs.length !== 1) return null;
9640
- return docs[0]?.id != null ? String(docs[0].id) : null;
9641
- };
9642
- const belongsToDocument = (comment, activeDocumentId, options = {}) => {
9643
- const { allowSingleDocumentMismatch = false } = options;
9644
- if (!activeDocumentId) return false;
9645
- const commentDocumentId = getCommentDocumentId(comment);
9646
- if (commentDocumentId) {
9647
- if (commentDocumentId === activeDocumentId) return true;
9648
- const singleOpenDocumentId = getSingleOpenDocumentId();
9649
- return allowSingleDocumentMismatch && singleOpenDocumentId === activeDocumentId;
9650
- }
9651
- return getSingleOpenDocumentId() === activeDocumentId;
9652
- };
9653
- const belongsToTrackedChangeSyncDocument = (comment, activeDocumentId) => {
9654
- return belongsToDocument(comment, activeDocumentId, { allowSingleDocumentMismatch: true });
9655
- };
9656
- const normalizeTrackedChangeDecisionType = (value) => {
9657
- const lower = typeof value === "string" ? value.toLowerCase() : "";
9658
- if (!lower) return null;
9659
- if (lower === "insert" || lower === "insertion" || lower === "trackinsert" || lower === "tableinsert" || lower === "paragraphsplit") return "insertion";
9660
- if (lower === "delete" || lower === "deletion" || lower === "trackdelete" || lower === "tabledelete") return "deletion";
9661
- return lower;
9662
- };
9663
- const trackedChangeDecisionKeepsCommentAnchor = ({ comment, decision } = {}) => {
9664
- const normalizedDecision = decision === "accept" || decision === "reject" ? decision : null;
9665
- if (!normalizedDecision) return false;
9666
- const type = normalizeTrackedChangeDecisionType(comment?.trackedChangeDisplayType) ?? normalizeTrackedChangeDecisionType(comment?.trackedChangeType);
9667
- return normalizedDecision === "accept" && type === "insertion" || normalizedDecision === "reject" && type === "deletion";
9668
- };
9669
- const getBodyTrackedChangeIdentityIds = (comment) => {
9670
- return [normalizeCommentId(comment.commentId), ...!normalizeCommentId(comment.trackedChangeCanonicalId) ? [
9671
- comment.importedId,
9672
- comment.trackedChangeAnchorKey,
9673
- ...normalizeTrackedChangePositionAliases(comment.trackedChangePositionAliases)
9674
- ] : []].map((id) => normalizeCommentId(id)).filter(Boolean);
9675
- };
9676
- const groupBodyTrackedChangeCommentsByIdentity = (comments) => {
9677
- const parents = comments.map((_, index) => index);
9678
- const findRoot = (index) => {
9679
- let root = index;
9680
- while (parents[root] !== root) root = parents[root];
9681
- while (parents[index] !== index) {
9682
- const next = parents[index];
9683
- parents[index] = root;
9684
- index = next;
9685
- }
9686
- return root;
9687
- };
9688
- const join = (left, right) => {
9689
- const leftRoot = findRoot(left);
9690
- const rightRoot = findRoot(right);
9691
- if (leftRoot === rightRoot) return;
9692
- parents[Math.max(leftRoot, rightRoot)] = Math.min(leftRoot, rightRoot);
9693
- };
9694
- const identityOwner = /* @__PURE__ */ new Map();
9695
- comments.forEach((comment, index) => {
9696
- getBodyTrackedChangeIdentityIds(comment).forEach((identityId) => {
9697
- const owner = identityOwner.get(identityId);
9698
- if (owner === void 0) identityOwner.set(identityId, index);
9699
- else join(index, owner);
9700
- });
9701
- });
9702
- const groups = /* @__PURE__ */ new Map();
9703
- comments.forEach((comment, index) => {
9704
- const root = findRoot(index);
9705
- const group = groups.get(root) ?? [];
9706
- group.push(comment);
9707
- groups.set(root, group);
9708
- });
9709
- return groups;
9710
- };
9711
- const mergeDuplicateBodyTrackedChangeComments = (groups) => {
9712
- const duplicates = /* @__PURE__ */ new Map();
9713
- groups.forEach(([survivor, ...duplicateRows]) => {
9714
- if (!survivor || duplicateRows.length === 0) return;
9715
- const resolvedDuplicate = duplicateRows.find((comment) => comment.resolvedTime != null);
9716
- if (survivor.resolvedTime == null && resolvedDuplicate) {
9717
- survivor.resolvedTime = resolvedDuplicate.resolvedTime;
9718
- survivor.resolvedById = resolvedDuplicate.resolvedById;
9719
- survivor.resolvedByEmail = resolvedDuplicate.resolvedByEmail;
9720
- survivor.resolvedByName = resolvedDuplicate.resolvedByName;
9721
- survivor.trackedChangeDecision = resolvedDuplicate.trackedChangeDecision;
9722
- }
9723
- survivor.trackedChangePositionAliases = normalizeTrackedChangePositionAliases([...normalizeTrackedChangePositionAliases(survivor.trackedChangePositionAliases), ...duplicateRows.flatMap((comment) => [
9724
- comment.commentId,
9725
- comment.importedId,
9726
- comment.trackedChangeCanonicalId,
9727
- ...normalizeTrackedChangePositionAliases(comment.trackedChangePositionAliases)
9728
- ])]);
9729
- duplicateRows.forEach((comment) => duplicates.set(comment, survivor));
9730
- });
9731
- return duplicates;
9732
- };
9733
- const createDroppedCommentIdMap = (duplicates) => {
9734
- const droppedCommentIds = /* @__PURE__ */ new Map();
9735
- duplicates.forEach((survivor, duplicate) => {
9736
- const fromId = normalizeCommentId(duplicate.commentId);
9737
- const toId = normalizeCommentId(survivor.commentId);
9738
- if (fromId && toId) droppedCommentIds.set(fromId, toId);
9739
- });
9740
- return droppedCommentIds;
9741
- };
9810
+ const { belongsToDocument, belongsToTrackedChangeSyncDocument } = createCommentDocumentScope(() => superdocStore.documents);
9742
9811
  const remapTrackedChangeReferences = (droppedCommentIds, activeDocumentId) => {
9743
9812
  const remapSelection = (selection) => {
9744
9813
  const selectedId = normalizeCommentId(selection.value);
@@ -9764,9 +9833,7 @@ var useCommentsStore = defineStore("comments", () => {
9764
9833
  });
9765
9834
  };
9766
9835
  const compactDuplicateBodyTrackedChangeComments = (activeDocumentId) => {
9767
- const candidates = commentsList.value.filter((comment) => isBodyTrackedChangeComment(comment) && belongsToTrackedChangeSyncDocument(comment, activeDocumentId));
9768
- const groups = groupBodyTrackedChangeCommentsByIdentity(candidates);
9769
- const duplicates = mergeDuplicateBodyTrackedChangeComments(groups);
9836
+ const duplicates = mergeDuplicateBodyTrackedChangeComments(groupBodyTrackedChangeCommentsByIdentity(commentsList.value.filter((comment) => isBodyTrackedChangeComment(comment) && belongsToTrackedChangeSyncDocument(comment, activeDocumentId))));
9770
9837
  if (!duplicates.size) return 0;
9771
9838
  commentsList.value = commentsList.value.filter((comment) => !duplicates.has(comment));
9772
9839
  remapTrackedChangeReferences(createDroppedCommentIdMap(duplicates), activeDocumentId);
@@ -9907,19 +9974,7 @@ var useCommentsStore = defineStore("comments", () => {
9907
9974
  });
9908
9975
  return resolvedCount;
9909
9976
  };
9910
- const collectTrackedChangeDecisionIds = (comment) => {
9911
- const trackedChangeIds = new Set(getCommentAliasIds(comment));
9912
- if (comment?.trackedChangeCanonicalId != null) trackedChangeIds.add(String(comment.trackedChangeCanonicalId));
9913
- const anchorKey = comment?.trackedChangeAnchorKey != null ? String(comment.trackedChangeAnchorKey) : null;
9914
- if (anchorKey) {
9915
- trackedChangeIds.add(anchorKey);
9916
- if (anchorKey.startsWith("tc::")) {
9917
- const rawId = anchorKey.slice(anchorKey.lastIndexOf("::") + 2);
9918
- if (rawId) trackedChangeIds.add(rawId);
9919
- }
9920
- }
9921
- return trackedChangeIds;
9922
- };
9977
+ const collectTrackedChangeDecisionIds = (comment) => collectTrackedChangeDecisionIdsWithAliases(comment, getCommentAliasIds(comment));
9923
9978
  const getTrackedChangeDecisionLinks = (comment) => {
9924
9979
  const linked = [];
9925
9980
  const seen = /* @__PURE__ */ new Set();
@@ -9930,28 +9985,6 @@ var useCommentsStore = defineStore("comments", () => {
9930
9985
  }
9931
9986
  return linked;
9932
9987
  };
9933
- const collectTrackedChangeEntityIdsFromReceipt = (receipt) => {
9934
- const record = receipt && typeof receipt === "object" ? receipt : null;
9935
- if (!record?.success) return /* @__PURE__ */ new Set();
9936
- const ids = /* @__PURE__ */ new Set();
9937
- const collect = (entry) => {
9938
- const ref = entry && typeof entry === "object" ? entry : null;
9939
- if (ref?.kind !== "entity" || ref.entityType !== "trackedChange") return;
9940
- if (ref.entityId != null && String(ref.entityId).length > 0) ids.add(String(ref.entityId));
9941
- };
9942
- if (Array.isArray(record.removed)) record.removed.forEach(collect);
9943
- if (Array.isArray(record.invalidatedRefs)) record.invalidatedRefs.forEach(collect);
9944
- return ids;
9945
- };
9946
- const collectReliableDecidedTrackedChangeIds = (outcome) => {
9947
- const ids = /* @__PURE__ */ new Set();
9948
- if (outcome?.decidedId != null && String(outcome.decidedId).length > 0) ids.add(String(outcome.decidedId));
9949
- if (Array.isArray(outcome?.decidedIds)) outcome.decidedIds.forEach((id) => {
9950
- if (id != null && String(id).length > 0) ids.add(String(id));
9951
- });
9952
- collectTrackedChangeEntityIdsFromReceipt(outcome?.receipt).forEach((id) => ids.add(id));
9953
- return ids;
9954
- };
9955
9988
  const detachLinkedCommentsForTrackedChangeDecision = ({ comment, decision } = {}) => {
9956
9989
  if (!comment?.trackedChange) return 0;
9957
9990
  if (!trackedChangeDecisionKeepsCommentAnchor({
@@ -10127,31 +10160,6 @@ var useCommentsStore = defineStore("comments", () => {
10127
10160
  removedIds
10128
10161
  };
10129
10162
  };
10130
- const clearV2ActiveTrackedChangeTarget = (adapter, decidedId) => {
10131
- if (!decidedId || typeof adapter?.clearActiveTrackedChangeTargetIfMatches !== "function") return;
10132
- try {
10133
- adapter.clearActiveTrackedChangeTargetIfMatches(decidedId);
10134
- } catch {}
10135
- };
10136
- const waitForTrackedDecisionCanonicalPaint = async ({ superdoc, receipt } = {}) => {
10137
- const readiness = superdoc?.activeEditor?.documentMutationReadiness;
10138
- if (receipt?.success !== true || typeof receipt?.txId !== "string" || !receipt.txId || typeof readiness?.whenPainted !== "function") return;
10139
- try {
10140
- await readiness.whenPainted(receipt);
10141
- const requestFrame = globalThis.requestAnimationFrame;
10142
- if (typeof requestFrame === "function") await new Promise((resolve) => {
10143
- let settled = false;
10144
- const finish = () => {
10145
- if (settled) return;
10146
- settled = true;
10147
- clearTimeout(fallback);
10148
- resolve();
10149
- };
10150
- const fallback = setTimeout(finish, 250);
10151
- requestFrame(() => requestFrame(() => setTimeout(finish, 0)));
10152
- });
10153
- } catch {}
10154
- };
10155
10163
  /**
10156
10164
  * Accept or reject the tracked change behind a sidebar row.
10157
10165
  *
@@ -10712,7 +10720,7 @@ var ellipsis_vertical_solid_default = "<svg xmlns=\"http://www.w3.org/2000/svg\"
10712
10720
  //#region ../../shared/common/icons/rotate-left-solid.svg?raw
10713
10721
  var rotate_left_solid_default = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d=\"M48.5 224L40 224c-13.3 0-24-10.7-24-24L16 72c0-9.7 5.8-18.5 14.8-22.2s19.3-1.7 26.2 5.2L98.6 96.6c87.6-86.5 228.7-86.2 315.8 1c87.5 87.5 87.5 229.3 0 316.8s-229.3 87.5-316.8 0c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0c62.5 62.5 163.8 62.5 226.3 0s62.5-163.8 0-226.3c-62.2-62.2-162.7-62.5-225.3-1L185 183c6.9 6.9 8.9 17.2 5.2 26.2s-12.5 14.8-22.2 14.8L48.5 224z\"/></svg>";
10714
10722
  //#endregion
10715
- //#region src/icons.js
10723
+ //#region src/icons.ts
10716
10724
  var superdocIcons = {
10717
10725
  comment: comment_solid_default,
10718
10726
  caretDown: caret_down_solid_default,
@@ -11074,12 +11082,9 @@ var InternalDropdown_default = /* @__PURE__ */ _plugin_vue_export_helper_default
11074
11082
  }
11075
11083
  }), [["__scopeId", "data-v-026f5d66"]]);
11076
11084
  //#endregion
11077
- //#region src/components/CommentsLayer/helpers.js
11085
+ //#region src/components/CommentsLayer/helpers.ts
11078
11086
  /**
11079
11087
  * Comments helper to format dates from timestamp
11080
- *
11081
- * @param {Number} timestamp The timestamp to format
11082
- * @returns {String} The formatted date
11083
11088
  */
11084
11089
  function formatDate(timestamp) {
11085
11090
  const date = new Date(timestamp);
@@ -11677,7 +11682,7 @@ var CommentInput_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/*
11677
11682
  }
11678
11683
  }), [["__scopeId", "data-v-aa97de44"]]);
11679
11684
  //#endregion
11680
- //#region src/internal/toolbar/built-in/url-safety.js
11685
+ //#region src/internal/toolbar/built-in/url-safety.ts
11681
11686
  /**
11682
11687
  * Minimal href sanitizer for the built-in link popover.
11683
11688
  *
@@ -11693,8 +11698,6 @@ var DANGEROUS_SCHEME = /^(javascript|data|vbscript):/i;
11693
11698
  var HAS_SCHEME = /^[a-z][a-z0-9+.-]*:/i;
11694
11699
  /**
11695
11700
  * Validate and normalize an href. Returns `{ href }` for safe values, or `null`.
11696
- * @param {string} value
11697
- * @returns {{ href: string }|null}
11698
11701
  */
11699
11702
  function sanitizeHref(value) {
11700
11703
  if (typeof value !== "string") return null;
@@ -11706,7 +11709,7 @@ function sanitizeHref(value) {
11706
11709
  return { href: trimmed };
11707
11710
  }
11708
11711
  //#endregion
11709
- //#region src/components/CommentsLayer/comment-urls.js
11712
+ //#region src/components/CommentsLayer/comment-urls.ts
11710
11713
  function isAbsoluteWebUrl(value) {
11711
11714
  if (!/^https?:\/\/[^\s/?#\\]+/i.test(value) || /[\s\\]/u.test(value)) return false;
11712
11715
  try {
@@ -11730,7 +11733,7 @@ function trimUrlPunctuation(value) {
11730
11733
  for (const character of value) {
11731
11734
  const close = closingDelimiter[character];
11732
11735
  if (close) balance[close] += 1;
11733
- else if (Object.hasOwn(balance, character)) balance[character] -= 1;
11736
+ else if (Object.prototype.hasOwnProperty.call(balance, character)) balance[character] -= 1;
11734
11737
  }
11735
11738
  let end = value.length;
11736
11739
  while (end > 0) {
@@ -11754,17 +11757,18 @@ function renderCommentHtml(value) {
11754
11757
  if (typeof document === "undefined") return value;
11755
11758
  const template = document.createElement("template");
11756
11759
  template.innerHTML = value;
11757
- for (const link of template.content.querySelectorAll("a")) {
11758
- const safe = sanitizeHref(link.getAttribute("href"));
11760
+ for (const link of Array.from(template.content.querySelectorAll("a"))) {
11761
+ const rawHref = link.getAttribute("href");
11762
+ const safe = rawHref === null ? null : sanitizeHref(rawHref);
11759
11763
  if (safe && (isAbsoluteWebUrl(safe.href) || /^(mailto|tel):\S+$/i.test(safe.href))) configureLink(link, safe.href);
11760
- else link.replaceWith(...link.childNodes);
11764
+ else link.replaceWith(...Array.from(link.childNodes));
11761
11765
  }
11762
11766
  const walker = document.createTreeWalker(template.content, NodeFilter.SHOW_TEXT);
11763
11767
  const textNodes = [];
11764
- while (walker.nextNode()) textNodes.push(walker.currentNode);
11768
+ while (walker.nextNode()) if (walker.currentNode instanceof Text) textNodes.push(walker.currentNode);
11765
11769
  for (const node of textNodes) {
11766
11770
  if (node.parentElement?.closest("a, script, style, textarea, code, pre")) continue;
11767
- const text = node.textContent;
11771
+ const text = node.data;
11768
11772
  const fragment = document.createDocumentFragment();
11769
11773
  let end = 0;
11770
11774
  for (const match of text.matchAll(/(^|[\s([{])(https?:\/\/[^\s<>"']+)/gi)) {
@@ -13445,21 +13449,25 @@ var commentsList_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/*
13445
13449
  }
13446
13450
  }), [["__scopeId", "data-v-8eca48e1"]]);
13447
13451
  //#endregion
13448
- //#region src/components/CommentsLayer/commentsList/super-comments-list.js
13452
+ //#region src/components/CommentsLayer/commentsList/super-comments-list.ts
13453
+ var isReviewDirectoryStore = (value) => isPlainObject$1(value) && typeof value.setReviewDirectoryFromV2 === "function" && typeof value.clearReviewDirectory === "function";
13454
+ var readCommentsStore = (superdoc) => {
13455
+ const store = superdoc?.["commentsStore"];
13456
+ return isReviewDirectoryStore(store) ? store : void 0;
13457
+ };
13449
13458
  /**
13450
13459
  * Comments list renderer (not floating comments)
13451
13460
  *
13452
13461
  * This renders a list of comments into an element, connected to main SuperDoc instance
13453
13462
  */
13454
13463
  var SuperComments = class extends import_eventemitter3.default {
13455
- element;
13456
- config = {
13457
- comments: [],
13458
- element: null,
13459
- commentsStore: null
13460
- };
13461
13464
  constructor(options, superdoc) {
13462
13465
  super();
13466
+ this.config = {
13467
+ comments: [],
13468
+ element: null,
13469
+ commentsStore: null
13470
+ };
13463
13471
  this.config = {
13464
13472
  ...this.config,
13465
13473
  ...options
@@ -13480,7 +13488,7 @@ var SuperComments = class extends import_eventemitter3.default {
13480
13488
  this.open();
13481
13489
  }
13482
13490
  syncDirectory() {
13483
- const store = this.superdoc?.commentsStore;
13491
+ const store = readCommentsStore(this.superdoc);
13484
13492
  if (!store) return;
13485
13493
  const comments = this.directorySnapshots.comments;
13486
13494
  const trackChanges = this.directorySnapshots.trackChanges;
@@ -13498,12 +13506,14 @@ var SuperComments = class extends import_eventemitter3.default {
13498
13506
  const acceptDirectorySnapshot = (snapshot) => {
13499
13507
  if (generation !== this.directoryGeneration) return;
13500
13508
  if ((snapshot?.listStatus ?? snapshot?.status) !== "ready") {
13501
- if (this.superdoc?.commentsStore) this.superdoc.commentsStore.isReviewDirectoryLoading = true;
13509
+ const store = readCommentsStore(this.superdoc);
13510
+ if (store) store.isReviewDirectoryLoading = true;
13502
13511
  return;
13503
13512
  }
13504
13513
  const items = Array.isArray(snapshot.items) ? snapshot.items : [];
13505
13514
  if (this.directoryItemRefs[family] === items) {
13506
- if (this.superdoc?.commentsStore) this.superdoc.commentsStore.isReviewDirectoryLoading = this.directorySnapshots.comments == null || this.directorySnapshots.trackChanges == null;
13515
+ const store = readCommentsStore(this.superdoc);
13516
+ if (store) store.isReviewDirectoryLoading = this.directorySnapshots.comments == null || this.directorySnapshots.trackChanges == null;
13507
13517
  return;
13508
13518
  }
13509
13519
  this.directoryItemRefs[family] = items;
@@ -13520,15 +13530,16 @@ var SuperComments = class extends import_eventemitter3.default {
13520
13530
  };
13521
13531
  const ui = this.superdoc?.ui;
13522
13532
  if (!ui) return;
13523
- if (this.superdoc?.commentsStore) {
13524
- this.superdoc.commentsStore.isReviewDirectoryActive = true;
13525
- this.superdoc.commentsStore.isReviewDirectoryLoading = true;
13533
+ const store = readCommentsStore(this.superdoc);
13534
+ if (store) {
13535
+ store.isReviewDirectoryActive = true;
13536
+ store.isReviewDirectoryLoading = true;
13526
13537
  }
13527
13538
  this.stopDirectoryObservers = [subscribe(ui.comments, "comments"), subscribe(ui.trackChanges, "trackChanges")];
13528
13539
  }
13529
13540
  createVueApp() {
13530
13541
  this.app = createApp(commentsList_default);
13531
- const parentProvides = this.superdoc?.app?._context?.provides;
13542
+ const parentProvides = this.superdoc?.["app"]?._context?.provides;
13532
13543
  if (parentProvides && this.app?._context?.provides) Object.setPrototypeOf(this.app._context.provides, parentProvides);
13533
13544
  if (this.superdoc?.pinia) {
13534
13545
  setActivePinia(this.superdoc.pinia);
@@ -13552,10 +13563,11 @@ var SuperComments = class extends import_eventemitter3.default {
13552
13563
  comments: null,
13553
13564
  trackChanges: null
13554
13565
  };
13555
- if (this.superdoc?.commentsStore) {
13556
- this.superdoc.commentsStore.clearReviewDirectory();
13557
- this.superdoc.commentsStore.isReviewDirectoryActive = false;
13558
- this.superdoc.commentsStore.isReviewDirectoryLoading = false;
13566
+ const store = readCommentsStore(this.superdoc);
13567
+ if (store) {
13568
+ store.clearReviewDirectory();
13569
+ store.isReviewDirectoryActive = false;
13570
+ store.isReviewDirectoryLoading = false;
13559
13571
  }
13560
13572
  if (this.app) {
13561
13573
  this.app.unmount();
@@ -13569,7 +13581,7 @@ var SuperComments = class extends import_eventemitter3.default {
13569
13581
  }
13570
13582
  };
13571
13583
  //#endregion
13572
- //#region src/composables/use-viewport-fit.js
13584
+ //#region src/composables/use-viewport-fit.ts
13573
13585
  var CSS_PX_PER_INCH = 96;
13574
13586
  var SIDEBAR_SELECTOR = ".superdoc__right-sidebar";
13575
13587
  var PDF_PAGE_SELECTOR = ".sd-pdf-viewer-page";
@@ -13674,7 +13686,7 @@ function useViewportFit({ getSuperdoc, superdocContainerWidth, isReady, activeZo
13674
13686
  const root = superdocRoot.value;
13675
13687
  if (!root?.querySelectorAll) return null;
13676
13688
  let widest = 0;
13677
- for (const page of root.querySelectorAll(PDF_PAGE_SELECTOR)) {
13689
+ for (const page of Array.from(root.querySelectorAll(PDF_PAGE_SELECTOR))) {
13678
13690
  const measured = Number(page.clientWidth) || Number(page.getBoundingClientRect?.().width) || 0;
13679
13691
  let scaleFactor = NaN;
13680
13692
  if (typeof window !== "undefined" && typeof window.getComputedStyle === "function") scaleFactor = Number.parseFloat(window.getComputedStyle(page).getPropertyValue("--scale-factor"));
@@ -15481,7 +15493,7 @@ var WhiteboardPage_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/
15481
15493
  }, null, 44, _hoisted_1$21);
15482
15494
  };
15483
15495
  }
15484
- }), [["__scopeId", "data-v-f730b33d"]]);
15496
+ }), [["__scopeId", "data-v-fdae8749"]]);
15485
15497
  //#endregion
15486
15498
  //#region src/components/Whiteboard/WhiteboardLayer.vue
15487
15499
  var WhiteboardLayer_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
@@ -15552,16 +15564,11 @@ var WhiteboardLayer_default = /* @__PURE__ */ _plugin_vue_export_helper_default(
15552
15564
  }), 128))], 4);
15553
15565
  };
15554
15566
  }
15555
- }), [["__scopeId", "data-v-980e1f94"]]);
15567
+ }), [["__scopeId", "data-v-800e1970"]]);
15556
15568
  //#endregion
15557
- //#region src/components/CommentsLayer/collect-removed-comment-ids.js
15569
+ //#region src/components/CommentsLayer/collect-removed-comment-ids.ts
15558
15570
  /**
15559
15571
  * Expand deleted comment ids through comment and tracked-change descendants.
15560
- *
15561
- * @param {ReadonlyArray<Record<string, any>>} comments
15562
- * @param {ReadonlyArray<string>} targetIds
15563
- * @param {(comment: Record<string, any>) => boolean} [isInScope]
15564
- * @returns {Set<string>}
15565
15572
  */
15566
15573
  var collectRemovedCommentIds = (comments, targetIds, isInScope = () => true) => {
15567
15574
  const targets = new Set(targetIds.map(String));
@@ -15644,7 +15651,7 @@ function normalizeCommentsUiConfig(commentsConfig) {
15644
15651
  return normalized;
15645
15652
  }
15646
15653
  //#endregion
15647
- //#region src/composables/use-comment-small-screen.js
15654
+ //#region src/composables/use-comment-small-screen.ts
15648
15655
  var SUPERDOC_DOCUMENT_SELECTOR = ".superdoc__document";
15649
15656
  var isValidCompactBreakpoint = (value) => {
15650
15657
  return isFiniteNumber(value) && value >= 0;
@@ -15724,10 +15731,11 @@ function useCommentSmallScreen({ commentsModuleConfig, superdocRoot, layers }) {
15724
15731
  }
15725
15732
  documentWidthTargets = nextTargets;
15726
15733
  if (!nextTargets.length) return;
15727
- documentWidthResizeObserver = new ResizeObserverClass(() => {
15734
+ const observer = new ResizeObserverClass(() => {
15728
15735
  recalculateCompactCommentsMode();
15729
15736
  });
15730
- nextTargets.forEach((el) => documentWidthResizeObserver.observe(el));
15737
+ documentWidthResizeObserver = observer;
15738
+ nextTargets.forEach((el) => observer.observe(el));
15731
15739
  };
15732
15740
  const getMeasuredDocumentWidth = () => {
15733
15741
  ensureDocumentWidthObserver();
@@ -15783,7 +15791,7 @@ function useCommentSmallScreen({ commentsModuleConfig, superdocRoot, layers }) {
15783
15791
  };
15784
15792
  }
15785
15793
  //#endregion
15786
- //#region src/composables/use-compact-comment-popover.js
15794
+ //#region src/composables/use-compact-comment-popover.ts
15787
15795
  var POPOVER_WIDTH_PX = 320;
15788
15796
  var SAFE_MARGIN_PX = 12;
15789
15797
  var MIN_BOTTOM_SPACE_PX = 220;
@@ -15813,7 +15821,7 @@ var resolveInteractionAnchor = (lastClickAnchor) => {
15813
15821
  var resolveInlineHighlightAnchorRect = ({ rootEl, comment, pendingComment }) => {
15814
15822
  if (Boolean(pendingComment?.value && comment?.commentId === pendingComment.value?.commentId)) {
15815
15823
  const nodes = rootEl.querySelectorAll(COMMENT_HIGHLIGHT_SELECTOR);
15816
- for (const node of nodes) {
15824
+ for (const node of Array.from(nodes)) {
15817
15825
  if (!parseCommentIds(node.getAttribute(COMMENT_HIGHLIGHT_DATA_ATTR)).includes("pending")) continue;
15818
15826
  if (typeof node.getBoundingClientRect !== "function") continue;
15819
15827
  return node.getBoundingClientRect();
@@ -15823,7 +15831,7 @@ var resolveInlineHighlightAnchorRect = ({ rootEl, comment, pendingComment }) =>
15823
15831
  if (!anchorId) return null;
15824
15832
  const safeId = String(anchorId);
15825
15833
  const highlightNodes = rootEl.querySelectorAll(COMMENT_HIGHLIGHT_SELECTOR);
15826
- for (const node of highlightNodes) {
15834
+ for (const node of Array.from(highlightNodes)) {
15827
15835
  if (!parseCommentIds(node.getAttribute(COMMENT_HIGHLIGHT_DATA_ATTR)).includes(safeId)) continue;
15828
15836
  if (typeof node.getBoundingClientRect !== "function") continue;
15829
15837
  return node.getBoundingClientRect();
@@ -15908,9 +15916,10 @@ function useCompactCommentPopover({ activeComment, pendingComment, activeCompact
15908
15916
  };
15909
15917
  const trackCompactPopoverClickAnchor = (e) => {
15910
15918
  const root = superdocRoot.value;
15911
- if (!root || !layers.value?.contains(e.target)) return;
15912
- const anchorElement = (typeof document.elementsFromPoint === "function" ? document.elementsFromPoint(e.clientX, e.clientY) : []).find((node) => node?.nodeType === 1 && root.contains(node) && node.closest("[data-track-change-id], .superdoc-comment-highlight, .sd-comment-anchor"))?.closest("[data-track-change-id], .superdoc-comment-highlight, .sd-comment-anchor") ?? (e.target?.nodeType === 1 ? e.target.closest("[data-track-change-id], .superdoc-comment-highlight, .sd-comment-anchor") : null);
15913
- if (clearCompactPopoverIfPdfClickedOutside(root, e.target, anchorElement)) return;
15919
+ const target = e.target instanceof Node ? e.target : null;
15920
+ if (!root || !layers.value?.contains(target)) return;
15921
+ const anchorElement = (typeof document.elementsFromPoint === "function" ? document.elementsFromPoint(e.clientX, e.clientY) : []).find((node) => node?.nodeType === 1 && root.contains(node) && node.closest("[data-track-change-id], .superdoc-comment-highlight, .sd-comment-anchor"))?.closest("[data-track-change-id], .superdoc-comment-highlight, .sd-comment-anchor") ?? (target instanceof Element ? target.closest("[data-track-change-id], .superdoc-comment-highlight, .sd-comment-anchor") : null);
15922
+ if (clearCompactPopoverIfPdfClickedOutside(root, target, anchorElement)) return;
15914
15923
  if (e.button !== 0 || e.pointerType !== "mouse") return;
15915
15924
  const anchorRect = anchorElement && typeof anchorElement.getBoundingClientRect === "function" ? anchorElement.getBoundingClientRect() : null;
15916
15925
  if (!anchorRect) return;
@@ -16144,7 +16153,7 @@ function normalizeHyperlinksConfig(config = {}) {
16144
16153
  };
16145
16154
  }
16146
16155
  //#endregion
16147
- //#region src/helpers/v2-review-target.js
16156
+ //#region src/helpers/v2-review-target.ts
16148
16157
  /**
16149
16158
  * Resolve the comments-store identity for a document-origin v2 review target.
16150
16159
  * Painted review carriers can become interactive before the asynchronous row
@@ -16160,15 +16169,16 @@ function resolveV2ReviewTargetCommentId(target, getComment) {
16160
16169
  return commentId != null ? String(commentId) : null;
16161
16170
  }
16162
16171
  //#endregion
16163
- //#region src/helpers/v2-mutation-exception.js
16172
+ //#region src/helpers/v2-mutation-exception.ts
16164
16173
  var FAILURE_SOURCES = /* @__PURE__ */ new Set(["shell", "receipt"]);
16165
16174
  var DIAGNOSTIC_CODE = /^[a-zA-Z][a-zA-Z0-9_-]{0,127}$/;
16166
16175
  var COMMAND_KIND = /^[a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?$/;
16167
16176
  function createV2MutationRejectionCause(event) {
16168
- if (!event || typeof event !== "object") return {};
16169
- const reason = event.reason ?? (event.failureSource === "receipt" ? event.failure?.code : void 0);
16177
+ if (!isPlainObject$1(event)) return {};
16178
+ const failure = isPlainObject$1(event.failure) ? event.failure : void 0;
16179
+ const reason = event.reason ?? (event.failureSource === "receipt" ? failure?.code : void 0);
16170
16180
  return {
16171
- ...FAILURE_SOURCES.has(event.failureSource) ? { failureSource: event.failureSource } : {},
16181
+ ...typeof event.failureSource === "string" && FAILURE_SOURCES.has(event.failureSource) ? { failureSource: event.failureSource } : {},
16172
16182
  ...typeof reason === "string" && DIAGNOSTIC_CODE.test(reason) ? { reason } : {},
16173
16183
  ...typeof event.inputKind === "string" && DIAGNOSTIC_CODE.test(event.inputKind) ? { inputKind: event.inputKind } : {},
16174
16184
  ...typeof event.editableCommandKind === "string" && event.editableCommandKind.length <= 128 && COMMAND_KIND.test(event.editableCommandKind) ? { editableCommandKind: event.editableCommandKind } : {}
@@ -16196,7 +16206,7 @@ function createV2MutationRejectionNotificationGate(matches) {
16196
16206
  };
16197
16207
  }
16198
16208
  //#endregion
16199
- //#region src/helpers/v2-author-required-rejection.js
16209
+ //#region src/helpers/v2-author-required-rejection.ts
16200
16210
  var NO_AUTHOR_SIGNAL = "no-author-configured";
16201
16211
  /** Stable, non-terminal exception code surfaced to consumers. */
16202
16212
  var V2_AUTHOR_REQUIRED_CODE = "author-required";
@@ -16208,15 +16218,11 @@ var V2_AUTHOR_REQUIRED_MESSAGE = "This edit needs an author identity. Set `user.
16208
16218
  function messageHasNoAuthorSignal(message) {
16209
16219
  return typeof message === "string" && message.includes(NO_AUTHOR_SIGNAL);
16210
16220
  }
16211
- /**
16212
- * @param {any} event - a `v2-host-event` payload.
16213
- * @returns {boolean} true when the rejection means the session needs an author.
16214
- */
16215
16221
  function isV2AuthorRequiredRejection(event) {
16216
- if (!event || event.type !== "mutation:rejected") return false;
16222
+ if (!isPlainObject$1(event) || event.type !== "mutation:rejected") return false;
16217
16223
  if (event.failureSource === "receipt") {
16218
16224
  const failure = event.failure;
16219
- if (!failure) return false;
16225
+ if (!isPlainObject$1(failure)) return false;
16220
16226
  return failure.code === "PRECONDITION_FAILED" && messageHasNoAuthorSignal(failure.message);
16221
16227
  }
16222
16228
  if (event.failureSource === "shell") {
@@ -16229,7 +16235,7 @@ function createV2AuthorRequiredNotificationGate() {
16229
16235
  return createV2MutationRejectionNotificationGate(isV2AuthorRequiredRejection);
16230
16236
  }
16231
16237
  //#endregion
16232
- //#region src/helpers/v2-bulk-decision-event.js
16238
+ //#region src/helpers/v2-bulk-decision-event.ts
16233
16239
  function toV2BulkDecisionEvent(documentId, fact) {
16234
16240
  if (fact?.schemaVersion !== 1 || fact.decision !== "accept" && fact.decision !== "reject") return null;
16235
16241
  return {
@@ -16241,7 +16247,7 @@ function toV2BulkDecisionEvent(documentId, fact) {
16241
16247
  };
16242
16248
  }
16243
16249
  //#endregion
16244
- //#region src/helpers/v2-keyboard-edit-rejection.js
16250
+ //#region src/helpers/v2-keyboard-edit-rejection.ts
16245
16251
  var EDIT_INPUT_KINDS = /* @__PURE__ */ new Set([
16246
16252
  "keydown",
16247
16253
  "beforeinput",
@@ -16291,7 +16297,7 @@ var EDIT_FAILURE_SOURCES = /* @__PURE__ */ new Set(["shell", "receipt"]);
16291
16297
  var V2_EDIT_REJECTED_CODE = "edit-rejected";
16292
16298
  var V2_EDIT_REJECTED_MESSAGE = "This edit couldn’t be completed. Adjust the selection and try again.";
16293
16299
  function isV2KeyboardEditRejection(event) {
16294
- return Boolean(event && event.type === "mutation:rejected" && event.origin === "document-surface" && EDIT_FAILURE_SOURCES.has(event.failureSource) && EDIT_INPUT_KINDS.has(event.inputKind) && (EDIT_COMMAND_KINDS.has(event.editableCommandKind) || event.editableCommandKind == null && EDIT_INPUT_WITHOUT_COMMAND_KINDS.has(event.inputKind)));
16300
+ return isPlainObject$1(event) && event.type === "mutation:rejected" && event.origin === "document-surface" && EDIT_FAILURE_SOURCES.has(event.failureSource) && EDIT_INPUT_KINDS.has(event.inputKind) && (EDIT_COMMAND_KINDS.has(event.editableCommandKind) || event.editableCommandKind == null && EDIT_INPUT_WITHOUT_COMMAND_KINDS.has(event.inputKind));
16295
16301
  }
16296
16302
  function createV2KeyboardEditRejectionException(documentId, event) {
16297
16303
  return {
@@ -16305,24 +16311,17 @@ function createV2KeyboardEditRejectionNotificationGate() {
16305
16311
  return createV2MutationRejectionNotificationGate(isV2KeyboardEditRejection);
16306
16312
  }
16307
16313
  //#endregion
16308
- //#region src/helpers/v2-selection-sync.js
16314
+ //#region src/helpers/v2-selection-sync.ts
16309
16315
  /**
16310
16316
  * A logical v2 selection snapshot represents a non-empty range when its anchor
16311
16317
  * and focus point at different block positions. Mirrors the range check the v2
16312
16318
  * shell uses when it emits `v2-selection-changed`.
16313
- *
16314
- * @param {{ anchor?: { blockId?: unknown, blockOffset?: unknown }, focus?: { blockId?: unknown, blockOffset?: unknown } } | null | undefined} snapshot
16315
- * @returns {boolean}
16316
16319
  */
16317
16320
  var isV2RangeSnapshot = (snapshot) => Boolean(snapshot?.anchor && snapshot?.focus && (snapshot.anchor.blockId !== snapshot.focus.blockId || snapshot.anchor.blockOffset !== snapshot.focus.blockOffset));
16318
16321
  /**
16319
16322
  * Detect a real browser text selection whose endpoints are outside the active
16320
16323
  * v2 mount. Editable host selections can have no native DOM range, so an
16321
16324
  * absent range must not count as an outside selection.
16322
- *
16323
- * @param {Selection | null | undefined} selection
16324
- * @param {Node | null | undefined} root
16325
- * @returns {boolean}
16326
16325
  */
16327
16326
  var hasOutsideV2DomRangeSelection = (selection, root) => {
16328
16327
  if (!selection || selection.rangeCount < 1 || selection.isCollapsed || !root) return false;
@@ -16338,10 +16337,6 @@ var hasOutsideV2DomRangeSelection = (selection, root) => {
16338
16337
  * host snapshot rather than clobber the selection the host just published.
16339
16338
  * Only editable modes use the host snapshot. Viewing mode keeps native DOM
16340
16339
  * selection, and unknown modes should not preserve stale host state.
16341
- *
16342
- * @param {string | null | undefined} documentMode
16343
- * @param {unknown} hostSnapshot
16344
- * @returns {boolean}
16345
16340
  */
16346
16341
  var shouldPreserveHostV2Selection = (documentMode, hostSnapshot) => {
16347
16342
  if (documentMode !== "editing" && documentMode !== "suggesting") return false;
@@ -16352,10 +16347,6 @@ var shouldPreserveHostV2Selection = (documentMode, hostSnapshot) => {
16352
16347
  * rebuilt. Keep an already-positioned comment affordance during that gap when
16353
16348
  * the host still owns a range; otherwise the button unmounts and remounts on
16354
16349
  * consecutive paint frames, making it blink and intercepting its own click.
16355
- *
16356
- * @param {boolean} hasHostRange
16357
- * @param {{ source?: unknown } | null | undefined} selectionPosition
16358
- * @returns {boolean}
16359
16350
  */
16360
16351
  var shouldRetainV2FloatingSelection = (hasHostRange, selectionPosition) => hasHostRange === true && selectionPosition?.source === "document-editor";
16361
16352
  //#endregion
@@ -16547,7 +16538,7 @@ function usePasswordPrompt({ getSurfaceManager, getPasswordPromptConfig, onUnhan
16547
16538
  })
16548
16539
  });
16549
16540
  } else {
16550
- const mod = await import("./chunks/PasswordPromptSurface-6mF6Azda.es.js");
16541
+ const mod = await import("./chunks/PasswordPromptSurface-CZqhDQQ1.es.js");
16551
16542
  const surfaceId = `password-prompt-${doc.id}`;
16552
16543
  handle = manager.open({
16553
16544
  id: surfaceId,
@@ -16649,9 +16640,6 @@ function createReplaceContinuation(session, { getCurrentSession, applySlice, onS
16649
16640
  }
16650
16641
  //#endregion
16651
16642
  //#region src/composables/use-find-replace.ts
16652
- function isThenable$2(value) {
16653
- return (typeof value === "object" || typeof value === "function") && value !== null && "then" in value && typeof value.then === "function";
16654
- }
16655
16643
  var DEFAULT_TEXTS = {
16656
16644
  findPlaceholder: "Find",
16657
16645
  findAriaLabel: "Find text",
@@ -16826,7 +16814,7 @@ function useFindReplace({ getSurfaceManager, getActiveEditor, activeEditorRef, g
16826
16814
  try {
16827
16815
  result = search.replace(replaceText.value);
16828
16816
  } catch {}
16829
- if (isThenable$2(result)) Promise.resolve(result).then(finish, finish);
16817
+ if (isThenable$1(result)) Promise.resolve(result).then(finish, finish);
16830
16818
  else finish();
16831
16819
  }
16832
16820
  function replaceAll() {
@@ -16848,7 +16836,7 @@ function useFindReplace({ getSurfaceManager, getActiveEditor, activeEditorRef, g
16848
16836
  try {
16849
16837
  result = search.replaceAll(replaceText.value);
16850
16838
  } catch {}
16851
- if (isThenable$2(result)) Promise.resolve(result).then(finish, finish);
16839
+ if (isThenable$1(result)) Promise.resolve(result).then(finish, finish);
16852
16840
  else finish();
16853
16841
  }
16854
16842
  function syncFromSearchSession() {
@@ -17210,7 +17198,7 @@ function useFindReplace({ getSurfaceManager, getActiveEditor, activeEditorRef, g
17210
17198
  } else {
17211
17199
  let FindReplaceSurface;
17212
17200
  try {
17213
- FindReplaceSurface = (await import("./chunks/FindReplaceSurface-BKVHzhQ4.es.js")).default;
17201
+ FindReplaceSurface = (await import("./chunks/FindReplaceSurface-B_5ggdWg.es.js")).default;
17214
17202
  } catch {
17215
17203
  opening = false;
17216
17204
  return;
@@ -17477,7 +17465,7 @@ var plus_solid_default = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0
17477
17465
  //#region ../../shared/common/icons/trash-can-solid.svg?raw
17478
17466
  var trash_can_solid_default = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 448 512\"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d=\"M135.2 17.7C140.6 6.8 151.7 0 163.8 0L284.2 0c12.1 0 23.2 6.8 28.6 17.7L320 32l96 0c17.7 0 32 14.3 32 32s-14.3 32-32 32L32 96C14.3 96 0 81.7 0 64S14.3 32 32 32l96 0 7.2-14.3zM32 128l384 0 0 320c0 35.3-28.7 64-64 64L96 512c-35.3 0-64-28.7-64-64l0-320zm96 64c-8.8 0-16 7.2-16 16l0 224c0 8.8 7.2 16 16 16s16-7.2 16-16l0-224c0-8.8-7.2-16-16-16zm96 0c-8.8 0-16 7.2-16 16l0 224c0 8.8 7.2 16 16 16s16-7.2 16-16l0-224c0-8.8-7.2-16-16-16zm96 0c-8.8 0-16 7.2-16 16l0 224c0 8.8 7.2 16 16 16s16-7.2 16-16l0-224c0-8.8-7.2-16-16-16z\"/></svg>";
17479
17467
  //#endregion
17480
- //#region src/internal/toolbar/built-in/toolbarIcons.js
17468
+ //#region src/internal/toolbar/built-in/toolbarIcons.ts
17481
17469
  var toolbarIcons = {
17482
17470
  undo: rotate_left_solid_default,
17483
17471
  redo: rotate_right_solid_default,
@@ -17870,7 +17858,7 @@ var LinkInput_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__
17870
17858
  }
17871
17859
  }), [["__scopeId", "data-v-172107e4"]]);
17872
17860
  //#endregion
17873
- //#region src/internal/toolbar/built-in/scroll-helpers.js
17861
+ //#region src/internal/toolbar/built-in/scroll-helpers.ts
17874
17862
  function getScrollableParent(element) {
17875
17863
  let currentElement = element;
17876
17864
  while (currentElement) {
@@ -17903,7 +17891,6 @@ function scrollToElement(targetElement, options = {
17903
17891
  var FLOATING_SURFACE_ID = "link-popover";
17904
17892
  var RECENT_OUTSIDE_CLOSE_MS = 500;
17905
17893
  var MAX_ANCHOR_NAVIGATION_STEPS = 4;
17906
- var isThenable$1 = (value) => Boolean(value && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function");
17907
17894
  function isLinkPopoverDocumentApi(value) {
17908
17895
  return isPlainObject$1(value) || typeof value === "function";
17909
17896
  }
@@ -20473,7 +20460,7 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
20473
20460
  __name: "SuperDoc",
20474
20461
  emits: ["selection-update"],
20475
20462
  setup(__props, { emit: __emit }) {
20476
- const PdfViewer = defineAsyncComponent(() => import("./chunks/PdfViewer-aOWhUVI7.es.js"));
20463
+ const PdfViewer = defineAsyncComponent(() => import("./chunks/PdfViewer-CW09MNrB.es.js"));
20477
20464
  const getDocumentLoadPassword = (doc) => doc.password ?? proxy.$superdoc.config.password;
20478
20465
  const resolveDocumentV2Collaboration = (doc) => {
20479
20466
  const rawConfig = doc?.v2Collaboration;
@@ -21276,7 +21263,7 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
21276
21263
  let v2SelectionToolbarRafHandle = 0;
21277
21264
  let v2SelectionToolbarTimeoutHandle = 0;
21278
21265
  let v2DomSelectionRafHandle = 0;
21279
- const buildV2EditorUpdatePayload = ({ editor, sourceEditor, surface = "body", headerId = null, sectionType = null } = {}) => {
21266
+ const buildV2EditorUpdatePayload = ({ editor, sourceEditor, surface = "body", headerId = null, sectionType = null, isRemote = false } = {}) => {
21280
21267
  const activeEditor = proxy.$superdoc?.activeEditor ?? null;
21281
21268
  const effectiveEditor = editor ?? sourceEditor ?? activeEditor ?? void 0;
21282
21269
  return {
@@ -21284,7 +21271,8 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
21284
21271
  sourceEditor: sourceEditor ?? effectiveEditor,
21285
21272
  surface,
21286
21273
  headerId,
21287
- sectionType
21274
+ sectionType,
21275
+ isRemote
21288
21276
  };
21289
21277
  };
21290
21278
  const emitV2EditorUpdate = (payload = {}) => {
@@ -21678,6 +21666,7 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
21678
21666
  v2ReviewWindowController.invalidate("collaboration:remote-review-changed");
21679
21667
  v2ReviewWindowController.refreshCommittedWindow("collaboration:remote-review-changed");
21680
21668
  }
21669
+ emitV2EditorUpdate({ isRemote: true });
21681
21670
  return;
21682
21671
  }
21683
21672
  if (event.type === "source:complete") {
@@ -23090,7 +23079,7 @@ var SuperDoc_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
23090
23079
  ], 46, _hoisted_1$17);
23091
23080
  };
23092
23081
  }
23093
- }), [["__scopeId", "data-v-26bcc2bd"]]);
23082
+ }), [["__scopeId", "data-v-d2540ad3"]]);
23094
23083
  //#endregion
23095
23084
  //#region src/core/create-app.ts
23096
23085
  var PINIA_DEVTOOLS_SETUP_EVENT = "devtools-plugin:setup";
@@ -25873,23 +25862,21 @@ function resolveBuiltInItemCommandId(name) {
25873
25862
  return resolveToolbarCommandId(name) ?? UNCATALOGED_ITEM_COMMAND_IDS[name] ?? null;
25874
25863
  }
25875
25864
  //#endregion
25876
- //#region src/internal/toolbar/built-in/helpers.js
25865
+ //#region src/internal/toolbar/built-in/helpers.ts
25877
25866
  var sanitizeNumber = (value, defaultNumber) => {
25878
- let sanitized = value.replace(/[^0-9.]/g, "");
25879
- sanitized = parseFloat(sanitized);
25880
- if (isNaN(sanitized)) sanitized = defaultNumber;
25881
- sanitized = parseFloat(sanitized);
25882
- return sanitized;
25883
- };
25884
- var throttle = (func, wait, options) => {
25885
- let timeout, args, result;
25867
+ const parsed = parseFloat(String(value ?? "").replace(/[^0-9.]/g, ""));
25868
+ return isNaN(parsed) ? defaultNumber : parsed;
25869
+ };
25870
+ var throttle = (func, wait, options = {}) => {
25871
+ let timeout;
25872
+ let args;
25873
+ let result;
25886
25874
  let previous = 0;
25887
- if (!options) options = {};
25888
25875
  const later = () => {
25889
25876
  previous = options.leading === false ? 0 : Date.now();
25890
- timeout = null;
25891
- result = func(...args);
25892
- if (!timeout) args = null;
25877
+ timeout = void 0;
25878
+ if (args) result = func(...args);
25879
+ if (!timeout) args = void 0;
25893
25880
  };
25894
25881
  const throttled = (...callArgs) => {
25895
25882
  const _now = Date.now();
@@ -25899,18 +25886,18 @@ var throttle = (func, wait, options) => {
25899
25886
  if (remaining <= 0 || remaining > wait) {
25900
25887
  if (timeout) {
25901
25888
  clearTimeout(timeout);
25902
- timeout = null;
25889
+ timeout = void 0;
25903
25890
  }
25904
25891
  previous = _now;
25905
25892
  result = func(...callArgs);
25906
- if (!timeout) args = null;
25893
+ if (!timeout) args = void 0;
25907
25894
  } else if (!timeout && options.trailing !== false) timeout = setTimeout(later, remaining);
25908
25895
  return result;
25909
25896
  };
25910
25897
  throttled.cancel = function() {
25911
25898
  clearTimeout(timeout);
25912
25899
  previous = 0;
25913
- timeout = args = null;
25900
+ timeout = args = void 0;
25914
25901
  };
25915
25902
  return throttled;
25916
25903
  };
@@ -26809,24 +26796,11 @@ var OverflowMenu_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/*
26809
26796
  }
26810
26797
  }), [["__scopeId", "data-v-d2e189fd"]]);
26811
26798
  //#endregion
26812
- //#region src/internal/toolbar/built-in/font-typeahead.js
26813
- /**
26814
- * Pure typeahead/autocomplete helpers for the font comboboxes (family + size).
26815
- *
26816
- * Matching is case-insensitive prefix matching on the logical font labels.
26817
- * Space is a normal query character, so the query is never split on spaces;
26818
- * only the outer whitespace is ignored when comparing.
26819
- *
26820
- * These functions hold no Vue or DOM state so CI can unit-test them in isolation.
26821
- */
26799
+ //#region src/internal/toolbar/built-in/font-typeahead.ts
26822
26800
  var normalize = (value) => String(value ?? "").trim().toLowerCase();
26823
26801
  /**
26824
26802
  * Index of the first label that starts with `query` (case-insensitive).
26825
- * An empty/whitespace query never matches.
26826
- *
26827
- * @param {string} query
26828
- * @param {ReadonlyArray<string>} labels
26829
- * @returns {number} matching index or -1
26803
+ * An empty/whitespace query never matches. Returns the matching index or -1.
26830
26804
  */
26831
26805
  var findPrefixMatchIndex = (query, labels) => {
26832
26806
  const q = normalize(query);
@@ -26840,12 +26814,7 @@ var findPrefixMatchIndex = (query, labels) => {
26840
26814
  * When `autocomplete` is true and a prefix match exists that is longer than the
26841
26815
  * typed query, the completion is shown with the suffix selected so the next
26842
26816
  * keystroke replaces it. When false (deletion) or no match exists, the raw
26843
- * query is shown with the caret at its end.
26844
- *
26845
- * @param {string} query - the user-typed portion
26846
- * @param {ReadonlyArray<string>} labels
26847
- * @param {{ autocomplete?: boolean }} [options]
26848
- * @returns {{ matchIndex: number, display: string, selectionStart: number, selectionEnd: number }}
26817
+ * query is shown with the caret at its end. `query` is the user-typed portion.
26849
26818
  */
26850
26819
  var computeTypeahead = (query, labels, { autocomplete = true } = {}) => {
26851
26820
  const typed = String(query ?? "");
@@ -26897,9 +26866,6 @@ var MAX_FONT_SIZE = 1638;
26897
26866
  * the nearest half point (DOCX/Word support half points such as 10.5), and clamps
26898
26867
  * to the supported range. Returns '' when nothing usable was typed, including
26899
26868
  * negative or sub-minimum values.
26900
- *
26901
- * @param {string} value
26902
- * @returns {string} point size (whole or half), or '' when empty/invalid
26903
26869
  */
26904
26870
  var normalizeCustomFontSize = (value) => {
26905
26871
  const cleaned = String(value ?? "").replace(/[^0-9.-]/g, "");
@@ -28590,7 +28556,7 @@ var Toolbar_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__PU
28590
28556
  }
28591
28557
  }), [["__scopeId", "data-v-bce7c04a"]]);
28592
28558
  //#endregion
28593
- //#region src/internal/toolbar/built-in/font-options.js
28559
+ //#region src/internal/toolbar/built-in/font-options.ts
28594
28560
  /**
28595
28561
  * Normalize a font dropdown option so each row renders in its own typeface.
28596
28562
  *
@@ -28946,7 +28912,7 @@ var StyleButtonsList_default = /* @__PURE__ */ _plugin_vue_export_helper_default
28946
28912
  }
28947
28913
  }), [["__scopeId", "data-v-539d0995"]]);
28948
28914
  //#endregion
28949
- //#region src/internal/toolbar/built-in/list-style-buttons.js
28915
+ //#region src/internal/toolbar/built-in/list-style-buttons.ts
28950
28916
  var bulletStyleButtons = [
28951
28917
  {
28952
28918
  key: "disc",
@@ -30257,7 +30223,7 @@ var PageNumberMenu_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/
30257
30223
  onClick: ($event) => selectTile(tile),
30258
30224
  onDblclick: applyPageNumbers,
30259
30225
  onKeydown: onTileKeydown
30260
- }, [(openBlock(), createElementBlock("svg", _hoisted_5, [_cache[4] || (_cache[4] = createStaticVNode("<rect class=\"sd-page-number-menu__sheet\" x=\"0.75\" y=\"0.75\" width=\"34.5\" height=\"44.5\" rx=\"2.5\" data-v-a6c124c0></rect><rect class=\"sd-page-number-menu__line\" x=\"7\" y=\"14\" width=\"22\" height=\"2\" rx=\"1\" data-v-a6c124c0></rect><rect class=\"sd-page-number-menu__line\" x=\"7\" y=\"19\" width=\"18\" height=\"2\" rx=\"1\" data-v-a6c124c0></rect><rect class=\"sd-page-number-menu__line\" x=\"7\" y=\"24\" width=\"22\" height=\"2\" rx=\"1\" data-v-a6c124c0></rect><rect class=\"sd-page-number-menu__line\" x=\"7\" y=\"29\" width=\"14\" height=\"2\" rx=\"1\" data-v-a6c124c0></rect>", 5)), createElementVNode("rect", {
30226
+ }, [(openBlock(), createElementBlock("svg", _hoisted_5, [_cache[4] || (_cache[4] = createStaticVNode("<rect class=\"sd-page-number-menu__sheet\" x=\"0.75\" y=\"0.75\" width=\"34.5\" height=\"44.5\" rx=\"2.5\" data-v-e3105afd></rect><rect class=\"sd-page-number-menu__line\" x=\"7\" y=\"14\" width=\"22\" height=\"2\" rx=\"1\" data-v-e3105afd></rect><rect class=\"sd-page-number-menu__line\" x=\"7\" y=\"19\" width=\"18\" height=\"2\" rx=\"1\" data-v-e3105afd></rect><rect class=\"sd-page-number-menu__line\" x=\"7\" y=\"24\" width=\"22\" height=\"2\" rx=\"1\" data-v-e3105afd></rect><rect class=\"sd-page-number-menu__line\" x=\"7\" y=\"29\" width=\"14\" height=\"2\" rx=\"1\" data-v-e3105afd></rect>", 5)), createElementVNode("rect", {
30261
30227
  class: "sd-page-number-menu__chip",
30262
30228
  x: CHIP_X[tile.alignment],
30263
30229
  y: CHIP_Y[tile.position],
@@ -30337,23 +30303,21 @@ var PageNumberMenu_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/
30337
30303
  ], 10, _hoisted_1);
30338
30304
  };
30339
30305
  }
30340
- }), [["__scopeId", "data-v-a6c124c0"]]);
30306
+ }), [["__scopeId", "data-v-e3105afd"]]);
30341
30307
  //#endregion
30342
- //#region src/internal/toolbar/built-in/page-number-feedback.js
30308
+ //#region src/internal/toolbar/built-in/page-number-feedback.ts
30343
30309
  var FLASH_CLASS = "sd-page-number-flash";
30344
30310
  var FLASH_MS = 1400;
30345
30311
  var nextFrame = (view) => new Promise((resolve) => {
30346
- if (typeof view?.requestAnimationFrame === "function") view.requestAnimationFrame(() => resolve());
30312
+ if (typeof view.requestAnimationFrame === "function") view.requestAnimationFrame(() => resolve());
30347
30313
  else setTimeout(resolve, 16);
30348
30314
  });
30349
30315
  /**
30350
30316
  * Briefly highlight the painted header or footer regions that are on screen,
30351
30317
  * so the user sees where page numbers landed without the caret leaving the
30352
30318
  * body. Regions are read after the repaint that follows the mutation; nothing
30353
- * happens when none is visible or the host is unavailable.
30354
- *
30355
- * @param {HTMLElement | null | undefined} host Document viewport host element.
30356
- * @param {'header' | 'footer'} kind
30319
+ * happens when none is visible or the host is unavailable. `host` is the
30320
+ * document viewport host element.
30357
30321
  */
30358
30322
  async function flashPageNumberRegions(host, kind) {
30359
30323
  const view = host?.ownerDocument?.defaultView;
@@ -30361,7 +30325,7 @@ async function flashPageNumberRegions(host, kind) {
30361
30325
  await nextFrame(view);
30362
30326
  await nextFrame(view);
30363
30327
  const viewportHeight = view.innerHeight;
30364
- const regions = [...host.querySelectorAll(`[data-sd-headerfooter-kind="${kind}"]`)].filter((region) => {
30328
+ const regions = Array.from(host.querySelectorAll(`[data-sd-headerfooter-kind="${kind}"]`)).filter((region) => {
30365
30329
  const rect = region.getBoundingClientRect();
30366
30330
  return rect.height > 0 && rect.bottom > 0 && rect.top < viewportHeight;
30367
30331
  });
@@ -31709,7 +31673,7 @@ var makeDefaultItems = ({ superToolbar, toolbarIcons: configuredIcons, toolbarTe
31709
31673
  };
31710
31674
  };
31711
31675
  //#endregion
31712
- //#region src/internal/toolbar/built-in/general.js
31676
+ //#region src/internal/toolbar/built-in/general.ts
31713
31677
  /**
31714
31678
  * Minimal DOM helpers for the built-in toolbar shell.
31715
31679
  *
@@ -31720,8 +31684,6 @@ var makeDefaultItems = ({ superToolbar, toolbarIcons: configuredIcons, toolbarTe
31720
31684
  */
31721
31685
  /**
31722
31686
  * Resolve a toolbar mount target from a selector string or element id.
31723
- * @param {string|HTMLElement|null|undefined} selector
31724
- * @returns {HTMLElement|null}
31725
31687
  */
31726
31688
  var findElementBySelector = (selector) => {
31727
31689
  if (!selector) return null;
@@ -31761,9 +31723,6 @@ function toSelectedValue(value) {
31761
31723
  function nonEmptyString(value) {
31762
31724
  return typeof value === "string" && value ? value : void 0;
31763
31725
  }
31764
- function isThenable(value) {
31765
- return (typeof value === "object" || typeof value === "function") && value !== null && "then" in value && typeof value.then === "function";
31766
- }
31767
31726
  function isToolbarCommandCallback(value) {
31768
31727
  return typeof value === "function";
31769
31728
  }
@@ -31786,7 +31745,7 @@ function executeCommand(ui, commandId, argument, options = {}) {
31786
31745
  if (!options.reportUnhandled || settled !== false) return;
31787
31746
  options.onError?.(/* @__PURE__ */ new Error(`[superdoc toolbar] Command "${commandId}" did not run. Check that it is enabled and has the required input.`));
31788
31747
  };
31789
- if (isThenable(result)) Promise.resolve(result).then((settled) => {
31748
+ if (isThenable$1(result)) Promise.resolve(result).then((settled) => {
31790
31749
  reportFailure(settled);
31791
31750
  options.onSettled?.();
31792
31751
  }, (error) => {
@@ -32138,7 +32097,7 @@ var BuiltInToolbar = class extends import_eventemitter3.default {
32138
32097
  argument: payload.argument,
32139
32098
  option: payload.option
32140
32099
  });
32141
- if (isThenable(result)) return Promise.resolve(result).catch((error) => {
32100
+ if (isThenable$1(result)) return Promise.resolve(result).catch((error) => {
32142
32101
  this.#emitCommandException(error, config.name);
32143
32102
  return false;
32144
32103
  });
@@ -32615,7 +32574,7 @@ var BuiltInToolbar = class extends import_eventemitter3.default {
32615
32574
  ui: this.ui,
32616
32575
  superdoc: this.superdoc
32617
32576
  });
32618
- if (isThenable(result)) Promise.resolve(result).catch((error) => this.#emitCommandException(error, name));
32577
+ if (isThenable$1(result)) Promise.resolve(result).catch((error) => this.#emitCommandException(error, name));
32619
32578
  }
32620
32579
  this.updateToolbarState();
32621
32580
  return;
@@ -33185,7 +33144,7 @@ var SuperDoc = class extends import_eventemitter3.default {
33185
33144
  }
33186
33145
  this.userColorMap = /* @__PURE__ */ new Map();
33187
33146
  this.colorIndex = 0;
33188
- this.version = "2.29.0-next.9";
33147
+ this.version = "2.29.0";
33189
33148
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
33190
33149
  this.superdocId = config.superdocId || v4();
33191
33150
  this.colors = this.config.colors ?? [];