superdoc 2.28.0-next.9 → 2.29.0-next.1

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 (94) hide show
  1. package/dist/chunks/{FindReplaceSurface-8V8AjgR4.cjs → FindReplaceSurface-BRs3JrCq.cjs} +1 -1
  2. package/dist/chunks/{FindReplaceSurface-RUiTFDt3.es.js → FindReplaceSurface-Dm043CZP.es.js} +1 -1
  3. package/dist/chunks/{PasswordPromptSurface-B5DHV6qr.cjs → PasswordPromptSurface-BpqP4pUa.cjs} +1 -1
  4. package/dist/chunks/{PasswordPromptSurface-BDpxqdzp.es.js → PasswordPromptSurface-DGjmN7A-.es.js} +1 -1
  5. package/dist/chunks/{PdfViewer-DjdsIh6n.es.js → PdfViewer-D4lVeOJu.es.js} +4 -3
  6. package/dist/chunks/{PdfViewer-omriDChK.cjs → PdfViewer-boENOZdF.cjs} +4 -3
  7. package/dist/chunks/{_plugin-vue_export-helper-BUdjGKyl.cjs → _plugin-vue_export-helper-6MBoygIY.cjs} +9 -0
  8. package/dist/chunks/{_plugin-vue_export-helper-7ZiLY07t.es.js → _plugin-vue_export-helper-CsJQtMvr.es.js} +4 -1
  9. package/dist/chunks/{create-super-doc-ui-B4c55pFy.cjs → create-super-doc-ui-0OA8hCNb.cjs} +390 -44
  10. package/dist/chunks/{create-super-doc-ui-C4Ka5Ph3.es.js → create-super-doc-ui-Duf65d0b.es.js} +357 -41
  11. package/dist/chunks/is-finite-number-BEXgTRgc.cjs +11 -0
  12. package/dist/chunks/is-finite-number-BpL4F38c.es.js +6 -0
  13. package/dist/collaboration-upgrade-engine.cjs +1 -1
  14. package/dist/collaboration-upgrade-engine.es.js +1 -1
  15. package/dist/document-api/src/capabilities/html-markdown-support.d.ts +3 -3
  16. package/dist/document-api/src/contract/operation-definitions.d.ts +2 -2
  17. package/dist/document-api/src/index.d.ts +1 -1
  18. package/dist/document-api/src/lists/lists.d.ts +79 -79
  19. package/dist/document-api/src/lists/lists.types.d.ts +1 -0
  20. package/dist/document-api/src/sections/sections.types.d.ts +5 -1
  21. package/dist/document-api/src/types/clipboard.d.ts +5 -1
  22. package/dist/document-api/src/types/receipt.d.ts +2 -1
  23. package/dist/document-api/src/write/write.d.ts +10 -9
  24. package/dist/layout-engine/contracts/src/index.d.ts +5 -1
  25. package/dist/layout-engine/contracts/src/run-helpers.d.ts +1 -0
  26. package/dist/layout-engine/layout-bridge/src/index.d.ts +1 -0
  27. package/dist/layout-engine/layout-bridge/src/place-inline-drawings.d.ts +9 -0
  28. package/dist/layout-engine/layout-engine/src/layout-drawing.d.ts +2 -1
  29. package/dist/layout-engine/layout-engine/src/paginator.d.ts +1 -0
  30. package/dist/layout-engine/painters/dom/src/page-content.d.ts +1 -1
  31. package/dist/layout-engine/painters/dom/src/persistent-page-surface.d.ts +2 -0
  32. package/dist/layout-engine/style-engine/src/ooxml/index.d.ts +1 -1
  33. package/dist/public/ui-react.cjs +1 -1
  34. package/dist/public/ui-react.es.js +1 -1
  35. package/dist/public/ui-vue.cjs +1 -1
  36. package/dist/public/ui-vue.es.js +1 -1
  37. package/dist/public/ui.cjs +3 -2
  38. package/dist/public/ui.es.js +3 -2
  39. package/dist/shared/font-system/src/resolver.d.ts +3 -3
  40. package/dist/style.css +1 -1
  41. package/dist/style.layered.css +1 -1
  42. package/dist/superdoc/src/SuperDoc.vue.d.ts +5 -3
  43. package/dist/superdoc/src/components/CommentsLayer/CommentDialog.vue.d.ts +1670 -24
  44. package/dist/superdoc/src/components/CommentsLayer/CommentHeader.vue.d.ts +2 -2
  45. package/dist/superdoc/src/components/CommentsLayer/CommentInput.vue.d.ts +2 -2
  46. package/dist/superdoc/src/components/CommentsLayer/FloatingComments.vue.d.ts +24 -0
  47. package/dist/superdoc/src/components/CommentsLayer/PdfCommentsLayer.vue.d.ts +4 -0
  48. package/dist/superdoc/src/components/general/Avatar.vue.d.ts +7 -0
  49. package/dist/superdoc/src/components/surfaces/SurfaceDialog.vue.d.ts +27 -9
  50. package/dist/superdoc/src/components/surfaces/SurfaceExternalMount.vue.d.ts +53 -16
  51. package/dist/superdoc/src/composables/use-high-contrast-mode.d.ts +8 -4
  52. package/dist/superdoc/src/composables/use-link-popover.d.ts +3 -3
  53. package/dist/superdoc/src/composables/use-superdoc-instance.d.ts +10 -0
  54. package/dist/superdoc/src/core/SuperDoc.d.ts +2 -6
  55. package/dist/superdoc/src/core/collaboration/helpers.d.ts +0 -5
  56. package/dist/superdoc/src/core/collaboration/permissions.d.ts +1 -0
  57. package/dist/superdoc/src/core/collaboration/resolve-v2-collaboration-target.d.ts +2 -1
  58. package/dist/superdoc/src/core/create-app.d.ts +2 -6
  59. package/dist/superdoc/src/core/editor-runtime/types.d.ts +2 -0
  60. package/dist/superdoc/src/core/editor-runtime/v2/v2-editor-runtime-adapter.d.ts +2 -0
  61. package/dist/superdoc/src/core/types/index.d.ts +10 -4
  62. package/dist/superdoc/src/core/v2-integration/internal-vue-runtime.d.ts +1 -0
  63. package/dist/superdoc/src/core/v2-integration/v2-integration.d.ts +104 -84
  64. package/dist/superdoc/src/helpers/is-finite-number.d.ts +1 -0
  65. package/dist/superdoc/src/helpers/v2-review-mutation-impact.d.ts +2 -0
  66. package/dist/superdoc/src/internal/diagnostics/diagnostic-dedupe.d.ts +2 -2
  67. package/dist/superdoc/src/internal/diagnostics/translate-diagnostic.d.ts +5 -0
  68. package/dist/superdoc/src/internal/toolbar/built-in/AIWriter.vue.d.ts +2 -2
  69. package/dist/superdoc/src/internal/toolbar/built-in/LinkInput.vue.d.ts +181 -36
  70. package/dist/superdoc/src/internal/toolbar/built-in/LinkedStyle.vue.d.ts +39 -10
  71. package/dist/superdoc/src/internal/toolbar/built-in/PageNumberMenu.vue.d.ts +133 -22
  72. package/dist/superdoc/src/internal/toolbar/built-in/SdTooltip.vue.d.ts +62 -23
  73. package/dist/superdoc/src/internal/toolbar/built-in/ToolbarButton.vue.d.ts +101 -16
  74. package/dist/superdoc/src/internal/toolbar/built-in/ToolbarButtonIcon.vue.d.ts +31 -10
  75. package/dist/superdoc/src/internal/toolbar/built-in/ToolbarComboBox.vue.d.ts +82 -11
  76. package/dist/superdoc/src/internal/toolbar/built-in/ToolbarDropdown.vue.d.ts +122 -33
  77. package/dist/superdoc/src/internal/toolbar/built-in/constants.d.ts +0 -48
  78. package/dist/superdoc/src/internal/toolbar/built-in/use-toolbar-item.d.ts +0 -1
  79. package/dist/superdoc/src/internal/toolbar/built-in-toolbar.d.ts +4 -1
  80. package/dist/superdoc/src/internal/toolbar/compatibility-catalog.d.ts +16 -0
  81. package/dist/superdoc/src/public/ui/types.d.ts +39 -1
  82. package/dist/superdoc/src/public/ui.d.cts +12 -0
  83. package/dist/superdoc/src/public/ui.d.ts +1 -1
  84. package/dist/superdoc/src/stores/comments-store.d.ts +158 -125
  85. package/dist/superdoc/src/stores/superdoc-store.d.ts +475 -376
  86. package/dist/superdoc.cjs +561 -1843
  87. package/dist/superdoc.es.js +766 -13144
  88. package/dist-cdn/style.layered.css +1 -1
  89. package/dist-cdn/superdoc.min.css +1 -1
  90. package/dist-cdn/superdoc.min.js +42 -42
  91. package/package.json +4 -3
  92. package/dist/superdoc/src/core/collaboration/collaboration.d.ts +0 -18
  93. package/dist/superdoc/src/helpers/group-changes.d.ts +0 -1
  94. package/dist/superdoc/src/internal/toolbar/built-in/OverflowMenu.vue.d.ts +0 -104
package/dist/superdoc.cjs CHANGED
@@ -1,16 +1,15 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_rolldown_runtime = require("./chunks/rolldown-runtime-74VwNCz7.cjs");
3
3
  const require_blank_docx = require("./chunks/blank-docx-BuFAbRjs.cjs");
4
- const require_create_super_doc_ui = require("./chunks/create-super-doc-ui-B4c55pFy.cjs");
4
+ const require_create_super_doc_ui = require("./chunks/create-super-doc-ui-0OA8hCNb.cjs");
5
5
  const require_eventemitter3 = require("./chunks/eventemitter3-C_TAnXOl.cjs");
6
6
  const require_uuid = require("./chunks/uuid-BhG0ngwk.cjs");
7
- const require__plugin_vue_export_helper = require("./chunks/_plugin-vue_export-helper-BUdjGKyl.cjs");
7
+ const require__plugin_vue_export_helper = require("./chunks/_plugin-vue_export-helper-6MBoygIY.cjs");
8
8
  const require_jszip = require("./chunks/jszip-D8mAFF-r.cjs");
9
+ const require_is_finite_number = require("./chunks/is-finite-number-BEXgTRgc.cjs");
9
10
  const require_constants = require("./chunks/constants-DpXuDx_g.cjs");
10
11
  let superdoc_entry_vue = require("vue");
11
12
  superdoc_entry_vue = require_rolldown_runtime.__toESM(superdoc_entry_vue, 1);
12
- require("y-websocket");
13
- require("@hocuspocus/provider");
14
13
  let yjs = require("yjs");
15
14
  //#region src/core/v2-integration/browser-peer-runtime.js
16
15
  var SUPERDOC_V2_BROWSER_RUNTIME_GLOBAL_KEY = "__SUPERDOC_V2_BROWSER_RUNTIME__";
@@ -260,7 +259,7 @@ var v_click_outside_default = {
260
259
  var DEFAULT_ENDPOINT = "https://ingest.superdoc.dev/v1/collect";
261
260
  function getSuperdocVersion() {
262
261
  try {
263
- return "2.28.0-next.9";
262
+ return "2.29.0-next.1";
264
263
  } catch {
265
264
  return "unknown";
266
265
  }
@@ -5399,7 +5398,7 @@ function normalizeRoomMode(value) {
5399
5398
  }
5400
5399
  function normalizeSyncTimeoutMs(value) {
5401
5400
  if (value === void 0) return void 0;
5402
- return typeof value === "number" && Number.isFinite(value) && value > 0 && value <= 2147483647 ? value : null;
5401
+ return require_is_finite_number.isFiniteNumber(value) && value > 0 && value <= 2147483647 ? value : null;
5403
5402
  }
5404
5403
  function withSyncTimeout(resolution, syncTimeoutMs) {
5405
5404
  if (!resolution.ok || syncTimeoutMs === void 0) return resolution;
@@ -5529,13 +5528,22 @@ function resolveLiveblocksFamily(candidate, authEndpointBaseUrl) {
5529
5528
  reason: "mixed-auth",
5530
5529
  message: "SuperDoc v2 Liveblocks collaboration accepts exactly one auth mode; pass either publicApiKey or authEndpoint, not both."
5531
5530
  };
5531
+ const baseUrlRaw = candidate.baseUrl;
5532
+ const baseUrl = baseUrlRaw === void 0 ? void 0 : normalizeHttpUrl(baseUrlRaw);
5533
+ if (baseUrl === null) return {
5534
+ ok: false,
5535
+ reason: "invalid-base-url",
5536
+ message: "SuperDoc v2 Liveblocks collaboration requires baseUrl to be an absolute http(s) URL."
5537
+ };
5538
+ const baseUrlOption = baseUrl ? { baseUrl } : {};
5532
5539
  if (publicApiKey) return {
5533
5540
  ok: true,
5534
5541
  target: {
5535
5542
  providerFamily: "liveblocks",
5536
5543
  documentId,
5537
5544
  roomMode,
5538
- publicApiKey
5545
+ publicApiKey,
5546
+ ...baseUrlOption
5539
5547
  }
5540
5548
  };
5541
5549
  const authEndpoint = normalizeHttpUrl(authEndpointRaw, authEndpointBaseUrl);
@@ -5550,7 +5558,8 @@ function resolveLiveblocksFamily(candidate, authEndpointBaseUrl) {
5550
5558
  providerFamily: "liveblocks",
5551
5559
  documentId,
5552
5560
  roomMode,
5553
- authEndpoint
5561
+ authEndpoint,
5562
+ ...baseUrlOption
5554
5563
  }
5555
5564
  };
5556
5565
  }
@@ -6576,7 +6585,7 @@ var useSuperdocStore = defineStore("superdoc", () => {
6576
6585
  currentConfig.value = config;
6577
6586
  if (config.zoom?.initial !== void 0) {
6578
6587
  const initialZoom = config.zoom.initial;
6579
- if (typeof initialZoom === "number" && Number.isFinite(initialZoom) && initialZoom > 0) activeZoom.value = initialZoom;
6588
+ if (require_is_finite_number.isFiniteNumber(initialZoom) && initialZoom > 0) activeZoom.value = initialZoom;
6580
6589
  else console.warn("[SuperDoc] zoom.initial expects a positive number representing percentage");
6581
6590
  }
6582
6591
  if (config.zoom?.mode !== void 0) {
@@ -6833,87 +6842,6 @@ var useSuperdocStore = defineStore("superdoc", () => {
6833
6842
  };
6834
6843
  });
6835
6844
  //#endregion
6836
- //#region src/helpers/group-changes.js
6837
- /**
6838
- * Track changes helper
6839
- * Combines replace transactions which are represented by insertion + deletion
6840
- *
6841
- * @param {Array} changes - Array of tracked changes from the editor
6842
- * @returns {Array} Grouped track changes array with combined replacements
6843
- */
6844
- var groupChanges = (changes) => {
6845
- const markMetaKeys = {
6846
- trackInsert: "insertedMark",
6847
- trackDelete: "deletionMark",
6848
- trackFormat: "formatMark"
6849
- };
6850
- const byId = /* @__PURE__ */ new Map();
6851
- for (const change of changes) {
6852
- const id = change.mark.attrs.id;
6853
- if (!byId.has(id)) byId.set(id, []);
6854
- byId.get(id).push(change);
6855
- }
6856
- const grouped = [];
6857
- for (const [, group] of byId) {
6858
- if (group.length === 1) {
6859
- const c = group[0];
6860
- const key = markMetaKeys[c.mark.type.name];
6861
- grouped.push({
6862
- from: c.from,
6863
- to: c.to,
6864
- [key]: c
6865
- });
6866
- continue;
6867
- }
6868
- const processed = /* @__PURE__ */ new Set();
6869
- for (let i = 0; i < group.length; i++) {
6870
- if (processed.has(i)) continue;
6871
- const c1 = group[i];
6872
- const c1Key = markMetaKeys[c1.mark.type.name];
6873
- const c2 = group[i + 1];
6874
- if (c2 && !processed.has(i + 1) && c1.to === c2.from && c1.mark.type.name !== c2.mark.type.name) {
6875
- const c2Key = markMetaKeys[c2.mark.type.name];
6876
- grouped.push({
6877
- from: c1.from,
6878
- to: c2.to,
6879
- [c1Key]: c1,
6880
- [c2Key]: c2
6881
- });
6882
- processed.add(i);
6883
- processed.add(i + 1);
6884
- continue;
6885
- }
6886
- let foundMatch = false;
6887
- for (let j = i + 1; j < group.length; j++) {
6888
- if (processed.has(j)) continue;
6889
- const cj = group[j];
6890
- if (c1.mark.type.name !== cj.mark.type.name) {
6891
- const cjKey = markMetaKeys[cj.mark.type.name];
6892
- grouped.push({
6893
- from: Math.min(c1.from, cj.from),
6894
- to: Math.max(c1.to, cj.to),
6895
- [c1Key]: c1,
6896
- [cjKey]: cj
6897
- });
6898
- processed.add(i);
6899
- processed.add(j);
6900
- foundMatch = true;
6901
- break;
6902
- }
6903
- }
6904
- if (!foundMatch) {
6905
- grouped.push({
6906
- from: c1.from,
6907
- to: c1.to,
6908
- [c1Key]: c1
6909
- });
6910
- processed.add(i);
6911
- }
6912
- }
6913
- }
6914
- return grouped;
6915
- };
6916
- //#endregion
6917
6845
  //#region src/stores/helpers/floating-comment-instances.js
6918
6846
  var HEADER_FOOTER_TRACKED_CHANGE_STORY_TYPE = "headerFooterPart";
6919
6847
  var toFinitePageIndex = (value) => {
@@ -7055,20 +6983,16 @@ var buildFloatingCommentInstances = ({ comment, positionKey, positionEntry, fall
7055
6983
  })];
7056
6984
  };
7057
6985
  //#endregion
7058
- //#region src/core/v2-integration/v2-integration.js
7059
- /** @type {() => Promise<unknown>} */
6986
+ //#region src/core/v2-integration/v2-integration.ts
7060
6987
  var engineModuleLoader = () => import("@superdoc/docx-engine");
7061
- /** @type {Promise<void> | null} */
7062
6988
  var engineModulePromise = null;
7063
- /** @type {((...args: unknown[]) => unknown) | null} */
7064
6989
  var createSuperDocV2Integration = null;
7065
- /** Load the engine before Vue evaluates the synchronous integration seam. */
7066
6990
  async function loadDefaultV2Integration() {
7067
6991
  if (!engineModulePromise) {
7068
6992
  const loadPromise = Promise.resolve().then(() => engineModuleLoader()).then((module) => {
7069
6993
  const factory = module && typeof module === "object" && "createSuperDocV2Integration" in module ? module.createSuperDocV2Integration : null;
7070
6994
  if (typeof factory !== "function") throw new TypeError("SuperDoc: the DOCX Engine module does not export createSuperDocV2Integration");
7071
- createSuperDocV2Integration = factory;
6995
+ createSuperDocV2Integration = () => factory();
7072
6996
  });
7073
6997
  engineModulePromise = loadPromise;
7074
6998
  loadPromise.catch(() => {
@@ -7080,7 +7004,6 @@ async function loadDefaultV2Integration() {
7080
7004
  }
7081
7005
  await engineModulePromise;
7082
7006
  }
7083
- /** Load the engine for editor startup, preserving the fail-closed stub on failure. */
7084
7007
  async function loadDefaultV2IntegrationOrFallback() {
7085
7008
  try {
7086
7009
  await loadDefaultV2Integration();
@@ -7089,12 +7012,8 @@ async function loadDefaultV2IntegrationOrFallback() {
7089
7012
  }
7090
7013
  }
7091
7014
  var V2_BODY_TRACKED_CHANGE_ANCHOR_PREFIX = "tc::body::";
7092
- /**
7093
- * @param {{ trackedChange?: unknown, trackedChangeAnchorKey?: unknown } | null | undefined} row
7094
- * @returns {boolean}
7095
- */
7096
7015
  function isV2SyntheticTrackedChangeRow(row) {
7097
- if (!row || row.trackedChange !== true) return false;
7016
+ if (!require_create_super_doc_ui.isPlainObject(row) || row.trackedChange !== true) return false;
7098
7017
  const anchorKey = row.trackedChangeAnchorKey;
7099
7018
  return typeof anchorKey === "string" && anchorKey.startsWith(V2_BODY_TRACKED_CHANGE_ANCHOR_PREFIX);
7100
7019
  }
@@ -7144,9 +7063,6 @@ var StubV2EditorComponent = require__plugin_vue_export_helper.defineComponent({
7144
7063
  return () => require__plugin_vue_export_helper.h("div", { class: "superdoc-v2-integration-missing" });
7145
7064
  }
7146
7065
  });
7147
- /**
7148
- * @returns {SuperDocV2Integration}
7149
- */
7150
7066
  function createStubV2Integration() {
7151
7067
  return {
7152
7068
  version: 1,
@@ -7159,30 +7075,25 @@ function createStubV2Integration() {
7159
7075
  isV2SyntheticTrackedChangeRow
7160
7076
  };
7161
7077
  }
7162
- /**
7163
- * Build the default v2 integration the runtime always uses. The v2
7164
- * browser shell is the only source of the editor runtime; no customer-provided
7165
- * integration is consulted. Falls back to the local stub only if the engine
7166
- * shell throws during construction (defensive, never selects v1).
7167
- *
7168
- * @returns {SuperDocV2Integration}
7169
- */
7078
+ function adoptEngineIntegration(engineIntegration) {
7079
+ const stub = createStubV2Integration();
7080
+ if (!require_create_super_doc_ui.isPlainObject(engineIntegration) || !engineIntegration.EditorComponent) return stub;
7081
+ const engine = engineIntegration;
7082
+ return {
7083
+ version: typeof engine.version === "number" ? engine.version : stub.version,
7084
+ capabilities: engine.capabilities ?? stub.capabilities,
7085
+ EditorComponent: engine.EditorComponent ?? stub.EditorComponent,
7086
+ RulerComponent: engine.RulerComponent ?? stub.RulerComponent,
7087
+ createGeometryPublisher: engine.createGeometryPublisher ?? stub.createGeometryPublisher,
7088
+ createReviewWindowController: engine.createReviewWindowController ?? stub.createReviewWindowController,
7089
+ isSyntheticTrackedChangeCommentLaneItem: engine.isSyntheticTrackedChangeCommentLaneItem ?? stub.isSyntheticTrackedChangeCommentLaneItem,
7090
+ isV2SyntheticTrackedChangeRow: engine.isV2SyntheticTrackedChangeRow ?? stub.isV2SyntheticTrackedChangeRow
7091
+ };
7092
+ }
7170
7093
  function createDefaultV2Integration() {
7171
7094
  if (!createSuperDocV2Integration) return createStubV2Integration();
7172
7095
  try {
7173
- const stub = createStubV2Integration();
7174
- const integration = createSuperDocV2Integration();
7175
- if (!integration || typeof integration !== "object" || !integration.EditorComponent) return stub;
7176
- return {
7177
- version: typeof integration.version === "number" ? integration.version : stub.version,
7178
- capabilities: integration.capabilities ?? stub.capabilities,
7179
- EditorComponent: integration.EditorComponent,
7180
- RulerComponent: integration.RulerComponent ?? stub.RulerComponent,
7181
- createGeometryPublisher: integration.createGeometryPublisher ?? stub.createGeometryPublisher,
7182
- createReviewWindowController: integration.createReviewWindowController ?? stub.createReviewWindowController,
7183
- isSyntheticTrackedChangeCommentLaneItem: integration.isSyntheticTrackedChangeCommentLaneItem ?? stub.isSyntheticTrackedChangeCommentLaneItem,
7184
- isV2SyntheticTrackedChangeRow: integration.isV2SyntheticTrackedChangeRow ?? stub.isV2SyntheticTrackedChangeRow
7185
- };
7096
+ return adoptEngineIntegration(createSuperDocV2Integration());
7186
7097
  } catch (error) {
7187
7098
  console.error("[SuperDoc] DOCX Engine integration failed to construct; using the stub.", error);
7188
7099
  return createStubV2Integration();
@@ -7474,20 +7385,6 @@ var buildTrackedChangeDecisionLinkIndex = (allComments, previous = /* @__PURE__
7474
7385
  };
7475
7386
  //#endregion
7476
7387
  //#region src/stores/comments-store.js
7477
- var Editor = class {
7478
- constructor() {
7479
- throw new Error("SuperDoc v2 beta: v1 editor-backed comment import paths are not available.");
7480
- }
7481
- };
7482
- var trackChangesHelpers = {
7483
- getTrackChanges: () => [],
7484
- enumerateStructuralRowChanges: () => []
7485
- };
7486
- var CommentsPluginKey = Symbol("comments-plugin-disabled");
7487
- var getRichTextExtensions = () => [];
7488
- var createOrUpdateTrackedChangeComment = () => null;
7489
- var getTrackedChangeIndex = () => null;
7490
- var resolveTrackedChangeInStory = () => null;
7491
7388
  var makeTrackedChangeAnchorKey = ({ storyKey, rawId }) => `tc::${storyKey}::${rawId}`;
7492
7389
  var COMMENT_DRAFT_BR_TAG = /<br(?:\s[^>]*)?\s*\/?>/gi;
7493
7390
  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;
@@ -7553,8 +7450,8 @@ var normalizeTrackedChangeImagePreview = (preview) => {
7553
7450
  if (!src || !src.startsWith("data:image/")) return null;
7554
7451
  const contentType = typeof preview.contentType === "string" && preview.contentType.startsWith("image/") ? preview.contentType : null;
7555
7452
  const role = typeof preview.role === "string" ? preview.role : null;
7556
- const width = typeof preview.width === "number" && Number.isFinite(preview.width) && preview.width > 0 ? preview.width : null;
7557
- const height = typeof preview.height === "number" && Number.isFinite(preview.height) && preview.height > 0 ? preview.height : null;
7453
+ const width = require_is_finite_number.isFiniteNumber(preview.width) && preview.width > 0 ? preview.width : null;
7454
+ const height = require_is_finite_number.isFiniteNumber(preview.height) && preview.height > 0 ? preview.height : null;
7558
7455
  const alt = typeof preview.alt === "string" && preview.alt.length > 0 ? preview.alt : "Tracked image preview";
7559
7456
  return {
7560
7457
  src,
@@ -7632,25 +7529,6 @@ var useCommentsStore = defineStore("comments", () => {
7632
7529
  rawId: String(rawId)
7633
7530
  });
7634
7531
  };
7635
- /**
7636
- * Compute the stable public id for a structural (whole-table) tracked change.
7637
- *
7638
- * This MUST match the public id the document-api projects for the same change
7639
- * (`tracked-change-resolver.groupTrackedChanges`), otherwise the right-rail
7640
- * accept/reject would route `trackChanges.decide` to a change that does not
7641
- * exist. The doc-api derives the public id as `word:structural:<sourceId>`
7642
- * for imported Word revisions, falling back to the per-import logical id.
7643
- * Reuse the exact rule here so the bubble id is the decide id.
7644
- *
7645
- * @param {{ sourceId?: string, id?: string }} structural
7646
- * @returns {string | null}
7647
- */
7648
- const buildStructuralTrackedChangeId = (structural) => {
7649
- if (!structural) return null;
7650
- const sourceId = structural.sourceId ? String(structural.sourceId) : "";
7651
- if (sourceId) return `word:structural:${sourceId}`;
7652
- return structural.id ? String(structural.id) : null;
7653
- };
7654
7532
  const superdocStore = useSuperdocStore();
7655
7533
  const commentsConfig = require__plugin_vue_export_helper.reactive({
7656
7534
  name: "comments",
@@ -7682,8 +7560,6 @@ var useCommentsStore = defineStore("comments", () => {
7682
7560
  const isDebugging = false;
7683
7561
  const debounceTimers = {};
7684
7562
  const trackedChangeResolutionSnapshots = /* @__PURE__ */ new WeakMap();
7685
- const importedTrackedChangeBootstrapTasks = /* @__PURE__ */ new Map();
7686
- let importedTrackedChangeBootstrapGeneration = 0;
7687
7563
  const isBenchmarkCommentsDebugEnabled = () => {
7688
7564
  if (typeof window === "undefined") return false;
7689
7565
  return "__labsSuperDocV2BenchmarkDebug" in window;
@@ -7710,6 +7586,11 @@ var useCommentsStore = defineStore("comments", () => {
7710
7586
  const suppressInternalExternal = require__plugin_vue_export_helper.ref(true);
7711
7587
  const currentCommentText = require__plugin_vue_export_helper.ref("");
7712
7588
  const currentCommentMentions = require__plugin_vue_export_helper.ref([]);
7589
+ let commentDraftRevision = 0;
7590
+ require__plugin_vue_export_helper.watch([currentCommentText, currentCommentMentions], () => commentDraftRevision++, {
7591
+ deep: true,
7592
+ flush: "sync"
7593
+ });
7713
7594
  const commentsList = require__plugin_vue_export_helper.ref([]);
7714
7595
  const reviewDirectoryList = require__plugin_vue_export_helper.shallowRef([]);
7715
7596
  let priorTrackedChangeThreadIndex = /* @__PURE__ */ new Map();
@@ -8043,17 +7924,6 @@ var useCommentsStore = defineStore("comments", () => {
8043
7924
  comment.resolvedByName = null;
8044
7925
  comment.trackedChangeDecision = null;
8045
7926
  };
8046
- const restoreResolvedMetadata = (comment) => {
8047
- if (!comment) return false;
8048
- const snapshot = trackedChangeResolutionSnapshots.get(comment);
8049
- if (!snapshot) return false;
8050
- comment.resolvedTime = snapshot.resolvedTime ?? Date.now();
8051
- comment.resolvedById = snapshot.resolvedById ?? null;
8052
- comment.resolvedByEmail = snapshot.resolvedByEmail ?? null;
8053
- comment.resolvedByName = snapshot.resolvedByName ?? null;
8054
- comment.trackedChangeDecision = snapshot.trackedChangeDecision ?? null;
8055
- return true;
8056
- };
8057
7927
  const getCommentEventPayload = (comment) => typeof comment?.getValues === "function" ? comment.getValues() : { ...comment };
8058
7928
  /**
8059
7929
  * Check if a comment originated from the document editor (or has no explicit source).
@@ -8068,129 +7938,14 @@ var useCommentsStore = defineStore("comments", () => {
8068
7938
  return source === DOCUMENT_EDITOR_SELECTION_SOURCE;
8069
7939
  };
8070
7940
  const isTrackedChangeThread = (comment) => Boolean(comment?.trackedChange) || Boolean(trackedChangeThreadParentIdForComment$1(comment));
8071
- const syncTrackedChangePositionsWithDocument = ({ documentId, editor } = {}) => {
8072
- if (!editor?.state) return 0;
8073
- if (!commentsList.value?.length) return 0;
8074
- const currentPositions = editorCommentPositions.value || {};
8075
- if (!Object.keys(currentPositions).length) return 0;
8076
- const resolveExistingPositionKey = (aliasIds) => aliasIds.find((key) => currentPositions[key] !== void 0) ?? null;
8077
- const candidateRootPositionKeys = /* @__PURE__ */ new Set();
8078
- const rootAliasesByPositionKey = /* @__PURE__ */ new Map();
8079
- commentsList.value.forEach((comment) => {
8080
- if (!comment?.trackedChange) return;
8081
- if (documentId) {
8082
- const resolvedDocumentId = comment?.fileId ?? null;
8083
- if (resolvedDocumentId && resolvedDocumentId !== documentId) return;
8084
- }
8085
- const aliasIds = getCommentAliasIds(comment);
8086
- const normalizedPositionKey = resolveExistingPositionKey(aliasIds);
8087
- if (!normalizedPositionKey) return;
8088
- candidateRootPositionKeys.add(normalizedPositionKey);
8089
- rootAliasesByPositionKey.set(normalizedPositionKey, new Set(aliasIds));
8090
- });
8091
- if (!candidateRootPositionKeys.size) return 0;
8092
- const trackedIds = new Set(trackChangesHelpers.getTrackChanges(editor.state).map(({ mark }) => mark?.attrs?.id).filter((id) => id !== void 0 && id !== null).map((id) => String(id)));
8093
- const trackedChangeIndex = typeof getTrackedChangeIndex === "function" ? getTrackedChangeIndex(editor) : null;
8094
- let liveAnchorKeySource = [];
8095
- try {
8096
- liveAnchorKeySource = trackedChangeIndex?.getAll?.() ?? [];
8097
- } catch {}
8098
- const liveAnchorKeys = new Set(liveAnchorKeySource.map((snapshot) => snapshot?.anchorKey).filter((anchorKey) => typeof anchorKey === "string" && anchorKey.length > 0));
8099
- const staleRootPositionKeys = new Set(Array.from(candidateRootPositionKeys).filter((positionKey) => {
8100
- const aliases = rootAliasesByPositionKey.get(positionKey) ?? /* @__PURE__ */ new Set([positionKey]);
8101
- if (Array.from(aliases).some((alias) => liveAnchorKeys.has(alias))) return false;
8102
- return !Array.from(aliases).some((alias) => trackedIds.has(alias));
8103
- }));
8104
- if (!staleRootPositionKeys.size) return 0;
8105
- const staleRootAliasIds = /* @__PURE__ */ new Set();
8106
- staleRootPositionKeys.forEach((positionKey) => {
8107
- (rootAliasesByPositionKey.get(positionKey) ?? /* @__PURE__ */ new Set([positionKey])).forEach((alias) => staleRootAliasIds.add(alias));
8108
- });
8109
- const stalePositionKeys = new Set(staleRootPositionKeys);
8110
- commentsList.value.forEach((comment) => {
8111
- const aliasIds = getCommentAliasIds(comment);
8112
- const normalizedPositionKey = resolveExistingPositionKey(aliasIds);
8113
- if (!normalizedPositionKey) return;
8114
- if ([
8115
- trackedChangeThreadParentIdForComment$1(comment),
8116
- comment?.threadingParentCommentId,
8117
- comment?.parentCommentId
8118
- ].map((id) => normalizeCommentId(id)).filter(Boolean).some((id) => staleRootAliasIds.has(id))) stalePositionKeys.add(normalizedPositionKey);
8119
- });
8120
- const nextPositions = { ...currentPositions };
8121
- stalePositionKeys.forEach((key) => {
8122
- delete nextPositions[key];
8123
- });
8124
- editorCommentPositions.value = nextPositions;
8125
- if (activeComment.value !== void 0 && activeComment.value !== null) {
8126
- const activeCommentModel = getComment(activeComment.value);
8127
- const activeAliases = new Set(getCommentAliasIds(activeCommentModel ?? activeComment.value));
8128
- const activeParentKeys = [
8129
- trackedChangeThreadParentIdForComment$1(activeCommentModel),
8130
- activeCommentModel?.threadingParentCommentId,
8131
- activeCommentModel?.parentCommentId
8132
- ].map((id) => normalizeCommentId(id)).filter(Boolean);
8133
- if (Array.from(activeAliases).some((id) => staleRootAliasIds.has(id)) || activeParentKeys.some((id) => staleRootAliasIds.has(id))) clearActiveCommentSelection();
8134
- }
8135
- return stalePositionKeys.size;
8136
- };
8137
- const collectStandardCommentDocumentState = (editor) => {
8138
- const doc = editor?.state?.doc;
8139
- if (!doc || typeof doc.descendants !== "function") return null;
8140
- const liveMarkIds = /* @__PURE__ */ new Set();
8141
- const resolvedAnchorIds = /* @__PURE__ */ new Set();
8142
- doc.descendants((node) => {
8143
- node.marks?.filter((mark) => mark?.type?.name === "commentMark").forEach((mark) => {
8144
- [mark.attrs?.commentId, mark.attrs?.importedId].map((id) => normalizeCommentId(id)).filter(Boolean).forEach((id) => liveMarkIds.add(id));
8145
- });
8146
- const typeName = node.type?.name;
8147
- if (typeName !== "commentRangeStart" && typeName !== "commentRangeEnd") return;
8148
- const anchorId = normalizeCommentId(node.attrs?.["w:id"]);
8149
- if (anchorId) resolvedAnchorIds.add(anchorId);
8150
- });
8151
- return {
8152
- liveMarkIds,
8153
- resolvedAnchorIds
8154
- };
8155
- };
8156
- /**
8157
- * Fall back to a live editor when the caller has none (the store watchers).
8158
- * `editorCommentPositions` refreshes asynchronously, so a positions-based
8159
- * decision taken mid-undo/redo can act on STALE keys — e.g. clearing the
8160
- * resolved metadata that the redo restore just wrote back. The document
8161
- * itself is the source of truth; prefer it whenever an editor is reachable.
8162
- */
8163
- const getFallbackCommentsEditor = () => {
8164
- const docs = superdocStore.documents;
8165
- if (!Array.isArray(docs)) return null;
8166
- for (const doc of docs) {
8167
- const editor = typeof doc?.getEditor === "function" ? doc.getEditor() : null;
8168
- if (editor?.state?.doc) return editor;
8169
- }
8170
- return null;
8171
- };
8172
- const syncResolvedCommentsWithDocument = ({ editor } = {}) => {
7941
+ const syncResolvedCommentsWithDocument = () => {
8173
7942
  if (v2CommentsAdapter.value) return 0;
8174
- const effectiveEditor = editor ?? getFallbackCommentsEditor();
8175
- const documentState = collectStandardCommentDocumentState(effectiveEditor);
8176
7943
  const docPositions = editorCommentPositions.value || {};
8177
7944
  const activeKeys = new Set(Object.keys(docPositions));
8178
- if (!documentState && !activeKeys.size) return 0;
7945
+ if (!activeKeys.size) return 0;
8179
7946
  let changed = 0;
8180
7947
  commentsList.value.forEach((comment) => {
8181
7948
  if (!isEditorBackedComment(comment) || isTrackedChangeThread(comment)) return;
8182
- if (documentState) {
8183
- const aliasIds = getCommentAliasIds(comment);
8184
- const hasLiveMark = aliasIds.some((id) => documentState.liveMarkIds.has(id));
8185
- const hasResolvedAnchor = aliasIds.some((id) => documentState.resolvedAnchorIds.has(id));
8186
- if (hasLiveMark && comment.resolvedTime != null) {
8187
- clearResolvedMetadata(comment);
8188
- changed += 1;
8189
- return;
8190
- }
8191
- if (!hasLiveMark && hasResolvedAnchor && comment.resolvedTime == null && restoreResolvedMetadata(comment)) changed += 1;
8192
- return;
8193
- }
8194
7949
  const { key } = resolveCommentPositionEntry(comment);
8195
7950
  if (!key) return;
8196
7951
  if (activeKeys.has(String(key)) && comment.resolvedTime != null) {
@@ -8208,23 +7963,6 @@ var useCommentsStore = defineStore("comments", () => {
8208
7963
  syncResolvedCommentsWithDocument();
8209
7964
  }, { deep: false });
8210
7965
  /**
8211
- * Normalize a position object to a consistent { start, end } format.
8212
- * Handles different editor position schemas (start/end, pos/to, from/to).
8213
- *
8214
- * @param {Object | null | undefined} position The position object
8215
- * @returns {{ start: number, end: number } | null} The normalized range or null
8216
- */
8217
- const getCommentPositionRange = (position) => {
8218
- if (!position) return null;
8219
- const start = position.start ?? position.pos ?? position.from;
8220
- const end = position.end ?? position.to ?? start;
8221
- if (!Number.isFinite(start) || !Number.isFinite(end)) return null;
8222
- return {
8223
- start,
8224
- end
8225
- };
8226
- };
8227
- /**
8228
7966
  * Get the editor position data for a comment.
8229
7967
  *
8230
7968
  * @param {Object | string} commentOrId The comment object or comment ID
@@ -8233,44 +7971,6 @@ var useCommentsStore = defineStore("comments", () => {
8233
7971
  const getCommentPosition = (commentOrId) => {
8234
7972
  return resolveCommentPositionEntry(commentOrId).entry ?? null;
8235
7973
  };
8236
- /**
8237
- * Get the text that a comment is anchored to in the document.
8238
- *
8239
- * @param {Object | string} commentOrId The comment object or comment ID
8240
- * @param {Object} [options] Options for text extraction
8241
- * @param {string} [options.separator=' '] Separator for textBetween when crossing nodes
8242
- * @param {boolean} [options.trim=true] Whether to trim whitespace from the result
8243
- * @returns {string | null} The anchored text or null if unavailable
8244
- */
8245
- const getCommentAnchoredText = (commentOrId, options = {}) => {
8246
- const comment = typeof commentOrId === "object" ? commentOrId : getComment(commentOrId);
8247
- if (!comment) return null;
8248
- const position = resolveCommentPositionEntry(commentOrId).entry ?? null;
8249
- const range = getCommentPositionRange(position);
8250
- if (!range) return null;
8251
- const docNode = (superdocStore.getDocument(comment.fileId)?.getEditor?.())?.state?.doc;
8252
- if (!docNode?.textBetween) return null;
8253
- const separator = options.separator ?? " ";
8254
- const text = docNode.textBetween(range.start, range.end, separator, separator);
8255
- return options.trim === false ? text : text?.trim();
8256
- };
8257
- /**
8258
- * Get both position and anchored text data for a comment.
8259
- *
8260
- * @param {Object | string} commentOrId The comment object or comment ID
8261
- * @param {Object} [options] Options passed to getCommentAnchoredText
8262
- * @param {string} [options.separator=' '] Separator for textBetween when crossing nodes
8263
- * @param {boolean} [options.trim=true] Whether to trim whitespace from the result
8264
- * @returns {{ position: Object, anchoredText: string | null } | null} The anchor data or null
8265
- */
8266
- const getCommentAnchorData = (commentOrId, options = {}) => {
8267
- const position = getCommentPosition(commentOrId);
8268
- if (!position) return null;
8269
- return {
8270
- position,
8271
- anchoredText: getCommentAnchoredText(commentOrId, options)
8272
- };
8273
- };
8274
7974
  const isThreadVisible = (comment) => {
8275
7975
  if (!isViewingMode.value) return true;
8276
7976
  const parent = getThreadParent(comment);
@@ -8315,7 +8015,7 @@ var useCommentsStore = defineStore("comments", () => {
8315
8015
  * @param {Object} param0.params The tracked change params
8316
8016
  * @returns {void}
8317
8017
  */
8318
- const handleTrackedChangeUpdate = ({ superdoc, params, broadcastChanges = true, documentState = void 0, trackedChangeIdentityIndex = null }) => {
8018
+ const handleTrackedChangeUpdate = ({ superdoc, params, broadcastChanges = true, trackedChangeIdentityIndex = null }) => {
8319
8019
  const span = startInteractionSpan("store.trackedChanges.handleUpdate", "store-reconciliation", {
8320
8020
  event: params?.event ?? null,
8321
8021
  changeId: params?.changeId ?? null,
@@ -8332,26 +8032,6 @@ var useCommentsStore = defineStore("comments", () => {
8332
8032
  const normalizedCustomAttributes = hasCustomAttributes ? normalizeTrackedChangeCustomAttributes(customAttributes) : void 0;
8333
8033
  const normalizedImportedId = hasImportedId ? importedId != null ? String(importedId) : null : void 0;
8334
8034
  const normalizedDocumentId = documentId != null ? String(documentId) : null;
8335
- if (!(trackedChangeDisplayType === "tableInsert" || trackedChangeDisplayType === "tableDelete") && normalizedChangeId) {
8336
- const effectiveDocumentId = normalizedDocumentId ?? (superdoc?.activeEditor?.options?.documentId != null ? String(superdoc.activeEditor.options.documentId) : null);
8337
- const docEditor = effectiveDocumentId ? superdocStore.getDocument(effectiveDocumentId)?.getEditor?.() : null;
8338
- const docState = documentState !== void 0 ? documentState : docEditor?.state ?? superdoc?.activeEditor?.state ?? null;
8339
- if (docState) {
8340
- const { ranges: tableRanges, ids: structuralIds } = computeTrackedTableSummaryForState(docState);
8341
- const ranges = trackChangesHelpers.getTrackChanges(docState, normalizedChangeId);
8342
- const inRange = tableRanges.length > 0 && ranges.length > 0 && isInlineRangeInsideTrackedTable(ranges, tableRanges);
8343
- const isStructuralRowIdEcho = ranges.length === 0 && structuralIds.has(normalizedChangeId);
8344
- if (inRange || isStructuralRowIdEcho) {
8345
- pruneSuppressedInlineTableComments({
8346
- suppressedIds: /* @__PURE__ */ new Set([normalizedChangeId]),
8347
- activeDocumentId: effectiveDocumentId,
8348
- superdoc,
8349
- broadcastChanges
8350
- });
8351
- return;
8352
- }
8353
- }
8354
- }
8355
8035
  const hasStoryMetadata = trackedChangeStory !== void 0 || trackedChangeStoryKind !== void 0 || trackedChangeStoryLabel !== void 0 || trackedChangeAnchorKey !== void 0;
8356
8036
  const normalizedTrackedChangeStory = hasStoryMetadata ? trackedChangeStory ?? null : BODY_TRACKED_CHANGE_STORY;
8357
8037
  const normalizedTrackedChangeStoryKind = hasStoryMetadata ? trackedChangeStoryKind ?? null : "body";
@@ -8545,38 +8225,6 @@ var useCommentsStore = defineStore("comments", () => {
8545
8225
  endInteractionSpan(span);
8546
8226
  }
8547
8227
  };
8548
- const collectTrackedChangeMarksByType = (trackedChanges = []) => ({
8549
- insertedMark: trackedChanges.find(({ mark }) => mark?.type?.name === "trackInsert")?.mark ?? null,
8550
- deletionMark: trackedChanges.find(({ mark }) => mark?.type?.name === "trackDelete")?.mark ?? null,
8551
- formatMark: trackedChanges.find(({ mark }) => mark?.type?.name === "trackFormat")?.mark ?? null
8552
- });
8553
- const refreshTrackedChangeCommentsByIds = ({ superdoc, editor, changeIds, broadcastChanges = true }) => {
8554
- if (!superdoc || !editor?.state || !Array.isArray(changeIds) || !changeIds.length) return;
8555
- const documentId = editor?.options?.documentId != null ? String(editor.options.documentId) : null;
8556
- if (!documentId) return;
8557
- for (const changeId of new Set(changeIds.map((id) => id != null ? String(id) : null).filter(Boolean))) {
8558
- const trackedChangesForId = trackChangesHelpers.getTrackChanges(editor.state, changeId);
8559
- if (!trackedChangesForId.length) continue;
8560
- const params = createOrUpdateTrackedChangeComment({
8561
- event: "update",
8562
- marks: collectTrackedChangeMarksByType(trackedChangesForId),
8563
- nodes: [],
8564
- newEditorState: editor.state,
8565
- documentId,
8566
- trackedChangesForId
8567
- });
8568
- if (!params) continue;
8569
- params.trackedChangeStory = BODY_TRACKED_CHANGE_STORY;
8570
- params.trackedChangeStoryKind = "body";
8571
- params.trackedChangeStoryLabel = "";
8572
- params.trackedChangeAnchorKey = buildBodyTrackedChangeAnchorKey(params.changeId ?? changeId);
8573
- handleTrackedChangeUpdate({
8574
- superdoc,
8575
- params,
8576
- broadcastChanges
8577
- });
8578
- }
8579
- };
8580
8228
  const requestInstantSidebarAlignment = (targetY = null, threadId = null, instanceId = null) => {
8581
8229
  const hasTargetY = Number.isFinite(targetY);
8582
8230
  instantSidebarAlignmentTargetY.value = hasTargetY ? targetY : null;
@@ -8831,10 +8479,10 @@ var useCommentsStore = defineStore("comments", () => {
8831
8479
  * Get a new pending comment
8832
8480
  *
8833
8481
  * @param {Object} param0
8834
- * @param {Object} param0.selection The selection object
8835
- * @param {String} param0.documentId The document ID
8836
- * @param {String} param0.parentCommentId The parent comment
8837
- * @returns {Object} The new comment object
8482
+ * @param {Object} [param0.selection] The selection object
8483
+ * @param {string | null} [param0.documentId] The document ID
8484
+ * @param {string | null} [param0.parentCommentId] The parent comment
8485
+ * @returns {ReturnType<typeof useComment>} The new comment object
8838
8486
  */
8839
8487
  const getPendingComment = ({ selection, documentId, parentCommentId, ...options }) => {
8840
8488
  return _getNewcomment({
@@ -8906,15 +8554,22 @@ var useCommentsStore = defineStore("comments", () => {
8906
8554
  *
8907
8555
  * @param {Object} param0
8908
8556
  * @param {Object} param0.superdoc The SuperDoc instance
8909
- * @returns {void}
8557
+ * @param {ReturnType<typeof useComment>} param0.comment The comment to add
8558
+ * @param {boolean} [param0.skipEditorUpdate] Skip writing the comment into the editor
8559
+ * @param {boolean} [param0.broadcastChanges] Emit and sync the change
8560
+ * @param {boolean} [param0.isHydration] The comment comes from import or collaboration
8561
+ * @returns {{ ok: boolean, reason?: string, detail?: string, code?: string } | Promise<{ ok: boolean, reason?: string, detail?: string, code?: string }>} The mutation outcome
8910
8562
  */
8911
8563
  const addCommentInternal = ({ superdoc, comment, skipEditorUpdate = false, broadcastChanges = true, isHydration = false }) => {
8912
8564
  if (commentsAreReadOnly() && !isHydration) return readOnlyMutationOutcome();
8913
8565
  const v2Adapter = !skipEditorUpdate && !isHydration ? getV2CommentsAdapter(superdoc) : null;
8914
8566
  if (v2Adapter && !comment.trackedChange) {
8915
- const submittedPendingComment = pendingComment.value;
8567
+ const pendingDraft = pendingComment.value;
8568
+ const draftRevision = commentDraftRevision;
8569
+ const draftActiveComment = activeComment.value;
8570
+ const draftActiveInstance = activeFloatingCommentInstanceId.value;
8916
8571
  const submittedPendingRequest = pendingCommentRequest;
8917
- const text = normalizeV2CommentDraftText(submittedPendingComment ? currentCommentText.value : comment.commentText);
8572
+ const text = normalizeV2CommentDraftText(pendingDraft ? currentCommentText.value : comment.commentText);
8918
8573
  const mentions = pendingComment.value ? currentCommentMentions.value : comment.mentions ?? [];
8919
8574
  const target = pendingComment.value ? pendingV2CommentTarget.value : null;
8920
8575
  const parentCommentId = comment.parentCommentId ? String(comment.parentCommentId) : pendingComment.value ? null : null;
@@ -8950,6 +8605,7 @@ var useCommentsStore = defineStore("comments", () => {
8950
8605
  });
8951
8606
  return outcome;
8952
8607
  }
8608
+ const ownsActiveDraftBeforeReconcile = activeComment.value === draftActiveComment && activeFloatingCommentInstanceId.value === draftActiveInstance;
8953
8609
  const reconciled = reconcileCommentsFromV2({
8954
8610
  superdoc,
8955
8611
  adapter: v2Adapter,
@@ -8961,14 +8617,17 @@ var useCommentsStore = defineStore("comments", () => {
8961
8617
  reconciled,
8962
8618
  documentId: v2Adapter.documentId
8963
8619
  });
8964
- const hadPendingComment = submittedPendingComment != null && pendingComment.value?.commentId === submittedPendingComment.commentId;
8620
+ const createdId = created?.commentId ?? null;
8621
+ const createdIsActive = createdId !== null && activeComment.value === createdId;
8622
+ const createdInstance = createdIsActive ? activeFloatingCommentInstanceId.value : null;
8965
8623
  const ownsSubmittedRequest = pendingCommentRequest === submittedPendingRequest;
8966
- if (hadPendingComment) if (ownsSubmittedRequest) removePendingComment(superdoc);
8624
+ const reconciliationClearedActiveDraft = ownsActiveDraftBeforeReconcile && activeComment.value === null && activeFloatingCommentInstanceId.value === null;
8625
+ const ownsPendingDraft = pendingDraft !== null && pendingComment.value === pendingDraft && commentDraftRevision === draftRevision && (createdIsActive || reconciliationClearedActiveDraft || activeComment.value === draftActiveComment && activeFloatingCommentInstanceId.value === draftActiveInstance);
8626
+ if (ownsPendingDraft) if (ownsSubmittedRequest) removePendingComment(superdoc);
8967
8627
  else resetPendingCommentState(superdoc, false);
8968
- const createdId = created?.commentId ?? null;
8969
- if (hadPendingComment && ownsSubmittedRequest && createdId) {
8628
+ if (ownsPendingDraft && ownsSubmittedRequest && createdId) {
8970
8629
  setActiveComment(superdoc, createdId);
8971
- setActiveFloatingCommentInstance(createdId);
8630
+ setActiveFloatingCommentInstance(createdInstance ?? createdId);
8972
8631
  }
8973
8632
  if (broadcastChanges) superdoc.emit("comments-update", {
8974
8633
  type: COMMENT_EVENTS.ADD,
@@ -9480,6 +9139,13 @@ var useCommentsStore = defineStore("comments", () => {
9480
9139
  * - successful mutation refreshes from v2 list and reconciles
9481
9140
  * - rejection preserves rows and emits a rejected `comments-update` event
9482
9141
  * - committed-but-refresh-failed surfaces honestly (no reconcile with `[]`)
9142
+ *
9143
+ * @param {Object} [param0]
9144
+ * @param {Object} [param0.superdoc] The SuperDoc instance.
9145
+ * @param {string | null} [param0.parentCommentId] The comment or tracked-change row being replied to.
9146
+ * @param {string} [param0.text] The reply text.
9147
+ * @param {Array<{ name?: string | null, email?: string | null }>} [param0.mentions] Users mentioned in the reply.
9148
+ * @param {{ kind: 'trackedChange', trackedChangeId: string, story?: unknown, side?: 'source' | 'destination' }} [param0.trackedChangeTarget] The tracked change a first reply anchors to.
9483
9149
  */
9484
9150
  const replyCommentV2 = async ({ superdoc, parentCommentId, text, mentions = [], trackedChangeTarget } = {}) => {
9485
9151
  if (commentsAreReadOnly()) return readOnlyMutationOutcome();
@@ -10186,178 +9852,6 @@ var useCommentsStore = defineStore("comments", () => {
10186
9852
  removePendingComment(superdoc);
10187
9853
  };
10188
9854
  /**
10189
- * Imported DOCX comments can omit the normalized author string.
10190
- * Strip the exporter suffix when present and tolerate missing metadata.
10191
- *
10192
- * @param {string | null | undefined} creatorName
10193
- * @returns {string | null}
10194
- */
10195
- const normalizeImportedCreatorName = (creatorName) => {
10196
- if (typeof creatorName !== "string") return null;
10197
- return creatorName.replace(/\s*\(imported\)\s*$/u, "").trim() || null;
10198
- };
10199
- /**
10200
- * Read the mounted editor view and state without touching `editor.state`.
10201
- * The editor convenience getter delegates to `view.state` and throws after
10202
- * teardown, which is precisely when a deferred import callback can run.
10203
- *
10204
- * @param {Object | null | undefined} editor
10205
- * @returns {{ view: Object, state: Object } | null}
10206
- */
10207
- const readMountedEditorSnapshot = (editor) => {
10208
- if (!editor) return null;
10209
- try {
10210
- if (editor.isDestroyed === true) return null;
10211
- const view = editor.view;
10212
- if (!view || view.isDestroyed === true || view.destroyed === true) return null;
10213
- const state = view.state;
10214
- if (!state) return null;
10215
- return {
10216
- view,
10217
- state
10218
- };
10219
- } catch {
10220
- return null;
10221
- }
10222
- };
10223
- const normalizeBootstrapDocumentId = (documentId) => documentId !== void 0 && documentId !== null && String(documentId).length > 0 ? String(documentId) : null;
10224
- /**
10225
- * Cancel deferred imported tracked-change comment work. Passing a document
10226
- * id cancels only that document; omitting it cancels every pending task.
10227
- *
10228
- * @param {string | null | undefined} documentId
10229
- * @returns {number} number of invalidated tasks
10230
- */
10231
- const cancelImportedTrackedChangeBootstrap = (documentId) => {
10232
- const normalizedDocumentId = normalizeBootstrapDocumentId(documentId);
10233
- const entries = normalizedDocumentId ? [[normalizedDocumentId, importedTrackedChangeBootstrapTasks.get(normalizedDocumentId)]] : Array.from(importedTrackedChangeBootstrapTasks.entries());
10234
- let canceled = 0;
10235
- for (const [taskDocumentId, task] of entries) {
10236
- if (!task) continue;
10237
- importedTrackedChangeBootstrapTasks.delete(taskDocumentId);
10238
- if (task.timeoutHandle !== null && task.timeoutHandle !== void 0) clearTimeout(task.timeoutHandle);
10239
- canceled += 1;
10240
- }
10241
- return canceled;
10242
- };
10243
- const captureImportedTrackedChangeBootstrapSnapshot = (editor) => {
10244
- const mountedEditor = readMountedEditorSnapshot(editor);
10245
- if (!mountedEditor) return null;
10246
- let trackedChanges = [];
10247
- try {
10248
- trackedChanges = trackChangesHelpers.getTrackChanges(mountedEditor.state) ?? [];
10249
- } catch {
10250
- return null;
10251
- }
10252
- const enumerateStructuralChanges = trackChangesHelpers?.enumerateStructuralRowChanges;
10253
- let structuralChanges = [];
10254
- if (typeof enumerateStructuralChanges === "function") try {
10255
- structuralChanges = enumerateStructuralChanges(mountedEditor.state) ?? [];
10256
- } catch {
10257
- structuralChanges = [];
10258
- }
10259
- let storySnapshots = [];
10260
- if (typeof getTrackedChangeIndex === "function") try {
10261
- storySnapshots = getTrackedChangeIndex(editor)?.getAll?.() ?? [];
10262
- } catch {
10263
- storySnapshots = [];
10264
- }
10265
- return {
10266
- ...mountedEditor,
10267
- trackedChanges,
10268
- structuralChanges,
10269
- storySnapshots
10270
- };
10271
- };
10272
- /**
10273
- * Bootstrap tracked-change comment threads after a DOCX import finishes.
10274
- *
10275
- * Initial import historically rebuilt only body tracked-change threads so
10276
- * resolved imported body comments stayed resolved. Header/footer and note
10277
- * tracked changes live outside the body PM state, so they need an additional
10278
- * story-aware bootstrap pass here.
10279
- *
10280
- * We intentionally keep the existing body-only rebuild instead of switching
10281
- * to the broader syncTrackedChangeComments() path so imported resolved body
10282
- * tracked-change threads preserve their initial resolved state.
10283
- *
10284
- * @param {Object | null | undefined} editor
10285
- * @param {Object | null | undefined} superdoc
10286
- * @param {Object | null | undefined} snapshot
10287
- * @returns {boolean}
10288
- */
10289
- const bootstrapImportedTrackedChangeComments = (editor, superdoc, snapshot = null) => {
10290
- if (!editor || !superdoc) return false;
10291
- const captured = snapshot ?? captureImportedTrackedChangeBootstrapSnapshot(editor);
10292
- if (!captured) return false;
10293
- createCommentForTrackChanges(editor, superdoc, captured.trackedChanges, {
10294
- editorState: captured.state,
10295
- editorView: captured.view
10296
- });
10297
- syncStoryTrackedChangeComments({
10298
- superdoc,
10299
- editor,
10300
- snapshots: captured.storySnapshots,
10301
- documentState: captured.state,
10302
- resolveFromEditor: false
10303
- });
10304
- syncStructuralTrackedChangeComments({
10305
- superdoc,
10306
- editor,
10307
- structuralChanges: captured.structuralChanges
10308
- });
10309
- return true;
10310
- };
10311
- const isCurrentImportedTrackedChangeBootstrap = (task) => {
10312
- if (!task) return false;
10313
- if (importedTrackedChangeBootstrapTasks.get(task.documentId) !== task) return false;
10314
- try {
10315
- const editorDocumentId = task.editor?.options?.documentId;
10316
- if (editorDocumentId != null && String(editorDocumentId) !== task.documentId) return false;
10317
- const mountedDocument = superdocStore.getDocument(task.documentId);
10318
- if (!mountedDocument) return false;
10319
- if (mountedDocument.getEditor?.() !== task.editor) return false;
10320
- } catch {
10321
- return false;
10322
- }
10323
- return true;
10324
- };
10325
- const runImportedTrackedChangeBootstrap = (task) => {
10326
- if (!isCurrentImportedTrackedChangeBootstrap(task)) {
10327
- if (importedTrackedChangeBootstrapTasks.get(task?.documentId) === task) importedTrackedChangeBootstrapTasks.delete(task.documentId);
10328
- return false;
10329
- }
10330
- const snapshot = captureImportedTrackedChangeBootstrapSnapshot(task.editor);
10331
- if (!snapshot || !isCurrentImportedTrackedChangeBootstrap(task)) {
10332
- if (importedTrackedChangeBootstrapTasks.get(task.documentId) === task) importedTrackedChangeBootstrapTasks.delete(task.documentId);
10333
- return false;
10334
- }
10335
- try {
10336
- return bootstrapImportedTrackedChangeComments(task.editor, task.superdoc, snapshot);
10337
- } finally {
10338
- if (importedTrackedChangeBootstrapTasks.get(task.documentId) === task) importedTrackedChangeBootstrapTasks.delete(task.documentId);
10339
- }
10340
- };
10341
- const scheduleImportedTrackedChangeBootstrap = ({ editor, superdoc, documentId, defer = true }) => {
10342
- const normalizedDocumentId = normalizeBootstrapDocumentId(documentId);
10343
- if (!normalizedDocumentId || !editor || !superdoc) return false;
10344
- cancelImportedTrackedChangeBootstrap(normalizedDocumentId);
10345
- const task = {
10346
- documentId: normalizedDocumentId,
10347
- editor,
10348
- superdoc,
10349
- generation: ++importedTrackedChangeBootstrapGeneration,
10350
- timeoutHandle: null
10351
- };
10352
- importedTrackedChangeBootstrapTasks.set(normalizedDocumentId, task);
10353
- if (!defer) return runImportedTrackedChangeBootstrap(task);
10354
- task.timeoutHandle = setTimeout(() => {
10355
- task.timeoutHandle = null;
10356
- runImportedTrackedChangeBootstrap(task);
10357
- }, 0);
10358
- return true;
10359
- };
10360
- /**
10361
9855
  * Drop imported threads and cached positions for one document id.
10362
9856
  *
10363
9857
  * Replace-file swaps call this before hydrating the replacement so stale
@@ -10374,7 +9868,6 @@ var useCommentsStore = defineStore("comments", () => {
10374
9868
  delete next[activeDocumentId];
10375
9869
  committedReviewPresentations.value = next;
10376
9870
  }
10377
- cancelImportedTrackedChangeBootstrap(activeDocumentId);
10378
9871
  const removedComments = commentsList.value.filter((comment) => belongsToDocument(comment, activeDocumentId, { allowSingleDocumentMismatch: true }));
10379
9872
  if (!removedComments.length) return;
10380
9873
  const removedAliasIds = /* @__PURE__ */ new Set();
@@ -10392,217 +9885,6 @@ var useCommentsStore = defineStore("comments", () => {
10392
9885
  const activeCommentId = activeComment.value != null ? String(activeComment.value) : null;
10393
9886
  if (activeCommentId && removedAliasIds.has(activeCommentId)) clearActiveCommentSelection();
10394
9887
  }
10395
- function resetCommentsForReplacedDocument(documentId) {
10396
- removeCommentsForDocument(documentId);
10397
- }
10398
- /**
10399
- * Initialize loaded comments into SuperDoc by mapping the imported
10400
- * comment data to SuperDoc useComment objects.
10401
- *
10402
- * Updates the commentsList ref with the new comments.
10403
- *
10404
- * @param {Object} param0
10405
- * @param {Array} param0.comments The comments to be loaded
10406
- * @param {String} param0.documentId The document ID
10407
- * @param {boolean} [param0.replacedFile] Whether this load replaces an existing document in place
10408
- * @returns {void}
10409
- */
10410
- const processLoadedDocxComments = async ({ superdoc, editor, comments, documentId, replacedFile = false }) => {
10411
- const document = superdocStore.getDocument(documentId);
10412
- if (document?.commentThreadingProfile) document.commentThreadingProfile.value = editor?.converter?.commentThreadingProfile || null;
10413
- if (replacedFile) resetCommentsForReplacedDocument(documentId);
10414
- comments.forEach((comment) => {
10415
- const textElements = Array.isArray(comment.elements) ? comment.elements : [];
10416
- const htmlContent = getHtmlFromComment(textElements);
10417
- if (!htmlContent && !comment.trackedChange) return;
10418
- const creatorName = normalizeImportedCreatorName(comment.creatorName);
10419
- const importedName = creatorName ? `${creatorName} (imported)` : null;
10420
- const newComment = useComment({
10421
- fileId: documentId,
10422
- fileType: document.type,
10423
- docxCommentJSON: textElements.length ? textElements : null,
10424
- commentId: comment.commentId,
10425
- isInternal: false,
10426
- parentCommentId: comment.parentCommentId,
10427
- trackedChangeParentId: comment.trackedChangeParentId,
10428
- trackedChangeThreadParentId: comment.trackedChangeThreadParentId,
10429
- creatorId: null,
10430
- creatorName,
10431
- createdTime: comment.createdTime,
10432
- creatorEmail: comment.creatorEmail,
10433
- importedAuthor: {
10434
- ...importedName ? { name: importedName } : {},
10435
- email: comment.creatorEmail
10436
- },
10437
- commentText: htmlContent,
10438
- resolvedTime: comment.isDone ? Date.now() : null,
10439
- resolvedById: null,
10440
- resolvedByEmail: comment.isDone ? comment.creatorEmail : null,
10441
- resolvedByName: comment.isDone ? importedName || "(Imported)" : null,
10442
- trackedChange: comment.trackedChange || false,
10443
- trackedChangeText: comment.trackedChangeText,
10444
- trackedChangeType: comment.trackedChangeType,
10445
- trackedChangeDisplayType: comment.trackedChangeDisplayType,
10446
- deletedText: comment.trackedDeletedText,
10447
- origin: comment.origin || "word",
10448
- threadingMethod: comment.threadingMethod,
10449
- threadingStyleOverride: comment.threadingStyleOverride,
10450
- threadingParentCommentId: comment.threadingParentCommentId,
10451
- originalXmlStructure: comment.originalXmlStructure
10452
- });
10453
- addHydratedComment({
10454
- superdoc,
10455
- comment: newComment
10456
- });
10457
- });
10458
- if (replacedFile) {
10459
- scheduleImportedTrackedChangeBootstrap({
10460
- editor,
10461
- superdoc,
10462
- documentId,
10463
- defer: false
10464
- });
10465
- return;
10466
- }
10467
- scheduleImportedTrackedChangeBootstrap({
10468
- editor,
10469
- superdoc,
10470
- documentId
10471
- });
10472
- };
10473
- const createCommentForTrackChanges = (editor, superdoc, trackedChangesOverride = null, options = {}) => {
10474
- const { reopenResolved = false, refreshExisting = false, broadcastChanges = true, editorState: editorStateOverride = null, editorView: editorViewOverride = null } = options;
10475
- const mountedEditor = editorStateOverride ? {
10476
- state: editorStateOverride,
10477
- view: editorViewOverride
10478
- } : readMountedEditorSnapshot(editor);
10479
- if (!mountedEditor?.state) return;
10480
- const editorState = mountedEditor.state;
10481
- const trackedChanges = trackedChangesOverride ?? trackChangesHelpers.getTrackChanges(editorState);
10482
- const groupedChanges = groupChanges(trackedChanges);
10483
- const activeDocumentId = editor?.options?.documentId != null ? String(editor.options.documentId) : null;
10484
- if (!activeDocumentId) return;
10485
- const skipIds = /* @__PURE__ */ new Set();
10486
- const existingTrackedChangeById = /* @__PURE__ */ new Map();
10487
- commentsList.value.forEach((comment) => {
10488
- if (!comment?.trackedChange) return;
10489
- if (!belongsToTrackedChangeSyncDocument(comment, activeDocumentId)) return;
10490
- if (!isBodyTrackedChangeComment(comment)) return;
10491
- const commentIds = [comment.commentId, comment.importedId].map((id) => id != null ? String(id) : null).filter(Boolean);
10492
- if (comment.resolvedTime) {
10493
- if (!reopenResolved) commentIds.forEach((id) => skipIds.add(id));
10494
- return;
10495
- }
10496
- commentIds.forEach((id) => {
10497
- existingTrackedChangeById.set(id, comment);
10498
- if (!refreshExisting) skipIds.add(id);
10499
- });
10500
- });
10501
- const changesByIdMap = /* @__PURE__ */ new Map();
10502
- for (const change of trackedChanges) {
10503
- const id = change.mark.attrs.id;
10504
- if (!changesByIdMap.has(id)) changesByIdMap.set(id, []);
10505
- changesByIdMap.get(id).push(change);
10506
- }
10507
- const documentId = activeDocumentId;
10508
- const processedIds = /* @__PURE__ */ new Set();
10509
- groupedChanges.forEach(({ insertedMark, deletionMark, formatMark }) => {
10510
- const id = insertedMark?.mark.attrs.id || deletionMark?.mark.attrs.id || formatMark?.mark.attrs.id;
10511
- if (id == null) return;
10512
- const normalizedId = String(id);
10513
- if (processedIds.has(normalizedId)) return;
10514
- processedIds.add(normalizedId);
10515
- if (!refreshExisting && skipIds.has(normalizedId)) return;
10516
- const existingTrackedChange = existingTrackedChangeById.get(normalizedId);
10517
- const marks = {
10518
- ...insertedMark && { insertedMark: insertedMark.mark },
10519
- ...deletionMark && { deletionMark: deletionMark.mark },
10520
- ...formatMark && { formatMark: formatMark.mark }
10521
- };
10522
- const params = createOrUpdateTrackedChangeComment({
10523
- event: existingTrackedChange ? "update" : "add",
10524
- marks,
10525
- nodes: [],
10526
- newEditorState: editorState,
10527
- documentId,
10528
- trackedChangesForId: changesByIdMap.get(id) || []
10529
- });
10530
- if (params) {
10531
- const anchorKey = buildBodyTrackedChangeAnchorKey(params.changeId ?? id);
10532
- params.trackedChangeStory = BODY_TRACKED_CHANGE_STORY;
10533
- params.trackedChangeStoryKind = "body";
10534
- params.trackedChangeStoryLabel = "";
10535
- params.trackedChangeAnchorKey = anchorKey;
10536
- handleTrackedChangeUpdate({
10537
- superdoc,
10538
- params,
10539
- broadcastChanges,
10540
- documentState: editorState
10541
- });
10542
- if (!existingTrackedChange) {
10543
- skipIds.add(normalizedId);
10544
- if (params.changeId != null) skipIds.add(String(params.changeId));
10545
- if (params.importedId != null) skipIds.add(String(params.importedId));
10546
- }
10547
- }
10548
- });
10549
- const editorView = mountedEditor.view;
10550
- try {
10551
- if (!editorView || editor.view !== editorView || editorView.isDestroyed === true || editorView.destroyed === true) return;
10552
- } catch {
10553
- return;
10554
- }
10555
- const { tr } = editorState;
10556
- tr.setMeta(CommentsPluginKey, { type: "force" });
10557
- editorView.dispatch(tr);
10558
- };
10559
- /**
10560
- * Remove inline tracked-change comments whose change id is subsumed by a
10561
- * tracked whole-table change. Mirrors the deletion-event emission of
10562
- * `pruneStaleTrackedChangeComments` but is keyed on an explicit suppressed-id
10563
- * set rather than mark liveness (the mark is still live; only the review item
10564
- * is unwanted). Also clears the active-comment selection if it pointed at a
10565
- * now-suppressed change, so no stale active-on-click dialog can reference it.
10566
- *
10567
- * @param {{ suppressedIds: Set<string>, activeDocumentId: string, superdoc: any, broadcastChanges?: boolean }} input
10568
- */
10569
- const pruneSuppressedInlineTableComments = ({ suppressedIds, activeDocumentId, superdoc = null, broadcastChanges = true }) => {
10570
- if (!(suppressedIds instanceof Set) || !suppressedIds.size || !activeDocumentId) return;
10571
- const removedComments = [];
10572
- commentsList.value = commentsList.value.filter((comment) => {
10573
- if (!comment?.trackedChange) return true;
10574
- if (!isBodyTrackedChangeComment(comment)) return true;
10575
- if (isStructuralTableBubble(comment)) return true;
10576
- if (!belongsToTrackedChangeSyncDocument(comment, activeDocumentId)) return true;
10577
- const commentId = comment.commentId != null ? String(comment.commentId) : null;
10578
- const importedId = comment.importedId != null ? String(comment.importedId) : null;
10579
- if (!(commentId && suppressedIds.has(commentId) || importedId && suppressedIds.has(importedId))) return true;
10580
- removedComments.push(comment);
10581
- return false;
10582
- });
10583
- if (!removedComments.length) return;
10584
- const removedIds = /* @__PURE__ */ new Set();
10585
- removedComments.forEach((comment) => {
10586
- if (comment.commentId != null) removedIds.add(String(comment.commentId));
10587
- if (comment.importedId != null) removedIds.add(String(comment.importedId));
10588
- const payload = getCommentEventPayload(comment);
10589
- const event = {
10590
- type: COMMENT_EVENTS.DELETED,
10591
- comment: payload,
10592
- changes: [{
10593
- key: "deleted",
10594
- commentId: payload.commentId,
10595
- fileId: payload.fileId
10596
- }]
10597
- };
10598
- if (broadcastChanges) {
10599
- syncCommentsToClients(superdoc, event);
10600
- superdoc?.emit?.("comments-update", event);
10601
- }
10602
- });
10603
- const activeCommentId = activeComment.value != null ? String(activeComment.value) : null;
10604
- if (activeCommentId && removedIds.has(activeCommentId)) clearActiveCommentSelection();
10605
- };
10606
9888
  const getCommentDocumentId = (comment) => {
10607
9889
  if (!comment) return null;
10608
9890
  if (comment.fileId != null) return String(comment.fileId);
@@ -11134,15 +10416,13 @@ var useCommentsStore = defineStore("comments", () => {
11134
10416
  } catch {}
11135
10417
  };
11136
10418
  /**
11137
- * Rebuild tracked-change comments from the current editor state.
11138
- *
11139
- * Useful after bulk document transforms (like diff replay) where tracked-change
11140
- * marks may be remapped and incremental tracked-change events are not emitted.
10419
+ * Accept or reject the tracked change behind a sidebar row.
11141
10420
  *
11142
10421
  * @param {Object} param0
11143
10422
  * @param {Object} param0.superdoc The SuperDoc instance.
11144
- * @param {Object} param0.editor The active Super Editor instance.
11145
- * @returns {void}
10423
+ * @param {Object} param0.comment The tracked-change row.
10424
+ * @param {string} param0.decision `'accept'` or `'reject'`.
10425
+ * @returns {{ ok: boolean, success?: boolean, reason?: string } | Promise<{ ok: boolean, success?: boolean, reason?: string }>} The decision outcome.
11146
10426
  */
11147
10427
  const decideTrackedChangeFromSidebar = ({ superdoc, comment, decision }) => {
11148
10428
  const disabledReason = trackedChangeDecisionDisabledReason(superdoc);
@@ -11458,286 +10738,6 @@ var useCommentsStore = defineStore("comments", () => {
11458
10738
  return rowDocumentId != null && String(rowDocumentId) === normalizedDocumentId;
11459
10739
  }).length;
11460
10740
  };
11461
- const syncTrackedChangeComments = ({ superdoc, editor, broadcastChanges = true }) => {
11462
- if (!superdoc || !editor) return;
11463
- const activeDocumentId = editor?.options?.documentId != null ? String(editor.options.documentId) : null;
11464
- if (!activeDocumentId) return;
11465
- const captured = captureImportedTrackedChangeBootstrapSnapshot(editor);
11466
- if (!captured) return;
11467
- const trackedChanges = captured.trackedChanges;
11468
- const liveTrackedChangeIds = /* @__PURE__ */ new Set();
11469
- trackedChanges.forEach((change) => {
11470
- const id = change?.mark?.attrs?.id;
11471
- if (id == null) return;
11472
- liveTrackedChangeIds.add(String(id));
11473
- });
11474
- const storySnapshots = captured.storySnapshots;
11475
- const liveTrackedChangeAnchorKeys = new Set(storySnapshots.map((snapshot) => snapshot?.anchorKey).filter((anchorKey) => typeof anchorKey === "string" && anchorKey.length > 0));
11476
- pruneStaleTrackedChangeComments(liveTrackedChangeIds, liveTrackedChangeAnchorKeys, activeDocumentId, superdoc, { broadcastChanges });
11477
- createCommentForTrackChanges(editor, superdoc, trackedChanges, {
11478
- reopenResolved: true,
11479
- refreshExisting: true,
11480
- broadcastChanges,
11481
- editorState: captured.state,
11482
- editorView: captured.view
11483
- });
11484
- syncStoryTrackedChangeComments({
11485
- superdoc,
11486
- editor,
11487
- broadcastChanges,
11488
- snapshots: storySnapshots,
11489
- documentState: captured.state
11490
- });
11491
- syncStructuralTrackedChangeComments({
11492
- superdoc,
11493
- editor,
11494
- broadcastChanges,
11495
- structuralChanges: captured.structuralChanges
11496
- });
11497
- };
11498
- /**
11499
- * Surface decidable whole-table structural tracked changes (table insert /
11500
- * table delete) as right-rail bubbles, mirroring the inline tracked-change
11501
- * path. Structural row revisions live on node attrs (not inline marks), so
11502
- * the inline `getTrackChanges` enumerator never sees them — they are
11503
- * enumerated separately here.
11504
- *
11505
- * Only `decidable` whole-table changes are surfaced; partial/mixed shapes are
11506
- * not actionable (the decision engine fails them closed) so they get no
11507
- * bubble. The bubble id is the document-api public id so accept/reject in the
11508
- * sidebar routes `trackChanges.decide` to the same change.
11509
- *
11510
- * Positioning: the bubble carries a body-story anchorKey (matching the
11511
- * tracked-change index snapshot) and a body PM range (table start/end). The
11512
- * DocumentRendererRuntime position pass emits a body-story position entry for that
11513
- * anchorKey, whose bounds resolve through the same `getRangeRects` path inline
11514
- * body comments/TC use — so it lines up with the table in layout-engine
11515
- * viewing mode.
11516
- */
11517
- const syncStructuralTrackedChangeComments = ({ superdoc, editor, broadcastChanges = true, structuralChanges: structuralChangesOverride = null }) => {
11518
- const activeDocumentId = editor?.options?.documentId != null ? String(editor.options.documentId) : null;
11519
- if (!activeDocumentId) return;
11520
- const enumerate = trackChangesHelpers?.enumerateStructuralRowChanges;
11521
- if (typeof enumerate !== "function") return;
11522
- let structuralChanges = structuralChangesOverride;
11523
- if (!Array.isArray(structuralChanges)) {
11524
- const mountedEditor = readMountedEditorSnapshot(editor);
11525
- if (!mountedEditor) return;
11526
- try {
11527
- structuralChanges = enumerate(mountedEditor.state) ?? [];
11528
- } catch {
11529
- structuralChanges = [];
11530
- }
11531
- }
11532
- for (const structural of structuralChanges) {
11533
- if (!structural?.decidable || !structural?.wholeTable) continue;
11534
- const publicId = buildStructuralTrackedChangeId(structural);
11535
- if (!publicId) continue;
11536
- const anchorKey = buildBodyTrackedChangeAnchorKey(publicId);
11537
- const displayType = structural.subtype === "table-insert" ? "tableInsert" : "tableDelete";
11538
- const trackedChangeType = structural.side === "insertion" ? "trackInsert" : "trackDelete";
11539
- const normalizedPublicId = String(publicId);
11540
- const normalizedAnchorKey = anchorKey != null ? String(anchorKey) : null;
11541
- const params = {
11542
- event: commentsList.value.find((comment) => {
11543
- if (!comment?.trackedChange) return false;
11544
- if (!belongsToTrackedChangeSyncDocument(comment, activeDocumentId)) return false;
11545
- const commentAnchorKey = comment.trackedChangeAnchorKey != null ? String(comment.trackedChangeAnchorKey) : null;
11546
- if (normalizedAnchorKey && commentAnchorKey) return commentAnchorKey === normalizedAnchorKey;
11547
- const commentId = comment.commentId != null ? String(comment.commentId) : null;
11548
- const importedId = comment.importedId != null ? String(comment.importedId) : null;
11549
- return commentId === normalizedPublicId || importedId === normalizedPublicId;
11550
- }) ? "update" : "add",
11551
- changeId: publicId,
11552
- trackedChangeText: "",
11553
- trackedChangeType,
11554
- trackedChangeDisplayType: displayType,
11555
- deletedText: null,
11556
- authorId: null,
11557
- authorEmail: structural.authorEmail || null,
11558
- authorImage: structural.authorImage || null,
11559
- date: structural.date || null,
11560
- author: structural.author || null,
11561
- importedAuthor: structural.importedAuthor ? { name: structural.importedAuthor } : null,
11562
- semanticColorKey: structural.semanticColorKey ?? null,
11563
- semanticColor: structural.semanticColor ?? null,
11564
- documentId: activeDocumentId,
11565
- coords: null,
11566
- trackedChangeStory: BODY_TRACKED_CHANGE_STORY,
11567
- trackedChangeStoryKind: "body",
11568
- trackedChangeStoryLabel: "",
11569
- trackedChangeAnchorKey: anchorKey
11570
- };
11571
- handleTrackedChangeUpdate({
11572
- superdoc,
11573
- params,
11574
- broadcastChanges
11575
- });
11576
- }
11577
- };
11578
- const syncStoryTrackedChangeComments = ({ superdoc, editor, broadcastChanges = true, snapshots = null, documentState = void 0, resolveFromEditor = true }) => {
11579
- const activeDocumentId = editor?.options?.documentId != null ? String(editor.options.documentId) : null;
11580
- if (!activeDocumentId) return;
11581
- let resolvedSnapshots = snapshots;
11582
- if (!Array.isArray(resolvedSnapshots)) {
11583
- if (typeof getTrackedChangeIndex !== "function") return;
11584
- if (!readMountedEditorSnapshot(editor)) return;
11585
- let index = null;
11586
- try {
11587
- index = getTrackedChangeIndex(editor);
11588
- } catch {
11589
- return;
11590
- }
11591
- if (!index) return;
11592
- try {
11593
- resolvedSnapshots = index.getAll();
11594
- } catch {
11595
- return;
11596
- }
11597
- }
11598
- for (const snapshot of resolvedSnapshots) {
11599
- if (snapshot.storyKind === "body") continue;
11600
- upsertStoryTrackedChangeComment({
11601
- superdoc,
11602
- editor,
11603
- snapshot,
11604
- documentId: activeDocumentId,
11605
- broadcastChanges,
11606
- documentState,
11607
- resolveFromEditor
11608
- });
11609
- }
11610
- };
11611
- const getStoryTrackedChangeDisplayType = (snapshot) => {
11612
- if (snapshot?.type !== "structural") return snapshot?.type ?? null;
11613
- return snapshot?.subtype === "table-delete" ? "tableDelete" : "tableInsert";
11614
- };
11615
- const getStoryTrackedChangeType = (snapshot) => {
11616
- if (snapshot?.type !== "structural") return snapshot?.type ?? null;
11617
- return snapshot?.subtype === "table-delete" ? "trackDelete" : "trackInsert";
11618
- };
11619
- const isStoryTrackedChangeDeletion = (snapshot) => {
11620
- if (!snapshot) return false;
11621
- if (snapshot.type === "delete") return true;
11622
- return snapshot.type === "structural" && snapshot.subtype === "table-delete";
11623
- };
11624
- const buildStoryTrackedChangeParams = ({ editor, snapshot, documentId, event, resolveFromEditor = true }) => {
11625
- const trackedChangeType = getStoryTrackedChangeType(snapshot);
11626
- const trackedChangeDisplayType = getStoryTrackedChangeDisplayType(snapshot);
11627
- const fallbackParams = {
11628
- event,
11629
- changeId: snapshot.runtimeRef.rawId,
11630
- trackedChangeText: isStoryTrackedChangeDeletion(snapshot) ? "" : snapshot.excerpt ?? "",
11631
- trackedChangeType,
11632
- trackedChangeDisplayType,
11633
- semanticColorKey: snapshot.semanticColorKey ?? null,
11634
- semanticColor: snapshot.semanticColor ?? null,
11635
- deletedText: isStoryTrackedChangeDeletion(snapshot) ? snapshot.excerpt ?? "" : null,
11636
- authorId: snapshot.authorId,
11637
- authorEmail: snapshot.authorEmail,
11638
- authorImage: snapshot.authorImage,
11639
- date: snapshot.date,
11640
- author: snapshot.author,
11641
- documentId,
11642
- coords: null,
11643
- trackedChangeStory: snapshot.story,
11644
- trackedChangeStoryKind: snapshot.storyKind,
11645
- trackedChangeStoryLabel: snapshot.storyLabel,
11646
- trackedChangeAnchorKey: snapshot.anchorKey
11647
- };
11648
- if (!resolveFromEditor || typeof resolveTrackedChangeInStory !== "function") return fallbackParams;
11649
- let resolvedChange = null;
11650
- try {
11651
- resolvedChange = resolveTrackedChangeInStory(editor, {
11652
- kind: "entity",
11653
- entityType: "trackedChange",
11654
- entityId: snapshot.runtimeRef.rawId,
11655
- story: snapshot.story
11656
- });
11657
- } catch {
11658
- resolvedChange = null;
11659
- }
11660
- const storyEditorState = resolvedChange?.editor?.state ?? null;
11661
- if (!storyEditorState) return fallbackParams;
11662
- let trackedChangesForId = [];
11663
- try {
11664
- trackedChangesForId = trackChangesHelpers.getTrackChanges(storyEditorState, resolvedChange.change.rawId) ?? [];
11665
- } catch {
11666
- trackedChangesForId = [];
11667
- }
11668
- const resolvedParams = createOrUpdateTrackedChangeComment({
11669
- event,
11670
- marks: collectTrackedChangeMarksByType(trackedChangesForId),
11671
- nodes: [],
11672
- newEditorState: storyEditorState,
11673
- documentId,
11674
- trackedChangesForId
11675
- });
11676
- if (!resolvedParams) return fallbackParams;
11677
- if (resolvedParams.semanticColorKey == null && snapshot.semanticColorKey != null) resolvedParams.semanticColorKey = snapshot.semanticColorKey;
11678
- if (resolvedParams.semanticColor == null && snapshot.semanticColor != null) resolvedParams.semanticColor = snapshot.semanticColor;
11679
- resolvedParams.trackedChangeStory = snapshot.story;
11680
- resolvedParams.trackedChangeStoryKind = snapshot.storyKind;
11681
- resolvedParams.trackedChangeStoryLabel = snapshot.storyLabel;
11682
- resolvedParams.trackedChangeAnchorKey = snapshot.anchorKey;
11683
- return resolvedParams;
11684
- };
11685
- const upsertStoryTrackedChangeComment = ({ superdoc, editor, snapshot, documentId, broadcastChanges, documentState, resolveFromEditor }) => {
11686
- if (!snapshot?.runtimeRef?.rawId) return;
11687
- const existingComment = commentsList.value.find((comment) => {
11688
- if (!comment?.trackedChange) return false;
11689
- const commentAnchorKey = comment.trackedChangeAnchorKey != null ? String(comment.trackedChangeAnchorKey) : null;
11690
- if (commentAnchorKey && snapshot.anchorKey) return commentAnchorKey === snapshot.anchorKey;
11691
- if (commentAnchorKey || snapshot.anchorKey) return false;
11692
- return comment.commentId === snapshot.runtimeRef.rawId || comment.importedId === snapshot.runtimeRef.rawId;
11693
- });
11694
- const params = buildStoryTrackedChangeParams({
11695
- editor,
11696
- snapshot,
11697
- documentId,
11698
- event: existingComment ? "update" : "add",
11699
- resolveFromEditor
11700
- });
11701
- handleTrackedChangeUpdate({
11702
- superdoc,
11703
- params,
11704
- broadcastChanges,
11705
- documentState
11706
- });
11707
- if (existingComment) {
11708
- existingComment.trackedChangeStory = snapshot.story;
11709
- existingComment.trackedChangeStoryKind = snapshot.storyKind;
11710
- existingComment.trackedChangeStoryLabel = snapshot.storyLabel;
11711
- existingComment.trackedChangeAnchorKey = snapshot.anchorKey;
11712
- }
11713
- };
11714
- const normalizeDocxSchemaForExport = (value) => {
11715
- if (!value) return [];
11716
- return (Array.isArray(value) ? value : [value]).filter(Boolean);
11717
- };
11718
- const translateCommentsForExport = () => {
11719
- const processedComments = [];
11720
- commentsList.value.forEach((comment) => {
11721
- const values = comment.getValues();
11722
- const richText = values.commentText;
11723
- const docxSchema = normalizeDocxSchemaForExport(values.docxCommentJSON);
11724
- const schema = docxSchema.length ? docxSchema : convertHtmlToSchema(richText);
11725
- processedComments.push({
11726
- ...values,
11727
- commentJSON: schema
11728
- });
11729
- });
11730
- return processedComments;
11731
- };
11732
- const convertHtmlToSchema = (commentHTML) => {
11733
- const json = new Editor({
11734
- mode: "text",
11735
- isHeadless: true,
11736
- content: commentHTML,
11737
- extensions: getRichTextExtensions()
11738
- }).getJSON();
11739
- return Array.isArray(json?.content) ? json.content.filter(Boolean) : [];
11740
- };
11741
10741
  /**
11742
10742
  * Triggered when the editor locations are updated
11743
10743
  * Updates floating comment locations from the editor
@@ -11800,150 +10800,12 @@ var useCommentsStore = defineStore("comments", () => {
11800
10800
  const clearEditorCommentPositions = () => {
11801
10801
  editorCommentPositions.value = {};
11802
10802
  };
11803
- /**
11804
- * Identify the single structural (whole-table) bubble for a tracked table so
11805
- * it is NEVER suppressed by the table-subsume filter below. The structural
11806
- * bubble is the parent "Added table" / "Deleted table" change; its public
11807
- * id is `word:structural:<id>` (or a bare structural fallback) and its display
11808
- * type is `tableInsert` / `tableDelete`.
11809
- *
11810
- * @param {Object} comment
11811
- * @returns {boolean}
11812
- */
11813
- const isStructuralTableBubble = (comment) => {
11814
- if (!comment?.trackedChange) return false;
11815
- const displayType = comment?.trackedChangeDisplayType;
11816
- if (displayType === "tableInsert" || displayType === "tableDelete") return true;
11817
- return [
11818
- comment?.commentId,
11819
- comment?.importedId,
11820
- comment?.trackedChangeAnchorKey
11821
- ].map((id) => id != null ? String(id) : "").filter(Boolean).some((id) => id.includes("word:structural:"));
11822
- };
11823
- /**
11824
- * Compute the decidable whole-table tracked-change ranges for a comment's
11825
- * document, memoized per editor state so the filter does not re-enumerate the
11826
- * document once per comment. Returns `[]` when the document has no tracked
11827
- * whole-table change (the common case), so non-tracked tables and inline-only
11828
- * tracked changes are never affected.
11829
- *
11830
- * @param {string | null | undefined} fileId
11831
- * @returns {Array<{ from: number, to: number }>}
11832
- */
11833
- const trackedTableSummaryCache = /* @__PURE__ */ new WeakMap();
11834
- /**
11835
- * Single source of truth for the decidable whole-table tracked changes in an
11836
- * editor state, enumerated and memoized ONCE per state. Returns:
11837
- * - `ranges`: each tracked whole-table's `{ from, to }` document span. Used to
11838
- * test whether an inline tracked change falls inside a tracked table.
11839
- * - `ids`: every change id associated with those tables (the change's public
11840
- * id / revisionId / revisionGroupId / sourceId plus each row's trackChange
11841
- * id / sourceId). Text typed inside a tracked-inserted row inherits that
11842
- * row's revision id, so such an inline change reports a changeId that is one
11843
- * of these — it must be subsumed by the structural bubble, not get its own
11844
- * review item.
11845
- *
11846
- * @param {object | null | undefined} state
11847
- * @returns {{ ranges: Array<{ from: number, to: number }>, ids: Set<string> }}
11848
- */
11849
- const computeTrackedTableSummaryForState = (state) => {
11850
- if (!state) return {
11851
- ranges: [],
11852
- ids: /* @__PURE__ */ new Set()
11853
- };
11854
- const cached = trackedTableSummaryCache.get(state);
11855
- if (cached) return cached;
11856
- const ranges = [];
11857
- const ids = /* @__PURE__ */ new Set();
11858
- const add = (value) => {
11859
- if (value != null && value !== "") ids.add(String(value));
11860
- };
11861
- const enumerate = trackChangesHelpers?.enumerateStructuralRowChanges;
11862
- if (typeof enumerate === "function") {
11863
- let structuralChanges = [];
11864
- try {
11865
- structuralChanges = enumerate(state) ?? [];
11866
- } catch {
11867
- structuralChanges = [];
11868
- }
11869
- for (const change of structuralChanges) {
11870
- if (!change?.decidable || !change?.wholeTable) continue;
11871
- const from = Number(change.tableFrom);
11872
- const to = Number(change.tableTo);
11873
- if (Number.isFinite(from) && Number.isFinite(to)) ranges.push({
11874
- from,
11875
- to
11876
- });
11877
- add(change.id);
11878
- add(change.revisionId);
11879
- add(change.revisionGroupId);
11880
- add(change.sourceId);
11881
- for (const row of change.rows || []) {
11882
- const tc = row?.node?.attrs?.trackChange;
11883
- add(tc?.id);
11884
- add(tc?.sourceId);
11885
- }
11886
- }
11887
- }
11888
- const summary = {
11889
- ranges,
11890
- ids
11891
- };
11892
- trackedTableSummaryCache.set(state, summary);
11893
- return summary;
11894
- };
11895
- const getTrackedTableRangesForDocument = (fileId) => {
11896
- const editor = superdocStore.getDocument(fileId)?.getEditor?.();
11897
- return computeTrackedTableSummaryForState(editor?.state).ranges;
11898
- };
11899
- /**
11900
- * True when every `{ from, to }` range of an inline tracked change is wholly
11901
- * contained within some decidable whole-table tracked-change range. Such an
11902
- * inline change is subsumed by the structural "Inserted/Deleted table" review
11903
- * item and must NOT become an independent review item (no comment object →
11904
- * no floating bubble and no active-on-click dialog). The underlying
11905
- * trackInsert/trackDelete mark (the green highlight) is untouched — only the
11906
- * review-item comment is suppressed.
11907
- *
11908
- * @param {Array<{ from?: number, to?: number }>} changeRanges
11909
- * @param {Array<{ from: number, to: number }>} tableRanges
11910
- * @returns {boolean}
11911
- */
11912
- const isInlineRangeInsideTrackedTable = (changeRanges, tableRanges) => {
11913
- if (!tableRanges?.length || !changeRanges?.length) return false;
11914
- return changeRanges.every((seg) => {
11915
- const start = Number(seg?.from);
11916
- const end = Number(seg?.to);
11917
- if (!Number.isFinite(start) || !Number.isFinite(end)) return false;
11918
- return tableRanges.some((table) => start >= table.from && end <= table.to);
11919
- });
11920
- };
11921
- /**
11922
- * Suppress an inline tracked-change bubble whose document range falls within a
11923
- * tracked whole-table change's range, so only the structural "Added table"
11924
- * / "Deleted table" bubble shows for that table (matching Word / Google Docs).
11925
- * The structural bubble itself, real user comments, and inline tracked changes
11926
- * inside a NON-tracked table are never suppressed.
11927
- *
11928
- * @param {Object} comment
11929
- * @returns {boolean} True when the bubble must NOT render.
11930
- */
11931
- const isInlineTrackedChangeInsideTrackedTable = (comment) => {
11932
- if (!comment?.trackedChange) return false;
11933
- if (isStructuralTableBubble(comment)) return false;
11934
- const ranges = getTrackedTableRangesForDocument(comment?.fileId);
11935
- if (!ranges.length) return false;
11936
- const entry = resolveCommentPositionEntry(comment).entry;
11937
- const range = getCommentPositionRange(entry);
11938
- if (!range) return false;
11939
- return ranges.some((table) => range.start >= table.from && range.end <= table.to);
11940
- };
11941
10803
  const getFloatingComments = require__plugin_vue_export_helper.computed(() => {
11942
10804
  return getGroupedComments.value?.parentComments.filter((c) => !c.resolvedTime).filter((c) => {
11943
10805
  if (!isEditorBackedComment(c)) return true;
11944
10806
  if (isTrackedChangeThread(c)) return true;
11945
10807
  return Boolean(resolveCommentPositionEntry(c).entry);
11946
- }).filter((c) => !isInlineTrackedChangeInsideTrackedTable(c));
10808
+ });
11947
10809
  });
11948
10810
  const getFloatingCommentInstances = require__plugin_vue_export_helper.computed(() => {
11949
10811
  return getFloatingComments.value.flatMap((comment) => {
@@ -11988,75 +10850,6 @@ var useCommentsStore = defineStore("comments", () => {
11988
10850
  if (typeof commentsVisible === "boolean") viewingVisibility.commentsVisible = commentsVisible;
11989
10851
  if (typeof trackChangesVisible === "boolean") viewingVisibility.trackChangesVisible = trackChangesVisible;
11990
10852
  };
11991
- /**
11992
- * Get HTML content from the comment text JSON (which uses DOCX schema)
11993
- *
11994
- * @param {Object} commentTextJson The comment text JSON
11995
- * @returns {string} The HTML content
11996
- */
11997
- const normalizeCommentForEditor = (node) => {
11998
- if (Array.isArray(node)) return node.map((child) => normalizeCommentForEditor(child)).flat().filter(Boolean);
11999
- if (!node || typeof node !== "object") return node;
12000
- const stripTextStyleAttrs = (attrs) => {
12001
- if (!attrs) return attrs;
12002
- const rest = { ...attrs };
12003
- delete rest.fontSize;
12004
- delete rest.fontFamily;
12005
- delete rest.eastAsiaFontFamily;
12006
- return Object.keys(rest).length ? rest : void 0;
12007
- };
12008
- const normalizeMark = (mark) => {
12009
- if (!mark) return mark;
12010
- const typeName = typeof mark.type === "string" ? mark.type : mark.type?.name;
12011
- const attrs = mark?.attrs ? { ...mark.attrs } : void 0;
12012
- if (typeName === "textStyle" && attrs) return {
12013
- ...mark,
12014
- attrs: stripTextStyleAttrs(attrs)
12015
- };
12016
- return {
12017
- ...mark,
12018
- attrs
12019
- };
12020
- };
12021
- const cloneMarks = (marks) => Array.isArray(marks) ? marks.filter(Boolean).map((mark) => normalizeMark(mark)) : void 0;
12022
- const cloneAttrs = (attrs) => attrs && typeof attrs === "object" ? { ...attrs } : void 0;
12023
- if (!Array.isArray(node.content)) return {
12024
- type: node.type,
12025
- ...node.text !== void 0 ? { text: node.text } : {},
12026
- ...node.attrs ? { attrs: cloneAttrs(node.attrs) } : {},
12027
- ...node.marks ? { marks: cloneMarks(node.marks) } : {}
12028
- };
12029
- const normalizedChildren = node.content.map((child) => normalizeCommentForEditor(child)).flat().filter(Boolean);
12030
- if (node.type === "run") return normalizedChildren;
12031
- return {
12032
- type: node.type,
12033
- ...node.attrs ? { attrs: cloneAttrs(node.attrs) } : {},
12034
- ...node.marks ? { marks: cloneMarks(node.marks) } : {},
12035
- content: normalizedChildren
12036
- };
12037
- };
12038
- const getHtmlFromComment = (commentTextElements) => {
12039
- const elementsArray = Array.isArray(commentTextElements) ? commentTextElements : commentTextElements ? [commentTextElements] : [];
12040
- if (!elementsArray.some((element) => element?.content?.length)) return;
12041
- try {
12042
- const normalizedContent = normalizeCommentForEditor(elementsArray);
12043
- const contentArray = Array.isArray(normalizedContent) ? normalizedContent : normalizedContent ? [normalizedContent] : [];
12044
- if (!contentArray.length) return null;
12045
- return new Editor({
12046
- mode: "text",
12047
- isHeadless: true,
12048
- content: {
12049
- type: "doc",
12050
- content: contentArray
12051
- },
12052
- loadFromSchema: true,
12053
- extensions: getRichTextExtensions()
12054
- }).getHTML();
12055
- } catch (error) {
12056
- console.warn("Failed to convert comment", error);
12057
- return;
12058
- }
12059
- };
12060
10853
  return {
12061
10854
  COMMENT_EVENTS,
12062
10855
  isDebugging,
@@ -12104,8 +10897,6 @@ var useCommentsStore = defineStore("comments", () => {
12104
10897
  getTrackedChangeThread,
12105
10898
  getCommentPositionKey,
12106
10899
  getCommentPosition,
12107
- getCommentAnchoredText,
12108
- getCommentAnchorData,
12109
10900
  resolveCommentPositionEntry,
12110
10901
  getCommentDocumentId,
12111
10902
  belongsToDocument,
@@ -12125,23 +10916,17 @@ var useCommentsStore = defineStore("comments", () => {
12125
10916
  cancelComment,
12126
10917
  deleteComment,
12127
10918
  removePendingComment,
12128
- cancelImportedTrackedChangeBootstrap,
12129
10919
  removeCommentsForDocument,
12130
10920
  setReviewDirectoryFromV2,
12131
10921
  clearReviewDirectory,
12132
- processLoadedDocxComments,
12133
- translateCommentsForExport,
12134
10922
  handleEditorLocationsUpdate,
12135
10923
  clearEditorCommentPositions,
12136
10924
  handleTrackedChangeUpdate,
12137
- refreshTrackedChangeCommentsByIds,
12138
10925
  syncResolvedCommentsWithDocument,
12139
- syncTrackedChangePositionsWithDocument,
12140
10926
  setActiveFloatingCommentInstance,
12141
10927
  requestInstantSidebarAlignment,
12142
10928
  peekInstantSidebarAlignment,
12143
10929
  clearInstantSidebarAlignment,
12144
- syncTrackedChangeComments,
12145
10930
  decideTrackedChangeFromSidebar,
12146
10931
  v2CommentsAdapter,
12147
10932
  setV2CommentsAdapter,
@@ -12165,6 +10950,18 @@ var useCommentsStore = defineStore("comments", () => {
12165
10950
  };
12166
10951
  });
12167
10952
  //#endregion
10953
+ //#region src/composables/use-superdoc-instance.ts
10954
+ function useSuperDocInstance() {
10955
+ const instance = require__plugin_vue_export_helper.getCurrentInstance();
10956
+ if (!instance?.proxy) throw new Error("useSuperDocInstance() must be called during a component setup function.");
10957
+ const superdoc = instance.appContext.config.globalProperties.$superdoc;
10958
+ if (!superdoc) throw new Error("useSuperDocInstance() found no SuperDoc registered at app.config.globalProperties.$superdoc.");
10959
+ return {
10960
+ proxy: instance.proxy,
10961
+ superdoc
10962
+ };
10963
+ }
10964
+ //#endregion
12168
10965
  //#region ../../shared/common/icons/comment-solid.svg?raw
12169
10966
  var comment_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=\"M512 240c0 114.9-114.6 208-256 208c-37.1 0-72.3-6.4-104.1-17.9c-11.9 8.7-31.3 20.6-54.3 30.6C73.6 471.1 44.7 480 16 480c-6.5 0-12.3-3.9-14.8-9.9c-2.5-6-1.1-12.8 3.4-17.4c0 0 0 0 0 0s0 0 0 0s0 0 0 0c0 0 0 0 0 0l.3-.3c.3-.3 .7-.7 1.3-1.4c1.1-1.2 2.8-3.1 4.9-5.7c4.1-5 9.6-12.4 15.2-21.6c10-16.6 19.5-38.4 21.4-62.9C17.7 326.8 0 285.1 0 240C0 125.1 114.6 32 256 32s256 93.1 256 208z\"/></svg>";
12170
10967
  //#endregion
@@ -12305,7 +11102,7 @@ var _hoisted_3$21 = {
12305
11102
  };
12306
11103
  var _hoisted_4$15 = ["innerHTML"];
12307
11104
  var _hoisted_5$11 = { class: "comments-dropdown__option-label" };
12308
- var _sfc_main$38 = {
11105
+ var _sfc_main$25 = {
12309
11106
  __name: "CommentsDropdown",
12310
11107
  props: {
12311
11108
  options: {
@@ -12455,14 +11252,14 @@ var _sfc_main$38 = {
12455
11252
  };
12456
11253
  }
12457
11254
  };
12458
- var CommentsDropdown_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$38, [["__scopeId", "data-v-7eced80a"]]);
11255
+ var CommentsDropdown_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$25, [["__scopeId", "data-v-7eced80a"]]);
12459
11256
  //#endregion
12460
11257
  //#region src/components/CommentsLayer/InternalDropdown.vue
12461
11258
  var _hoisted_1$30 = { class: "sd-comment-option" };
12462
11259
  var _hoisted_2$23 = ["innerHTML"];
12463
11260
  var _hoisted_3$20 = { class: "sd-option-state" };
12464
11261
  var _hoisted_4$14 = ["innerHTML"];
12465
- var _sfc_main$37 = {
11262
+ var _sfc_main$24 = {
12466
11263
  __name: "InternalDropdown",
12467
11264
  props: {
12468
11265
  state: {
@@ -12545,7 +11342,7 @@ var _sfc_main$37 = {
12545
11342
  };
12546
11343
  }
12547
11344
  };
12548
- var InternalDropdown_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$37, [["__scopeId", "data-v-138d641e"]]);
11345
+ var InternalDropdown_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$24, [["__scopeId", "data-v-138d641e"]]);
12549
11346
  //#endregion
12550
11347
  //#region src/components/CommentsLayer/helpers.js
12551
11348
  /**
@@ -12578,122 +11375,6 @@ function formatDate(timestamp) {
12578
11375
  return `${`${formattedHours}:${minutes.toString().padStart(2, "0")}${meridiem}`} ${month} ${day}`;
12579
11376
  }
12580
11377
  //#endregion
12581
- //#region src/core/collaboration/permissions.js
12582
- var PERMISSIONS = Object.freeze({
12583
- RESOLVE_OWN: "RESOLVE_OWN",
12584
- RESOLVE_OTHER: "RESOLVE_OTHER",
12585
- REJECT_OWN: "REJECT_OWN",
12586
- REJECT_OTHER: "REJECT_OTHER",
12587
- COMMENTS_OVERFLOW_OWN: "COMMENTS_OVERFLOW",
12588
- COMMENTS_OVERFLOW_OTHER: "COMMENTS_OVERFLOW_OTHER",
12589
- COMMENTS_DELETE_OWN: "COMMENTS_DELETE_OWN",
12590
- COMMENTS_DELETE_OTHER: "COMMENTS_DELETE_OTHER",
12591
- UPLOAD_VERSION: "UPLOAD_VERSION",
12592
- VERSION_HISTORY: "VERSION_HISTORY"
12593
- });
12594
- var ROLES = Object.freeze({
12595
- EDITOR: "editor",
12596
- SUGGESTER: "suggester",
12597
- VIEWER: "viewer"
12598
- });
12599
- var PERMISSION_MATRIX = Object.freeze({
12600
- [PERMISSIONS.RESOLVE_OWN]: {
12601
- internal: [ROLES.EDITOR],
12602
- external: [ROLES.EDITOR]
12603
- },
12604
- [PERMISSIONS.RESOLVE_OTHER]: {
12605
- internal: [ROLES.EDITOR],
12606
- external: [ROLES.EDITOR]
12607
- },
12608
- [PERMISSIONS.REJECT_OWN]: {
12609
- internal: [ROLES.EDITOR, ROLES.SUGGESTER],
12610
- external: [ROLES.EDITOR, ROLES.SUGGESTER]
12611
- },
12612
- [PERMISSIONS.REJECT_OTHER]: {
12613
- internal: [ROLES.EDITOR],
12614
- external: [ROLES.EDITOR]
12615
- },
12616
- [PERMISSIONS.COMMENTS_OVERFLOW_OWN]: {
12617
- internal: [ROLES.EDITOR, ROLES.SUGGESTER],
12618
- external: [ROLES.EDITOR, ROLES.SUGGESTER]
12619
- },
12620
- [PERMISSIONS.COMMENTS_OVERFLOW_OTHER]: {
12621
- internal: [ROLES.EDITOR],
12622
- external: [ROLES.EDITOR]
12623
- },
12624
- [PERMISSIONS.COMMENTS_DELETE_OWN]: {
12625
- internal: [ROLES.EDITOR, ROLES.SUGGESTER],
12626
- external: [ROLES.EDITOR, ROLES.SUGGESTER]
12627
- },
12628
- [PERMISSIONS.COMMENTS_DELETE_OTHER]: {
12629
- internal: [ROLES.EDITOR],
12630
- external: [ROLES.EDITOR]
12631
- },
12632
- [PERMISSIONS.UPLOAD_VERSION]: {
12633
- internal: [ROLES.EDITOR],
12634
- external: []
12635
- },
12636
- [PERMISSIONS.VERSION_HISTORY]: {
12637
- internal: [ROLES.EDITOR],
12638
- external: []
12639
- }
12640
- });
12641
- var pickResolver = (context = {}) => {
12642
- if (typeof context.permissionResolver === "function") return context.permissionResolver;
12643
- if (typeof context.superdoc?.config?.permissionResolver === "function") return context.superdoc.config.permissionResolver;
12644
- const deprecatedResolver = context.superdoc?.config?.modules?.comments?.permissionResolver;
12645
- if (typeof deprecatedResolver === "function") return deprecatedResolver;
12646
- return null;
12647
- };
12648
- var BUILT_IN_PERMISSION_METHOD = Symbol.for("superdoc.internal.permission-method.builtin");
12649
- var BUILT_IN_PERMISSION_RESOLVER = Symbol.for("superdoc.internal.permission-resolver.builtin");
12650
- /** Create the shell's internal, live tracked-change permission shim. */
12651
- var createTrackedChangePermissionResolver = (superdoc) => {
12652
- const isBuiltInPolicy = () => superdoc.canPerformPermission?.[BUILT_IN_PERMISSION_METHOD] === true && pickResolver({ superdoc }) === null;
12653
- const resolver = (payload = {}) => isBuiltInPolicy() ? defaultDecisionFor(payload.permission, superdoc.config.role, superdoc.config.isInternal) : superdoc.canPerformPermission({
12654
- ...payload,
12655
- role: superdoc.config.role,
12656
- isInternal: superdoc.config.isInternal
12657
- });
12658
- Object.defineProperty(resolver, BUILT_IN_PERMISSION_RESOLVER, { value: isBuiltInPolicy });
12659
- return resolver;
12660
- };
12661
- var defaultDecisionFor = (permission, role, isInternal) => {
12662
- const internalExternal = isInternal ? "internal" : "external";
12663
- return PERMISSION_MATRIX[permission]?.[internalExternal]?.includes(role) ?? false;
12664
- };
12665
- /**
12666
- * Resolve a client-side permission through the built-in matrix and optional
12667
- * resolver.
12668
- *
12669
- * @param {string} permission The permission to check
12670
- * @param {string} role The role to check
12671
- * @param {boolean} isInternal The internal/external flag
12672
- * @param {object} [context] Context passed to the permission resolver
12673
- * @param {object | null} [context.comment] The comment/tracked change being evaluated
12674
- * @param {object | null} [context.superdoc] The SuperDoc instance
12675
- * @param {object | null} [context.currentUser] The active user object performing the action
12676
- * @param {Function} [context.permissionResolver] Explicit resolver override
12677
- * @param {object | null} [context.trackedChange] Tracked change metadata (for tracked-change permissions)
12678
- * @returns {boolean} Whether the permission is allowed
12679
- */
12680
- var isAllowed = (permission, role, isInternal, context = {}) => {
12681
- const defaultDecision = defaultDecisionFor(permission, role, isInternal);
12682
- const resolver = pickResolver(context);
12683
- if (typeof resolver !== "function") return defaultDecision;
12684
- const decision = resolver({
12685
- permission,
12686
- role,
12687
- isInternal,
12688
- defaultDecision,
12689
- comment: context.comment ?? null,
12690
- currentUser: context.currentUser ?? context.superdoc?.config?.user ?? null,
12691
- superdoc: context.superdoc ?? null,
12692
- trackedChange: context.trackedChange ?? null
12693
- });
12694
- return typeof decision === "boolean" ? decision : defaultDecision;
12695
- };
12696
- //#endregion
12697
11378
  //#region src/components/general/Avatar.vue
12698
11379
  var _hoisted_1$29 = { class: "user-container" };
12699
11380
  var _hoisted_2$22 = ["src"];
@@ -12701,7 +11382,7 @@ var _hoisted_3$19 = {
12701
11382
  key: 1,
12702
11383
  class: "user-bg"
12703
11384
  };
12704
- var _sfc_main$36 = {
11385
+ var _sfc_main$23 = {
12705
11386
  __name: "Avatar",
12706
11387
  props: { user: {
12707
11388
  type: Object,
@@ -12726,7 +11407,7 @@ var _sfc_main$36 = {
12726
11407
  };
12727
11408
  }
12728
11409
  };
12729
- var Avatar_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$36, [["__scopeId", "data-v-c95b2073"]]);
11410
+ var Avatar_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$23, [["__scopeId", "data-v-c95b2073"]]);
12730
11411
  //#endregion
12731
11412
  //#region src/components/CommentsLayer/CommentHeader.vue
12732
11413
  var _hoisted_1$28 = { class: "card-section comment-header" };
@@ -12758,7 +11439,7 @@ var _hoisted_9$4 = [
12758
11439
  ];
12759
11440
  var _hoisted_10$4 = { class: "overflow-menu__icon" };
12760
11441
  var _hoisted_11$4 = ["innerHTML"];
12761
- var _sfc_main$35 = {
11442
+ var _sfc_main$22 = {
12762
11443
  __name: "CommentHeader",
12763
11444
  props: {
12764
11445
  timestamp: {
@@ -12879,11 +11560,12 @@ var _sfc_main$35 = {
12879
11560
  if (props.isPendingInput) return false;
12880
11561
  return true;
12881
11562
  });
11563
+ const resolveIsDisabled = () => props.config.allowResolve === false;
12882
11564
  const allowResolve = require__plugin_vue_export_helper.computed(() => {
12883
11565
  if (!generallyAllowed.value) return false;
12884
11566
  if (props.comment.trackedChange) {
12885
11567
  if (!trackedChangeDecisionsVisible.value) return false;
12886
- } else if (!commentMutationsVisible.value || props.config.allowResolve === false) return false;
11568
+ } else if (!commentMutationsVisible.value || resolveIsDisabled()) return false;
12887
11569
  if (props.comment.parentCommentId) return false;
12888
11570
  if (trackedChangeThreadParentId.value) return false;
12889
11571
  const context = {
@@ -12891,8 +11573,8 @@ var _sfc_main$35 = {
12891
11573
  currentUser: proxy.$superdoc.config.user,
12892
11574
  superdoc: proxy.$superdoc
12893
11575
  };
12894
- if (isOwnComment.value) return isAllowed(PERMISSIONS.RESOLVE_OWN, role, isInternal, context);
12895
- return isAllowed(PERMISSIONS.RESOLVE_OTHER, role, isInternal, context);
11576
+ if (isOwnComment.value) return require_create_super_doc_ui.isAllowed(require_create_super_doc_ui.PERMISSIONS.RESOLVE_OWN, role, isInternal, context);
11577
+ return require_create_super_doc_ui.isAllowed(require_create_super_doc_ui.PERMISSIONS.RESOLVE_OTHER, role, isInternal, context);
12896
11578
  });
12897
11579
  const allowReject = require__plugin_vue_export_helper.computed(() => {
12898
11580
  if (!generallyAllowed.value) return false;
@@ -12903,12 +11585,12 @@ var _sfc_main$35 = {
12903
11585
  currentUser: proxy.$superdoc.config.user,
12904
11586
  superdoc: proxy.$superdoc
12905
11587
  };
12906
- if (isOwnComment.value) return isAllowed(PERMISSIONS.REJECT_OWN, role, isInternal, context);
12907
- return isAllowed(PERMISSIONS.REJECT_OTHER, role, isInternal, context);
11588
+ if (isOwnComment.value) return require_create_super_doc_ui.isAllowed(require_create_super_doc_ui.PERMISSIONS.REJECT_OWN, role, isInternal, context);
11589
+ return require_create_super_doc_ui.isAllowed(require_create_super_doc_ui.PERMISSIONS.REJECT_OTHER, role, isInternal, context);
12908
11590
  });
12909
11591
  const allowReopen = require__plugin_vue_export_helper.computed(() => {
12910
11592
  if (!commentMutationsVisible.value) return false;
12911
- if (props.config.allowResolve === false) return false;
11593
+ if (resolveIsDisabled()) return false;
12912
11594
  if (!props.reopenSupported) return false;
12913
11595
  if (!props.comment) return false;
12914
11596
  if (!props.comment.resolvedTime) return false;
@@ -12922,8 +11604,8 @@ var _sfc_main$35 = {
12922
11604
  currentUser: proxy.$superdoc.config.user,
12923
11605
  superdoc: proxy.$superdoc
12924
11606
  };
12925
- if (isOwnComment.value) return isAllowed(PERMISSIONS.RESOLVE_OWN, role, isInternal, context);
12926
- return isAllowed(PERMISSIONS.RESOLVE_OTHER, role, isInternal, context);
11607
+ if (isOwnComment.value) return require_create_super_doc_ui.isAllowed(require_create_super_doc_ui.PERMISSIONS.RESOLVE_OWN, role, isInternal, context);
11608
+ return require_create_super_doc_ui.isAllowed(require_create_super_doc_ui.PERMISSIONS.RESOLVE_OTHER, role, isInternal, context);
12927
11609
  });
12928
11610
  const allowOverflow = require__plugin_vue_export_helper.computed(() => {
12929
11611
  if (!generallyAllowed.value) return false;
@@ -12945,15 +11627,15 @@ var _sfc_main$35 = {
12945
11627
  currentUser: proxy.$superdoc.config.user,
12946
11628
  superdoc: proxy.$superdoc
12947
11629
  };
12948
- if (isOwnComment && isAllowed(PERMISSIONS.COMMENTS_DELETE_OWN, role, isInternal, context)) options.add("delete");
12949
- else if (!isOwnComment && isAllowed(PERMISSIONS.COMMENTS_DELETE_OTHER, role, isInternal, context)) options.add("delete");
11630
+ if (isOwnComment && require_create_super_doc_ui.isAllowed(require_create_super_doc_ui.PERMISSIONS.COMMENTS_DELETE_OWN, role, isInternal, context)) options.add("delete");
11631
+ else if (!isOwnComment && require_create_super_doc_ui.isAllowed(require_create_super_doc_ui.PERMISSIONS.COMMENTS_DELETE_OTHER, role, isInternal, context)) options.add("delete");
12950
11632
  options.forEach((option) => allowedOptions.push(OVERFLOW_OPTIONS[option]));
12951
11633
  return allowedOptions;
12952
11634
  });
12953
11635
  const handleResolve = () => {
12954
11636
  if (props.comment?.trackedChange) {
12955
11637
  if (!trackedChangeDecisionsVisible.value) return;
12956
- } else if (!commentMutationsVisible.value || props.config.allowResolve === false) return;
11638
+ } else if (!commentMutationsVisible.value || resolveIsDisabled()) return;
12957
11639
  if (props.resolveDisabledReason) return;
12958
11640
  emit("resolve");
12959
11641
  };
@@ -12963,7 +11645,7 @@ var _sfc_main$35 = {
12963
11645
  emit("reject");
12964
11646
  };
12965
11647
  const handleReopen = () => {
12966
- if (!commentMutationsVisible.value || props.config.allowResolve === false) return;
11648
+ if (!commentMutationsVisible.value || resolveIsDisabled()) return;
12967
11649
  if (props.reopenDisabledReason) return;
12968
11650
  emit("reopen");
12969
11651
  };
@@ -13038,7 +11720,7 @@ var _sfc_main$35 = {
13038
11720
  };
13039
11721
  }
13040
11722
  };
13041
- var CommentHeader_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$35, [["__scopeId", "data-v-b2a33943"]]);
11723
+ var CommentHeader_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$22, [["__scopeId", "data-v-3af1135b"]]);
13042
11724
  //#endregion
13043
11725
  //#region src/components/CommentsLayer/CommentInput.vue
13044
11726
  var _hoisted_1$27 = { class: "input-section" };
@@ -13060,7 +11742,7 @@ var _hoisted_6$7 = {
13060
11742
  class: "comment-mention-option__email"
13061
11743
  };
13062
11744
  var commentInputSequence = 0;
13063
- var _sfc_main$34 = {
11745
+ var _sfc_main$21 = {
13064
11746
  __name: "CommentInput",
13065
11747
  props: {
13066
11748
  users: {
@@ -13259,7 +11941,7 @@ var _sfc_main$34 = {
13259
11941
  };
13260
11942
  }
13261
11943
  };
13262
- var CommentInput_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$34, [["__scopeId", "data-v-0720a671"]]);
11944
+ var CommentInput_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$21, [["__scopeId", "data-v-0720a671"]]);
13263
11945
  //#endregion
13264
11946
  //#region src/internal/toolbar/built-in/url-safety.js
13265
11947
  /**
@@ -13369,7 +12051,7 @@ function renderCommentHtml(value) {
13369
12051
  return template.innerHTML;
13370
12052
  }
13371
12053
  //#endregion
13372
- //#region src/components/CommentsLayer/CommentDialog.vue
12054
+ //#region src/components/CommentsLayer/CommentDialog.vue?vue&type=script&setup=true&lang.ts
13373
12055
  var _hoisted_1$26 = [
13374
12056
  "aria-label",
13375
12057
  "data-comment-instance-id",
@@ -13458,33 +12140,33 @@ var _hoisted_42 = {
13458
12140
  };
13459
12141
  var _hoisted_43 = { class: "reply-input-wrapper" };
13460
12142
  var _hoisted_44 = { class: "reply-actions" };
13461
- var _hoisted_45 = ["onClick"];
13462
- var _hoisted_46 = [
12143
+ var _hoisted_45 = [
13463
12144
  "onClick",
13464
12145
  "disabled",
13465
12146
  "data-disabled-reason"
13466
12147
  ];
13467
- var _hoisted_47 = { class: "collapsed-avatars" };
13468
- var _hoisted_48 = {
12148
+ var _hoisted_46 = { class: "collapsed-avatars" };
12149
+ var _hoisted_47 = {
13469
12150
  key: 3,
13470
12151
  class: "comment-separator"
13471
12152
  };
13472
- var _hoisted_49 = {
12153
+ var _hoisted_48 = {
13473
12154
  key: 3,
13474
12155
  class: "tracked-change-decision-alert",
13475
12156
  role: "alert"
13476
12157
  };
13477
- var _hoisted_50 = { class: "tracked-change-decision-alert__message" };
13478
- var _hoisted_51 = ["disabled", "data-disabled-reason"];
13479
- var _hoisted_52 = {
12158
+ var _hoisted_49 = { class: "tracked-change-decision-alert__message" };
12159
+ var _hoisted_50 = ["disabled", "data-disabled-reason"];
12160
+ var _hoisted_51 = {
13480
12161
  key: 1,
13481
12162
  class: "reply-expanded"
13482
12163
  };
13483
- var _hoisted_53 = { class: "reply-input-wrapper" };
13484
- var _hoisted_54 = { class: "reply-actions" };
13485
- var _hoisted_55 = ["disabled", "data-disabled-reason"];
12164
+ var _hoisted_52 = { class: "reply-input-wrapper" };
12165
+ var _hoisted_53 = { class: "reply-actions" };
12166
+ var _hoisted_54 = ["disabled", "data-disabled-reason"];
13486
12167
  var commentEditSessions = /* @__PURE__ */ new WeakMap();
13487
- var _sfc_main$33 = {
12168
+ var commentReplySessions = /* @__PURE__ */ new WeakMap();
12169
+ var CommentDialog_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ require__plugin_vue_export_helper.defineComponent({
13488
12170
  __name: "CommentDialog",
13489
12171
  props: {
13490
12172
  comment: {
@@ -13529,15 +12211,20 @@ var _sfc_main$33 = {
13529
12211
  setup(__props, { emit: __emit }) {
13530
12212
  const emit = __emit;
13531
12213
  const props = __props;
13532
- const { proxy } = require__plugin_vue_export_helper.getCurrentInstance();
12214
+ const proxy = useSuperDocInstance().proxy;
13533
12215
  const superdocStore = useSuperdocStore();
13534
- const commentsStore = useCommentsStore();
12216
+ const piniaCommentsStore = useCommentsStore();
12217
+ const commentsStore = piniaCommentsStore;
13535
12218
  const editSessionOwner = {};
12219
+ const replySessionOwner = {};
13536
12220
  const retireOwnEditSession = () => {
13537
12221
  if (commentEditSessions.get(commentsStore)?.owner === editSessionOwner) commentEditSessions.delete(commentsStore);
13538
12222
  };
12223
+ const retireOwnReplySession = () => {
12224
+ if (commentReplySessions.get(commentsStore)?.owner === replySessionOwner) commentReplySessions.delete(commentsStore);
12225
+ };
13539
12226
  const { addComment, cancelComment, deleteComment, getCommentAliasIds, removePendingComment, getCommentDocumentId, requestInstantSidebarAlignment, resolveCommentPositionEntry, clearInstantSidebarAlignment, setActiveFloatingCommentInstance } = commentsStore;
13540
- const { suppressInternalExternal, getConfig, activeComment, activeFloatingCommentInstanceId, floatingCommentsOffset, pendingComment, currentCommentText, currentCommentMentions, isDebugging, editingCommentId, editorCommentPositions, isCommentHighlighted } = storeToRefs(commentsStore);
12227
+ const { suppressInternalExternal, getConfig, activeComment, activeFloatingCommentInstanceId, floatingCommentsOffset, pendingComment, currentCommentText, currentCommentMentions, isDebugging, editingCommentId, editorCommentPositions, isCommentHighlighted } = storeToRefs(piniaCommentsStore);
13541
12228
  const isInternal = require__plugin_vue_export_helper.ref(true);
13542
12229
  const commentInput = require__plugin_vue_export_helper.ref(null);
13543
12230
  const editCommentInputs = require__plugin_vue_export_helper.ref(/* @__PURE__ */ new Map());
@@ -13552,8 +12239,8 @@ var _sfc_main$33 = {
13552
12239
  ];
13553
12240
  const TRACKED_CHANGE_PREVIEW_MAX_PX = 90;
13554
12241
  const trackedChangeImagePreviewStyle = (preview) => {
13555
- const width = typeof preview?.width === "number" && Number.isFinite(preview.width) ? preview.width : null;
13556
- const height = typeof preview?.height === "number" && Number.isFinite(preview.height) ? preview.height : null;
12242
+ const width = require_is_finite_number.isFiniteNumber(preview?.width) ? preview.width : null;
12243
+ const height = require_is_finite_number.isFiniteNumber(preview?.height) ? preview.height : null;
13557
12244
  if (!width || !height || width <= 0 || height <= 0) return {};
13558
12245
  const scale = Math.min(TRACKED_CHANGE_PREVIEW_MAX_PX / width, TRACKED_CHANGE_PREVIEW_MAX_PX / height, 1);
13559
12246
  return {
@@ -13605,13 +12292,14 @@ var _sfc_main$33 = {
13605
12292
  const findIgnoredElementByGeometry = (clientX, clientY) => {
13606
12293
  if (!Number.isFinite(clientX) || !Number.isFinite(clientY)) return null;
13607
12294
  const ignoredElements = document.querySelectorAll(CLICK_OUTSIDE_IGNORED_SELECTORS);
13608
- for (const element of ignoredElements) if (element instanceof HTMLElement && elementContainsClickPoint(element, clientX, clientY)) return element;
12295
+ for (const element of Array.from(ignoredElements)) if (element instanceof HTMLElement && elementContainsClickPoint(element, clientX, clientY)) return element;
13609
12296
  return null;
13610
12297
  };
13611
12298
  const focusEditInput = (commentId) => {
13612
12299
  editCommentInputs.value.get(commentId)?.focus?.();
13613
12300
  };
13614
12301
  const commentDialogElement = require__plugin_vue_export_helper.ref(null);
12302
+ const trackedChangeStoryType = (story) => typeof story === "object" ? story?.storyType : void 0;
13615
12303
  const getCommentFocusThreadId = (comment) => {
13616
12304
  if (comment.resolvedTime) return comment.commentId;
13617
12305
  return comment.importedId || comment.commentId;
@@ -13637,7 +12325,7 @@ var _sfc_main$33 = {
13637
12325
  };
13638
12326
  const getEntryBoundsCoordinate = (entry, coordinate) => {
13639
12327
  const value = entry?.bounds?.[coordinate];
13640
- return Number.isFinite(value) ? value : null;
12328
+ return require_is_finite_number.isFiniteNumber(value) ? value : null;
13641
12329
  };
13642
12330
  const entriesShareLine = (entry, candidateEntry) => {
13643
12331
  if (!entry || !candidateEntry) return false;
@@ -13651,12 +12339,7 @@ var _sfc_main$33 = {
13651
12339
  const candidateLeft = getEntryBoundsCoordinate(candidateEntry, "left");
13652
12340
  const entryRight = getEntryBoundsCoordinate(entry, "right");
13653
12341
  const candidateRight = getEntryBoundsCoordinate(candidateEntry, "right");
13654
- if ([
13655
- entryLeft,
13656
- candidateLeft,
13657
- entryRight,
13658
- candidateRight
13659
- ].some((value) => value == null)) return false;
12342
+ if (entryLeft == null || candidateLeft == null || entryRight == null || candidateRight == null) return false;
13660
12343
  return candidateLeft < entryRight && entryLeft < candidateRight;
13661
12344
  };
13662
12345
  const entriesOverlapRange = (entry, candidateEntry) => {
@@ -13664,12 +12347,7 @@ var _sfc_main$33 = {
13664
12347
  const entryEnd = entry?.end;
13665
12348
  const candidateStart = candidateEntry?.start;
13666
12349
  const candidateEnd = candidateEntry?.end;
13667
- if (![
13668
- entryStart,
13669
- entryEnd,
13670
- candidateStart,
13671
- candidateEnd
13672
- ].every(Number.isFinite)) return false;
12350
+ if (!require_is_finite_number.isFiniteNumber(entryStart) || !require_is_finite_number.isFiniteNumber(entryEnd) || !require_is_finite_number.isFiniteNumber(candidateStart) || !require_is_finite_number.isFiniteNumber(candidateEnd)) return false;
13673
12351
  return candidateStart <= entryEnd && entryStart <= candidateEnd;
13674
12352
  };
13675
12353
  const shouldIncludeThreadAlias = (entry, candidateEntry) => {
@@ -13690,7 +12368,7 @@ var _sfc_main$33 = {
13690
12368
  return [...lookupIds];
13691
12369
  };
13692
12370
  const isDialogAlreadyAlignedWithTarget = (dialogElement, targetClientY, tolerancePx = 24) => {
13693
- if (!Number.isFinite(targetClientY) || typeof dialogElement?.getBoundingClientRect !== "function") return false;
12371
+ if (!require_is_finite_number.isFiniteNumber(targetClientY) || typeof dialogElement?.getBoundingClientRect !== "function") return false;
13694
12372
  const dialogTop = dialogElement.getBoundingClientRect().top;
13695
12373
  return Number.isFinite(dialogTop) && Math.abs(dialogTop - targetClientY) <= tolerancePx;
13696
12374
  };
@@ -13716,14 +12394,19 @@ var _sfc_main$33 = {
13716
12394
  if (showInputSection.value && index === visible.length - 1) return true;
13717
12395
  return visible.length > 1 && index !== visible.length - 1;
13718
12396
  });
12397
+ const commentsAreReadOnly = () => getConfig.value?.readOnly === true;
12398
+ const resolveIsDisabled = () => getConfig.value?.allowResolve === false;
13719
12399
  const showInputSection = require__plugin_vue_export_helper.computed(() => {
13720
- return !getConfig.readOnly && isDialogActive.value && !props.comment.resolvedTime && !isEditingAnyComment.value;
12400
+ return !commentsAreReadOnly() && isDialogActive.value && !props.comment.resolvedTime && !isEditingAnyComment.value;
13721
12401
  });
13722
12402
  const readOnlyMutationOutcome = () => ({
13723
12403
  ok: false,
13724
12404
  reason: "read-only-document"
13725
12405
  });
13726
- const commentsAreReadOnly = () => getConfig.value?.readOnly === true;
12406
+ const resolveDisabledOutcome = () => ({
12407
+ ok: false,
12408
+ reason: "resolve-disabled"
12409
+ });
13727
12410
  const trackedChangeDecisionsAreDisabled = () => {
13728
12411
  const allowDecisions = proxy.$superdoc?.interactionConfig?.trackedChanges?.allowDecisions;
13729
12412
  if (typeof allowDecisions === "boolean") return !allowDecisions;
@@ -13736,6 +12419,11 @@ var _sfc_main$33 = {
13736
12419
  const isReplying = require__plugin_vue_export_helper.ref(false);
13737
12420
  const isSubmittingReply = require__plugin_vue_export_helper.ref(false);
13738
12421
  const isSubmittingNewComment = require__plugin_vue_export_helper.ref(false);
12422
+ let replyDraftRevision = 0;
12423
+ require__plugin_vue_export_helper.watch([currentCommentText, currentCommentMentions], () => replyDraftRevision++, {
12424
+ deep: true,
12425
+ flush: "sync"
12426
+ });
13739
12427
  const commentSaveFailure = require__plugin_vue_export_helper.ref("");
13740
12428
  const commentSaveFailureMessage = (outcome, hasDraft = true) => {
13741
12429
  return `Your comment could not be saved${outcome?.detail === "document-mode-read-only" ? " because the document or connection is read-only" : outcome?.code === "PERMISSION_DENIED" ? " because you do not have permission" : ""}.${hasDraft ? " Your draft is still here. Try again or cancel." : " Try again."}`;
@@ -13746,6 +12434,7 @@ var _sfc_main$33 = {
13746
12434
  ok: false,
13747
12435
  reason: v2WriteCapability.value?.reason ?? "v2-write-unavailable"
13748
12436
  };
12437
+ commentReplySessions.set(commentsStore, { owner: replySessionOwner });
13749
12438
  commentSaveFailure.value = "";
13750
12439
  isReplying.value = true;
13751
12440
  require__plugin_vue_export_helper.nextTick(() => {
@@ -13795,7 +12484,7 @@ var _sfc_main$33 = {
13795
12484
  require__plugin_vue_export_helper.nextTick(() => emit("resize"));
13796
12485
  };
13797
12486
  const setParentBodyRef = (el) => {
13798
- parentBodyRef.value = el ?? null;
12487
+ parentBodyRef.value = el;
13799
12488
  };
13800
12489
  const checkOverflow = () => {
13801
12490
  if (textExpanded.value) return;
@@ -13878,7 +12567,7 @@ var _sfc_main$33 = {
13878
12567
  };
13879
12568
  const isInternalDropdownDisabled = require__plugin_vue_export_helper.computed(() => {
13880
12569
  if (props.comment.resolvedTime) return true;
13881
- return getConfig.value.readOnly;
12570
+ return commentsAreReadOnly();
13882
12571
  });
13883
12572
  const isEditingThisComment = require__plugin_vue_export_helper.computed(() => (comment) => {
13884
12573
  return isDialogActive.value && editingCommentId.value === comment.commentId;
@@ -13888,7 +12577,7 @@ var _sfc_main$33 = {
13888
12577
  return comments.value.some((c) => c.commentId === editingCommentId.value);
13889
12578
  });
13890
12579
  const shouldShowInternalExternal = require__plugin_vue_export_helper.computed(() => {
13891
- if (getConfig.value.readOnly) return false;
12580
+ if (commentsAreReadOnly()) return false;
13892
12581
  if (!proxy.$superdoc.config.isInternal) return false;
13893
12582
  if (isV2Mode.value) return false;
13894
12583
  return !suppressInternalExternal.value && !props.comment.trackedChange;
@@ -13932,7 +12621,7 @@ var _sfc_main$33 = {
13932
12621
  if (editor) {
13933
12622
  const { entry: resolvedFocusEntry } = resolveCommentPositionEntry(props.comment);
13934
12623
  const focusEntry = props.floatingPositionEntry ?? resolvedFocusEntry;
13935
- const usePageScopedAnchorOnly = Number.isFinite(props.floatingPageIndex) && props.comment?.trackedChangeStory?.storyType === "headerFooterPart";
12624
+ const usePageScopedAnchorOnly = Number.isFinite(props.floatingPageIndex) && trackedChangeStoryType(props.comment?.trackedChangeStory) === "headerFooterPart";
13936
12625
  const visibleAnchorTargetY = getVisibleThreadAnchorClientY(props.parent, focusEntry);
13937
12626
  const visibleHighlightTargetY = usePageScopedAnchorOnly ? null : getVisibleThreadHighlightClientY(getThreadHighlightLookupIds(props.comment));
13938
12627
  const visibleThreadTargetY = Number.isFinite(visibleHighlightTargetY) ? visibleHighlightTargetY : visibleAnchorTargetY;
@@ -13984,6 +12673,15 @@ var _sfc_main$33 = {
13984
12673
  commentsStore.setActiveComment(proxy.$superdoc, activeComment.value);
13985
12674
  isCommentHighlighted.value = false;
13986
12675
  };
12676
+ const captureCommentEditorOwner = () => {
12677
+ const editor = proxy.$superdoc.activeEditor;
12678
+ const adapter = editor.v2Comments;
12679
+ const document = editor.doc;
12680
+ return {
12681
+ adapter,
12682
+ isCurrent: () => proxy.$superdoc.activeEditor === editor && editor.v2Comments === adapter && editor.doc === document
12683
+ };
12684
+ };
13987
12685
  const handleAddComment = async () => {
13988
12686
  if (commentsAreReadOnly()) return readOnlyMutationOutcome();
13989
12687
  if (isV2WriteDisabled.value) return {
@@ -13998,6 +12696,13 @@ var _sfc_main$33 = {
13998
12696
  isSubmittingReply.value = true;
13999
12697
  commentSaveFailure.value = "";
14000
12698
  try {
12699
+ const session = commentReplySessions.get(commentsStore);
12700
+ const draftRevision = replyDraftRevision;
12701
+ const editorOwner = captureCommentEditorOwner();
12702
+ const threadId = props.comment.commentId;
12703
+ const fileId = props.comment.fileId;
12704
+ const pendingDraft = pendingComment.value;
12705
+ const edit = editingCommentId.value;
14001
12706
  const parentCommentId = getV2ExistingReplyParentId(props.comment);
14002
12707
  const trackedChangeTarget = getV2TrackedChangeCommentTarget(props.comment);
14003
12708
  const outcome = await commentsStore.replyCommentV2({
@@ -14012,6 +12717,8 @@ var _sfc_main$33 = {
14012
12717
  require__plugin_vue_export_helper.nextTick(() => emit("resize"));
14013
12718
  return outcome;
14014
12719
  }
12720
+ if (session?.owner !== replySessionOwner || commentReplySessions.get(commentsStore) !== session || replyDraftRevision !== draftRevision || !editorOwner.isCurrent() || props.comment.commentId !== threadId || props.comment.fileId !== fileId || pendingComment.value !== pendingDraft || editingCommentId.value !== edit || !isDialogActive.value || !isReplying.value) return outcome;
12721
+ retireOwnReplySession();
14015
12722
  isReplying.value = false;
14016
12723
  currentCommentText.value = "";
14017
12724
  currentCommentMentions.value = [];
@@ -14132,7 +12839,7 @@ var _sfc_main$33 = {
14132
12839
  const getReopenDisabledReason = () => {
14133
12840
  if (!isV2Mode.value) return null;
14134
12841
  if (!v2CommentsAdapter.value) return "v2-comments-adapter-missing";
14135
- if (getConfig.value?.readOnly) return "read-only-document";
12842
+ if (commentsAreReadOnly()) return "read-only-document";
14136
12843
  if (isV2WriteDisabled.value) return v2WriteCapability.value?.reason ?? "v2-write-unavailable";
14137
12844
  return null;
14138
12845
  };
@@ -14235,10 +12942,7 @@ var _sfc_main$33 = {
14235
12942
  if (trackedChangeDecisionsAreDisabled()) return trackedChangeDecisionDisabledOutcome();
14236
12943
  } else {
14237
12944
  if (commentsAreReadOnly()) return readOnlyMutationOutcome();
14238
- if (getConfig.value?.allowResolve === false) return {
14239
- ok: false,
14240
- reason: "resolve-disabled"
14241
- };
12945
+ if (resolveIsDisabled()) return resolveDisabledOutcome();
14242
12946
  }
14243
12947
  const customHandler = proxy.$superdoc.config.onTrackedChangeBubbleAccept;
14244
12948
  if (props.comment.trackedChange && isV2Mode.value) {
@@ -14303,10 +13007,7 @@ var _sfc_main$33 = {
14303
13007
  };
14304
13008
  const handleReopen = async () => {
14305
13009
  if (commentsAreReadOnly()) return readOnlyMutationOutcome();
14306
- if (getConfig.value?.allowResolve === false) return {
14307
- ok: false,
14308
- reason: "resolve-disabled"
14309
- };
13010
+ if (resolveIsDisabled()) return resolveDisabledOutcome();
14310
13011
  if (!isV2Mode.value || !v2CommentsAdapter.value) return;
14311
13012
  const outcome = await commentsStore.reopenCommentV2({
14312
13013
  superdoc: proxy.$superdoc,
@@ -14331,7 +13032,7 @@ var _sfc_main$33 = {
14331
13032
  owner: editSessionOwner,
14332
13033
  submission: null
14333
13034
  });
14334
- currentCommentText.value = comment?.commentText?.value ?? comment?.commentText ?? "";
13035
+ currentCommentText.value = comment?.commentText ?? "";
14335
13036
  currentCommentMentions.value = Array.isArray(comment?.mentions) ? [...comment.mentions] : [];
14336
13037
  activeComment.value = props.comment.commentId;
14337
13038
  if (props.floatingInstanceId) setActiveFloatingCommentInstance(props.floatingInstanceId);
@@ -14358,10 +13059,8 @@ var _sfc_main$33 = {
14358
13059
  const session = commentEditSessions.get(commentsStore);
14359
13060
  const submission = Symbol("comment-edit-submission");
14360
13061
  if (session?.owner === editSessionOwner) session.submission = submission;
14361
- const editor = proxy.$superdoc.activeEditor;
14362
- const adapter = editor.v2Comments;
14363
- const documentId = adapter.documentId;
14364
- const document = editor.doc;
13062
+ const editorOwner = captureCommentEditorOwner();
13063
+ const documentId = editorOwner.adapter.documentId;
14365
13064
  const thread = props.comment;
14366
13065
  const draft = currentCommentText.value;
14367
13066
  const outcome = await commentsStore.editCommentV2({
@@ -14369,7 +13068,7 @@ var _sfc_main$33 = {
14369
13068
  commentId: comment.commentId,
14370
13069
  text: draft
14371
13070
  });
14372
- if (session?.owner !== editSessionOwner || commentEditSessions.get(commentsStore) !== session || session.submission !== submission || proxy.$superdoc.activeEditor !== editor || editor.v2Comments !== adapter || adapter.documentId !== documentId || editor.doc !== document || props.comment !== thread || editingCommentId.value !== comment.commentId || currentCommentText.value !== draft) return outcome;
13071
+ if (session?.owner !== editSessionOwner || commentEditSessions.get(commentsStore) !== session || session.submission !== submission || !editorOwner.isCurrent() || editorOwner.adapter.documentId !== documentId || props.comment !== thread || editingCommentId.value !== comment.commentId || currentCommentText.value !== draft) return outcome;
14373
13072
  if (!outcome?.ok) {
14374
13073
  commentSaveFailure.value = commentSaveFailureMessage(outcome);
14375
13074
  return outcome;
@@ -14405,16 +13104,17 @@ var _sfc_main$33 = {
14405
13104
  const getProcessedDate = (timestamp) => {
14406
13105
  return typeof timestamp === "string" ? new Date(timestamp).getTime() : timestamp;
14407
13106
  };
14408
- const handleCancel = (comment) => {
13107
+ const handleCancel = () => {
14409
13108
  commentSaveFailure.value = "";
14410
13109
  retireOwnEditSession();
13110
+ retireOwnReplySession();
14411
13111
  editingCommentId.value = null;
14412
13112
  isReplying.value = false;
14413
13113
  cancelComment(proxy.$superdoc);
14414
13114
  };
14415
13115
  const usersFiltered = require__plugin_vue_export_helper.computed(() => {
14416
13116
  const users = proxy.$superdoc.users;
14417
- if (props.comment.isInternal === true) return users.filter((user) => user.access === "internal" || user.access?.role === "internal");
13117
+ if (props.comment.isInternal === true) return users.filter((user) => user.access === "internal" || typeof user.access === "object" && user.access?.role === "internal");
14418
13118
  return users;
14419
13119
  });
14420
13120
  require__plugin_vue_export_helper.onMounted(() => {
@@ -14434,6 +13134,7 @@ var _sfc_main$33 = {
14434
13134
  });
14435
13135
  require__plugin_vue_export_helper.onBeforeUnmount(() => {
14436
13136
  retireOwnEditSession();
13137
+ retireOwnReplySession();
14437
13138
  proxy.$superdoc?.off?.("active-editor-change", refreshActiveEditor);
14438
13139
  });
14439
13140
  require__plugin_vue_export_helper.watch(showInputSection, (isVisible) => {
@@ -14450,7 +13151,7 @@ var _sfc_main$33 = {
14450
13151
  focusEditInput(commentId);
14451
13152
  });
14452
13153
  });
14453
- require__plugin_vue_export_helper.watch(() => getConfig.value?.readOnly === true, (readOnly) => {
13154
+ require__plugin_vue_export_helper.watch(commentsAreReadOnly, (readOnly) => {
14454
13155
  if (!readOnly) return;
14455
13156
  isReplying.value = false;
14456
13157
  if (comments.value.some((comment) => comment.commentId === editingCommentId.value)) editingCommentId.value = null;
@@ -14538,11 +13239,11 @@ var _sfc_main$33 = {
14538
13239
  timestamp: getProcessedDate(comment.createdTime),
14539
13240
  comment,
14540
13241
  "is-active": isDialogActive.value,
14541
- "resolve-disabled-reason": getResolveDisabledReason(comment),
14542
- "reject-disabled-reason": getRejectDisabledReason(comment),
13242
+ "resolve-disabled-reason": getResolveDisabledReason(comment) ?? void 0,
13243
+ "reject-disabled-reason": getRejectDisabledReason(comment) ?? void 0,
14543
13244
  "reopen-supported": isV2Mode.value && Boolean(v2CommentsAdapter.value),
14544
- "reopen-disabled-reason": getReopenDisabledReason(),
14545
- "write-disabled-reason": v2OverflowWriteDisabledReason.value,
13245
+ "reopen-disabled-reason": getReopenDisabledReason() ?? void 0,
13246
+ "write-disabled-reason": v2OverflowWriteDisabledReason.value ?? void 0,
14546
13247
  onResolve: handleResolve,
14547
13248
  onReject: handleReject,
14548
13249
  onReopen: handleReopen,
@@ -14609,7 +13310,7 @@ var _sfc_main$33 = {
14609
13310
  ref_for: true,
14610
13311
  ref: index === 0 ? setParentBodyRef : void 0,
14611
13312
  innerHTML: renderedCommentTexts.value.get(comment.commentId)
14612
- }, null, 10, _hoisted_40)) : require__plugin_vue_export_helper.unref(isDebugging) && !isEditingThisComment.value(comment) ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_41, require__plugin_vue_export_helper.toDisplayString(require__plugin_vue_export_helper.unref(editorCommentPositions)[comment.importedId !== void 0 ? comment.importedId : comment.commentId]?.bounds), 1)) : (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_42, [require__plugin_vue_export_helper.createElementVNode("div", _hoisted_43, [require__plugin_vue_export_helper.createVNode(CommentInput_default, {
13313
+ }, null, 10, _hoisted_40)) : require__plugin_vue_export_helper.unref(isDebugging) && !isEditingThisComment.value(comment) ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_41, require__plugin_vue_export_helper.toDisplayString(require__plugin_vue_export_helper.unref(editorCommentPositions)[String(comment.importedId !== void 0 ? comment.importedId : comment.commentId)]?.bounds), 1)) : (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_42, [require__plugin_vue_export_helper.createElementVNode("div", _hoisted_43, [require__plugin_vue_export_helper.createVNode(CommentInput_default, {
14613
13314
  ref_for: true,
14614
13315
  ref: setEditCommentInputRef(comment.commentId),
14615
13316
  users: [],
@@ -14618,13 +13319,13 @@ var _sfc_main$33 = {
14618
13319
  comment
14619
13320
  }, null, 8, ["config", "comment"])]), require__plugin_vue_export_helper.createElementVNode("div", _hoisted_44, [require__plugin_vue_export_helper.createElementVNode("button", {
14620
13321
  class: "sd-button reply-btn-cancel",
14621
- onClick: require__plugin_vue_export_helper.withModifiers(($event) => handleCancel(comment), ["stop", "prevent"])
14622
- }, "Cancel", 8, _hoisted_45), require__plugin_vue_export_helper.createElementVNode("button", {
13322
+ onClick: require__plugin_vue_export_helper.withModifiers(handleCancel, ["stop", "prevent"])
13323
+ }, "Cancel"), require__plugin_vue_export_helper.createElementVNode("button", {
14623
13324
  class: require__plugin_vue_export_helper.normalizeClass(["sd-button primary reply-btn-primary", { "sd-is-disabled": !hasTextContent.value || isV2WriteDisabled.value }]),
14624
13325
  onClick: require__plugin_vue_export_helper.withModifiers(($event) => handleCommentUpdate(comment), ["stop", "prevent"]),
14625
13326
  disabled: !hasTextContent.value || isV2WriteDisabled.value,
14626
13327
  "data-disabled-reason": isV2WriteDisabled.value ? v2WriteCapability.value?.reason ?? null : null
14627
- }, " Update ", 10, _hoisted_46)])])),
13328
+ }, " Update ", 10, _hoisted_45)])])),
14628
13329
  shouldTruncate.value && isTextOverflowing.value && index === 0 && !isEditingThisComment.value(comment) ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", {
14629
13330
  key: 3,
14630
13331
  class: "show-more-toggle",
@@ -14639,29 +13340,29 @@ var _sfc_main$33 = {
14639
13340
  shouldCollapseThread.value && index === 0 ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock(require__plugin_vue_export_helper.Fragment, { key: 2 }, [_cache[14] || (_cache[14] = require__plugin_vue_export_helper.createElementVNode("div", { class: "comment-separator" }, null, -1)), require__plugin_vue_export_helper.createElementVNode("div", {
14640
13341
  class: "collapsed-replies",
14641
13342
  onClick: require__plugin_vue_export_helper.withModifiers(expandThread, ["stop", "prevent"])
14642
- }, [require__plugin_vue_export_helper.createElementVNode("div", _hoisted_47, [(require__plugin_vue_export_helper.openBlock(true), require__plugin_vue_export_helper.createElementBlock(require__plugin_vue_export_helper.Fragment, null, require__plugin_vue_export_helper.renderList(collapsedReplyAuthors.value, (author) => {
13343
+ }, [require__plugin_vue_export_helper.createElementVNode("div", _hoisted_46, [(require__plugin_vue_export_helper.openBlock(true), require__plugin_vue_export_helper.createElementBlock(require__plugin_vue_export_helper.Fragment, null, require__plugin_vue_export_helper.renderList(collapsedReplyAuthors.value, (author) => {
14643
13344
  return require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createBlock(Avatar_default, {
14644
- key: author.email || author.name,
13345
+ key: (author.email || author.name) ?? void 0,
14645
13346
  user: author,
14646
13347
  class: "mini-avatar"
14647
13348
  }, null, 8, ["user"]);
14648
13349
  }), 128))]), require__plugin_vue_export_helper.createElementVNode("span", null, require__plugin_vue_export_helper.toDisplayString(collapsedReplyCount.value) + " more " + require__plugin_vue_export_helper.toDisplayString(collapsedReplyCount.value === 1 ? "reply" : "replies"), 1)])], 64)) : require__plugin_vue_export_helper.createCommentVNode("", true),
14649
- showSeparator.value(index) ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_48)) : require__plugin_vue_export_helper.createCommentVNode("", true)
13350
+ showSeparator.value(index) ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_47)) : require__plugin_vue_export_helper.createCommentVNode("", true)
14650
13351
  ]);
14651
13352
  }), 128)),
14652
- trackedChangeDecisionFailure.value ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_49, [require__plugin_vue_export_helper.createElementVNode("span", _hoisted_50, require__plugin_vue_export_helper.toDisplayString(trackedChangeDecisionFailureMessage.value), 1), require__plugin_vue_export_helper.createElementVNode("button", {
13353
+ trackedChangeDecisionFailure.value ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_48, [require__plugin_vue_export_helper.createElementVNode("span", _hoisted_49, require__plugin_vue_export_helper.toDisplayString(trackedChangeDecisionFailureMessage.value), 1), require__plugin_vue_export_helper.createElementVNode("button", {
14653
13354
  type: "button",
14654
13355
  class: "sd-button tracked-change-decision-alert__retry",
14655
13356
  onClick: require__plugin_vue_export_helper.withModifiers(retryTrackedChangeDecision, ["stop", "prevent"])
14656
13357
  }, " Retry ")])) : require__plugin_vue_export_helper.createCommentVNode("", true),
14657
- showInputSection.value && !require__plugin_vue_export_helper.unref(getConfig).readOnly ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock(require__plugin_vue_export_helper.Fragment, { key: 4 }, [!isReplying.value ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("button", {
13358
+ showInputSection.value ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock(require__plugin_vue_export_helper.Fragment, { key: 4 }, [!isReplying.value ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("button", {
14658
13359
  key: 0,
14659
13360
  type: "button",
14660
13361
  class: require__plugin_vue_export_helper.normalizeClass(["reply-pill", { "sd-is-disabled": isV2WriteDisabled.value }]),
14661
13362
  onClick: require__plugin_vue_export_helper.withModifiers(startReply, ["stop", "prevent"]),
14662
13363
  disabled: isV2WriteDisabled.value,
14663
13364
  "data-disabled-reason": isV2WriteDisabled.value ? v2WriteCapability.value?.reason ?? null : null
14664
- }, " Reply or add others with @ ", 10, _hoisted_51)) : (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_52, [require__plugin_vue_export_helper.createElementVNode("div", _hoisted_53, [require__plugin_vue_export_helper.createVNode(CommentInput_default, {
13365
+ }, " Reply or add others with @ ", 10, _hoisted_50)) : (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_51, [require__plugin_vue_export_helper.createElementVNode("div", _hoisted_52, [require__plugin_vue_export_helper.createVNode(CommentInput_default, {
14665
13366
  ref_key: "commentInput",
14666
13367
  ref: commentInput,
14667
13368
  users: usersFiltered.value,
@@ -14672,7 +13373,7 @@ var _sfc_main$33 = {
14672
13373
  "users",
14673
13374
  "config",
14674
13375
  "comment"
14675
- ])]), require__plugin_vue_export_helper.createElementVNode("div", _hoisted_54, [require__plugin_vue_export_helper.createElementVNode("button", {
13376
+ ])]), require__plugin_vue_export_helper.createElementVNode("div", _hoisted_53, [require__plugin_vue_export_helper.createElementVNode("button", {
14676
13377
  class: "sd-button reply-btn-cancel",
14677
13378
  onClick: require__plugin_vue_export_helper.withModifiers(handleCancel, ["stop", "prevent"])
14678
13379
  }, "Cancel"), require__plugin_vue_export_helper.createElementVNode("button", {
@@ -14680,12 +13381,14 @@ var _sfc_main$33 = {
14680
13381
  onClick: require__plugin_vue_export_helper.withModifiers(handleAddComment, ["stop", "prevent"]),
14681
13382
  disabled: !hasTextContent.value || isV2WriteDisabled.value || isSubmittingReply.value,
14682
13383
  "data-disabled-reason": v2ReplyDisabledReason.value
14683
- }, " Reply ", 10, _hoisted_55)])]))], 64)) : require__plugin_vue_export_helper.createCommentVNode("", true)
13384
+ }, " Reply ", 10, _hoisted_54)])]))], 64)) : require__plugin_vue_export_helper.createCommentVNode("", true)
14684
13385
  ], 64))], 14, _hoisted_1$26)), [[_directive_click_outside, handleClickOutside]]);
14685
13386
  };
14686
13387
  }
14687
- };
14688
- var CommentDialog_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$33, [["__scopeId", "data-v-f8b79c74"]]);
13388
+ });
13389
+ //#endregion
13390
+ //#region src/components/CommentsLayer/CommentDialog.vue
13391
+ var CommentDialog_default = /* @__PURE__ */ require__plugin_vue_export_helper._plugin_vue_export_helper_default(CommentDialog_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-752d9e0b"]]);
14689
13392
  //#endregion
14690
13393
  //#region src/components/CommentsLayer/commentsList/ReviewDirectoryListItem.vue
14691
13394
  var _hoisted_1$25 = [
@@ -14699,7 +13402,7 @@ var _hoisted_1$25 = [
14699
13402
  "data-comment-page-index",
14700
13403
  "data-review-directory-index"
14701
13404
  ];
14702
- var _sfc_main$32 = {
13405
+ var _sfc_main$20 = {
14703
13406
  __name: "ReviewDirectoryListItem",
14704
13407
  props: {
14705
13408
  item: {
@@ -14830,14 +13533,14 @@ var _sfc_main$32 = {
14830
13533
  };
14831
13534
  }
14832
13535
  };
14833
- var ReviewDirectoryListItem_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$32, [["__scopeId", "data-v-29650a06"]]);
13536
+ var ReviewDirectoryListItem_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$20, [["__scopeId", "data-v-29650a06"]]);
14834
13537
  //#endregion
14835
13538
  //#region src/components/CommentsLayer/commentsList/commentsList.vue
14836
13539
  var _hoisted_1$24 = ["aria-busy"];
14837
13540
  var _hoisted_2$18 = { key: 0 };
14838
13541
  var _hoisted_3$15 = { key: 1 };
14839
13542
  var REPEATED_HEADER_FOOTER_STORY_TYPE = "headerFooterPart";
14840
- var _sfc_main$31 = {
13543
+ var _sfc_main$19 = {
14841
13544
  __name: "commentsList",
14842
13545
  props: {
14843
13546
  showMainComments: {
@@ -14998,7 +13701,7 @@ var _sfc_main$31 = {
14998
13701
  };
14999
13702
  }
15000
13703
  };
15001
- var commentsList_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$31, [["__scopeId", "data-v-89244745"]]);
13704
+ var commentsList_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$19, [["__scopeId", "data-v-89244745"]]);
15002
13705
  //#endregion
15003
13706
  //#region src/components/CommentsLayer/commentsList/super-comments-list.js
15004
13707
  /**
@@ -15135,10 +13838,10 @@ var FIT_WIDTH_DEFAULTS = Object.freeze({
15135
13838
  });
15136
13839
  var resolveFitWidthOptions = (rawFitConfig) => {
15137
13840
  const raw = rawFitConfig && typeof rawFitConfig === "object" ? rawFitConfig : {};
15138
- const positiveOr = (value, fallback) => typeof value === "number" && Number.isFinite(value) && value > 0 ? value : fallback;
13841
+ const positiveOr = (value, fallback) => require_is_finite_number.isFiniteNumber(value) && value > 0 ? value : fallback;
15139
13842
  const min = positiveOr(raw.min, FIT_WIDTH_DEFAULTS.min);
15140
13843
  const max = positiveOr(raw.max, FIT_WIDTH_DEFAULTS.max);
15141
- const padding = typeof raw.padding === "number" && Number.isFinite(raw.padding) && raw.padding >= 0 ? raw.padding : FIT_WIDTH_DEFAULTS.padding;
13844
+ const padding = require_is_finite_number.isFiniteNumber(raw.padding) && raw.padding >= 0 ? raw.padding : FIT_WIDTH_DEFAULTS.padding;
15142
13845
  return {
15143
13846
  min: Math.min(min, max),
15144
13847
  max: Math.max(min, max),
@@ -15162,12 +13865,12 @@ var normalizePdfPageMeasurement = (measured, scaleFactor, zoomFactor) => {
15162
13865
  var resolveV2WidestPageWidth = (snapshot) => {
15163
13866
  if (!snapshot || typeof snapshot !== "object") return 0;
15164
13867
  const published = snapshot.widestPageWidthPx;
15165
- if (typeof published === "number" && Number.isFinite(published)) return published;
13868
+ if (require_is_finite_number.isFiniteNumber(published)) return published;
15166
13869
  let widestPage = 0;
15167
13870
  const pages = snapshot.pages;
15168
13871
  if (Array.isArray(pages)) for (const page of pages) {
15169
13872
  const width = page?.base?.widthPx;
15170
- if (typeof width === "number" && Number.isFinite(width) && width > widestPage) widestPage = width;
13873
+ if (require_is_finite_number.isFiniteNumber(width) && width > widestPage) widestPage = width;
15171
13874
  }
15172
13875
  return widestPage;
15173
13876
  };
@@ -15184,7 +13887,7 @@ var resolveEditorPageWidth = (editor) => {
15184
13887
  const pages = editor.getPages?.();
15185
13888
  if (Array.isArray(pages)) for (const page of pages) {
15186
13889
  const width = page?.size?.w;
15187
- if (typeof width === "number" && Number.isFinite(width) && width > widestPage) widestPage = width;
13890
+ if (require_is_finite_number.isFiniteNumber(width) && width > widestPage) widestPage = width;
15188
13891
  }
15189
13892
  } catch {
15190
13893
  widestPage = 0;
@@ -15197,7 +13900,7 @@ var resolveEditorPageWidth = (editor) => {
15197
13900
  pageStyles = null;
15198
13901
  }
15199
13902
  const pageWidthInches = pageStyles?.pageSize?.width;
15200
- if (typeof pageWidthInches === "number" && Number.isFinite(pageWidthInches) && pageWidthInches > 0) return pageWidthInches * CSS_PX_PER_INCH;
13903
+ if (require_is_finite_number.isFiniteNumber(pageWidthInches) && pageWidthInches > 0) return pageWidthInches * CSS_PX_PER_INCH;
15201
13904
  return null;
15202
13905
  };
15203
13906
  /**
@@ -15337,6 +14040,27 @@ function useViewportFit({ getSuperdoc, superdocContainerWidth, isReady, activeZo
15337
14040
  return { evaluateViewport };
15338
14041
  }
15339
14042
  //#endregion
14043
+ //#region src/composables/use-high-contrast-mode.ts
14044
+ var HIGH_CONTRAST_MODE_KEY = Symbol("superdoc-high-contrast-mode");
14045
+ function createHighContrastMode() {
14046
+ const isHighContrastMode = require__plugin_vue_export_helper.ref(false);
14047
+ return {
14048
+ isHighContrastMode,
14049
+ setHighContrastMode: (value) => {
14050
+ isHighContrastMode.value = value;
14051
+ }
14052
+ };
14053
+ }
14054
+ function createHighContrastOff() {
14055
+ return {
14056
+ isHighContrastMode: require__plugin_vue_export_helper.readonly(require__plugin_vue_export_helper.ref(false)),
14057
+ setHighContrastMode: () => {}
14058
+ };
14059
+ }
14060
+ function useHighContrastMode() {
14061
+ return require__plugin_vue_export_helper.inject(HIGH_CONTRAST_MODE_KEY, createHighContrastOff, true);
14062
+ }
14063
+ //#endregion
15340
14064
  //#region ../layout-engine/contracts/src/author-colors.ts
15341
14065
  /**
15342
14066
  * Curated, high-contrast fallback palette. Used when neither `overrides` nor
@@ -15593,7 +14317,7 @@ var resolveRemovedReviewCardContinuityTarget = ({ previousIds, currentIds, remov
15593
14317
  return null;
15594
14318
  };
15595
14319
  //#endregion
15596
- //#region src/components/CommentsLayer/FloatingComments.vue
14320
+ //#region src/components/CommentsLayer/FloatingComments.vue?vue&type=script&setup=true&lang.ts
15597
14321
  var _hoisted_1$23 = [
15598
14322
  "data-comment-id",
15599
14323
  "data-comment-instance-id",
@@ -15602,7 +14326,7 @@ var _hoisted_1$23 = [
15602
14326
  "data-comment-page-index"
15603
14327
  ];
15604
14328
  var _heightsCache = {};
15605
- var _sfc_main$30 = {
14329
+ var FloatingComments_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ require__plugin_vue_export_helper.defineComponent({
15606
14330
  __name: "FloatingComments",
15607
14331
  props: {
15608
14332
  currentDocument: {
@@ -15645,9 +14369,10 @@ var _sfc_main$30 = {
15645
14369
  };
15646
14370
  const props = __props;
15647
14371
  const superdocStore = useSuperdocStore();
15648
- const commentsStore = useCommentsStore();
14372
+ const piniaCommentsStore = useCommentsStore();
14373
+ const commentsStore = piniaCommentsStore;
15649
14374
  const { clearInstantSidebarAlignment } = commentsStore;
15650
- const { activeComment, activeFloatingCommentInstanceId, editorCommentPositions, pendingComment, editingCommentId, instantSidebarAlignmentTargetY, instantSidebarAlignmentThreadId, instantSidebarAlignmentInstanceId } = storeToRefs(commentsStore);
14375
+ const { activeComment, activeFloatingCommentInstanceId, editorCommentPositions, pendingComment, editingCommentId, instantSidebarAlignmentTargetY, instantSidebarAlignmentThreadId, instantSidebarAlignmentInstanceId } = storeToRefs(piniaCommentsStore);
15651
14376
  const { activeZoom } = storeToRefs(superdocStore);
15652
14377
  const committedPresentation = require__plugin_vue_export_helper.computed(() => commentsStore.committedReviewPresentations?.[String(props.currentDocument?.id)] ?? null);
15653
14378
  const committedInstances = require__plugin_vue_export_helper.computed(() => {
@@ -15754,7 +14479,7 @@ var _sfc_main$30 = {
15754
14479
  return bottom != null ? bottom * zoom : anchorTop;
15755
14480
  }
15756
14481
  const bottom = instance?.positionEntry?.bounds?.bottom;
15757
- return Number.isFinite(bottom) ? bottom : anchorTop;
14482
+ return require_is_finite_number.isFiniteNumber(bottom) ? bottom : anchorTop;
15758
14483
  };
15759
14484
  const geometryBearingInstances = require__plugin_vue_export_helper.computed(() => {
15760
14485
  const positioned = [];
@@ -15762,8 +14487,8 @@ var _sfc_main$30 = {
15762
14487
  const id = instance?.id;
15763
14488
  const threadId = getThreadId(instance?.comment);
15764
14489
  const anchorTop = getAnchorTop(instance);
15765
- if (id == null || threadId == null || !Number.isFinite(anchorTop)) continue;
15766
- const top = normalizeFloatingAnchorTop(anchorTop, instance.comment);
14490
+ if (id == null || threadId == null || !require_is_finite_number.isFiniteNumber(anchorTop)) continue;
14491
+ const top = normalizeFloatingAnchorTop(anchorTop);
15767
14492
  positioned.push({
15768
14493
  id,
15769
14494
  threadId,
@@ -15785,8 +14510,7 @@ var _sfc_main$30 = {
15785
14510
  return shouldMountFloatingCommentDialog({
15786
14511
  id: position?.id,
15787
14512
  visibleIds: committedPresentation.value ? new Set(allPositions.value.filter((item) => item.instanceRef?.mount).map((item) => item.id)) : visibleIds.value,
15788
- activeCommentInstanceId: activeCommentInstanceId.value,
15789
- comment: position?.commentRef
14513
+ activeCommentInstanceId: activeCommentInstanceId.value
15790
14514
  });
15791
14515
  };
15792
14516
  const getFloatingViewportRange = () => {
@@ -16142,14 +14866,14 @@ var _sfc_main$30 = {
16142
14866
  if (!directDecisionContinuity) return;
16143
14867
  const actionElement = (event?.target instanceof Element ? event.target : null)?.closest?.("[data-comment-action]");
16144
14868
  const action = actionElement?.getAttribute?.("data-comment-action");
16145
- if (!((action === "resolve" || action === "reject") && floatingCommentsContainer.value?.contains?.(actionElement))) releaseDirectDecisionContinuity();
14869
+ if (!((action === "resolve" || action === "reject") && floatingCommentsContainer.value?.contains?.(actionElement ?? null))) releaseDirectDecisionContinuity();
16146
14870
  };
16147
14871
  const clearDeferredRemeasureTimers = () => {
16148
14872
  remeasureTimers.forEach(clearTimeout);
16149
14873
  remeasureTimers = [];
16150
14874
  };
16151
14875
  const remeasureCommentKeys = (keys) => {
16152
- for (const key of keys.filter(Boolean)) {
14876
+ for (const key of keys.filter((candidate) => Boolean(candidate))) {
16153
14877
  const el = placeholderRefs.value[key];
16154
14878
  if (!el) continue;
16155
14879
  const dialog = el.querySelector(".comments-dialog");
@@ -16270,7 +14994,7 @@ var _sfc_main$30 = {
16270
14994
  removedId: removedKey
16271
14995
  });
16272
14996
  const targetClientY = (targetKey ? placeholderRefs.value[targetKey] : null)?.getBoundingClientRect?.().top;
16273
- if (!targetKey || !Number.isFinite(targetClientY)) {
14997
+ if (!targetKey || !require_is_finite_number.isFiniteNumber(targetClientY)) {
16274
14998
  clearSidebarContinuityAnchor();
16275
14999
  return false;
16276
15000
  }
@@ -16283,9 +15007,9 @@ var _sfc_main$30 = {
16283
15007
  return true;
16284
15008
  };
16285
15009
  const prepareSidebarContinuityForDirectDecision = (event) => {
16286
- const actionElement = event?.target?.closest?.("[data-comment-action]");
15010
+ const actionElement = (event?.target instanceof Element ? event.target : null)?.closest?.("[data-comment-action]");
16287
15011
  const action = actionElement?.getAttribute?.("data-comment-action");
16288
- if (action !== "resolve" && action !== "reject") return;
15012
+ if (!actionElement || action !== "resolve" && action !== "reject") return;
16289
15013
  releaseDirectDecisionContinuity();
16290
15014
  if (actionElement.getAttribute?.("aria-disabled") === "true") return;
16291
15015
  const removedKey = (actionElement.closest?.("[data-comment-id]"))?.getAttribute?.("data-comment-id");
@@ -16301,7 +15025,7 @@ var _sfc_main$30 = {
16301
15025
  removedId: removedKey
16302
15026
  });
16303
15027
  const targetClientY = (targetKey ? placeholderRefs.value[targetKey] : null)?.getBoundingClientRect?.().top;
16304
- if (!targetKey || !Number.isFinite(targetClientY)) return;
15028
+ if (!targetKey || !require_is_finite_number.isFiniteNumber(targetClientY)) return;
16305
15029
  directDecisionContinuity = {
16306
15030
  removedKey,
16307
15031
  targetKey,
@@ -16361,7 +15085,7 @@ var _sfc_main$30 = {
16361
15085
  instantAlignmentInstanceKey,
16362
15086
  instantSidebarAlignmentTargetY
16363
15087
  ], ([activeKey, requestKey, targetY]) => {
16364
- if (!activeKey || !requestKey || activeKey !== requestKey || !Number.isFinite(targetY)) return;
15088
+ if (!activeKey || !requestKey || activeKey !== requestKey || !require_is_finite_number.isFiniteNumber(targetY)) return;
16365
15089
  applyInstantSidebarAlignment(activeKey, targetY);
16366
15090
  });
16367
15091
  require__plugin_vue_export_helper.watch(editingCommentId, () => {
@@ -16418,10 +15142,10 @@ var _sfc_main$30 = {
16418
15142
  let prevActiveLayoutTop = null;
16419
15143
  require__plugin_vue_export_helper.watch(allPositions, (positions) => {
16420
15144
  const activePosition = activeCommentInstanceId.value ? positions.find((position) => position.id === activeCommentInstanceId.value) : null;
16421
- const activeAnchorTop = typeof activePosition?.anchorTop === "number" && Number.isFinite(activePosition.anchorTop) ? activePosition.anchorTop : null;
15145
+ const activeAnchorTop = require_is_finite_number.isFiniteNumber(activePosition?.anchorTop) ? activePosition.anchorTop : null;
16422
15146
  const sameActiveInstance = activeCommentInstanceId.value === prevActiveInstanceId;
16423
15147
  const activeAnchorMoved = sameActiveInstance && activeAnchorTop != null && prevActiveAnchorTop != null && Math.abs(activeAnchorTop - prevActiveAnchorTop) > 1;
16424
- const activeLayoutTop = typeof activePosition?.top === "number" && Number.isFinite(activePosition.top) ? activePosition.top : null;
15148
+ const activeLayoutTop = require_is_finite_number.isFiniteNumber(activePosition?.top) ? activePosition.top : null;
16425
15149
  const activeLayoutMoved = sameActiveInstance && activeLayoutTop != null && prevActiveLayoutTop != null && Math.abs(activeLayoutTop - prevActiveLayoutTop) > 1;
16426
15150
  if (activeAnchorMoved && sidebarOffsetY.value !== 0 && !Number.isFinite(instantSidebarAlignmentTargetY.value)) {
16427
15151
  sidebarOffsetY.value = 0;
@@ -16585,8 +15309,8 @@ var _sfc_main$30 = {
16585
15309
  parent: __props.parent,
16586
15310
  comment: pos.commentRef,
16587
15311
  "floating-instance-id": pos.id,
16588
- "floating-page-index": pos.pageIndex,
16589
- "floating-position-entry": pos.instanceRef?.positionEntry ?? null,
15312
+ "floating-page-index": pos.pageIndex ?? void 0,
15313
+ "floating-position-entry": pos.instanceRef?.positionEntry ?? void 0,
16590
15314
  "is-floating-instance-active": pos.id === activeCommentInstanceId.value
16591
15315
  }, null, 8, [
16592
15316
  "onResize",
@@ -16600,8 +15324,10 @@ var _sfc_main$30 = {
16600
15324
  }), 128))], 4)], 36);
16601
15325
  };
16602
15326
  }
16603
- };
16604
- var FloatingComments_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$30, [["__scopeId", "data-v-145f83db"]]);
15327
+ });
15328
+ //#endregion
15329
+ //#region src/components/CommentsLayer/FloatingComments.vue
15330
+ var FloatingComments_default = /* @__PURE__ */ require__plugin_vue_export_helper._plugin_vue_export_helper_default(FloatingComments_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-e74251e0"]]);
16605
15331
  //#endregion
16606
15332
  //#region src/components/CommentsLayer/PdfCommentsLayer.vue
16607
15333
  var _hoisted_1$22 = {
@@ -16880,7 +15606,7 @@ var useWhiteboard = ({ proxy, layers, documents, modules }) => {
16880
15606
  //#endregion
16881
15607
  //#region src/components/Whiteboard/WhiteboardPage.vue
16882
15608
  var _hoisted_1$21 = ["data-page-index"];
16883
- var _sfc_main$28 = {
15609
+ var _sfc_main$17 = {
16884
15610
  __name: "WhiteboardPage",
16885
15611
  props: {
16886
15612
  whiteboard: {
@@ -17015,10 +15741,10 @@ var _sfc_main$28 = {
17015
15741
  };
17016
15742
  }
17017
15743
  };
17018
- var WhiteboardPage_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$28, [["__scopeId", "data-v-c876c9b5"]]);
15744
+ var WhiteboardPage_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$17, [["__scopeId", "data-v-c876c9b5"]]);
17019
15745
  //#endregion
17020
15746
  //#region src/components/Whiteboard/WhiteboardLayer.vue
17021
- var _sfc_main$27 = {
15747
+ var _sfc_main$16 = {
17022
15748
  __name: "WhiteboardLayer",
17023
15749
  props: {
17024
15750
  whiteboard: {
@@ -17087,7 +15813,7 @@ var _sfc_main$27 = {
17087
15813
  };
17088
15814
  }
17089
15815
  };
17090
- var WhiteboardLayer_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$27, [["__scopeId", "data-v-54546c3d"]]);
15816
+ var WhiteboardLayer_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$16, [["__scopeId", "data-v-54546c3d"]]);
17091
15817
  //#endregion
17092
15818
  //#region src/components/CommentsLayer/collect-removed-comment-ids.js
17093
15819
  /**
@@ -17130,18 +15856,6 @@ var collectRemovedCommentIds = (comments, targetIds, isInScope = () => true) =>
17130
15856
  }
17131
15857
  return removedIds;
17132
15858
  };
17133
- //#endregion
17134
- //#region src/composables/use-high-contrast-mode.js
17135
- var isHighContrastMode = require__plugin_vue_export_helper.ref(false);
17136
- function useHighContrastMode() {
17137
- const setHighContrastMode = (value) => {
17138
- isHighContrastMode.value = value;
17139
- };
17140
- return {
17141
- isHighContrastMode,
17142
- setHighContrastMode
17143
- };
17144
- }
17145
15859
  var VALID_COMMENTS_LAYOUTS = /* @__PURE__ */ new Set([
17146
15860
  "auto",
17147
15861
  "sidebar",
@@ -17180,13 +15894,13 @@ function normalizeCommentsUiConfig(commentsConfig) {
17180
15894
  if (deprecatedTarget === void 0) delete normalized.compactMeasurementSelector;
17181
15895
  else normalized.compactMeasurementSelector = deprecatedTarget;
17182
15896
  const deprecatedBreakpoint = commentsConfig.compactBreakpointPx;
17183
- if (!(typeof deprecatedBreakpoint === "number" && Number.isFinite(deprecatedBreakpoint) && deprecatedBreakpoint >= 0)) delete normalized.compactBreakpointPx;
15897
+ if (!(require_is_finite_number.isFiniteNumber(deprecatedBreakpoint) && deprecatedBreakpoint >= 0)) delete normalized.compactBreakpointPx;
17184
15898
  delete normalized.layout;
17185
15899
  delete normalized.responsive;
17186
15900
  if (isCommentsLayout(layout)) normalized.layout = layout;
17187
15901
  const normalizedResponsive = {};
17188
15902
  if (target !== void 0) normalizedResponsive.target = target;
17189
- if (typeof breakpoint === "number" && Number.isFinite(breakpoint) && breakpoint >= 0) normalizedResponsive.breakpoint = breakpoint;
15903
+ if (require_is_finite_number.isFiniteNumber(breakpoint) && breakpoint >= 0) normalizedResponsive.breakpoint = breakpoint;
17190
15904
  if (Object.keys(normalizedResponsive).length > 0) normalized.responsive = normalizedResponsive;
17191
15905
  return normalized;
17192
15906
  }
@@ -17194,7 +15908,7 @@ function normalizeCommentsUiConfig(commentsConfig) {
17194
15908
  //#region src/composables/use-comment-small-screen.js
17195
15909
  var SUPERDOC_DOCUMENT_SELECTOR = ".superdoc__document";
17196
15910
  var isValidCompactBreakpoint = (value) => {
17197
- return typeof value === "number" && Number.isFinite(value) && value >= 0;
15911
+ return require_is_finite_number.isFiniteNumber(value) && value >= 0;
17198
15912
  };
17199
15913
  var getRequiredSidebarWidth = (documentWidth) => {
17200
15914
  return documentWidth + 320 + 24;
@@ -17341,18 +16055,17 @@ var COMMENT_HIGHLIGHT_DATA_ATTR = "data-comment-ids";
17341
16055
  var PDF_COMMENT_ANCHOR_SELECTOR = ".sd-comment-anchor";
17342
16056
  var clamp = (value, min, max) => Math.min(Math.max(value, min), max);
17343
16057
  var toNumber = (value) => Number(value);
17344
- var isFiniteNumber = (value) => Number.isFinite(value);
17345
16058
  var getCommentAnchorId = (comment) => comment?.commentId ?? comment?.importedId ?? null;
17346
16059
  var parseCommentIds = (value) => String(value || "").split(",").map((s) => s.trim()).filter(Boolean);
17347
16060
  var resolveInteractionAnchor = (lastClickAnchor) => {
17348
16061
  const anchor = lastClickAnchor?.value;
17349
16062
  if (!anchor) return null;
17350
16063
  const ts = toNumber(anchor.ts);
17351
- if (!isFiniteNumber(ts) || Date.now() - ts > INTERACTION_ANCHOR_TTL_MS) return null;
16064
+ if (!require_is_finite_number.isFiniteNumber(ts) || Date.now() - ts > INTERACTION_ANCHOR_TTL_MS) return null;
17352
16065
  const x = toNumber(anchor.x);
17353
16066
  const rectBottom = toNumber(anchor.anchorRect?.bottom);
17354
- const y = isFiniteNumber(rectBottom) ? rectBottom : toNumber(anchor.y);
17355
- if (!isFiniteNumber(x) || !isFiniteNumber(y)) return null;
16067
+ const y = require_is_finite_number.isFiniteNumber(rectBottom) ? rectBottom : toNumber(anchor.y);
16068
+ if (!require_is_finite_number.isFiniteNumber(x) || !require_is_finite_number.isFiniteNumber(y)) return null;
17356
16069
  return {
17357
16070
  x,
17358
16071
  y
@@ -17383,7 +16096,7 @@ var resolveInlineHighlightAnchorRect = ({ rootEl, comment, pendingComment }) =>
17383
16096
  var resolveEntryAnchorBottom = (resolveCommentPositionEntry, comment) => {
17384
16097
  const { entry } = resolveCommentPositionEntry(getCommentAnchorId(comment));
17385
16098
  const boundsBottom = toNumber(entry?.bounds?.bottom);
17386
- if (isFiniteNumber(boundsBottom)) return boundsBottom;
16099
+ if (require_is_finite_number.isFiniteNumber(boundsBottom)) return boundsBottom;
17387
16100
  return toNumber(entry?.bounds?.top);
17388
16101
  };
17389
16102
  var isPdfContextForAnchorLookup = ({ selectionPosition, comment, pendingComment }) => selectionPosition.value?.source === "pdf" || comment?.selection?.source === "pdf" || pendingComment.value?.selection?.source === "pdf";
@@ -17397,9 +16110,9 @@ var resolvePdfDomAnchorBottom = ({ rootEl, layersRect, comment }) => {
17397
16110
  var resolvePendingSelectionAnchorBottom = ({ comment, pendingComment, selectionPosition, activeZoom }) => {
17398
16111
  if (!pendingComment.value || comment?.commentId !== pendingComment.value?.commentId) return NaN;
17399
16112
  const selectedBottom = toNumber(selectionPosition.value?.bottom);
17400
- if (isFiniteNumber(selectedBottom)) return selectedBottom * (selectionPosition.value?.source === "pdf" ? (activeZoom.value ?? 100) / 100 : 1);
16113
+ if (require_is_finite_number.isFiniteNumber(selectedBottom)) return selectedBottom * (selectionPosition.value?.source === "pdf" ? (activeZoom.value ?? 100) / 100 : 1);
17401
16114
  const selectedTop = toNumber(selectionPosition.value?.top);
17402
- if (!isFiniteNumber(selectedTop)) return NaN;
16115
+ if (!require_is_finite_number.isFiniteNumber(selectedTop)) return NaN;
17403
16116
  return selectedTop * (selectionPosition.value?.source === "pdf" ? (activeZoom.value ?? 100) / 100 : 1);
17404
16117
  };
17405
16118
  var toPopoverStyle = ({ top, left }) => ({
@@ -17411,7 +16124,7 @@ var resolvePopoverPosition = ({ rootRect, layersRect, anchorBottom, anchorClient
17411
16124
  const top = clamp(layersRect.top - rootRect.top + anchorBottom + ANCHOR_TOP_OFFSET_PX, SAFE_MARGIN_PX, Math.max(SAFE_MARGIN_PX, rootRect.height - MIN_BOTTOM_SPACE_PX));
17412
16125
  const maxLeft = Math.max(SAFE_MARGIN_PX, rootRect.width - POPOVER_WIDTH_PX - SAFE_MARGIN_PX);
17413
16126
  let left;
17414
- if (isFiniteNumber(anchorClientX)) left = clamp(anchorClientX - rootRect.left + SAFE_MARGIN_PX, SAFE_MARGIN_PX, maxLeft);
16127
+ if (require_is_finite_number.isFiniteNumber(anchorClientX)) left = clamp(anchorClientX - rootRect.left + SAFE_MARGIN_PX, SAFE_MARGIN_PX, maxLeft);
17415
16128
  else {
17416
16129
  const rightCandidate = rootRect.width - (layersRect.left - rootRect.left + layersRect.width) + SAFE_MARGIN_PX;
17417
16130
  left = clamp(rootRect.width - rightCandidate - POPOVER_WIDTH_PX, SAFE_MARGIN_PX, maxLeft);
@@ -17498,7 +16211,7 @@ function useCompactCommentPopover({ activeComment, pendingComment, activeCompact
17498
16211
  anchorBottom = inlineRect.bottom - layersRect.top;
17499
16212
  anchorClientX = inlineRect.left;
17500
16213
  } else anchorBottom = resolveEntryAnchorBottom(resolveCommentPositionEntry, comment);
17501
- if (!isFiniteNumber(anchorBottom) && isPdfContextForAnchorLookup({
16214
+ if (!require_is_finite_number.isFiniteNumber(anchorBottom) && isPdfContextForAnchorLookup({
17502
16215
  selectionPosition,
17503
16216
  comment,
17504
16217
  pendingComment
@@ -17507,13 +16220,13 @@ function useCompactCommentPopover({ activeComment, pendingComment, activeCompact
17507
16220
  layersRect,
17508
16221
  comment
17509
16222
  });
17510
- if (!isFiniteNumber(anchorBottom)) anchorBottom = resolvePendingSelectionAnchorBottom({
16223
+ if (!require_is_finite_number.isFiniteNumber(anchorBottom)) anchorBottom = resolvePendingSelectionAnchorBottom({
17511
16224
  comment,
17512
16225
  pendingComment,
17513
16226
  selectionPosition,
17514
16227
  activeZoom
17515
16228
  });
17516
- if (!isFiniteNumber(anchorBottom)) return fallback;
16229
+ if (!require_is_finite_number.isFiniteNumber(anchorBottom)) return fallback;
17517
16230
  return toPopoverStyle(resolvePopoverPosition({
17518
16231
  rootRect,
17519
16232
  layersRect,
@@ -18122,7 +16835,7 @@ function usePasswordPrompt({ getSurfaceManager, getPasswordPromptConfig, onUnhan
18122
16835
  })
18123
16836
  });
18124
16837
  } else {
18125
- const PasswordPromptSurface = (await Promise.resolve().then(() => require("./chunks/PasswordPromptSurface-B5DHV6qr.cjs"))).default;
16838
+ const PasswordPromptSurface = (await Promise.resolve().then(() => require("./chunks/PasswordPromptSurface-BpqP4pUa.cjs"))).default;
18126
16839
  const surfaceId = `password-prompt-${doc.id}`;
18127
16840
  handle = manager.open({
18128
16841
  id: surfaceId,
@@ -18817,7 +17530,7 @@ function useFindReplace({ getSurfaceManager, getActiveEditor, activeEditorRef, g
18817
17530
  } else {
18818
17531
  let FindReplaceSurface;
18819
17532
  try {
18820
- FindReplaceSurface = (await Promise.resolve().then(() => require("./chunks/FindReplaceSurface-8V8AjgR4.cjs"))).default;
17533
+ FindReplaceSurface = (await Promise.resolve().then(() => require("./chunks/FindReplaceSurface-BRs3JrCq.cjs"))).default;
18821
17534
  } catch {
18822
17535
  opening = false;
18823
17536
  return;
@@ -19170,7 +17883,7 @@ var toolbarIcons = {
19170
17883
  formattingMarks: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><text x=\"12\" y=\"18\" text-anchor=\"middle\" font-family=\"Arial, Helvetica, sans-serif\" font-size=\"20\" font-weight=\"700\" fill=\"currentColor\">¶</text></svg>\n"
19171
17884
  };
19172
17885
  //#endregion
19173
- //#region src/internal/toolbar/built-in/LinkInput.vue
17886
+ //#region src/internal/toolbar/built-in/LinkInput.vue?vue&type=script&setup=true&lang.ts
19174
17887
  var _hoisted_1$20 = {
19175
17888
  key: 0,
19176
17889
  class: "link-title"
@@ -19234,7 +17947,7 @@ var _hoisted_18$1 = {
19234
17947
  * `btn-link-remove`, `btn-link-open`, `input[name="link"]`) is preserved so the
19235
17948
  * proof lane and behavior tests keep working.
19236
17949
  */
19237
- var _sfc_main$26 = {
17950
+ var LinkInput_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ require__plugin_vue_export_helper.defineComponent({
19238
17951
  __name: "LinkInput",
19239
17952
  props: {
19240
17953
  showInput: {
@@ -19385,7 +18098,7 @@ var _sfc_main$26 = {
19385
18098
  commandError.value = "";
19386
18099
  try {
19387
18100
  const result = await runLinkCommand(payload);
19388
- if (result === false || result == null || typeof result === "object" && (result.success === false || result.status === "rejected")) {
18101
+ if (result === false || result == null || typeof result === "object" && result.success === false) {
19389
18102
  commandError.value = "Could not apply link. Check the selection and try again.";
19390
18103
  return;
19391
18104
  }
@@ -19495,8 +18208,10 @@ var _sfc_main$26 = {
19495
18208
  ], 2);
19496
18209
  };
19497
18210
  }
19498
- };
19499
- var LinkInput_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$26, [["__scopeId", "data-v-360db842"]]);
18211
+ });
18212
+ //#endregion
18213
+ //#region src/internal/toolbar/built-in/LinkInput.vue
18214
+ var LinkInput_default = /* @__PURE__ */ require__plugin_vue_export_helper._plugin_vue_export_helper_default(LinkInput_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-172107e4"]]);
19500
18215
  //#endregion
19501
18216
  //#region src/internal/toolbar/built-in/scroll-helpers.js
19502
18217
  function getScrollableParent(element) {
@@ -20812,6 +19527,7 @@ function createV2EditorRuntimeAdapter(options) {
20812
19527
  }
20813
19528
  const result = await host.dispatch(mapped);
20814
19529
  switch (result.status) {
19530
+ case "selected": return { status: "selected" };
20815
19531
  case "committed":
20816
19532
  invalidatePositionTokens();
20817
19533
  return {
@@ -21261,8 +19977,11 @@ function translateRenderReadinessDiagnostic(diag, ctx = {}) {
21261
19977
  else if (severity === "error") diagnosticCode = "RENDER_ERROR";
21262
19978
  else return null;
21263
19979
  const message = reason || code;
19980
+ const error = new Error(typeof diag.error?.message === "string" ? diag.error.message : message);
19981
+ if (typeof diag.error?.name === "string") error.name = diag.error.name;
19982
+ if (typeof diag.error?.stack === "string") error.stack = diag.error.stack;
21264
19983
  return {
21265
- error: new Error(message),
19984
+ error,
21266
19985
  diagnosticCode,
21267
19986
  diagnosticStage: unusableFurniture ? "parse" : "render",
21268
19987
  severity,
@@ -21409,7 +20128,7 @@ function translateExportDiagnostic(error, ctx = {}) {
21409
20128
  * event only fires on success, fires AFTER the diagnostics events on the
21410
20129
  * success path, and never fires at all for a failed attempt.
21411
20130
  *
21412
- * @param {{generation?: unknown}} [payload]
20131
+ * @param {{generation?: unknown} | null} [payload]
21413
20132
  * @returns {number}
21414
20133
  */
21415
20134
  function getV2DiagnosticGeneration(payload) {
@@ -21482,8 +20201,8 @@ function isBootDiagnosticRedundant(bootDiagnostic, reason, translatedRecords) {
21482
20201
  return Boolean(bootDiagnostic) && bootDiagnostic.internalCode === reason && translatedRecords.length > 0;
21483
20202
  }
21484
20203
  //#endregion
21485
- //#region src/components/surfaces/SurfaceExternalMount.vue
21486
- var _sfc_main$25 = {
20204
+ //#region src/components/surfaces/SurfaceExternalMount.vue?vue&type=script&setup=true&lang.ts
20205
+ var SurfaceExternalMount_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ require__plugin_vue_export_helper.defineComponent({
21487
20206
  __name: "SurfaceExternalMount",
21488
20207
  props: {
21489
20208
  surfaceId: {
@@ -21545,8 +20264,10 @@ var _sfc_main$25 = {
21545
20264
  }, null, 512);
21546
20265
  };
21547
20266
  }
21548
- };
21549
- var SurfaceExternalMount_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$25, [["__scopeId", "data-v-b2412c5d"]]);
20267
+ });
20268
+ //#endregion
20269
+ //#region src/components/surfaces/SurfaceExternalMount.vue
20270
+ var SurfaceExternalMount_default = /* @__PURE__ */ require__plugin_vue_export_helper._plugin_vue_export_helper_default(SurfaceExternalMount_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-d1081bc8"]]);
21550
20271
  //#endregion
21551
20272
  //#region src/components/surfaces/focusable-selector.js
21552
20273
  /**
@@ -21562,11 +20283,11 @@ var FOCUSABLE_SELECTOR = [
21562
20283
  "[tabindex]:not([tabindex=\"-1\"])"
21563
20284
  ].join(", ");
21564
20285
  //#endregion
21565
- //#region src/components/surfaces/SurfaceDialog.vue
20286
+ //#region src/components/surfaces/SurfaceDialog.vue?vue&type=script&setup=true&lang.ts
21566
20287
  var _hoisted_1$19 = ["aria-labelledby", "aria-label"];
21567
20288
  var _hoisted_2$15 = ["id"];
21568
20289
  var _hoisted_3$13 = { class: "sd-surface-dialog__content" };
21569
- var _sfc_main$24 = {
20290
+ var SurfaceDialog_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ require__plugin_vue_export_helper.defineComponent({
21570
20291
  __name: "SurfaceDialog",
21571
20292
  props: {
21572
20293
  surface: {
@@ -21613,7 +20334,7 @@ var _sfc_main$24 = {
21613
20334
  if (props.scrollLockTarget) scrollLockTarget = props.scrollLockTarget;
21614
20335
  else {
21615
20336
  const superdocRoot = dialogRef.value?.closest(".superdoc");
21616
- scrollLockTarget = superdocRoot?.querySelector(".superdoc__layers") ?? superdocRoot;
20337
+ scrollLockTarget = superdocRoot?.querySelector(".superdoc__layers") ?? superdocRoot ?? null;
21617
20338
  }
21618
20339
  if (!scrollLockTarget) return;
21619
20340
  originalOverflow = scrollLockTarget.style.overflow;
@@ -21714,14 +20435,16 @@ var _sfc_main$24 = {
21714
20435
  ])) : __props.surface.component ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createBlock(require__plugin_vue_export_helper.resolveDynamicComponent(__props.surface.component), require__plugin_vue_export_helper.normalizeProps(require__plugin_vue_export_helper.mergeProps({ key: 1 }, mergedComponentProps.value)), null, 16)) : require__plugin_vue_export_helper.createCommentVNode("", true)])], 12, _hoisted_1$19)], 32);
21715
20436
  };
21716
20437
  }
21717
- };
21718
- var SurfaceDialog_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$24, [["__scopeId", "data-v-5cee3b11"]]);
20438
+ });
20439
+ //#endregion
20440
+ //#region src/components/surfaces/SurfaceDialog.vue
20441
+ var SurfaceDialog_default = /* @__PURE__ */ require__plugin_vue_export_helper._plugin_vue_export_helper_default(SurfaceDialog_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-6ce23dd7"]]);
21719
20442
  //#endregion
21720
20443
  //#region src/components/surfaces/SurfaceFloating.vue
21721
20444
  var _hoisted_1$18 = ["aria-labelledby", "aria-label"];
21722
20445
  var _hoisted_2$14 = ["id"];
21723
20446
  var _hoisted_3$12 = { class: "sd-surface-floating__content" };
21724
- var _sfc_main$23 = {
20447
+ var _sfc_main$15 = {
21725
20448
  __name: "SurfaceFloating",
21726
20449
  props: { surface: {
21727
20450
  type: Object,
@@ -21870,10 +20593,10 @@ var _sfc_main$23 = {
21870
20593
  };
21871
20594
  }
21872
20595
  };
21873
- var SurfaceFloating_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$23, [["__scopeId", "data-v-cd2be5db"]]);
20596
+ var SurfaceFloating_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$15, [["__scopeId", "data-v-cd2be5db"]]);
21874
20597
  //#endregion
21875
20598
  //#region src/components/surfaces/SurfaceHost.vue
21876
- var _sfc_main$22 = {
20599
+ var _sfc_main$14 = {
21877
20600
  __name: "SurfaceHost",
21878
20601
  props: { geometryTarget: {
21879
20602
  type: Object,
@@ -22095,9 +20818,9 @@ var _sfc_main$22 = {
22095
20818
  };
22096
20819
  }
22097
20820
  };
22098
- var SurfaceHost_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$22, [["__scopeId", "data-v-dad99b67"]]);
20821
+ var SurfaceHost_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$14, [["__scopeId", "data-v-dad99b67"]]);
22099
20822
  //#endregion
22100
- //#region src/SuperDoc.vue
20823
+ //#region src/SuperDoc.vue?vue&type=script&setup=true&lang.ts
22101
20824
  var _hoisted_1$17 = ["data-superdoc-ui-owner"];
22102
20825
  var _hoisted_2$13 = ["innerHTML"];
22103
20826
  var _hoisted_3$11 = { class: "superdoc__document document" };
@@ -22105,11 +20828,11 @@ var _hoisted_4$9 = { class: "floating-comments" };
22105
20828
  var TRACKED_CHANGE_CARRIERS_RESTAMPED_EVENT = "superdoc:v2-tracked-change-carriers-restamped";
22106
20829
  var UNAVAILABLE_COMMAND_RESULT = false;
22107
20830
  var V2_SELECTION_TOOLBAR_SYNC_RETRY_FRAMES = 3;
22108
- var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default({
20831
+ var SuperDoc_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ require__plugin_vue_export_helper.defineComponent({
22109
20832
  __name: "SuperDoc",
22110
20833
  emits: ["selection-update"],
22111
20834
  setup(__props, { emit: __emit }) {
22112
- const PdfViewer = require__plugin_vue_export_helper.defineAsyncComponent(() => Promise.resolve().then(() => require("./chunks/PdfViewer-omriDChK.cjs")));
20835
+ const PdfViewer = require__plugin_vue_export_helper.defineAsyncComponent(() => Promise.resolve().then(() => require("./chunks/PdfViewer-boENOZdF.cjs")));
22113
20836
  const getDocumentLoadPassword = (doc) => doc.password ?? proxy.$superdoc.config.password;
22114
20837
  const resolveDocumentV2Collaboration = (doc) => {
22115
20838
  const rawConfig = doc?.v2Collaboration;
@@ -22155,10 +20878,10 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22155
20878
  }
22156
20879
  });
22157
20880
  const { getConfig, documentsWithConverations, commentsList, pendingComment, activeComment, skipSelectionUpdate, commentsByDocument, isCommentsListVisible, isFloatingCommentsReady, generalCommentIds, hasSyncedCollaborationComments, editorCommentPositions, hasInitializedLocations, isCommentHighlighted, hasOpenTrackedChanges } = storeToRefs(commentsStore);
22158
- const { showAddComment, handleEditorLocationsUpdate, handleTrackedChangeUpdate, refreshTrackedChangeCommentsByIds, syncTrackedChangePositionsWithDocument, syncTrackedChangeComments, addComment, addHydratedComment, getComment, resolveCommentPositionEntry, belongsToDocument, COMMENT_EVENTS, requestInstantSidebarAlignment, peekInstantSidebarAlignment, clearInstantSidebarAlignment } = commentsStore;
22159
- const { proxy } = require__plugin_vue_export_helper.getCurrentInstance();
20881
+ const { showAddComment, handleEditorLocationsUpdate, handleTrackedChangeUpdate, addComment, addHydratedComment, getComment, resolveCommentPositionEntry, belongsToDocument, COMMENT_EVENTS, requestInstantSidebarAlignment, peekInstantSidebarAlignment, clearInstantSidebarAlignment } = commentsStore;
20882
+ const { proxy, superdoc } = useSuperDocInstance();
22160
20883
  commentsStore.proxy = proxy;
22161
- const documentOpenTelemetry = createDocumentOpenTelemetry(proxy.$superdoc.config);
20884
+ const documentOpenTelemetry = createDocumentOpenTelemetry(superdoc.config);
22162
20885
  const resolvedEditorIntegration = createDefaultV2Integration();
22163
20886
  const V2DocumentEditor = require__plugin_vue_export_helper.markRaw(resolvedEditorIntegration.EditorComponent);
22164
20887
  const V2Ruler = resolvedEditorIntegration.RulerComponent ? require__plugin_vue_export_helper.markRaw(resolvedEditorIntegration.RulerComponent) : null;
@@ -22207,7 +20930,6 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22207
20930
  const layers = require__plugin_vue_export_helper.ref(null);
22208
20931
  const rightSidebarRef = require__plugin_vue_export_helper.ref(null);
22209
20932
  const pdfViewerRef = require__plugin_vue_export_helper.ref(null);
22210
- const pendingReplayTrackedChangeSync = require__plugin_vue_export_helper.ref(false);
22211
20933
  const toolsMenuPosition = require__plugin_vue_export_helper.reactive({
22212
20934
  top: null,
22213
20935
  right: "-25px",
@@ -22269,21 +20991,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22269
20991
  });
22270
20992
  }
22271
20993
  });
22272
- const pdfConfig = proxy.$superdoc.config.modules?.pdf || {};
22273
- const flushPendingReplayTrackedChangeSync = () => {
22274
- if (!pendingReplayTrackedChangeSync.value) return;
22275
- pendingReplayTrackedChangeSync.value = false;
22276
- syncTrackedChangeComments({
22277
- superdoc: proxy.$superdoc,
22278
- editor: proxy.$superdoc?.activeEditor
22279
- });
22280
- };
22281
- const scheduleReplayTrackedChangeSync = () => {
22282
- pendingReplayTrackedChangeSync.value = true;
22283
- require__plugin_vue_export_helper.nextTick(() => {
22284
- flushPendingReplayTrackedChangeSync();
22285
- });
22286
- };
20994
+ const pdfConfig = superdoc.config.modules?.pdf || {};
22287
20995
  const handleDocumentReady = (documentId, container) => {
22288
20996
  const doc = getDocument(documentId);
22289
20997
  if (!doc || doc.loadScope && !doc.loadScope.finish()) return;
@@ -22386,7 +21094,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22386
21094
  if (typeof bindSessionShortcuts !== "function") return;
22387
21095
  const unbind = bindSessionShortcuts({
22388
21096
  routes: createV2SessionShortcutRoutes({
22389
- resolveToolbarElement: () => proxy.$superdoc?.toolbar?.toolbarContainer ?? null,
21097
+ resolveToolbarElement: () => (proxy.$superdoc?.toolbar)?.toolbarContainer ?? null,
22390
21098
  getDocumentApi: () => documentApi ?? null,
22391
21099
  ...firstPartyCommandMutation ? { runReferenceMutation: (memberPath, input) => firstPartyCommandMutation.run(memberPath, [input]) } : {},
22392
21100
  pageNumberCommand: {
@@ -22421,7 +21129,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22421
21129
  if (document && provider?.sendStateless) document.provider = null;
22422
21130
  const entry = v2Runtimes.get(documentId);
22423
21131
  if (!entry) return;
22424
- proxy.$superdoc.unregisterEditorRuntime(entry.runtimeId);
21132
+ proxy.$superdoc["unregisterEditorRuntime"](entry.runtimeId);
22425
21133
  v2Runtimes.delete(documentId);
22426
21134
  const hostRoot = subDocumentRoots.get(documentId);
22427
21135
  if (hostRoot) unmarkRuntimeRoot(hostRoot);
@@ -22441,7 +21149,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22441
21149
  host,
22442
21150
  getLegacyEditorProjection: () => facade,
22443
21151
  onUnregister: (id) => {
22444
- proxy.$superdoc.unregisterEditorRuntime(id);
21152
+ proxy.$superdoc["unregisterEditorRuntime"](id);
22445
21153
  const current = v2Runtimes.get(documentId);
22446
21154
  if (current && current.runtimeId === id) v2Runtimes.delete(documentId);
22447
21155
  const hostRoot = subDocumentRoots.get(documentId);
@@ -22450,12 +21158,12 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22450
21158
  });
22451
21159
  adapter.attachMountHandle(mount ?? null);
22452
21160
  markRuntimeRoot(root, runtimeId);
22453
- proxy.$superdoc.registerEditorRuntime(adapter.runtime);
21161
+ proxy.$superdoc["registerEditorRuntime"](adapter.runtime);
22454
21162
  v2Runtimes.set(documentId, {
22455
21163
  runtimeId,
22456
21164
  adapter
22457
21165
  });
22458
- proxy.$superdoc.setActiveRuntime(runtimeId, "v2-editor-ready");
21166
+ proxy.$superdoc["setActiveRuntime"](runtimeId, "v2-editor-ready");
22459
21167
  return true;
22460
21168
  };
22461
21169
  const v2ReviewWindowController = resolvedEditorIntegration.createReviewWindowController({ applyReviewWindow: (ctx, result) => commentsStore.applyReviewWindowFromV2?.({
@@ -22981,7 +21689,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22981
21689
  if (!isV2Mode.value) return;
22982
21690
  let handles = null;
22983
21691
  try {
22984
- handles = proxy.$superdoc?.activeEditor?.host?.getHandles?.() ?? null;
21692
+ handles = (proxy.$superdoc?.activeEditor)?.host?.getHandles?.() ?? null;
22985
21693
  } catch {
22986
21694
  handles = null;
22987
21695
  }
@@ -23060,7 +21768,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
23060
21768
  syncV2SelectionToolbarState();
23061
21769
  };
23062
21770
  const getActiveV2MountContainer = () => {
23063
- return v2GeometryRender.value?.mountContainer ?? proxy.$superdoc?.activeEditor?.mount?.container ?? null;
21771
+ return v2GeometryRender.value?.mountContainer ?? (proxy.$superdoc?.activeEditor)?.mount?.container ?? null;
23064
21772
  };
23065
21773
  const escapeCssIdent = (value) => {
23066
21774
  const raw = String(value);
@@ -23283,7 +21991,6 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
23283
21991
  v2PageMetricsSnapshot.value = null;
23284
21992
  const clearedDocumentId = payload?.documentId == null ? null : String(payload.documentId);
23285
21993
  clearV2MutationRejectionNotifications(clearedDocumentId);
23286
- commentsStore.cancelImportedTrackedChangeBootstrap?.(clearedDocumentId ?? void 0);
23287
21994
  if (clearedDocumentId) v2MountStagesByDocumentId.delete(clearedDocumentId);
23288
21995
  if (latestV2MountStage && (clearedDocumentId == null || latestV2MountStage.dataset?.superdocV2DocumentId === clearedDocumentId)) latestV2MountStage = null;
23289
21996
  v2ReviewWindowController.reset("render-cleared");
@@ -23299,7 +22006,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
23299
22006
  ...event,
23300
22007
  documentId: document?.id ?? null
23301
22008
  }));
23302
- if (event.type === "mutation:committed" && event.origin === "extension") return;
22009
+ if (event.type === "mutation:committed" && event.dryRun) return;
23303
22010
  const documentId = document?.id ?? null;
23304
22011
  if (event.type === "history:changed" && event.state) {
23305
22012
  proxy.$superdoc.emit("history-change", {
@@ -23363,7 +22070,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
23363
22070
  if (event.type === "mutation:committed") {
23364
22071
  const bulkDecisionEvent = toV2BulkDecisionEvent(documentId, event.trackedChangeBulkDecision);
23365
22072
  if (bulkDecisionEvent) proxy.$superdoc.emit("tracked-changes:bulk-decision", bulkDecisionEvent);
23366
- emitV2EditorUpdate();
22073
+ if (require_create_super_doc_ui.mutationCommittedEventChangedDocument(event)) emitV2EditorUpdate();
23367
22074
  }
23368
22075
  if (event.type !== "mutation:committed") return;
23369
22076
  if (event.origin === "history") v2ReviewWindowController.refreshCommittedWindow(`history-${event.direction}`);
@@ -23463,6 +22170,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
23463
22170
  case "collaboration-room-corrupt": return "SuperDoc v2 found a structurally invalid collaboration room. No changes were made.";
23464
22171
  case "collaboration-v2-room-missing": return "SuperDoc v2 could not find a committed v2 collaboration room. No changes were made. Use roomMode: \"create\" only when creating a new room.";
23465
22172
  case "collaboration-v2-room-already-exists": return "SuperDoc v2 was asked to create a collaboration room that already exists. Use roomMode: \"join\" to open it.";
22173
+ case "collaboration-session-invalidated": return "This collaboration session is no longer current. Please reopen the shared document with roomMode: \"join\".";
23466
22174
  case "collaboration-v2-room-initializing": return "The SuperDoc v2 collaboration room has not completed initialization. This open attempt did not modify it.";
23467
22175
  case "collaboration-v2-room-bootstrap-stalled": return "The SuperDoc v2 collaboration room bootstrap appears stalled. This open attempt did not modify it. Preserve the room data if a create retry cannot recover it.";
23468
22176
  case "collaboration-open-intent-invalid": return "SuperDoc v2 received an invalid collaboration room mode. No provider was connected.";
@@ -23473,10 +22181,17 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
23473
22181
  const normalizeV2EditorFailureDetail = (detail) => typeof detail === "string" && detail.trim().length > 0 ? detail.trim() : null;
23474
22182
  const onV2EditorFailed = (payload) => {
23475
22183
  documents.value.find((doc) => doc.id === payload?.documentId)?.loadScope?.finish();
23476
- clearActiveV2EditorFacade(payload?.documentId ?? null);
23477
22184
  const reason = typeof payload?.reason === "string" && payload.reason.length > 0 ? payload.reason : "open-failed";
23478
22185
  const detail = normalizeV2EditorFailureDetail(payload?.detail);
23479
22186
  const documentId = typeof payload?.documentId === "string" && payload.documentId.length > 0 ? payload.documentId : null;
22187
+ const retiredDocument = reason === "collaboration-session-invalidated" && documentId ? getDocument(documentId) : null;
22188
+ const retiredExporter = retiredDocument?.getEditor?.();
22189
+ clearActiveV2EditorFacade(payload?.documentId ?? null);
22190
+ if (retiredExporter?.editorVersion === 2 && typeof retiredExporter.exportDocx === "function") {
22191
+ retiredDocument.isReady = false;
22192
+ if (v2Runtimes.has(documentId)) clearV2RuntimeRegistration(documentId);
22193
+ retiredDocument.setEditor?.(retiredExporter);
22194
+ }
23480
22195
  if (reason === "worker-transport-failed") {
23481
22196
  proxy.$superdoc.emit("exception", {
23482
22197
  error: /* @__PURE__ */ new Error("Worker transport failed."),
@@ -23503,7 +22218,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
23503
22218
  ...workerFailure ? { workerFailure } : {},
23504
22219
  reason
23505
22220
  };
23506
- if (reason === "collaboration-v1-config-unsupported" || reason === "collaboration-room-format-unsupported" || reason === "collaboration-room-format-conflict" || reason === "collaboration-room-corrupt" || reason === "collaboration-v2-room-missing" || reason === "collaboration-v2-room-already-exists" || reason === "collaboration-v2-room-initializing" || reason === "collaboration-v2-room-bootstrap-stalled" || reason === "collaboration-open-intent-invalid" || reason === "collaboration-config-invalid") console.warn(`[SuperDoc] ${message}`, logContext);
22221
+ if (reason === "collaboration-v1-config-unsupported" || reason === "collaboration-room-format-unsupported" || reason === "collaboration-room-format-conflict" || reason === "collaboration-room-corrupt" || reason === "collaboration-v2-room-missing" || reason === "collaboration-v2-room-already-exists" || reason === "collaboration-session-invalidated" || reason === "collaboration-v2-room-initializing" || reason === "collaboration-v2-room-bootstrap-stalled" || reason === "collaboration-open-intent-invalid" || reason === "collaboration-config-invalid") console.warn(`[SuperDoc] ${message}`, logContext);
23507
22222
  else console.error(`[SuperDoc] ${message}`, logContext);
23508
22223
  proxy.$superdoc.emit("exception", collaborationException && reason !== "collaboration-config-invalid" ? collaborationException : {
23509
22224
  error: new Error(message),
@@ -23564,7 +22279,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
23564
22279
  }
23565
22280
  };
23566
22281
  const activateRuntimeFromEvent = (event, reason) => {
23567
- proxy.$superdoc?.activateRuntimeFromEventTarget?.(event.target, reason);
22282
+ proxy.$superdoc?.["activateRuntimeFromEventTarget"]?.(event.target, reason);
23568
22283
  };
23569
22284
  const handleRuntimeFocusIn = (event) => activateRuntimeFromEvent(event, "focusin");
23570
22285
  const handleRuntimePointerDown = (event) => activateRuntimeFromEvent(event, "pointerdown");
@@ -23682,7 +22397,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
23682
22397
  commentHighlights: proxy.$superdoc.uiConfig.comments.highlights,
23683
22398
  resolveTrackedChangeColor: composeAuthorColorResolver(proxy.$superdoc.config.modules?.trackChanges?.authorColors)
23684
22399
  } : void 0,
23685
- permissionResolver: createTrackedChangePermissionResolver(proxy.$superdoc)
22400
+ permissionResolver: require_create_super_doc_ui.createTrackedChangePermissionResolver(proxy.$superdoc)
23686
22401
  };
23687
22402
  };
23688
22403
  const REPLAY_MUTABLE_COMMENT_FIELDS = /* @__PURE__ */ new Set([
@@ -23809,7 +22524,6 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
23809
22524
  existingComment: null
23810
22525
  };
23811
22526
  };
23812
- if (type === "replayCompleted") scheduleReplayTrackedChangeSync();
23813
22527
  if (COMMENT_EVENTS?.ADD && type === COMMENT_EVENTS.ADD && commentPayload) {
23814
22528
  commentPayload = normalizeReplayCommentModelPayload(commentPayload);
23815
22529
  const currentUser = proxy.$superdoc?.user;
@@ -23973,8 +22687,8 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
23973
22687
  if (!isCommentsEnabled.value) return false;
23974
22688
  return !getConfig.value?.readOnly && selectionPosition.value;
23975
22689
  });
23976
- require__plugin_vue_export_helper.watch(showCommentsSidebar, (value) => {
23977
- proxy.$superdoc.broadcastSidebarToggle(value);
22690
+ require__plugin_vue_export_helper.watch(() => Boolean(showCommentsSidebar.value), (isOpened) => {
22691
+ proxy.$superdoc.broadcastSidebarToggle(isOpened);
23978
22692
  });
23979
22693
  useViewportFit({
23980
22694
  getSuperdoc: () => proxy.$superdoc,
@@ -24055,7 +22769,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
24055
22769
  const activeElement = document.activeElement;
24056
22770
  if (!(activeElement instanceof Node)) return false;
24057
22771
  if (root?.contains(activeElement)) return true;
24058
- const activeEditorDom = proxy.$superdoc?.activeEditor?.view?.dom;
22772
+ const activeEditorDom = (proxy.$superdoc?.activeEditor?.view)?.dom;
24059
22773
  return activeEditorDom instanceof Node && (activeElement === activeEditorDom || activeEditorDom.contains?.(activeElement));
24060
22774
  }
24061
22775
  /**
@@ -24118,7 +22832,6 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
24118
22832
  handleFormattingMarksShortcut(e);
24119
22833
  }
24120
22834
  require__plugin_vue_export_helper.onBeforeUnmount(() => {
24121
- commentsStore.cancelImportedTrackedChangeBootstrap?.();
24122
22835
  passwordPrompt.destroy();
24123
22836
  findReplace.destroy();
24124
22837
  linkPopover.destroy();
@@ -24249,16 +22962,18 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
24249
22962
  resetSelection();
24250
22963
  selectionLayer.value.style.pointerEvents = "auto";
24251
22964
  require__plugin_vue_export_helper.nextTick(() => {
22965
+ const layer = selectionLayer.value;
22966
+ if (!layer) return;
24252
22967
  isDragging.value = true;
24253
- selectionLayer.value.style.pointerEvents = "none";
22968
+ layer.style.pointerEvents = "none";
24254
22969
  const pageNumber = getPdfPageNumberFromEvent(e);
24255
- selectionLayer.value.style.pointerEvents = "auto";
22970
+ layer.style.pointerEvents = "auto";
24256
22971
  if (!pageNumber) {
24257
22972
  isDragging.value = false;
24258
- selectionLayer.value.style.pointerEvents = "none";
22973
+ layer.style.pointerEvents = "none";
24259
22974
  return;
24260
22975
  }
24261
- const layerBounds = selectionLayer.value.getBoundingClientRect();
22976
+ const layerBounds = layer.getBoundingClientRect();
24262
22977
  const zoom = activeZoom.value / 100;
24263
22978
  const x = (e.clientX - layerBounds.left) / zoom;
24264
22979
  const y = (e.clientY - layerBounds.top) / zoom;
@@ -24268,7 +22983,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
24268
22983
  page: pageNumber,
24269
22984
  source: "pdf"
24270
22985
  });
24271
- selectionLayer.value.addEventListener("mousemove", handleDragMove);
22986
+ layer.addEventListener("mousemove", handleDragMove);
24272
22987
  });
24273
22988
  };
24274
22989
  const handleDragMove = (e) => {
@@ -24343,7 +23058,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
24343
23058
  if (typeof container === "string") return (typeof document !== "undefined" ? document : globalThis.document)?.querySelector(container) ?? null;
24344
23059
  return typeof HTMLElement !== "undefined" && container instanceof HTMLElement ? container : null;
24345
23060
  };
24346
- const getActiveV2DocumentId = () => proxy.$superdoc?.activeEditor?.documentId ?? proxy.$superdoc?.activeEditor?.options?.documentId ?? null;
23061
+ const getActiveV2DocumentId = () => (proxy.$superdoc?.activeEditor)?.documentId ?? proxy.$superdoc?.activeEditor?.options?.documentId ?? null;
24347
23062
  const resolveV2RulerAlignmentContainer = () => {
24348
23063
  if (resolvedRulerContainer.value) return resolveV2RulerContainer();
24349
23064
  const activeDocumentId = getActiveV2DocumentId();
@@ -24734,7 +23449,10 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
24734
23449
  ], 46, _hoisted_1$17);
24735
23450
  };
24736
23451
  }
24737
- }, [["__scopeId", "data-v-f2db957f"]]);
23452
+ });
23453
+ //#endregion
23454
+ //#region src/SuperDoc.vue
23455
+ var SuperDoc_default = /* @__PURE__ */ require__plugin_vue_export_helper._plugin_vue_export_helper_default(SuperDoc_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-da95e5c5"]]);
24738
23456
  //#endregion
24739
23457
  //#region src/core/create-app.js
24740
23458
  var PINIA_DEVTOOLS_SETUP_EVENT = "devtools-plugin:setup";
@@ -24936,29 +23654,28 @@ var setPiniaDevtoolsSuppressedForApp = (app, isSuppressed) => {
24936
23654
  * @property {import('pinia').Pinia} pinia The Pinia store instance attached to `app`
24937
23655
  * @property {ReturnType<typeof useSuperdocStore>} superdocStore The SuperDoc Pinia store
24938
23656
  * @property {ReturnType<typeof useCommentsStore>} commentsStore The Comments Pinia store
24939
- * @property {ReturnType<typeof useHighContrastMode>} highContrastModeStore The high-contrast mode composable refs (`isHighContrastMode`, `setHighContrastMode`). Named `*Store` for historical reasons; this is a plain Vue composable, not a Pinia store.
24940
23657
  */
24941
23658
  /**
24942
23659
  * Generate the superdoc vue app
24943
23660
  *
24944
- * @param {Object} [options]
23661
+ * @param {Object} options
24945
23662
  * @param {boolean} [options.disablePiniaDevtools=false] Disable Pinia devtools registration for this app instance
24946
- * @returns {SuperdocVueAppRefs} An object containing the vue app, the pinia reference, the superdoc/comments Pinia stores, and the high-contrast mode composable
23663
+ * @param {import('../composables/use-high-contrast-mode').HighContrastMode} options.highContrastMode The owning SuperDoc's high-contrast state, provided to the app
23664
+ * @returns {SuperdocVueAppRefs} An object containing the vue app, the pinia reference, and the superdoc/comments Pinia stores
24947
23665
  */
24948
- var createSuperdocVueApp = ({ disablePiniaDevtools = false } = {}) => {
23666
+ var createSuperdocVueApp = ({ disablePiniaDevtools = false, highContrastMode }) => {
24949
23667
  const app = require__plugin_vue_export_helper.createApp(SuperDoc_default);
24950
23668
  const pinia = createPinia();
24951
23669
  const cleanupPiniaDevtoolsSuppression = setPiniaDevtoolsSuppressedForApp(app, disablePiniaDevtools);
24952
23670
  let superdocStore;
24953
23671
  let commentsStore;
24954
- let highContrastModeStore;
24955
23672
  try {
24956
23673
  app.use(pinia);
24957
23674
  if (disablePiniaDevtools) purgeDevtoolsPluginQueueForApp(app);
24958
23675
  app.directive("click-outside", v_click_outside_default);
24959
23676
  superdocStore = useSuperdocStore();
24960
23677
  commentsStore = useCommentsStore();
24961
- highContrastModeStore = useHighContrastMode();
23678
+ app.provide(HIGH_CONTRAST_MODE_KEY, highContrastMode);
24962
23679
  } catch (error) {
24963
23680
  cleanupPiniaDevtoolsSuppression();
24964
23681
  throw error;
@@ -24974,8 +23691,7 @@ var createSuperdocVueApp = ({ disablePiniaDevtools = false } = {}) => {
24974
23691
  app,
24975
23692
  pinia,
24976
23693
  superdocStore,
24977
- commentsStore,
24978
- highContrastModeStore
23694
+ commentsStore
24979
23695
  };
24980
23696
  };
24981
23697
  //#endregion
@@ -38853,6 +37569,69 @@ var EditorRuntimeRegistry = class {
38853
37569
  } catch {}
38854
37570
  }
38855
37571
  };
37572
+ //#endregion
37573
+ //#region src/internal/toolbar/compatibility-catalog.ts
37574
+ /**
37575
+ * Internal built-in toolbar compatibility catalog (V2 toolbar parity, phase 1).
37576
+ *
37577
+ * This module is the SINGLE place the legacy built-in toolbar item names (the
37578
+ * ids v1 toolbars, `modules.toolbar.groups`, and the docs use) are mapped onto
37579
+ * the V2 world. Later renderers, the toolbar authority, and any proof helper
37580
+ * consume this catalog instead of rediscovering the mapping ad hoc.
37581
+ *
37582
+ * It does NOT re-implement command routing. The V2 command controller catalog
37583
+ * in `../../public/ui/commands.ts` stays the single source of truth for how a
37584
+ * command is backed; every `controller-routed` entry here points at a canonical
37585
+ * command id that must exist there (enforced by `assertCatalogAlignedWithController`).
37586
+ *
37587
+ * Every documented built-in item is classified into exactly one disposition:
37588
+ *
37589
+ * - `controller-routed` → driven by the V2 command controller (a routed
37590
+ * command id in `COMMAND_CATALOG`).
37591
+ * - `host-routed` → driven by a public `SuperDoc`-instance method the built-in
37592
+ * shell owns directly (e.g. formatting-marks toggle), not by the controller
37593
+ * command set.
37594
+ * - `shell-owned` → pure rendered-shell chrome/config the built-in toolbar
37595
+ * owns (custom buttons, layout groups). Has no command and no document
37596
+ * effect of its own.
37597
+ * - `unsupported` → documented built-in item that is explicitly out of V2
37598
+ * functional parity (a signed product decision). The controller command (if
37599
+ * any) fails closed with `command-unsupported`; the docs do not call it
37600
+ * supported.
37601
+ * - `unresolved` → documented today but with no identified public V2 surface
37602
+ * yet. Recorded explicitly so later phases close it deliberately rather than
37603
+ * pretending it already works.
37604
+ *
37605
+ * Nothing here reintroduces a public `headless-toolbar*` export; the catalog is
37606
+ * internal to the `superdoc` package.
37607
+ */
37608
+ var TABLE_ACTION_COMMAND_IDS_BY_OPTION = {
37609
+ addRowBefore: "table-add-row-before",
37610
+ addRowAfter: "table-add-row-after",
37611
+ deleteRow: "table-delete-row",
37612
+ addColumnBefore: "table-add-column-before",
37613
+ addColumnAfter: "table-add-column-after",
37614
+ deleteColumn: "table-delete-column",
37615
+ deleteTable: "table-delete",
37616
+ deleteCellAndTableBorders: "table-remove-borders",
37617
+ mergeCells: "table-merge-cells",
37618
+ splitCell: "table-split-cell",
37619
+ fixTables: "table-fix"
37620
+ };
37621
+ var TABLE_ACTION_COMMAND_IDS = Object.values(TABLE_ACTION_COMMAND_IDS_BY_OPTION);
37622
+ function tableActionCommandId(option) {
37623
+ return TABLE_ACTION_COMMAND_IDS_BY_OPTION[option];
37624
+ }
37625
+ /**
37626
+ * Member controller command ids the legacy `tableActions` dropdown fans out
37627
+ * into. These are real V2 `tables.*` operations now routed through the shared
37628
+ * table-context facade (`ui.tables` / `host.getTableContext()`): each is a
37629
+ * `routed` controller command that enables when a table context is resolvable
37630
+ * and fails closed with `table-context-unavailable` otherwise. The dropdown
37631
+ * itself is shell chrome; its members are controller-routed.
37632
+ */
37633
+ var ROUTED_TABLE_ACTION_COMMAND_IDS = TABLE_ACTION_COMMAND_IDS.filter((commandId) => require_create_super_doc_ui.getCommandDescriptor(commandId)?.disposition === "routed");
37634
+ var UNCATALOGED_ITEM_COMMAND_IDS = { tableOfContents: "table-of-contents-insert" };
38856
37635
  /**
38857
37636
  * The built-in toolbar compatibility catalog. Order groups items the way the
38858
37637
  * docs present them; it is documentation-only.
@@ -39024,18 +37803,7 @@ var BUILT_IN_TOOLBAR_CATALOG = [
39024
37803
  instanceMethod: null,
39025
37804
  disposition: "shell-owned",
39026
37805
  group: "center",
39027
- memberCommandIds: [
39028
- "table-add-row-before",
39029
- "table-add-row-after",
39030
- "table-delete-row",
39031
- "table-add-column-before",
39032
- "table-add-column-after",
39033
- "table-delete-column",
39034
- "table-delete",
39035
- "table-merge-cells",
39036
- "table-split-cell",
39037
- "table-remove-borders"
39038
- ],
37806
+ memberCommandIds: ROUTED_TABLE_ACTION_COMMAND_IDS,
39039
37807
  note: "table editing dropdown is shell chrome; its member commands are controller-routed through the shared table-context facade (ui.tables / host.getTableContext()) and fail closed with table-context-unavailable when the caret is not in a table"
39040
37808
  },
39041
37809
  {
@@ -39135,6 +37903,9 @@ function resolveToolbarCommandId(name) {
39135
37903
  const entry = CATALOG_BY_NAME.get(name);
39136
37904
  return entry?.disposition === "controller-routed" ? entry.commandId : null;
39137
37905
  }
37906
+ function resolveBuiltInItemCommandId(name) {
37907
+ return resolveToolbarCommandId(name) ?? UNCATALOGED_ITEM_COMMAND_IDS[name] ?? null;
37908
+ }
39138
37909
  //#endregion
39139
37910
  //#region src/internal/toolbar/built-in/helpers.js
39140
37911
  var sanitizeNumber = (value, defaultNumber) => {
@@ -39178,10 +37949,10 @@ var throttle = (func, wait, options) => {
39178
37949
  return throttled;
39179
37950
  };
39180
37951
  //#endregion
39181
- //#region src/internal/toolbar/built-in/ToolbarButtonIcon.vue
37952
+ //#region src/internal/toolbar/built-in/ToolbarButtonIcon.vue?vue&type=script&setup=true&lang.ts
39182
37953
  var _hoisted_1$16 = { class: "sd-toolbar-icon" };
39183
37954
  var _hoisted_2$12 = ["innerHTML"];
39184
- var _sfc_main$20 = {
37955
+ var ToolbarButtonIcon_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ require__plugin_vue_export_helper.defineComponent({
39185
37956
  __name: "ToolbarButtonIcon",
39186
37957
  props: {
39187
37958
  name: {
@@ -39217,10 +37988,12 @@ var _sfc_main$20 = {
39217
37988
  }, null, 4)) : require__plugin_vue_export_helper.createCommentVNode("", true)]);
39218
37989
  };
39219
37990
  }
39220
- };
39221
- var ToolbarButtonIcon_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$20, [["__scopeId", "data-v-65ecd5b1"]]);
37991
+ });
39222
37992
  //#endregion
39223
- //#region src/internal/toolbar/built-in/ToolbarButton.vue
37993
+ //#region src/internal/toolbar/built-in/ToolbarButtonIcon.vue
37994
+ var ToolbarButtonIcon_default = /* @__PURE__ */ require__plugin_vue_export_helper._plugin_vue_export_helper_default(ToolbarButtonIcon_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-e72eee56"]]);
37995
+ //#endregion
37996
+ //#region src/internal/toolbar/built-in/ToolbarButton.vue?vue&type=script&setup=true&lang.ts
39224
37997
  var _hoisted_1$15 = [
39225
37998
  "role",
39226
37999
  "aria-label",
@@ -39247,7 +38020,7 @@ var _hoisted_11$1 = {
39247
38020
  "aria-live": "polite",
39248
38021
  class: "sd-visually-hidden"
39249
38022
  };
39250
- var _sfc_main$19 = {
38023
+ var ToolbarButton_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ require__plugin_vue_export_helper.defineComponent({
39251
38024
  __name: "ToolbarButton",
39252
38025
  props: {
39253
38026
  iconColor: {
@@ -39290,9 +38063,9 @@ var _sfc_main$19 = {
39290
38063
  ],
39291
38064
  setup(__props, { emit: __emit }) {
39292
38065
  const emit = __emit;
39293
- const { proxy } = require__plugin_vue_export_helper.getCurrentInstance();
38066
+ const proxy = require__plugin_vue_export_helper.getCurrentInstance()?.proxy;
39294
38067
  const props = __props;
39295
- const { name, active, icon, label, hideLabel, iconColor, hasCaret, splitButton, disabled, expand, inlineTextInputVisible, hasInlineTextInput, minWidth, style, attributes } = props.toolbarItem;
38068
+ const { name, active, icon, label, hideLabel, iconColor, hasCaret, splitButton, disabled, expand, inlineTextInputVisible, hasInlineTextInput, style, attributes } = props.toolbarItem;
39296
38069
  const isSplit = require__plugin_vue_export_helper.computed(() => Boolean(splitButton?.value) && Boolean(hasCaret?.value));
39297
38070
  const itemName = require__plugin_vue_export_helper.computed(() => name?.value ?? "");
39298
38071
  const inlineTextInput = require__plugin_vue_export_helper.ref("");
@@ -39404,17 +38177,13 @@ var _sfc_main$19 = {
39404
38177
  }
39405
38178
  if (itemName.value === "fontSize") require__plugin_vue_export_helper.nextTick(focusEditorSurface);
39406
38179
  };
39407
- const getStyle = require__plugin_vue_export_helper.computed(() => {
39408
- if (style.value) return style.value;
39409
- return { minWidth: props.minWidth };
39410
- });
39411
38180
  const caretIcon = require__plugin_vue_export_helper.computed(() => {
39412
38181
  return expand?.value ? toolbarIcons.dropdownCaretUp : toolbarIcons.dropdownCaretDown;
39413
38182
  });
39414
38183
  return (_ctx, _cache) => {
39415
38184
  return require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", {
39416
38185
  class: require__plugin_vue_export_helper.normalizeClass(["sd-toolbar-item", require__plugin_vue_export_helper.unref(attributes).className]),
39417
- style: require__plugin_vue_export_helper.normalizeStyle(getStyle.value),
38186
+ style: require__plugin_vue_export_helper.normalizeStyle(require__plugin_vue_export_helper.unref(style)),
39418
38187
  role: __props.isOverflowItem ? "menuitem" : "button",
39419
38188
  "aria-label": require__plugin_vue_export_helper.unref(attributes).ariaLabel,
39420
38189
  "aria-disabled": require__plugin_vue_export_helper.unref(disabled) ? "true" : void 0,
@@ -39518,8 +38287,10 @@ var _sfc_main$19 = {
39518
38287
  ], 10, _hoisted_2$11)], 46, _hoisted_1$15);
39519
38288
  };
39520
38289
  }
39521
- };
39522
- var ToolbarButton_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$19, [["__scopeId", "data-v-96796456"]]);
38290
+ });
38291
+ //#endregion
38292
+ //#region src/internal/toolbar/built-in/ToolbarButton.vue
38293
+ var ToolbarButton_default = /* @__PURE__ */ require__plugin_vue_export_helper._plugin_vue_export_helper_default(ToolbarButton_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-40889353"]]);
39523
38294
  //#endregion
39524
38295
  //#region src/internal/toolbar/built-in/ToolbarSeparator.vue
39525
38296
  var _hoisted_1$14 = {
@@ -39527,7 +38298,7 @@ var _hoisted_1$14 = {
39527
38298
  role: "separator",
39528
38299
  "aria-label": "Toolbar separator"
39529
38300
  };
39530
- var _sfc_main$18 = {
38301
+ var _sfc_main$13 = {
39531
38302
  __name: "ToolbarSeparator",
39532
38303
  props: { active: {
39533
38304
  type: Boolean,
@@ -39548,9 +38319,9 @@ var _sfc_main$18 = {
39548
38319
  };
39549
38320
  }
39550
38321
  };
39551
- var ToolbarSeparator_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$18, [["__scopeId", "data-v-cb82253a"]]);
38322
+ var ToolbarSeparator_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$13, [["__scopeId", "data-v-cb82253a"]]);
39552
38323
  //#endregion
39553
- //#region src/internal/toolbar/built-in/ToolbarDropdown.vue
38324
+ //#region src/internal/toolbar/built-in/ToolbarDropdown.vue?vue&type=script&setup=true&lang.ts
39554
38325
  var _hoisted_1$13 = { class: "toolbar-dropdown" };
39555
38326
  var _hoisted_2$10 = ["data-superdoc-ui-owner"];
39556
38327
  var _hoisted_3$9 = ["onClick"];
@@ -39560,7 +38331,7 @@ var _hoisted_4$7 = {
39560
38331
  };
39561
38332
  var _hoisted_5$5 = { class: "toolbar-dropdown-option__label" };
39562
38333
  var TRIGGER_FOCUS_SELECTOR = "button, [href], input, select, textarea, [role=\"button\"], [tabindex]:not([tabindex=\"-1\"])";
39563
- var _sfc_main$17 = {
38334
+ var ToolbarDropdown_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ require__plugin_vue_export_helper.defineComponent({
39564
38335
  __name: "ToolbarDropdown",
39565
38336
  props: {
39566
38337
  options: {
@@ -39717,7 +38488,7 @@ var _sfc_main$17 = {
39717
38488
  if (!value) return false;
39718
38489
  if (typeof value === "string") return value.split(/\s+/).includes("sd-selected");
39719
38490
  if (Array.isArray(value)) return value.some(classHasSelected);
39720
- if (typeof value === "object") return Boolean(value["sd-selected"]);
38491
+ if (typeof value === "object") return "sd-selected" in value && Boolean(value["sd-selected"]);
39721
38492
  return false;
39722
38493
  };
39723
38494
  const isOptionSelected = (option) => {
@@ -39949,8 +38720,10 @@ var _sfc_main$17 = {
39949
38720
  })], 8, ["to"]))]);
39950
38721
  };
39951
38722
  }
39952
- };
39953
- var ToolbarDropdown_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$17, [["__scopeId", "data-v-e6f71d76"]]);
38723
+ });
38724
+ //#endregion
38725
+ //#region src/internal/toolbar/built-in/ToolbarDropdown.vue
38726
+ var ToolbarDropdown_default = /* @__PURE__ */ require__plugin_vue_export_helper._plugin_vue_export_helper_default(ToolbarDropdown_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-50758732"]]);
39954
38727
  //#endregion
39955
38728
  //#region src/internal/toolbar/built-in/toolbar-focus-helpers.js
39956
38729
  var preventEditorFocusTransfer = (event) => {
@@ -39974,7 +38747,7 @@ var refocusEditorSurface = (superToolbar, preferredEditor = null) => {
39974
38747
  };
39975
38748
  //#endregion
39976
38749
  //#region src/internal/toolbar/built-in/OverflowMenu.vue
39977
- var _sfc_main$16 = {
38750
+ var _sfc_main$12 = {
39978
38751
  __name: "OverflowMenu",
39979
38752
  props: {
39980
38753
  toolbarItem: {
@@ -40071,7 +38844,7 @@ var _sfc_main$16 = {
40071
38844
  };
40072
38845
  }
40073
38846
  };
40074
- var OverflowMenu_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$16, [["__scopeId", "data-v-1227fcf9"]]);
38847
+ var OverflowMenu_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$12, [["__scopeId", "data-v-1227fcf9"]]);
40075
38848
  //#endregion
40076
38849
  //#region src/internal/toolbar/built-in/font-typeahead.js
40077
38850
  /**
@@ -40174,7 +38947,7 @@ var normalizeCustomFontSize = (value) => {
40174
38947
  return String(Math.min(halfPoint, MAX_FONT_SIZE));
40175
38948
  };
40176
38949
  //#endregion
40177
- //#region src/internal/toolbar/built-in/ToolbarComboBox.vue
38950
+ //#region src/internal/toolbar/built-in/ToolbarComboBox.vue?vue&type=script&setup=true&lang.ts
40178
38951
  var _hoisted_1$12 = ["data-item"];
40179
38952
  var _hoisted_2$9 = [
40180
38953
  "id",
@@ -40209,7 +38982,7 @@ var _hoisted_8$1 = {
40209
38982
  class: "sd-button-label sd-font-combobox__legacy-label",
40210
38983
  "aria-hidden": "true"
40211
38984
  };
40212
- var _sfc_main$15 = {
38985
+ var ToolbarComboBox_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ require__plugin_vue_export_helper.defineComponent({
40213
38986
  __name: "ToolbarComboBox",
40214
38987
  props: {
40215
38988
  item: {
@@ -40695,11 +39468,13 @@ var _sfc_main$15 = {
40695
39468
  ], 14, _hoisted_1$12);
40696
39469
  };
40697
39470
  }
40698
- };
40699
- var ToolbarComboBox_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$15, [["__scopeId", "data-v-eb442535"]]);
39471
+ });
39472
+ //#endregion
39473
+ //#region src/internal/toolbar/built-in/ToolbarComboBox.vue
39474
+ var ToolbarComboBox_default = /* @__PURE__ */ require__plugin_vue_export_helper._plugin_vue_export_helper_default(ToolbarComboBox_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-e9143b7e"]]);
40700
39475
  //#endregion
40701
39476
  //#region src/internal/toolbar/built-in/FontFamilyCombobox.vue
40702
- var _sfc_main$14 = {
39477
+ var _sfc_main$11 = {
40703
39478
  __name: "FontFamilyCombobox",
40704
39479
  props: {
40705
39480
  item: {
@@ -40740,7 +39515,7 @@ var _sfc_main$14 = {
40740
39515
  };
40741
39516
  //#endregion
40742
39517
  //#region src/internal/toolbar/built-in/FontSizeCombobox.vue
40743
- var _sfc_main$13 = {
39518
+ var _sfc_main$10 = {
40744
39519
  __name: "FontSizeCombobox",
40745
39520
  props: {
40746
39521
  item: {
@@ -40780,9 +39555,10 @@ var _sfc_main$13 = {
40780
39555
  }
40781
39556
  };
40782
39557
  //#endregion
40783
- //#region src/internal/toolbar/built-in/SdTooltip.vue
39558
+ //#region src/internal/toolbar/built-in/SdTooltip.vue?vue&type=script&setup=true&lang.ts
40784
39559
  var AUTO_HIDE_DELAY = 2500;
40785
- var _sfc_main$12 = /*@__PURE__*/ Object.assign({ inheritAttrs: false }, {
39560
+ var SdTooltip_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ require__plugin_vue_export_helper.defineComponent({
39561
+ inheritAttrs: false,
40786
39562
  __name: "SdTooltip",
40787
39563
  props: {
40788
39564
  trigger: {
@@ -40997,7 +39773,9 @@ var _sfc_main$12 = /*@__PURE__*/ Object.assign({ inheritAttrs: false }, {
40997
39773
  };
40998
39774
  }
40999
39775
  });
41000
- var SdTooltip_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$12, [["__scopeId", "data-v-71c6de4c"]]);
39776
+ //#endregion
39777
+ //#region src/internal/toolbar/built-in/SdTooltip.vue
39778
+ var SdTooltip_default = /* @__PURE__ */ require__plugin_vue_export_helper._plugin_vue_export_helper_default(SdTooltip_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-dfd6f1d1"]]);
41001
39779
  //#endregion
41002
39780
  //#region src/internal/toolbar/built-in/ButtonGroup.vue
41003
39781
  var _hoisted_1$11 = [
@@ -41010,7 +39788,7 @@ var _hoisted_3$7 = { key: 0 };
41010
39788
  var _hoisted_4$5 = { key: 0 };
41011
39789
  var _hoisted_5$3 = { key: 0 };
41012
39790
  var _hoisted_6$2 = { key: 0 };
41013
- var _sfc_main$11 = {
39791
+ var _sfc_main$9 = {
41014
39792
  __name: "ButtonGroup",
41015
39793
  props: {
41016
39794
  toolbarItems: {
@@ -41385,7 +40163,7 @@ var _sfc_main$11 = {
41385
40163
  disabled: !item.tooltip?.value,
41386
40164
  "content-style": { fontFamily: props.uiFontFamily }
41387
40165
  }, {
41388
- trigger: require__plugin_vue_export_helper.withCtx(() => [require__plugin_vue_export_helper.createVNode(_sfc_main$14, {
40166
+ trigger: require__plugin_vue_export_helper.withCtx(() => [require__plugin_vue_export_helper.createVNode(_sfc_main$11, {
41389
40167
  item,
41390
40168
  "ui-font-family": props.uiFontFamily,
41391
40169
  class: "sd-toolbar-button sd-editor-toolbar-dropdown",
@@ -41402,7 +40180,7 @@ var _sfc_main$11 = {
41402
40180
  disabled: !item.tooltip?.value,
41403
40181
  "content-style": { fontFamily: props.uiFontFamily }
41404
40182
  }, {
41405
- trigger: require__plugin_vue_export_helper.withCtx(() => [require__plugin_vue_export_helper.createVNode(_sfc_main$13, {
40183
+ trigger: require__plugin_vue_export_helper.withCtx(() => [require__plugin_vue_export_helper.createVNode(_sfc_main$10, {
41406
40184
  item,
41407
40185
  "ui-font-family": props.uiFontFamily,
41408
40186
  class: "sd-toolbar-button sd-editor-toolbar-dropdown",
@@ -41501,7 +40279,7 @@ var _sfc_main$11 = {
41501
40279
  };
41502
40280
  }
41503
40281
  };
41504
- var ButtonGroup_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$11, [["__scopeId", "data-v-fb216897"]]);
40282
+ var ButtonGroup_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$9, [["__scopeId", "data-v-fb216897"]]);
41505
40283
  var TOOLBAR_FONTS = [
41506
40284
  ["Arial", "sans-serif"],
41507
40285
  ["Arial Black", "sans-serif"],
@@ -41633,54 +40411,6 @@ var RESPONSIVE_BREAKPOINTS = {
41633
40411
  lg: 1280,
41634
40412
  xl: 1410
41635
40413
  };
41636
- var HEADLESS_ITEM_MAP = {
41637
- undo: "undo",
41638
- redo: "redo",
41639
- bold: "bold",
41640
- italic: "italic",
41641
- underline: "underline",
41642
- strike: "strikethrough",
41643
- acceptTrackedChangeBySelection: "track-changes-accept-selection",
41644
- rejectTrackedChangeOnSelection: "track-changes-reject-selection",
41645
- ruler: "ruler",
41646
- formattingMarks: "formatting-marks",
41647
- zoom: "zoom",
41648
- measurementUnit: "measurement-unit",
41649
- documentMode: "document-mode",
41650
- link: "link",
41651
- fontFamily: "font-family",
41652
- fontSize: "font-size",
41653
- list: "bullet-list",
41654
- numberedlist: "numbered-list",
41655
- table: "table-insert",
41656
- image: "image",
41657
- tableOfContents: "table-of-contents-insert",
41658
- color: "text-color",
41659
- highlight: "highlight-color",
41660
- textAlign: "text-align",
41661
- lineHeight: "line-height",
41662
- linkedStyles: "linked-style",
41663
- indentleft: "indent-decrease",
41664
- indentright: "indent-increase",
41665
- directionLtr: "direction-ltr",
41666
- directionRtl: "direction-rtl",
41667
- clearFormatting: "clear-formatting",
41668
- copyFormat: "copy-format"
41669
- };
41670
- var TABLE_ACTION_COMMAND_MAP = {
41671
- addRowBefore: "table-add-row-before",
41672
- addRowAfter: "table-add-row-after",
41673
- deleteRow: "table-delete-row",
41674
- addColumnBefore: "table-add-column-before",
41675
- addColumnAfter: "table-add-column-after",
41676
- deleteColumn: "table-delete-column",
41677
- deleteTable: "table-delete",
41678
- deleteCellAndTableBorders: "table-remove-borders",
41679
- mergeCells: "table-merge-cells",
41680
- splitCell: "table-split-cell",
41681
- fixTables: "table-fix"
41682
- };
41683
- var TABLE_ACTION_COMMAND_IDS = Object.values(TABLE_ACTION_COMMAND_MAP);
41684
40414
  //#endregion
41685
40415
  //#region src/internal/toolbar/built-in/Toolbar.vue
41686
40416
  var _hoisted_1$10 = ["data-superdoc-ui-owner"];
@@ -41956,7 +40686,6 @@ var useToolbarItem = (options) => {
41956
40686
  const style = require__plugin_vue_export_helper.ref(options.style);
41957
40687
  const isNarrow = require__plugin_vue_export_helper.ref(options.isNarrow);
41958
40688
  const isWide = require__plugin_vue_export_helper.ref(options.isWide);
41959
- const minWidth = require__plugin_vue_export_helper.ref(options.minWidth);
41960
40689
  const layoutWidth = require__plugin_vue_export_helper.ref(options.layoutWidth);
41961
40690
  const suppressActiveHighlight = require__plugin_vue_export_helper.ref(options.suppressActiveHighlight || false);
41962
40691
  const argument = require__plugin_vue_export_helper.ref(options.argument);
@@ -42033,7 +40762,6 @@ var useToolbarItem = (options) => {
42033
40762
  style,
42034
40763
  isNarrow,
42035
40764
  isWide,
42036
- minWidth,
42037
40765
  layoutWidth,
42038
40766
  argument,
42039
40767
  parentItem,
@@ -42174,7 +40902,7 @@ var _hoisted_1$8 = [
42174
40902
  "aria-label",
42175
40903
  "onKeydown"
42176
40904
  ];
42177
- var _sfc_main$8 = {
40905
+ var _sfc_main$6 = {
42178
40906
  __name: "StyleButtonsList",
42179
40907
  props: {
42180
40908
  buttons: {
@@ -42259,7 +40987,7 @@ var _sfc_main$8 = {
42259
40987
  };
42260
40988
  }
42261
40989
  };
42262
- var StyleButtonsList_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$8, [["__scopeId", "data-v-44f37ff6"]]);
40990
+ var StyleButtonsList_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$6, [["__scopeId", "data-v-44f37ff6"]]);
42263
40991
  //#endregion
42264
40992
  //#region src/internal/toolbar/built-in/list-style-buttons.js
42265
40993
  var bulletStyleButtons = [
@@ -42329,7 +41057,7 @@ var _hoisted_3$6 = ["innerHTML"];
42329
41057
  var _hoisted_4$4 = { class: "document-mode-column text-column" };
42330
41058
  var _hoisted_5$2 = { class: "document-mode-type" };
42331
41059
  var _hoisted_6$1 = { class: "document-mode-description" };
42332
- var _sfc_main$7 = {
41060
+ var _sfc_main$5 = {
42333
41061
  __name: "DocumentMode",
42334
41062
  props: { options: { type: Array } },
42335
41063
  emits: ["select"],
@@ -42394,9 +41122,9 @@ var _sfc_main$7 = {
42394
41122
  };
42395
41123
  }
42396
41124
  };
42397
- var DocumentMode_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$7, [["__scopeId", "data-v-bee14d7a"]]);
41125
+ var DocumentMode_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$5, [["__scopeId", "data-v-bee14d7a"]]);
42398
41126
  //#endregion
42399
- //#region src/internal/toolbar/built-in/LinkedStyle.vue
41127
+ //#region src/internal/toolbar/built-in/LinkedStyle.vue?vue&type=script&setup=true&lang.ts
42400
41128
  var _hoisted_1$6 = {
42401
41129
  class: "linked-style-buttons",
42402
41130
  "data-editor-ui-surface": ""
@@ -42426,7 +41154,7 @@ var _hoisted_4$3 = ["innerHTML"];
42426
41154
  * (`data-item="btn-linkedStyles-option"`, keyboard navigation) and makes no
42427
41155
  * v1-only shape assumptions.
42428
41156
  */
42429
- var _sfc_main$6 = {
41157
+ var LinkedStyle_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ require__plugin_vue_export_helper.defineComponent({
42430
41158
  __name: "LinkedStyle",
42431
41159
  props: {
42432
41160
  styles: {
@@ -42527,8 +41255,10 @@ var _sfc_main$6 = {
42527
41255
  }), 128))]);
42528
41256
  };
42529
41257
  }
42530
- };
42531
- var LinkedStyle_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$6, [["__scopeId", "data-v-b5a32523"]]);
41258
+ });
41259
+ //#endregion
41260
+ //#region src/internal/toolbar/built-in/LinkedStyle.vue
41261
+ var LinkedStyle_default = /* @__PURE__ */ require__plugin_vue_export_helper._plugin_vue_export_helper_default(LinkedStyle_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-4e36f956"]]);
42532
41262
  //#endregion
42533
41263
  //#region src/internal/toolbar/built-in/AIWriter.vue
42534
41264
  var _hoisted_1$5 = ["placeholder"];
@@ -42541,7 +41271,7 @@ var _hoisted_3$4 = {
42541
41271
  var _hoisted_4$2 = ["disabled"];
42542
41272
  var DEFAULT_AI_ENDPOINT = "https://sd-dev-express-gateway-i6xtm.ondigitalocean.app/insights";
42543
41273
  var SYSTEM_PROMPT = "You are an expert copywriter and you are immersed in a document editor. Only write what is asked for.";
42544
- var _sfc_main$5 = {
41274
+ var _sfc_main$4 = {
42545
41275
  __name: "AIWriter",
42546
41276
  props: {
42547
41277
  selectedText: {
@@ -42699,7 +41429,7 @@ var _sfc_main$5 = {
42699
41429
  };
42700
41430
  }
42701
41431
  };
42702
- var AIWriter_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$5, [["__scopeId", "data-v-67f6c6f7"]]);
41432
+ var AIWriter_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$4, [["__scopeId", "data-v-67f6c6f7"]]);
42703
41433
  //#endregion
42704
41434
  //#region src/internal/toolbar/built-in/IconGridRow.vue
42705
41435
  var _hoisted_1$4 = [
@@ -42710,7 +41440,7 @@ var _hoisted_1$4 = [
42710
41440
  var _hoisted_2$4 = ["innerHTML"];
42711
41441
  var _hoisted_3$3 = ["innerHTML"];
42712
41442
  var ROW_SIZE$1 = 7;
42713
- var _sfc_main$4 = {
41443
+ var _sfc_main$3 = {
42714
41444
  __name: "IconGridRow",
42715
41445
  props: {
42716
41446
  icons: {
@@ -42837,7 +41567,7 @@ var _sfc_main$4 = {
42837
41567
  };
42838
41568
  }
42839
41569
  };
42840
- var IconGridRow_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$4, [["__scopeId", "data-v-05eb02fc"]]);
41570
+ var IconGridRow_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$3, [["__scopeId", "data-v-05eb02fc"]]);
42841
41571
  //#endregion
42842
41572
  //#region ../../shared/common/icons/droplet-slash.svg?raw
42843
41573
  var droplet_slash_default = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 640 512\"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d=\"M320 512c53.2 0 101.4-21.6 136.1-56.6l-298.3-235C140 257.1 128 292.3 128 320c0 106 86 192 192 192zM505.2 370.7c4.4-16.2 6.8-33.1 6.8-50.7c0-91.2-130.2-262.3-166.6-308.3C339.4 4.2 330.5 0 320.9 0l-1.8 0c-9.6 0-18.5 4.2-24.5 11.7C277.8 33 240.7 81.3 205.8 136L38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L505.2 370.7zM224 336c0 44.2 35.8 80 80 80c8.8 0 16 7.2 16 16s-7.2 16-16 16c-61.9 0-112-50.1-112-112c0-8.8 7.2-16 16-16s16 7.2 16 16z\"/></svg>\n";
@@ -42846,7 +41576,7 @@ var droplet_slash_default = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\
42846
41576
  var _hoisted_1$3 = { class: "options-grid-wrap" };
42847
41577
  var _hoisted_2$3 = ["innerHTML"];
42848
41578
  var _hoisted_3$2 = { class: "option-grid-ctn" };
42849
- var _sfc_main$3 = {
41579
+ var _sfc_main$2 = {
42850
41580
  __name: "IconGrid",
42851
41581
  props: {
42852
41582
  icons: {
@@ -42894,7 +41624,7 @@ var _sfc_main$3 = {
42894
41624
  };
42895
41625
  }
42896
41626
  };
42897
- var IconGrid_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$3, [["__scopeId", "data-v-52b0283a"]]);
41627
+ var IconGrid_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$2, [["__scopeId", "data-v-52b0283a"]]);
42898
41628
  //#endregion
42899
41629
  //#region src/internal/toolbar/built-in/color-dropdown-helpers.js
42900
41630
  var closeDropdown$1 = (dropdown) => {
@@ -43132,6 +41862,7 @@ var TableGrid_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_
43132
41862
  //#region src/internal/toolbar/built-in/TableActions.vue
43133
41863
  var _hoisted_1$1 = { class: "toolbar-table-actions" };
43134
41864
  var _hoisted_2$1 = [
41865
+ "aria-disabled",
43135
41866
  "onClick",
43136
41867
  "data-item",
43137
41868
  "ariaLabel"
@@ -43139,19 +41870,24 @@ var _hoisted_2$1 = [
43139
41870
  var _hoisted_3$1 = { class: "toolbar-table-actions__icon" };
43140
41871
  var _hoisted_4$1 = ["innerHTML"];
43141
41872
  var _hoisted_5$1 = { class: "toolbar-table-actions__label" };
43142
- var _sfc_main$1 = {
41873
+ var _sfc_main = {
43143
41874
  __name: "TableActions",
43144
41875
  props: { options: { type: Array } },
43145
41876
  emits: ["select"],
43146
41877
  setup(__props, { emit: __emit }) {
43147
41878
  const emit = __emit;
43148
41879
  const handleClick = (item) => {
41880
+ if (item.disabled) return;
43149
41881
  emit("select", { command: item.command });
43150
41882
  };
43151
41883
  return (_ctx, _cache) => {
43152
41884
  return require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_1$1, [(require__plugin_vue_export_helper.openBlock(true), require__plugin_vue_export_helper.createElementBlock(require__plugin_vue_export_helper.Fragment, null, require__plugin_vue_export_helper.renderList(__props.options, (option) => {
43153
41885
  return require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", {
43154
- class: require__plugin_vue_export_helper.normalizeClass(["toolbar-table-actions__item", { "toolbar-table-actions__item--border": option.bottomBorder }]),
41886
+ class: require__plugin_vue_export_helper.normalizeClass(["toolbar-table-actions__item", {
41887
+ "toolbar-table-actions__item--border": option.bottomBorder,
41888
+ "sd-disabled": option.disabled
41889
+ }]),
41890
+ "aria-disabled": option.disabled ? "true" : void 0,
43155
41891
  onClick: ($event) => handleClick(option),
43156
41892
  "data-item": option.props?.["data-item"] || "",
43157
41893
  ariaLabel: option.props?.ariaLabel,
@@ -43164,9 +41900,9 @@ var _sfc_main$1 = {
43164
41900
  };
43165
41901
  }
43166
41902
  };
43167
- var TableActions_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$1, [["__scopeId", "data-v-0cdad084"]]);
41903
+ var TableActions_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main, [["__scopeId", "data-v-72123aae"]]);
43168
41904
  //#endregion
43169
- //#region src/internal/toolbar/built-in/PageNumberMenu.vue
41905
+ //#region src/internal/toolbar/built-in/PageNumberMenu.vue?vue&type=script&setup=true&lang.ts
43170
41906
  var _hoisted_1 = ["aria-busy"];
43171
41907
  var _hoisted_2 = ["aria-disabled"];
43172
41908
  var _hoisted_3 = {
@@ -43214,7 +41950,7 @@ var _hoisted_20 = ["disabled"];
43214
41950
  var _hoisted_21 = ["disabled"];
43215
41951
  var _hoisted_22 = ["disabled"];
43216
41952
  var _hoisted_23 = { class: "sd-page-number-menu__cursor-text" };
43217
- var _sfc_main = {
41953
+ var PageNumberMenu_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ require__plugin_vue_export_helper.defineComponent({
43218
41954
  __name: "PageNumberMenu",
43219
41955
  props: {
43220
41956
  /** Command state of `page-numbers-apply`, read when the popover opens. */
@@ -43343,7 +42079,7 @@ var _sfc_main = {
43343
42079
  const { isHighContrastMode } = useHighContrastMode();
43344
42080
  const remembered = props.initialChoice ?? {};
43345
42081
  const position = require__plugin_vue_export_helper.ref(remembered.position === "top" ? "top" : "bottom");
43346
- const alignment = require__plugin_vue_export_helper.ref(ALIGNMENTS.some((entry) => entry.value === remembered.alignment) ? remembered.alignment : "right");
42082
+ const alignment = require__plugin_vue_export_helper.ref(isAlignment(remembered.alignment) ? remembered.alignment : "right");
43347
42083
  const showOnFirstPage = require__plugin_vue_export_helper.ref(remembered.showOnFirstPage !== false);
43348
42084
  const format = require__plugin_vue_export_helper.ref("decimal");
43349
42085
  const restart = require__plugin_vue_export_helper.ref(false);
@@ -43378,6 +42114,9 @@ var _sfc_main = {
43378
42114
  const platform = typeof navigator === "undefined" ? "" : navigator.platform || navigator.userAgent || "";
43379
42115
  return /Mac|iPhone|iPad/i.test(platform) ? "⌥⇧⌘P" : "Ctrl+Alt+Shift+P";
43380
42116
  });
42117
+ function isAlignment(value) {
42118
+ return ALIGNMENTS.some((entry) => entry.value === value);
42119
+ }
43381
42120
  function isTileSelected(tile) {
43382
42121
  return tile.position === position.value && tile.alignment === alignment.value;
43383
42122
  }
@@ -43447,8 +42186,12 @@ var _sfc_main = {
43447
42186
  const value = Math.floor(Number(startAt.value));
43448
42187
  return Number.isFinite(value) && value >= 0 ? value : 1;
43449
42188
  }
42189
+ function failureDetails(result) {
42190
+ if (typeof result !== "object" || result === null || result.success) return null;
42191
+ return require_create_super_doc_ui.isPlainObject(result.failure?.details) ? result.failure.details : null;
42192
+ }
43450
42193
  function failureMessage(result, action) {
43451
- const details = result?.failure?.details;
42194
+ const details = failureDetails(result);
43452
42195
  if (details?.reason === "page-number-has-content") return `A page number shares its line with other text. Edit the ${details.kind === "header" ? "header" : "footer"} directly to change it.`;
43453
42196
  if (details?.reason === "page-number-exists") return "This section already has page numbers.";
43454
42197
  if (action === "remove") return "Page numbers couldn’t be removed. Try again.";
@@ -43466,7 +42209,7 @@ var _sfc_main = {
43466
42209
  await loaded;
43467
42210
  const { execute, outcome } = prepare();
43468
42211
  const result = await execute();
43469
- if (result === true || result?.success === true) {
42212
+ if (result === true || typeof result === "object" && result !== null && result.success === true) {
43470
42213
  props.close(outcome);
43471
42214
  return;
43472
42215
  }
@@ -43516,8 +42259,9 @@ var _sfc_main = {
43516
42259
  }
43517
42260
  require__plugin_vue_export_helper.onMounted(() => {
43518
42261
  require__plugin_vue_export_helper.nextTick(() => tileRefs.value[focusIndex.value]?.focus({ preventScroll: true }));
43519
- if (typeof props.loadCurrent !== "function") return;
43520
- loaded = Promise.resolve().then(() => props.loadCurrent()).then(adoptCurrent, () => adoptCurrent(null)).finally(() => {
42262
+ const loadCurrent = props.loadCurrent;
42263
+ if (typeof loadCurrent !== "function") return;
42264
+ loaded = Promise.resolve().then(() => loadCurrent()).then(adoptCurrent, () => adoptCurrent(null)).finally(() => {
43521
42265
  loading.value = false;
43522
42266
  });
43523
42267
  });
@@ -43556,7 +42300,7 @@ var _sfc_main = {
43556
42300
  onClick: ($event) => selectTile(tile),
43557
42301
  onDblclick: applyPageNumbers,
43558
42302
  onKeydown: onTileKeydown
43559
- }, [(require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("svg", _hoisted_5, [_cache[4] || (_cache[4] = require__plugin_vue_export_helper.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-30327fd0></rect><rect class=\"sd-page-number-menu__line\" x=\"7\" y=\"14\" width=\"22\" height=\"2\" rx=\"1\" data-v-30327fd0></rect><rect class=\"sd-page-number-menu__line\" x=\"7\" y=\"19\" width=\"18\" height=\"2\" rx=\"1\" data-v-30327fd0></rect><rect class=\"sd-page-number-menu__line\" x=\"7\" y=\"24\" width=\"22\" height=\"2\" rx=\"1\" data-v-30327fd0></rect><rect class=\"sd-page-number-menu__line\" x=\"7\" y=\"29\" width=\"14\" height=\"2\" rx=\"1\" data-v-30327fd0></rect>", 5)), require__plugin_vue_export_helper.createElementVNode("rect", {
42303
+ }, [(require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("svg", _hoisted_5, [_cache[4] || (_cache[4] = require__plugin_vue_export_helper.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)), require__plugin_vue_export_helper.createElementVNode("rect", {
43560
42304
  class: "sd-page-number-menu__chip",
43561
42305
  x: CHIP_X[tile.alignment],
43562
42306
  y: CHIP_Y[tile.position],
@@ -43636,8 +42380,10 @@ var _sfc_main = {
43636
42380
  ], 10, _hoisted_1);
43637
42381
  };
43638
42382
  }
43639
- };
43640
- var PageNumberMenu_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main, [["__scopeId", "data-v-30327fd0"]]);
42383
+ });
42384
+ //#endregion
42385
+ //#region src/internal/toolbar/built-in/PageNumberMenu.vue
42386
+ var PageNumberMenu_default = /* @__PURE__ */ require__plugin_vue_export_helper._plugin_vue_export_helper_default(PageNumberMenu_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-a6c124c0"]]);
43641
42387
  //#endregion
43642
42388
  //#region src/internal/toolbar/built-in/page-number-feedback.js
43643
42389
  var FLASH_CLASS = "sd-page-number-flash";
@@ -44279,7 +43025,10 @@ var makeDefaultItems = ({ superToolbar, toolbarIcons, toolbarTexts, toolbarFonts
44279
43025
  ];
44280
43026
  function renderTableActions(tableActionsItem) {
44281
43027
  return require__plugin_vue_export_helper.h(TableActions_default, {
44282
- options: tableActionsOptions,
43028
+ options: tableActionsOptions.map((option) => ({
43029
+ ...option,
43030
+ disabled: !superToolbar.isCommandEnabled(tableActionCommandId(option.command))
43031
+ })),
44283
43032
  onSelect: (event) => {
44284
43033
  closeDropdown(tableActionsItem);
44285
43034
  const { command } = event;
@@ -45054,8 +43803,6 @@ var findElementBySelector = (selector) => {
45054
43803
  * Internal only: nothing here is a public package export and no
45055
43804
  * `headless-toolbar*` subpath is reintroduced.
45056
43805
  */
45057
- var HEADLESS_COMMAND_IDS = HEADLESS_ITEM_MAP;
45058
- var TABLE_ACTION_COMMANDS = TABLE_ACTION_COMMAND_MAP;
45059
43806
  function isThenable(value) {
45060
43807
  return (typeof value === "object" || typeof value === "function") && value !== null && "then" in value && typeof value.then === "function";
45061
43808
  }
@@ -45071,15 +43818,6 @@ function isListenerTarget(value) {
45071
43818
  function hasClosest(target) {
45072
43819
  return target !== null && "closest" in target && typeof target.closest === "function";
45073
43820
  }
45074
- /**
45075
- * Resolve a legacy built-in item name to its canonical V2 controller command
45076
- * id. The compatibility catalog is the primary truth; a small supplemental map
45077
- * (`HEADLESS_ITEM_MAP`) covers documented items the renderer can surface that
45078
- * are not modeled as catalog rows yet (e.g. table-of-contents, direction).
45079
- */
45080
- function resolveCommandId(name) {
45081
- return resolveToolbarCommandId(name) ?? HEADLESS_COMMAND_IDS[name] ?? null;
45082
- }
45083
43821
  function executeCommand(ui, commandId, argument, options = {}) {
45084
43822
  if (!ui?.commands || !commandId) return false;
45085
43823
  if (typeof ui.commands.has === "function" && !ui.commands.has(commandId)) return false;
@@ -45161,7 +43899,8 @@ var BuiltInToolbar = class extends require_eventemitter3.import_eventemitter3.de
45161
43899
  #groupItems;
45162
43900
  #highlightOptions;
45163
43901
  #painterListenersDetach;
45164
- constructor(config = {}) {
43902
+ #highContrastMode;
43903
+ constructor(config) {
45165
43904
  super();
45166
43905
  this.config = {
45167
43906
  selector: null,
@@ -45203,6 +43942,7 @@ var BuiltInToolbar = class extends require_eventemitter3.import_eventemitter3.de
45203
43942
  this.#makeToolbarItems();
45204
43943
  this.updateToolbarState();
45205
43944
  };
43945
+ this.#highContrastMode = config.highContrastMode;
45206
43946
  this.config = {
45207
43947
  ...this.config,
45208
43948
  ...config
@@ -45267,6 +44007,7 @@ var BuiltInToolbar = class extends require_eventemitter3.import_eventemitter3.de
45267
44007
  this.app = require__plugin_vue_export_helper.createApp(Toolbar_default);
45268
44008
  this.app.directive("click-outside", v_click_outside_default);
45269
44009
  this.app.config.globalProperties.$toolbar = this;
44010
+ this.app.provide(HIGH_CONTRAST_MODE_KEY, this.#highContrastMode);
45270
44011
  this.toolbar = this.app.mount(this.toolbarContainer);
45271
44012
  this.updateToolbarState();
45272
44013
  } catch (error) {
@@ -45600,18 +44341,22 @@ var BuiltInToolbar = class extends require_eventemitter3.import_eventemitter3.de
45600
44341
  #isFontFamilyMixedState(commandState) {
45601
44342
  return Boolean(commandState) && commandState?.disabled === false && commandState?.value == null;
45602
44343
  }
44344
+ isCommandEnabled(commandId) {
44345
+ if (!commandId) return false;
44346
+ const commandState = this.snapshot?.commands?.[commandId];
44347
+ return Boolean(commandState && !commandState.disabled);
44348
+ }
45603
44349
  #applyHeadlessState(item) {
45604
44350
  const name = item.name.value;
45605
44351
  if (item.isCustomToolbarItem && typeof item.command === "string") {
45606
44352
  const commandState = this.snapshot?.commands?.[item.command];
45607
- item.setDisabled(item.initiallyDisabled || !commandState || Boolean(commandState.disabled));
44353
+ item.setDisabled(item.initiallyDisabled || !this.isCommandEnabled(item.command));
45608
44354
  if (commandState?.active) item.activate();
45609
44355
  else item.deactivate();
45610
44356
  return true;
45611
44357
  }
45612
44358
  if (name === "tableActions") {
45613
- const hasAnyEnabled = TABLE_ACTION_COMMAND_IDS.map((commandId) => this.snapshot?.commands?.[commandId]).some((state) => state && !state.disabled);
45614
- item.setDisabled(!hasAnyEnabled);
44359
+ item.setDisabled(!TABLE_ACTION_COMMAND_IDS.some((commandId) => this.isCommandEnabled(commandId)));
45615
44360
  return true;
45616
44361
  }
45617
44362
  if (name === "search") {
@@ -45630,7 +44375,7 @@ var BuiltInToolbar = class extends require_eventemitter3.import_eventemitter3.de
45630
44375
  else item.deactivate();
45631
44376
  return true;
45632
44377
  }
45633
- const commandId = resolveCommandId(name);
44378
+ const commandId = resolveBuiltInItemCommandId(name);
45634
44379
  if (!commandId) return false;
45635
44380
  const commandState = this.snapshot?.commands?.[commandId];
45636
44381
  if (shouldKeepEnabledForV1ToolbarParity(name, commandState)) item.setDisabled(false);
@@ -45795,12 +44540,12 @@ var BuiltInToolbar = class extends require_eventemitter3.import_eventemitter3.de
45795
44540
  if (name === "image" && argument == null) return this.#startImagePick();
45796
44541
  if (name === "tableActions") {
45797
44542
  const tableAction = typeof argument === "object" && argument !== null && "command" in argument ? argument.command : void 0;
45798
- const commandId = typeof tableAction === "string" ? TABLE_ACTION_COMMANDS[tableAction] : void 0;
44543
+ const commandId = typeof tableAction === "string" ? tableActionCommandId(tableAction) : void 0;
45799
44544
  if (!commandId) return false;
45800
44545
  return executeCommand(this.ui, commandId, void 0, callbacks);
45801
44546
  }
45802
44547
  if (getBuiltInToolbarItem(name)?.disposition === "unsupported") return true;
45803
- const commandId = resolveCommandId(name);
44548
+ const commandId = resolveBuiltInItemCommandId(name);
45804
44549
  if (!commandId) return false;
45805
44550
  return executeCommand(this.ui, commandId, argument, callbacks);
45806
44551
  }
@@ -46237,6 +44982,10 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
46237
44982
  return this.#surfacesConfig;
46238
44983
  }
46239
44984
  #surfaceManager;
44985
+ /**
44986
+ * @private
44987
+ */
44988
+ #highContrastMode;
46240
44989
  #sourceLifecycleReady;
46241
44990
  #pendingSourceLifecycle;
46242
44991
  /**
@@ -46310,6 +45059,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
46310
45059
  this.users = [];
46311
45060
  this.whiteboard = null;
46312
45061
  this.colors = [];
45062
+ this.#highContrastMode = createHighContrastMode();
46313
45063
  this.readyEditors = 0;
46314
45064
  this.#sourceLifecycleReady = false;
46315
45065
  this.#pendingSourceLifecycle = [];
@@ -46466,7 +45216,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
46466
45216
  }
46467
45217
  this.userColorMap = /* @__PURE__ */ new Map();
46468
45218
  this.colorIndex = 0;
46469
- this.version = "2.28.0-next.9";
45219
+ this.version = "2.29.0-next.1";
46470
45220
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
46471
45221
  this.superdocId = config.superdocId || require_uuid.v4();
46472
45222
  this.colors = this.config.colors ?? [];
@@ -46766,7 +45516,10 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
46766
45516
  });
46767
45517
  }
46768
45518
  #initVueApp() {
46769
- const { app, pinia, superdocStore, commentsStore, highContrastModeStore } = createSuperdocVueApp({ disablePiniaDevtools: Boolean(this.config.disablePiniaDevtools) });
45519
+ const { app, pinia, superdocStore, commentsStore } = createSuperdocVueApp({
45520
+ disablePiniaDevtools: Boolean(this.config.disablePiniaDevtools),
45521
+ highContrastMode: this.#highContrastMode
45522
+ });
46770
45523
  this.app = app;
46771
45524
  this.pinia = pinia;
46772
45525
  this.app.config.globalProperties.$config = this.config;
@@ -46775,7 +45528,6 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
46775
45528
  this.app.provide("surfaceManager", this.#surfaceManager);
46776
45529
  this.superdocStore = superdocStore;
46777
45530
  this.commentsStore = commentsStore;
46778
- this.highContrastModeStore = highContrastModeStore;
46779
45531
  if (typeof this.superdocStore.setExceptionHandler === "function") this.superdocStore.setExceptionHandler((payload) => this.emit("exception", payload));
46780
45532
  this.superdocStore.init(this.config);
46781
45533
  const commentsModuleConfig = this.config.modules.comments;
@@ -47173,7 +45925,8 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
47173
45925
  roomMode: target.roomMode,
47174
45926
  ...syncTimeoutOption,
47175
45927
  ...target.publicApiKey ? { publicApiKey: target.publicApiKey } : {},
47176
- ...target.authEndpoint ? { authEndpoint: target.authEndpoint } : {}
45928
+ ...target.authEndpoint ? { authEndpoint: target.authEndpoint } : {},
45929
+ ...target.baseUrl ? { baseUrl: target.baseUrl } : {}
47177
45930
  };
47178
45931
  if (target.providerFamily === "hocuspocus") return {
47179
45932
  providerType: "hocuspocus",
@@ -47847,7 +46600,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
47847
46600
  const getValues = storeComment?.getValues;
47848
46601
  resolvedComment = typeof getValues === "function" ? getValues.call(storeComment) : storeComment;
47849
46602
  }
47850
- return isAllowed(permission, role, isInternal, {
46603
+ return require_create_super_doc_ui.isAllowed(permission, role, isInternal, {
47851
46604
  superdoc: this,
47852
46605
  currentUser: this.config.user,
47853
46606
  comment: resolvedComment ?? null,
@@ -47879,7 +46632,8 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
47879
46632
  toolbarGroups: toolbarUi.options.toolbarGroups,
47880
46633
  icons: toolbarUi.options.icons,
47881
46634
  texts: toolbarUi.options.texts,
47882
- uiDisplayFallbackFont: this.config.uiDisplayFallbackFont
46635
+ uiDisplayFallbackFont: this.config.uiDisplayFallbackFont,
46636
+ highContrastMode: this.#highContrastMode
47883
46637
  });
47884
46638
  } catch (error) {
47885
46639
  console.warn("[SuperDoc] built-in toolbar mount failed", error);
@@ -48254,7 +47008,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
48254
47008
  * superdoc.setZoom(50); // Set zoom to 50%
48255
47009
  */
48256
47010
  setZoom(percent) {
48257
- if (typeof percent !== "number" || !Number.isFinite(percent) || percent <= 0) {
47011
+ if (!require_is_finite_number.isFiniteNumber(percent) || percent <= 0) {
48258
47012
  console.warn("[SuperDoc] setZoom expects a positive number representing percentage");
48259
47013
  return;
48260
47014
  }
@@ -48489,23 +47243,6 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
48489
47243
  confirmed
48490
47244
  };
48491
47245
  }
48492
- const legacyReplaceFile = activeEditor && !isV2ActiveEditorFacade(activeEditor) ? activeEditor.replaceFile : null;
48493
- if (typeof legacyReplaceFile === "function") {
48494
- const result = await legacyReplaceFile.call(activeEditor, source);
48495
- const legacyState = result && typeof result === "object" ? result.state : void 0;
48496
- const legacyConfirmed = legacyState === void 0 || legacyState === null || legacyState === "review-ready" || legacyState === "editing-ready";
48497
- if (legacyConfirmed) {
48498
- this.#replaceActiveDocumentData(activeEditor, source);
48499
- this.emit("document-replaced", {
48500
- editor: activeEditor,
48501
- host: activeEditor?.host
48502
- });
48503
- }
48504
- return {
48505
- raw: result,
48506
- confirmed: legacyConfirmed
48507
- };
48508
- }
48509
47246
  throw new Error("SuperDoc: replaceFile is unavailable for the active editor");
48510
47247
  }
48511
47248
  /**
@@ -48518,19 +47255,6 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
48518
47255
  commentsType,
48519
47256
  isFinalDoc
48520
47257
  });
48521
- const uiStoreHydrated = this.config?.modules?.comments !== false;
48522
- let legacyComments;
48523
- let legacyCommentsComputed = false;
48524
- const getLegacyCommentsForV1 = () => {
48525
- if (legacyCommentsComputed) return legacyComments;
48526
- legacyCommentsComputed = true;
48527
- if (commentsType === "clean") legacyComments = [];
48528
- else if (uiStoreHydrated && this.commentsStore && typeof this.commentsStore.translateCommentsForExport === "function") {
48529
- legacyComments = this.commentsStore.translateCommentsForExport();
48530
- if (!Array.isArray(legacyComments)) legacyComments = [];
48531
- }
48532
- return legacyComments;
48533
- };
48534
47258
  const bridgedExportErrors = /* @__PURE__ */ new WeakSet();
48535
47259
  const rememberBridgedExportError = (payload) => {
48536
47260
  if ("editor" in payload && payload.error && typeof payload.error === "object") bridgedExportErrors.add(payload.error);
@@ -48541,7 +47265,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
48541
47265
  if (policies !== void 0 && documents.some((doc) => {
48542
47266
  if (doc.type !== "application/vnd.openxmlformats-officedocument.wordprocessingml.document") return false;
48543
47267
  const editor = doc.getEditor?.();
48544
- return editor?.editorVersion !== 2 || typeof editor.exportDocx !== "function";
47268
+ return !isV2ActiveEditorFacade(editor) || typeof editor.exportDocx !== "function";
48545
47269
  })) throw new Error("Independent DOCX export policies require a mounted V2 exporter for every document.");
48546
47270
  const docxPromises = documents.map(async (doc) => {
48547
47271
  if (!doc || doc.type !== "application/vnd.openxmlformats-officedocument.wordprocessingml.document") return null;
@@ -48554,19 +47278,13 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
48554
47278
  if (isDocumentByteSource(doc.data)) return this.#savedDocxToBlob(doc.data);
48555
47279
  return null;
48556
47280
  };
48557
- if (!editor || typeof editor.exportDocx !== "function") return fallbackDocx();
48558
- const isV2Editor = editor.editorVersion === 2;
47281
+ if (!isV2ActiveEditorFacade(editor) || typeof editor.exportDocx !== "function") return fallbackDocx();
48559
47282
  try {
48560
- const exported = await editor.exportDocx(isV2Editor ? {
47283
+ const exported = await editor.exportDocx({
48561
47284
  isFinalDoc,
48562
47285
  commentsType,
48563
47286
  policies,
48564
47287
  fieldsHighlightColor
48565
- } : {
48566
- isFinalDoc,
48567
- comments: getLegacyCommentsForV1(),
48568
- commentsType,
48569
- fieldsHighlightColor
48570
47288
  });
48571
47289
  if (exported) return exported;
48572
47290
  } catch (error) {
@@ -48580,7 +47298,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
48580
47298
  editor: null
48581
47299
  }));
48582
47300
  }
48583
- if (isV2Editor) throw error;
47301
+ throw error;
48584
47302
  }
48585
47303
  return fallbackDocx();
48586
47304
  });
@@ -48723,7 +47441,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
48723
47441
  setHighContrastMode(isHighContrast) {
48724
47442
  if (!this.activeEditor) return;
48725
47443
  this.activeEditor.setHighContrastMode?.(isHighContrast);
48726
- this.highContrastModeStore?.setHighContrastMode(isHighContrast);
47444
+ this.#highContrastMode.setHighContrastMode(isHighContrast);
48727
47445
  }
48728
47446
  };
48729
47447
  Object.defineProperty(SuperDoc.prototype.canPerformPermission, Symbol.for("superdoc.internal.permission-method.builtin"), { value: true });