@harbour-enterprises/superdoc 1.0.0-beta.99 → 1.0.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 (28) hide show
  1. package/dist/chunks/{PdfViewer-DF-v5Yrr.es.js → PdfViewer-BKujh9gl.es.js} +1 -1
  2. package/dist/chunks/{PdfViewer-BtuTHUW7.cjs → PdfViewer-Cu04k0JZ.cjs} +1 -1
  3. package/dist/chunks/{index-BBu9BBvp.cjs → index-CZ4149Px.cjs} +3 -3
  4. package/dist/chunks/{index-CJy3FxL7.es.js → index-Cl0tjE1C.es.js} +3 -3
  5. package/dist/chunks/{index-BB0msI45-DUPBw4Bh.es.js → index-Dlj3l0Hk-BuYH_UIe.es.js} +1 -1
  6. package/dist/chunks/{index-BB0msI45-CPU6Ak2R.cjs → index-Dlj3l0Hk-CJ0YBOja.cjs} +1 -1
  7. package/dist/chunks/{super-editor.es-C04sFzVD.cjs → super-editor.es-CjRtsxTt.cjs} +973 -178
  8. package/dist/chunks/{super-editor.es-BiaFIbw-.es.js → super-editor.es-D0WByw5h.es.js} +973 -178
  9. package/dist/packages/superdoc/src/core/SuperDoc.d.ts.map +1 -1
  10. package/dist/super-editor/ai-writer.es.js +2 -2
  11. package/dist/super-editor/chunks/{converter-B_cVJPnh.js → converter-BS4FD8AG.js} +12 -6
  12. package/dist/super-editor/chunks/{docx-zipper-fPWx7kV0.js → docx-zipper-DpiCpt0d.js} +1 -1
  13. package/dist/super-editor/chunks/{editor-DS9z42Je.js → editor-BeacbTQe.js} +963 -170
  14. package/dist/super-editor/chunks/{index-BB0msI45.js → index-Dlj3l0Hk.js} +1 -1
  15. package/dist/super-editor/chunks/{toolbar-aIFlIr6h.js → toolbar-BNQDvBCn.js} +2 -2
  16. package/dist/super-editor/converter.es.js +1 -1
  17. package/dist/super-editor/docx-zipper.es.js +2 -2
  18. package/dist/super-editor/editor.es.js +3 -3
  19. package/dist/super-editor/file-zipper.es.js +1 -1
  20. package/dist/super-editor/super-editor.es.js +10 -10
  21. package/dist/super-editor/toolbar.es.js +2 -2
  22. package/dist/super-editor.cjs +1 -1
  23. package/dist/super-editor.es.js +1 -1
  24. package/dist/superdoc.cjs +2 -2
  25. package/dist/superdoc.es.js +2 -2
  26. package/dist/superdoc.umd.js +975 -180
  27. package/dist/superdoc.umd.js.map +1 -1
  28. package/package.json +10 -1
@@ -39792,7 +39792,7 @@ function importCommentData({ docx, editor, converter }) {
39792
39792
  const trackedDeletedText = attributes["custom:trackedDeletedText"] !== "null" ? attributes["custom:trackedDeletedText"] : null;
39793
39793
  const date = new Date(createdDate);
39794
39794
  const unixTimestampMs = date.getTime();
39795
- const parsedComment = nodeListHandler.handler({
39795
+ const parsedElements = nodeListHandler.handler({
39796
39796
  nodes: el.elements,
39797
39797
  nodeListHandler,
39798
39798
  docx,
@@ -39800,7 +39800,7 @@ function importCommentData({ docx, editor, converter }) {
39800
39800
  converter,
39801
39801
  path: [el]
39802
39802
  });
39803
- const { attrs } = parsedComment[0];
39803
+ const { attrs } = parsedElements[0];
39804
39804
  const paraId = attrs["w14:paraId"];
39805
39805
  return {
39806
39806
  commentId: internalId || v4(),
@@ -39808,7 +39808,8 @@ function importCommentData({ docx, editor, converter }) {
39808
39808
  creatorName: authorName,
39809
39809
  creatorEmail: authorEmail,
39810
39810
  createdTime: unixTimestampMs,
39811
- textJson: parsedComment[0],
39811
+ textJson: parsedElements[0],
39812
+ elements: parsedElements,
39812
39813
  initials,
39813
39814
  paraId,
39814
39815
  trackedChange,
@@ -39834,7 +39835,12 @@ const generateCommentsWithExtendedData = ({ docx, comments }) => {
39834
39835
  const { elements = [] } = initialElements[0] ?? {};
39835
39836
  const commentEx = elements.filter((el) => el.name === "w15:commentEx");
39836
39837
  return comments.map((comment) => {
39837
- const extendedDef = commentEx.find((ce2) => ce2.attributes["w15:paraId"] === comment.paraId);
39838
+ const extendedDef = commentEx.find((ce2) => {
39839
+ const isIncludedInCommentElements = comment.elements?.some(
39840
+ (el) => el.attrs?.["w14:paraId"] === ce2.attributes["w15:paraId"]
39841
+ );
39842
+ return isIncludedInCommentElements;
39843
+ });
39838
39844
  if (!extendedDef) return { ...comment, isDone: comment.isDone ?? false };
39839
39845
  const { isDone, paraIdParent } = getExtendedDetails(extendedDef);
39840
39846
  let parentComment;
@@ -41955,7 +41961,7 @@ const updateCommentsIdsAndExtensible = (comments = [], commentsIds, extensible)
41955
41961
  name: "w16cex:commentExtensible",
41956
41962
  attributes: {
41957
41963
  "w16cex:durableId": newDurableId,
41958
- "w16cex:dateUtc": toIsoNoFractional()
41964
+ "w16cex:dateUtc": toIsoNoFractional(comment.createdTime)
41959
41965
  }
41960
41966
  };
41961
41967
  extensibleUpdated.elements[0].elements.push(newExtensible);
@@ -42421,7 +42427,7 @@ const _SuperConverter = class _SuperConverter2 {
42421
42427
  static getStoredSuperdocVersion(docx) {
42422
42428
  return _SuperConverter2.getStoredCustomProperty(docx, "SuperdocVersion");
42423
42429
  }
42424
- static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.0-beta.99") {
42430
+ static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.0-next.1") {
42425
42431
  return _SuperConverter2.setStoredCustomProperty(docx, "SuperdocVersion", version2, false);
42426
42432
  }
42427
42433
  /**
@@ -45733,7 +45739,7 @@ var __privateGet$1 = (obj, member, getter) => (__accessCheck$1(obj, member, "rea
45733
45739
  var __privateAdd$1 = (obj, member, value) => member.has(obj) ? __typeError$1("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
45734
45740
  var __privateSet = (obj, member, value, setter) => (__accessCheck$1(obj, member, "write to private field"), member.set(obj, value), value);
45735
45741
  var __privateMethod$1 = (obj, member, method) => (__accessCheck$1(obj, member, "access private method"), method);
45736
- var _Attribute_static, getGlobalAttributes_fn, getNodeAndMarksAttributes_fn, _Schema_static, createNodesSchema_fn, createMarksSchema_fn, _events, _ExtensionService_instances, setupExtensions_fn, attachEditorEvents_fn, _editor, _stateValidators, _xmlValidators, _requiredNodeTypes, _requiredMarkTypes, _SuperValidator_instances, initializeValidators_fn, collectValidatorRequirements_fn, analyzeDocument_fn, dispatchWithFallback_fn, _commandService, _Editor_instances, initContainerElement_fn, init_fn, initRichText_fn, onFocus_fn, checkHeadless_fn, registerCopyHandler_fn, insertNewFileData_fn, getPluginKeyName_fn, createExtensionService_fn, createCommandService_fn, createConverter_fn, initMedia_fn, initFonts_fn, checkFonts_fn, determineUnsupportedFonts_fn, createSchema_fn, generatePmData_fn, createView_fn, onCollaborationReady_fn, initComments_fn, dispatchTransaction_fn, handleNodeSelection_fn, prepareDocumentForImport_fn, prepareDocumentForExport_fn, endCollaboration_fn, validateDocumentInit_fn, validateDocumentExport_fn, initDevTools_fn, _map, _editor2, _descriptors, _collections, _editorEntries, _maxCachedEditors, _editorAccessOrder, _pendingCreations, _cacheHits, _cacheMisses, _evictions, _HeaderFooterEditorManager_instances, hasConverter_fn, extractCollections_fn, collectDescriptors_fn, teardownMissingEditors_fn, teardownEditors_fn, createEditor_fn, createEditorContainer_fn, registerConverterEditor_fn, unregisterConverterEditor_fn, updateAccessOrder_fn, enforceCacheSizeLimit_fn, _manager, _mediaFiles, _blockCache, _HeaderFooterLayoutAdapter_instances, getBlocks_fn, getConverterContext_fn, _selectionOverlay, _activeEditorHost, _activeDecorationContainer, _activeRegion, _borderLine, _dimmingOverlay, _EditorOverlayManager_instances, findDecorationContainer_fn, ensureEditorHost_fn, positionEditorHost_fn, showHeaderFooterBorder_fn, hideHeaderFooterBorder_fn, _instances, _options, _editor3, _visibleHost, _viewportHost, _painterHost, _selectionOverlay2, _hiddenHost, _layoutOptions, _layoutState, _domPainter, _dragHandlerCleanup, _layoutError, _layoutErrorState, _errorBanner, _errorBannerMessage, _telemetryEmitter, _renderScheduled, _pendingDocChange, _isRerendering, _selectionUpdateScheduled, _remoteCursorUpdateScheduled, _rafHandle, _editorListeners, _sectionMetadata, _documentMode, _inputBridge, _trackedChangesMode, _trackedChangesEnabled, _trackedChangesOverrides, _headerFooterManager, _headerFooterAdapter, _headerFooterIdentifier, _multiSectionIdentifier, _headerLayoutResults, _footerLayoutResults, _headerLayoutsByRId, _footerLayoutsByRId, _headerDecorationProvider, _footerDecorationProvider, _headerFooterManagerCleanups, _headerRegions, _footerRegions, _session, _activeHeaderFooterEditor, _overlayManager, _hoverOverlay, _hoverTooltip, _modeBanner, _ariaLiveRegion, _hoverRegion, _clickCount, _lastClickTime, _lastClickPosition, _lastSelectedImageBlockId, _dragAnchor, _isDragging, _dragExtensionMode, _cellAnchor, _cellDragMode, _remoteCursorState, _remoteCursorElements, _remoteCursorDirty, _remoteCursorOverlay, _localSelectionLayer, _awarenessCleanup, _scrollCleanup, _scrollTimeout, _lastRemoteCursorRenderTime, _remoteCursorThrottleTimeout, _PresentationEditor_instances, collectCommentPositions_fn, aggregateLayoutBounds_fn, safeCleanup_fn, setupEditorListeners_fn, setupCollaborationCursors_fn, updateLocalAwarenessCursor_fn, normalizeAwarenessStates_fn, getFallbackColor_fn, getValidatedColor_fn, scheduleRemoteCursorUpdate_fn, scheduleRemoteCursorReRender_fn, updateRemoteCursors_fn, renderRemoteCursors_fn, renderRemoteCaret_fn, renderRemoteCursorLabel_fn, renderRemoteSelection_fn, setupPointerHandlers_fn, setupDragHandlers_fn, focusEditorAfterImageSelection_fn, setupInputBridge_fn, initHeaderFooterRegistry_fn, _handlePointerDown, getFirstTextPosition_fn, registerPointerClick_fn, getCellPosFromTableHit_fn, getTablePosFromHit_fn, shouldUseCellSelection_fn, setCellAnchor_fn, clearCellAnchor_fn, hitTestTable_fn, selectWordAt_fn, selectParagraphAt_fn, calculateExtendedSelection_fn, isWordCharacter_fn, _handlePointerMove, _handlePointerLeave, _handlePointerUp, _handleDragOver, _handleDrop, _handleDoubleClick, _handleKeyDown, focusHeaderFooterShortcut_fn, scheduleRerender_fn, flushRerenderQueue_fn, rerender_fn, ensurePainter_fn, scheduleSelectionUpdate_fn, updateSelection_fn, resolveLayoutOptions_fn, buildHeaderFooterInput_fn, computeHeaderFooterConstraints_fn, layoutPerRIdHeaderFooters_fn, updateDecorationProviders_fn, createDecorationProvider_fn, findHeaderFooterPageForPageNumber_fn, computeDecorationBox_fn, computeExpectedSectionType_fn, rebuildHeaderFooterRegions_fn, hitTestHeaderFooterRegion_fn, pointInRegion_fn, activateHeaderFooterRegion_fn, enterHeaderFooterMode_fn, exitHeaderFooterMode_fn, getActiveDomTarget_fn, emitHeaderFooterModeChanged_fn, emitHeaderFooterEditingContext_fn, updateAwarenessSession_fn, updateModeBanner_fn, announce_fn, validateHeaderFooterEditPermission_fn, emitHeaderFooterEditBlocked_fn, resolveDescriptorForRegion_fn, createDefaultHeaderFooter_fn, getPageElement_fn, scrollPageIntoView_fn, computeAnchorMap_fn, waitForPageMount_fn, getBodyPageHeight_fn, getHeaderFooterPageHeight_fn, applyDomCorrectionToRects_fn, renderCellSelectionOverlay_fn, renderSelectionRects_fn, renderHoverRegion_fn, clearHoverRegion_fn, renderCaretOverlay_fn, getHeaderFooterContext_fn, computeHeaderFooterSelectionRects_fn, syncTrackedChangesPreferences_fn, deriveTrackedChangesMode_fn, deriveTrackedChangesEnabled_fn, getTrackChangesPluginState_fn, computeDefaultLayoutDefaults_fn, parseColumns_fn, inchesToPx_fn, applyZoom_fn, createLayoutMetrics_fn, getPageOffsetX_fn, convertPageLocalToOverlayCoords_fn, computeDomCaretPageLocal_fn, normalizeClientPoint_fn, computeCaretLayoutRectGeometry_fn, computeCaretLayoutRect_fn, computeTableCaretLayoutRect_fn, findLineContainingPos_fn, lineHeightBeforeIndex_fn, getCurrentPageIndex_fn, findRegionForPage_fn, handleLayoutError_fn, decorateError_fn, showLayoutErrorBanner_fn, dismissErrorBanner_fn, createHiddenHost_fn, _windowRoot, _layoutSurfaces, _getTargetDom, _isEditable, _onTargetChanged, _listeners, _currentTarget, _destroyed, _useWindowFallback, _PresentationInputBridge_instances, addListener_fn, dispatchToTarget_fn, forwardKeyboardEvent_fn, forwardTextEvent_fn, forwardCompositionEvent_fn, forwardContextMenu_fn, isEventOnActiveTarget_fn, shouldSkipSurface_fn, isInLayoutSurface_fn, getListenerTargets_fn, isPlainCharacterKey_fn, _DocumentSectionView_instances, init_fn2, addToolTip_fn, _ParagraphNodeView_instances, checkShouldUpdate_fn, updateHTMLAttributes_fn, updateDOMStyles_fn, resolveNeighborParagraphProperties_fn, updateListStyles_fn, initList_fn, checkIsList_fn, createMarker_fn, createSeparator_fn, calculateTabSeparatorStyle_fn, calculateMarkerStyle_fn, removeList_fn, getParagraphContext_fn, scheduleAnimation_fn, cancelScheduledAnimation_fn, _FieldAnnotationView_instances, createAnnotation_fn, _AutoPageNumberNodeView_instances, renderDom_fn, scheduleUpdateNodeStyle_fn, _VectorShapeView_instances, ensureParentPositioned_fn, _ShapeGroupView_instances, ensureParentPositioned_fn2;
45742
+ var _Attribute_static, getGlobalAttributes_fn, getNodeAndMarksAttributes_fn, _Schema_static, createNodesSchema_fn, createMarksSchema_fn, _events, _ExtensionService_instances, setupExtensions_fn, attachEditorEvents_fn, _editor, _stateValidators, _xmlValidators, _requiredNodeTypes, _requiredMarkTypes, _SuperValidator_instances, initializeValidators_fn, collectValidatorRequirements_fn, analyzeDocument_fn, dispatchWithFallback_fn, _commandService, _Editor_instances, initContainerElement_fn, init_fn, initRichText_fn, onFocus_fn, checkHeadless_fn, registerCopyHandler_fn, insertNewFileData_fn, getPluginKeyName_fn, createExtensionService_fn, createCommandService_fn, createConverter_fn, initMedia_fn, initFonts_fn, checkFonts_fn, determineUnsupportedFonts_fn, createSchema_fn, generatePmData_fn, createView_fn, onCollaborationReady_fn, initComments_fn, dispatchTransaction_fn, handleNodeSelection_fn, prepareDocumentForImport_fn, prepareDocumentForExport_fn, endCollaboration_fn, validateDocumentInit_fn, validateDocumentExport_fn, initDevTools_fn, _map, _editor2, _descriptors, _collections, _editorEntries, _maxCachedEditors, _editorAccessOrder, _pendingCreations, _cacheHits, _cacheMisses, _evictions, _HeaderFooterEditorManager_instances, hasConverter_fn, extractCollections_fn, collectDescriptors_fn, teardownMissingEditors_fn, teardownEditors_fn, createEditor_fn, createEditorContainer_fn, registerConverterEditor_fn, unregisterConverterEditor_fn, updateAccessOrder_fn, enforceCacheSizeLimit_fn, _manager, _mediaFiles, _blockCache, _HeaderFooterLayoutAdapter_instances, getBlocks_fn, getConverterContext_fn, _selectionOverlay, _activeEditorHost, _activeDecorationContainer, _activeRegion, _borderLine, _dimmingOverlay, _EditorOverlayManager_instances, findDecorationContainer_fn, ensureEditorHost_fn, positionEditorHost_fn, showHeaderFooterBorder_fn, hideHeaderFooterBorder_fn, _instances, _options, _editor3, _visibleHost, _viewportHost, _painterHost, _selectionOverlay2, _hiddenHost, _layoutOptions, _layoutState, _domPainter, _pageGeometryHelper, _dragHandlerCleanup, _layoutError, _layoutErrorState, _errorBanner, _errorBannerMessage, _telemetryEmitter, _renderScheduled, _pendingDocChange, _isRerendering, _selectionUpdateScheduled, _remoteCursorUpdateScheduled, _rafHandle, _editorListeners, _sectionMetadata, _documentMode, _inputBridge, _trackedChangesMode, _trackedChangesEnabled, _trackedChangesOverrides, _headerFooterManager, _headerFooterAdapter, _headerFooterIdentifier, _multiSectionIdentifier, _headerLayoutResults, _footerLayoutResults, _headerLayoutsByRId, _footerLayoutsByRId, _headerDecorationProvider, _footerDecorationProvider, _headerFooterManagerCleanups, _headerRegions, _footerRegions, _session, _activeHeaderFooterEditor, _overlayManager, _hoverOverlay, _hoverTooltip, _modeBanner, _ariaLiveRegion, _hoverRegion, _clickCount, _lastClickTime, _lastClickPosition, _lastSelectedImageBlockId, _dragAnchor, _isDragging, _dragExtensionMode, _cellAnchor, _cellDragMode, _remoteCursorState, _remoteCursorElements, _remoteCursorDirty, _remoteCursorOverlay, _localSelectionLayer, _awarenessCleanup, _scrollCleanup, _scrollTimeout, _lastRemoteCursorRenderTime, _remoteCursorThrottleTimeout, _PresentationEditor_instances, collectCommentPositions_fn, aggregateLayoutBounds_fn, safeCleanup_fn, setupEditorListeners_fn, setupCollaborationCursors_fn, updateLocalAwarenessCursor_fn, normalizeAwarenessStates_fn, getFallbackColor_fn, getValidatedColor_fn, scheduleRemoteCursorUpdate_fn, scheduleRemoteCursorReRender_fn, updateRemoteCursors_fn, renderRemoteCursors_fn, renderRemoteCaret_fn, renderRemoteCursorLabel_fn, renderRemoteSelection_fn, setupPointerHandlers_fn, setupDragHandlers_fn, focusEditorAfterImageSelection_fn, setupInputBridge_fn, initHeaderFooterRegistry_fn, _handlePointerDown, getFirstTextPosition_fn, registerPointerClick_fn, getCellPosFromTableHit_fn, getTablePosFromHit_fn, shouldUseCellSelection_fn, setCellAnchor_fn, clearCellAnchor_fn, hitTestTable_fn, selectWordAt_fn, selectParagraphAt_fn, calculateExtendedSelection_fn, isWordCharacter_fn, _handlePointerMove, _handlePointerLeave, _handlePointerUp, _handleDragOver, _handleDrop, _handleDoubleClick, _handleKeyDown, focusHeaderFooterShortcut_fn, scheduleRerender_fn, flushRerenderQueue_fn, rerender_fn, ensurePainter_fn, scheduleSelectionUpdate_fn, updateSelection_fn, resolveLayoutOptions_fn, buildHeaderFooterInput_fn, computeHeaderFooterConstraints_fn, layoutPerRIdHeaderFooters_fn, updateDecorationProviders_fn, createDecorationProvider_fn, findHeaderFooterPageForPageNumber_fn, computeDecorationBox_fn, computeExpectedSectionType_fn, rebuildHeaderFooterRegions_fn, hitTestHeaderFooterRegion_fn, pointInRegion_fn, activateHeaderFooterRegion_fn, enterHeaderFooterMode_fn, exitHeaderFooterMode_fn, getActiveDomTarget_fn, emitHeaderFooterModeChanged_fn, emitHeaderFooterEditingContext_fn, updateAwarenessSession_fn, updateModeBanner_fn, announce_fn, validateHeaderFooterEditPermission_fn, emitHeaderFooterEditBlocked_fn, resolveDescriptorForRegion_fn, createDefaultHeaderFooter_fn, getPageElement_fn, scrollPageIntoView_fn, computeAnchorMap_fn, waitForPageMount_fn, getEffectivePageGap_fn, getBodyPageHeight_fn, getHeaderFooterPageHeight_fn, applyDomCorrectionToRects_fn, renderCellSelectionOverlay_fn, renderSelectionRects_fn, renderHoverRegion_fn, clearHoverRegion_fn, renderCaretOverlay_fn, getHeaderFooterContext_fn, computeHeaderFooterSelectionRects_fn, syncTrackedChangesPreferences_fn, deriveTrackedChangesMode_fn, deriveTrackedChangesEnabled_fn, getTrackChangesPluginState_fn, computeDefaultLayoutDefaults_fn, parseColumns_fn, inchesToPx_fn, applyZoom_fn, createLayoutMetrics_fn, getPageOffsetX_fn, convertPageLocalToOverlayCoords_fn, computeDomCaretPageLocal_fn, normalizeClientPoint_fn, computeCaretLayoutRectGeometry_fn, computeCaretLayoutRect_fn, computeTableCaretLayoutRect_fn, findLineContainingPos_fn, lineHeightBeforeIndex_fn, getCurrentPageIndex_fn, findRegionForPage_fn, handleLayoutError_fn, decorateError_fn, showLayoutErrorBanner_fn, dismissErrorBanner_fn, createHiddenHost_fn, _windowRoot, _layoutSurfaces, _getTargetDom, _isEditable, _onTargetChanged, _listeners, _currentTarget, _destroyed, _useWindowFallback, _PresentationInputBridge_instances, addListener_fn, dispatchToTarget_fn, forwardKeyboardEvent_fn, forwardTextEvent_fn, forwardCompositionEvent_fn, forwardContextMenu_fn, isEventOnActiveTarget_fn, shouldSkipSurface_fn, isInLayoutSurface_fn, getListenerTargets_fn, isPlainCharacterKey_fn, _DocumentSectionView_instances, init_fn2, addToolTip_fn, _ParagraphNodeView_instances, checkShouldUpdate_fn, updateHTMLAttributes_fn, updateDOMStyles_fn, resolveNeighborParagraphProperties_fn, updateListStyles_fn, initList_fn, checkIsList_fn, createMarker_fn, createSeparator_fn, calculateTabSeparatorStyle_fn, calculateMarkerStyle_fn, removeList_fn, getParagraphContext_fn, scheduleAnimation_fn, cancelScheduledAnimation_fn, _FieldAnnotationView_instances, createAnnotation_fn, _AutoPageNumberNodeView_instances, renderDom_fn, scheduleUpdateNodeStyle_fn, _VectorShapeView_instances, ensureParentPositioned_fn, _ShapeGroupView_instances, ensureParentPositioned_fn2;
45737
45743
  var GOOD_LEAF_SIZE = 200;
45738
45744
  var RopeSequence = function RopeSequence2() {
45739
45745
  };
@@ -54817,6 +54823,14 @@ const toggleNode = (typeOrName, toggleTypeOrName, attrs = {}) => ({ state: state
54817
54823
  const selectAll = () => ({ state: state2, dispatch }) => selectAll$1(state2, dispatch);
54818
54824
  const deleteSelection = () => ({ state: state2, tr, dispatch }) => {
54819
54825
  const { from: from2, to, empty: empty2 } = state2.selection;
54826
+ if (typeof document !== "undefined" && document.getSelection) {
54827
+ const currentDomSelection = document.getSelection();
54828
+ const selectedLength = currentDomSelection?.toString?.().length;
54829
+ const isCollapsed = currentDomSelection?.isCollapsed;
54830
+ if (!isCollapsed && selectedLength === 1) {
54831
+ return false;
54832
+ }
54833
+ }
54820
54834
  if (empty2) {
54821
54835
  return deleteSelection$1(state2, dispatch);
54822
54836
  }
@@ -57116,12 +57130,14 @@ const prepareCommentsForImport = (doc2, tr, schema, converter) => {
57116
57130
  importedId: node.attrs["w:id"]
57117
57131
  });
57118
57132
  if (type2.name === "commentRangeStart") {
57119
- toMark.push({
57120
- commentId: resolvedCommentId,
57121
- importedId,
57122
- internal,
57123
- start: pos
57124
- });
57133
+ if (!matchingImportedComment?.isDone) {
57134
+ toMark.push({
57135
+ commentId: resolvedCommentId,
57136
+ importedId,
57137
+ internal,
57138
+ start: pos
57139
+ });
57140
+ }
57125
57141
  ensureFallbackComment({
57126
57142
  converter,
57127
57143
  matchingImportedComment,
@@ -59639,7 +59655,7 @@ const isHeadless = (editor) => {
59639
59655
  const shouldSkipNodeView = (editor) => {
59640
59656
  return isHeadless(editor);
59641
59657
  };
59642
- const summaryVersion = "1.0.0-beta.99";
59658
+ const summaryVersion = "1.0.0-next.1";
59643
59659
  const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
59644
59660
  const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
59645
59661
  function mapAttributes(attrs) {
@@ -59999,11 +60015,11 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
59999
60015
  if (!this.options.isNewFile || !this.options.collaborationProvider) return;
60000
60016
  const provider = this.options.collaborationProvider;
60001
60017
  const postSyncInit = () => {
60002
- provider.off("synced", postSyncInit);
60018
+ provider.off?.("synced", postSyncInit);
60003
60019
  __privateMethod$1(this, _Editor_instances, insertNewFileData_fn).call(this);
60004
60020
  };
60005
60021
  if (provider.synced) __privateMethod$1(this, _Editor_instances, insertNewFileData_fn).call(this);
60006
- else provider.on("synced", postSyncInit);
60022
+ else provider.on?.("synced", postSyncInit);
60007
60023
  }
60008
60024
  /**
60009
60025
  * Replace content of editor that was created with loadFromSchema option
@@ -60428,7 +60444,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
60428
60444
  { default: remarkStringify },
60429
60445
  { default: remarkGfm }
60430
60446
  ] = await Promise.all([
60431
- Promise.resolve().then(() => require("./index-BB0msI45-CPU6Ak2R.cjs")),
60447
+ Promise.resolve().then(() => require("./index-Dlj3l0Hk-CJ0YBOja.cjs")),
60432
60448
  Promise.resolve().then(() => require("./index-DRCvimau-H4Ck3S9a.cjs")),
60433
60449
  Promise.resolve().then(() => require("./index-C_x_N6Uh-Db3CUJMX.cjs")),
60434
60450
  Promise.resolve().then(() => require("./index-D_sWOSiG-BtDZzJ6I.cjs")),
@@ -60633,7 +60649,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
60633
60649
  * Process collaboration migrations
60634
60650
  */
60635
60651
  processCollaborationMigrations() {
60636
- console.debug("[checkVersionMigrations] Current editor version", "1.0.0-beta.99");
60652
+ console.debug("[checkVersionMigrations] Current editor version", "1.0.0-next.1");
60637
60653
  if (!this.options.ydoc) return;
60638
60654
  const metaMap = this.options.ydoc.getMap("meta");
60639
60655
  let docVersion = metaMap.get("version");
@@ -63748,6 +63764,7 @@ function hydrateImageBlocks(blocks, mediaFiles) {
63748
63764
  if (cellChanged) {
63749
63765
  return {
63750
63766
  ...cell,
63767
+ // Cast to expected type - hydrateBlock preserves block kinds, just hydrates image sources
63751
63768
  blocks: hydratedBlocks.length > 0 ? hydratedBlocks : cell.blocks,
63752
63769
  paragraph: hydratedParagraph
63753
63770
  };
@@ -67368,7 +67385,7 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
67368
67385
  };
67369
67386
  }
67370
67387
  const hasValidNumbering = rawNumberingProps && isValidNumberingId(rawNumberingProps.numId);
67371
- if (hasValidNumbering) {
67388
+ if (hasValidNumbering && rawNumberingProps) {
67372
67389
  const numberingProps = rawNumberingProps;
67373
67390
  const numId = numberingProps.numId;
67374
67391
  const ilvl = Number.isFinite(numberingProps.ilvl) ? Math.max(0, Math.floor(Number(numberingProps.ilvl))) : 0;
@@ -67408,6 +67425,8 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
67408
67425
  const resolvedCounterValue = path[path.length - 1] ?? counterValue;
67409
67426
  const enrichedNumberingProps = {
67410
67427
  ...numberingProps,
67428
+ numId: numberingProps.numId,
67429
+ ilvl: numberingProps.ilvl,
67411
67430
  path,
67412
67431
  counterValue: resolvedCounterValue
67413
67432
  };
@@ -69504,7 +69523,7 @@ const parseTableCell = (args) => {
69504
69523
  context.nextBlockId,
69505
69524
  context.positions
69506
69525
  );
69507
- if (drawingBlock) {
69526
+ if (drawingBlock && drawingBlock.kind === "drawing") {
69508
69527
  blocks.push(drawingBlock);
69509
69528
  }
69510
69529
  continue;
@@ -69515,7 +69534,7 @@ const parseTableCell = (args) => {
69515
69534
  context.nextBlockId,
69516
69535
  context.positions
69517
69536
  );
69518
- if (drawingBlock) {
69537
+ if (drawingBlock && drawingBlock.kind === "drawing") {
69519
69538
  blocks.push(drawingBlock);
69520
69539
  }
69521
69540
  continue;
@@ -69526,7 +69545,7 @@ const parseTableCell = (args) => {
69526
69545
  context.nextBlockId,
69527
69546
  context.positions
69528
69547
  );
69529
- if (drawingBlock) {
69548
+ if (drawingBlock && drawingBlock.kind === "drawing") {
69530
69549
  blocks.push(drawingBlock);
69531
69550
  }
69532
69551
  continue;
@@ -69537,7 +69556,7 @@ const parseTableCell = (args) => {
69537
69556
  context.nextBlockId,
69538
69557
  context.positions
69539
69558
  );
69540
- if (drawingBlock) {
69559
+ if (drawingBlock && drawingBlock.kind === "drawing") {
69541
69560
  blocks.push(drawingBlock);
69542
69561
  }
69543
69562
  }
@@ -69992,7 +70011,19 @@ function toFlowBlocks(pmDoc, options) {
69992
70011
  bookmarks2,
69993
70012
  hyperlinkConfig2,
69994
70013
  themeColorsParam ?? themeColors,
69995
- paragraphConverter
70014
+ paragraphConverter,
70015
+ converterCtx ?? converterContext,
70016
+ {
70017
+ listCounterContext: { getListCounter, incrementListCounter, resetListCounter },
70018
+ converters: {
70019
+ paragraphToFlowBlocks: paragraphConverter,
70020
+ imageNodeToBlock,
70021
+ vectorShapeNodeToDrawingBlock,
70022
+ shapeGroupNodeToDrawingBlock,
70023
+ shapeContainerNodeToDrawingBlock,
70024
+ shapeTextboxNodeToDrawingBlock
70025
+ }
70026
+ }
69996
70027
  );
69997
70028
  const handlerContext = {
69998
70029
  blocks,
@@ -70013,6 +70044,7 @@ function toFlowBlocks(pmDoc, options) {
70013
70044
  currentParagraphIndex: 0
70014
70045
  },
70015
70046
  converters: {
70047
+ // Type assertion needed due to signature mismatch between actual function and type definition
70016
70048
  paragraphToFlowBlocks: paragraphConverter,
70017
70049
  tableNodeToBlock: tableConverter,
70018
70050
  imageNodeToBlock,
@@ -70108,6 +70140,7 @@ function paragraphToFlowBlocks(para, nextBlockId, positions, defaultFont, defaul
70108
70140
  {
70109
70141
  listCounterContext,
70110
70142
  converters: {
70143
+ // Type assertion needed due to signature mismatch between actual function and type definition
70111
70144
  paragraphToFlowBlocks: paragraphToFlowBlocks$1,
70112
70145
  imageNodeToBlock,
70113
70146
  vectorShapeNodeToDrawingBlock,
@@ -70121,7 +70154,7 @@ function paragraphToFlowBlocks(para, nextBlockId, positions, defaultFont, defaul
70121
70154
  converterContext
70122
70155
  );
70123
70156
  }
70124
- function tableNodeToBlock(node, nextBlockId, positions, defaultFont, defaultSize, styleContext, trackedChanges, bookmarks, hyperlinkConfig, themeColors, converterContext) {
70157
+ function tableNodeToBlock(node, nextBlockId, positions, defaultFont, defaultSize, styleContext, trackedChanges, bookmarks, hyperlinkConfig, themeColors, _paragraphToFlowBlocksParam, converterContext, options) {
70125
70158
  return tableNodeToBlock$1(
70126
70159
  node,
70127
70160
  nextBlockId,
@@ -70135,8 +70168,9 @@ function tableNodeToBlock(node, nextBlockId, positions, defaultFont, defaultSize
70135
70168
  themeColors,
70136
70169
  paragraphToFlowBlocks,
70137
70170
  converterContext,
70138
- {
70171
+ options ?? {
70139
70172
  converters: {
70173
+ // Type assertion needed due to signature mismatch between actual function and type definition
70140
70174
  paragraphToFlowBlocks: paragraphToFlowBlocks$1,
70141
70175
  imageNodeToBlock,
70142
70176
  vectorShapeNodeToDrawingBlock,
@@ -72716,7 +72750,7 @@ const containerStyles = {
72716
72750
  alignItems: "center",
72717
72751
  background: "transparent",
72718
72752
  padding: "0",
72719
- gap: "24px",
72753
+ // gap is set dynamically by renderer based on pageGap option (default: 24px)
72720
72754
  overflowY: "auto"
72721
72755
  };
72722
72756
  const containerStylesHorizontal = {
@@ -72726,7 +72760,7 @@ const containerStylesHorizontal = {
72726
72760
  justifyContent: "safe center",
72727
72761
  background: "transparent",
72728
72762
  padding: "0",
72729
- gap: "20px",
72763
+ // gap is set dynamically by renderer based on pageGap option (default: 20px for horizontal)
72730
72764
  overflowX: "auto",
72731
72765
  minHeight: "100%"
72732
72766
  };
@@ -74440,6 +74474,49 @@ const hashParagraphBorders$1 = (borders) => {
74440
74474
  if (borders.left) parts.push(`l:[${hashParagraphBorder$1(borders.left)}]`);
74441
74475
  return parts.join(";");
74442
74476
  };
74477
+ const isNoneBorder$1 = (value) => {
74478
+ return typeof value === "object" && value !== null && "none" in value && value.none === true;
74479
+ };
74480
+ const isBorderSpec$1 = (value) => {
74481
+ return typeof value === "object" && value !== null && !("none" in value);
74482
+ };
74483
+ const hashBorderSpec$1 = (border) => {
74484
+ const parts = [];
74485
+ if (border.style !== void 0) parts.push(`s:${border.style}`);
74486
+ if (border.width !== void 0) parts.push(`w:${border.width}`);
74487
+ if (border.color !== void 0) parts.push(`c:${border.color}`);
74488
+ if (border.space !== void 0) parts.push(`sp:${border.space}`);
74489
+ return parts.join(",");
74490
+ };
74491
+ const hashTableBorderValue$1 = (borderValue) => {
74492
+ if (borderValue === void 0) return "";
74493
+ if (borderValue === null) return "null";
74494
+ if (isNoneBorder$1(borderValue)) return "none";
74495
+ if (isBorderSpec$1(borderValue)) {
74496
+ return hashBorderSpec$1(borderValue);
74497
+ }
74498
+ return "";
74499
+ };
74500
+ const hashTableBorders$1 = (borders) => {
74501
+ if (!borders) return "";
74502
+ const parts = [];
74503
+ if (borders.top !== void 0) parts.push(`t:[${hashTableBorderValue$1(borders.top)}]`);
74504
+ if (borders.right !== void 0) parts.push(`r:[${hashTableBorderValue$1(borders.right)}]`);
74505
+ if (borders.bottom !== void 0) parts.push(`b:[${hashTableBorderValue$1(borders.bottom)}]`);
74506
+ if (borders.left !== void 0) parts.push(`l:[${hashTableBorderValue$1(borders.left)}]`);
74507
+ if (borders.insideH !== void 0) parts.push(`ih:[${hashTableBorderValue$1(borders.insideH)}]`);
74508
+ if (borders.insideV !== void 0) parts.push(`iv:[${hashTableBorderValue$1(borders.insideV)}]`);
74509
+ return parts.join(";");
74510
+ };
74511
+ const hashCellBorders$1 = (borders) => {
74512
+ if (!borders) return "";
74513
+ const parts = [];
74514
+ if (borders.top) parts.push(`t:[${hashBorderSpec$1(borders.top)}]`);
74515
+ if (borders.right) parts.push(`r:[${hashBorderSpec$1(borders.right)}]`);
74516
+ if (borders.bottom) parts.push(`b:[${hashBorderSpec$1(borders.bottom)}]`);
74517
+ if (borders.left) parts.push(`l:[${hashBorderSpec$1(borders.left)}]`);
74518
+ return parts.join(";");
74519
+ };
74443
74520
  const hasStringProp = (run2, prop) => {
74444
74521
  return prop in run2 && typeof run2[prop] === "string";
74445
74522
  };
@@ -74529,6 +74606,7 @@ function isMinimalWordLayout(value) {
74529
74606
  const LIST_MARKER_GAP$1 = 8;
74530
74607
  const DEFAULT_TAB_INTERVAL_PX$1 = 48;
74531
74608
  const DEFAULT_PAGE_HEIGHT_PX = 1056;
74609
+ const DEFAULT_VIRTUALIZED_PAGE_GAP$1 = 72;
74532
74610
  const COMMENT_EXTERNAL_COLOR = "#B1124B";
74533
74611
  const COMMENT_INTERNAL_COLOR = "#078383";
74534
74612
  const COMMENT_INACTIVE_ALPHA = "22";
@@ -74658,10 +74736,11 @@ const _DomPainter = class _DomPainter2 {
74658
74736
  this.totalPages = 0;
74659
74737
  this.linkIdCounter = 0;
74660
74738
  this.pendingTooltips = /* @__PURE__ */ new WeakMap();
74739
+ this.pageGap = 24;
74661
74740
  this.virtualEnabled = false;
74662
74741
  this.virtualWindow = 5;
74663
74742
  this.virtualOverscan = 0;
74664
- this.virtualGap = 72;
74743
+ this.virtualGap = DEFAULT_VIRTUALIZED_PAGE_GAP$1;
74665
74744
  this.virtualPaddingTop = null;
74666
74745
  this.topSpacerEl = null;
74667
74746
  this.bottomSpacerEl = null;
@@ -74680,13 +74759,14 @@ const _DomPainter = class _DomPainter2 {
74680
74759
  this.blockLookup = this.buildBlockLookup(blocks, measures);
74681
74760
  this.headerProvider = options.headerProvider;
74682
74761
  this.footerProvider = options.footerProvider;
74762
+ const defaultGap = this.layoutMode === "horizontal" ? 20 : 24;
74763
+ this.pageGap = typeof options.pageGap === "number" && Number.isFinite(options.pageGap) ? Math.max(0, options.pageGap) : defaultGap;
74683
74764
  if (this.layoutMode === "vertical" && options.virtualization?.enabled) {
74684
74765
  this.virtualEnabled = true;
74685
74766
  this.virtualWindow = Math.max(1, options.virtualization.window ?? 5);
74686
74767
  this.virtualOverscan = Math.max(0, options.virtualization.overscan ?? 0);
74687
- if (typeof options.virtualization.gap === "number" && Number.isFinite(options.virtualization.gap)) {
74688
- this.virtualGap = Math.max(0, options.virtualization.gap);
74689
- }
74768
+ const hasExplicitVirtualGap = typeof options.virtualization.gap === "number" && Number.isFinite(options.virtualization.gap);
74769
+ this.virtualGap = hasExplicitVirtualGap ? Math.max(0, options.virtualization.gap) : DEFAULT_VIRTUALIZED_PAGE_GAP$1;
74690
74770
  if (typeof options.virtualization.paddingTop === "number" && Number.isFinite(options.virtualization.paddingTop)) {
74691
74771
  this.virtualPaddingTop = Math.max(0, options.virtualization.paddingTop);
74692
74772
  }
@@ -74787,6 +74867,7 @@ const _DomPainter = class _DomPainter2 {
74787
74867
  const mode = this.layoutMode;
74788
74868
  if (mode === "horizontal") {
74789
74869
  applyStyles$2(mount2, containerStylesHorizontal);
74870
+ mount2.style.gap = `${this.pageGap}px`;
74790
74871
  this.renderHorizontal(layout, mount2);
74791
74872
  this.currentLayout = layout;
74792
74873
  this.pageStates = [];
@@ -74809,6 +74890,7 @@ const _DomPainter = class _DomPainter2 {
74809
74890
  this.changedBlocks.clear();
74810
74891
  return;
74811
74892
  }
74893
+ mount2.style.gap = `${this.pageGap}px`;
74812
74894
  if (!this.currentLayout || this.pageStates.length === 0) {
74813
74895
  this.fullRender(layout);
74814
74896
  } else {
@@ -75133,9 +75215,15 @@ const _DomPainter = class _DomPainter2 {
75133
75215
  const container = existing ?? this.doc.createElement("div");
75134
75216
  container.className = className;
75135
75217
  container.innerHTML = "";
75136
- const offset2 = data.offset ?? (kind === "footer" ? pageEl.clientHeight - data.height : 0);
75218
+ const baseOffset = data.offset ?? (kind === "footer" ? pageEl.clientHeight - data.height : 0);
75137
75219
  const marginLeft = data.marginLeft ?? 0;
75138
75220
  const marginRight = page.margins?.right ?? 0;
75221
+ let effectiveHeight = data.height;
75222
+ let effectiveOffset = baseOffset;
75223
+ if (kind === "footer" && typeof data.contentHeight === "number" && Number.isFinite(data.contentHeight) && data.contentHeight > 0 && data.contentHeight > data.height) {
75224
+ effectiveHeight = data.contentHeight;
75225
+ effectiveOffset = baseOffset - (data.contentHeight - data.height);
75226
+ }
75139
75227
  container.style.position = "absolute";
75140
75228
  container.style.left = `${marginLeft}px`;
75141
75229
  if (typeof data.contentWidth === "number") {
@@ -75144,8 +75232,8 @@ const _DomPainter = class _DomPainter2 {
75144
75232
  container.style.width = `calc(100% - ${marginLeft + marginRight}px)`;
75145
75233
  }
75146
75234
  container.style.pointerEvents = "none";
75147
- container.style.height = `${data.height}px`;
75148
- container.style.top = `${Math.max(0, offset2)}px`;
75235
+ container.style.height = `${effectiveHeight}px`;
75236
+ container.style.top = `${Math.max(0, effectiveOffset)}px`;
75149
75237
  container.style.zIndex = "1";
75150
75238
  container.style.overflow = "visible";
75151
75239
  let footerYOffset = 0;
@@ -75154,7 +75242,7 @@ const _DomPainter = class _DomPainter2 {
75154
75242
  const fragHeight = "height" in f2 && typeof f2.height === "number" ? f2.height : this.estimateFragmentHeight(f2);
75155
75243
  return Math.max(max2, f2.y + Math.max(0, fragHeight));
75156
75244
  }, 0);
75157
- footerYOffset = Math.max(0, data.height - contentHeight);
75245
+ footerYOffset = Math.max(0, effectiveHeight - contentHeight);
75158
75246
  }
75159
75247
  const context = {
75160
75248
  pageNumber: page.number,
@@ -77644,6 +77732,25 @@ const deriveBlockVersion = (block) => {
77644
77732
  hash2 = hashNumber(hash2, cellBlocks.length);
77645
77733
  hash2 = hashNumber(hash2, cell.rowSpan ?? 1);
77646
77734
  hash2 = hashNumber(hash2, cell.colSpan ?? 1);
77735
+ if (cell.attrs) {
77736
+ const cellAttrs = cell.attrs;
77737
+ if (cellAttrs.borders) {
77738
+ hash2 = hashString(hash2, hashCellBorders$1(cellAttrs.borders));
77739
+ }
77740
+ if (cellAttrs.padding) {
77741
+ const p = cellAttrs.padding;
77742
+ hash2 = hashNumber(hash2, p.top ?? 0);
77743
+ hash2 = hashNumber(hash2, p.right ?? 0);
77744
+ hash2 = hashNumber(hash2, p.bottom ?? 0);
77745
+ hash2 = hashNumber(hash2, p.left ?? 0);
77746
+ }
77747
+ if (cellAttrs.verticalAlign) {
77748
+ hash2 = hashString(hash2, cellAttrs.verticalAlign);
77749
+ }
77750
+ if (cellAttrs.background) {
77751
+ hash2 = hashString(hash2, cellAttrs.background);
77752
+ }
77753
+ }
77647
77754
  for (const cellBlock of cellBlocks) {
77648
77755
  hash2 = hashString(hash2, cellBlock?.kind ?? "unknown");
77649
77756
  if (cellBlock?.kind === "paragraph") {
@@ -77689,6 +77796,18 @@ const deriveBlockVersion = (block) => {
77689
77796
  }
77690
77797
  }
77691
77798
  }
77799
+ if (tableBlock.attrs) {
77800
+ const tblAttrs = tableBlock.attrs;
77801
+ if (tblAttrs.borders) {
77802
+ hash2 = hashString(hash2, hashTableBorders$1(tblAttrs.borders));
77803
+ }
77804
+ if (tblAttrs.borderCollapse) {
77805
+ hash2 = hashString(hash2, tblAttrs.borderCollapse);
77806
+ }
77807
+ if (tblAttrs.cellSpacing !== void 0) {
77808
+ hash2 = hashNumber(hash2, tblAttrs.cellSpacing);
77809
+ }
77810
+ }
77692
77811
  return [block.id, tableBlock.rows.length, hash2.toString(16)].join("|");
77693
77812
  }
77694
77813
  return block.id;
@@ -78022,6 +78141,7 @@ const createDomPainter = (options) => {
78022
78141
  const painter = new DomPainter(options.blocks, options.measures, {
78023
78142
  pageStyles: options.pageStyles,
78024
78143
  layoutMode: options.layoutMode,
78144
+ pageGap: options.pageGap,
78025
78145
  headerProvider: options.headerProvider,
78026
78146
  footerProvider: options.footerProvider,
78027
78147
  virtualization: options.virtualization,
@@ -78440,7 +78560,7 @@ function isListItem(markerWidth, block) {
78440
78560
  return false;
78441
78561
  }
78442
78562
  const wordLayout = getWordLayoutConfig(block);
78443
- const hasListAttrs = block.attrs?.listItem != null || wordLayout?.marker != null;
78563
+ const hasListAttrs = block.attrs?.listItem != null || block.attrs?.numberingProperties != null || wordLayout?.marker != null;
78444
78564
  if (hasListAttrs) {
78445
78565
  return true;
78446
78566
  }
@@ -78870,7 +78990,7 @@ function computeNextSectionPropsAtBreak(blocks) {
78870
78990
  });
78871
78991
  return nextSectionPropsAtBreak;
78872
78992
  }
78873
- function scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight = 0) {
78993
+ function scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight = 0, maxFooterContentHeight = 0) {
78874
78994
  const next = { ...state2 };
78875
78995
  const calcRequiredTopMargin = (headerDistance, baseTop) => {
78876
78996
  if (maxHeaderContentHeight > 0) {
@@ -78878,6 +78998,12 @@ function scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight
78878
78998
  }
78879
78999
  return Math.max(baseTop, headerDistance);
78880
79000
  };
79001
+ const calcRequiredBottomMargin = (footerDistance, baseBottom) => {
79002
+ if (maxFooterContentHeight > 0) {
79003
+ return Math.max(baseBottom, footerDistance + maxFooterContentHeight);
79004
+ }
79005
+ return Math.max(baseBottom, footerDistance);
79006
+ };
78881
79007
  if (block.attrs?.isFirstSection && !next.hasAnyPages) {
78882
79008
  if (block.pageSize) {
78883
79009
  next.activePageSize = { w: block.pageSize.w, h: block.pageSize.h };
@@ -78898,7 +79024,7 @@ function scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight
78898
79024
  const footerDistance = Math.max(0, block.margins.footer);
78899
79025
  next.activeFooterDistance = footerDistance;
78900
79026
  next.pendingFooterDistance = footerDistance;
78901
- next.activeBottomMargin = Math.max(baseMargins.bottom, footerDistance);
79027
+ next.activeBottomMargin = calcRequiredBottomMargin(footerDistance, baseMargins.bottom);
78902
79028
  next.pendingBottomMargin = next.activeBottomMargin;
78903
79029
  }
78904
79030
  if (block.columns) {
@@ -78921,8 +79047,14 @@ function scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight
78921
79047
  next.pendingTopMargin = nextTop;
78922
79048
  next.pendingHeaderDistance = nextHeader;
78923
79049
  }
78924
- next.pendingBottomMargin = typeof footerPx === "number" ? Math.max(baseMargins.bottom, footerPx) : nextBottom;
78925
- next.pendingFooterDistance = typeof footerPx === "number" ? Math.max(0, footerPx) : nextFooter;
79050
+ if (typeof footerPx === "number") {
79051
+ const newFooterDist = Math.max(0, footerPx);
79052
+ next.pendingFooterDistance = newFooterDist;
79053
+ next.pendingBottomMargin = calcRequiredBottomMargin(newFooterDist, baseMargins.bottom);
79054
+ } else {
79055
+ next.pendingBottomMargin = nextBottom;
79056
+ next.pendingFooterDistance = nextFooter;
79057
+ }
78926
79058
  if (block.pageSize) {
78927
79059
  next.pendingPageSize = { w: block.pageSize.w, h: block.pageSize.h };
78928
79060
  }
@@ -80522,7 +80654,7 @@ function layoutDocument(blocks, measures, options = {}) {
80522
80654
  if (contentWidth <= 0) {
80523
80655
  throw new Error("layoutDocument: pageSize and margins yield non-positive content area");
80524
80656
  }
80525
- const validateHeaderHeight = (height) => {
80657
+ const validateContentHeight = (height) => {
80526
80658
  if (height === void 0) return 0;
80527
80659
  if (!Number.isFinite(height) || height < 0) return 0;
80528
80660
  return height;
@@ -80530,15 +80662,25 @@ function layoutDocument(blocks, measures, options = {}) {
80530
80662
  const headerContentHeights = options.headerContentHeights;
80531
80663
  const maxHeaderContentHeight = headerContentHeights ? Math.max(
80532
80664
  0,
80533
- validateHeaderHeight(headerContentHeights.default),
80534
- validateHeaderHeight(headerContentHeights.first),
80535
- validateHeaderHeight(headerContentHeights.even),
80536
- validateHeaderHeight(headerContentHeights.odd)
80665
+ validateContentHeight(headerContentHeights.default),
80666
+ validateContentHeight(headerContentHeights.first),
80667
+ validateContentHeight(headerContentHeights.even),
80668
+ validateContentHeight(headerContentHeights.odd)
80537
80669
  ) : 0;
80538
80670
  const headerDistance = margins.header ?? margins.top;
80539
80671
  const effectiveTopMargin = maxHeaderContentHeight > 0 ? Math.max(margins.top, headerDistance + maxHeaderContentHeight) : margins.top;
80672
+ const footerContentHeights = options.footerContentHeights;
80673
+ const maxFooterContentHeight = footerContentHeights ? Math.max(
80674
+ 0,
80675
+ validateContentHeight(footerContentHeights.default),
80676
+ validateContentHeight(footerContentHeights.first),
80677
+ validateContentHeight(footerContentHeights.even),
80678
+ validateContentHeight(footerContentHeights.odd)
80679
+ ) : 0;
80680
+ const footerDistance = margins.footer ?? margins.bottom;
80681
+ const effectiveBottomMargin = maxFooterContentHeight > 0 ? Math.max(margins.bottom, footerDistance + maxFooterContentHeight) : margins.bottom;
80540
80682
  let activeTopMargin = effectiveTopMargin;
80541
- let activeBottomMargin = margins.bottom;
80683
+ let activeBottomMargin = effectiveBottomMargin;
80542
80684
  let pendingTopMargin = null;
80543
80685
  let pendingBottomMargin = null;
80544
80686
  let activeHeaderDistance = margins.header ?? margins.top;
@@ -80561,7 +80703,7 @@ function layoutDocument(blocks, measures, options = {}) {
80561
80703
  const nextSectionPropsAtBreak = computeNextSectionPropsAtBreak(blocks);
80562
80704
  const scheduleSectionBreakCompat = (block, state2, baseMargins) => {
80563
80705
  if (typeof scheduleSectionBreak === "function") {
80564
- return scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight);
80706
+ return scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight, maxFooterContentHeight);
80565
80707
  }
80566
80708
  const next = { ...state2 };
80567
80709
  if (block.attrs?.isFirstSection && !next.hasAnyPages) {
@@ -80582,10 +80724,11 @@ function layoutDocument(blocks, measures, options = {}) {
80582
80724
  next.pendingTopMargin = next.activeTopMargin;
80583
80725
  }
80584
80726
  if (block.margins?.footer !== void 0) {
80585
- const footerDistance = Math.max(0, block.margins.footer);
80586
- next.activeFooterDistance = footerDistance;
80587
- next.pendingFooterDistance = footerDistance;
80588
- next.activeBottomMargin = Math.max(baseMargins.bottom, footerDistance);
80727
+ const footerDistance2 = Math.max(0, block.margins.footer);
80728
+ next.activeFooterDistance = footerDistance2;
80729
+ next.pendingFooterDistance = footerDistance2;
80730
+ const requiredBottom = maxFooterContentHeight > 0 ? footerDistance2 + maxFooterContentHeight : footerDistance2;
80731
+ next.activeBottomMargin = Math.max(baseMargins.bottom, requiredBottom);
80589
80732
  next.pendingBottomMargin = next.activeBottomMargin;
80590
80733
  }
80591
80734
  if (block.columns) {
@@ -80630,7 +80773,13 @@ function layoutDocument(blocks, measures, options = {}) {
80630
80773
  } else {
80631
80774
  next.pendingTopMargin = nextTop;
80632
80775
  }
80633
- next.pendingBottomMargin = typeof footerPx === "number" ? Math.max(baseMargins.bottom, footerPx) : nextBottom;
80776
+ if (typeof footerPx === "number") {
80777
+ const sectionFooter = next.pendingFooterDistance;
80778
+ const requiredBottom = maxFooterContentHeight > 0 ? sectionFooter + maxFooterContentHeight : sectionFooter;
80779
+ next.pendingBottomMargin = Math.max(baseMargins.bottom, requiredBottom);
80780
+ } else {
80781
+ next.pendingBottomMargin = nextBottom;
80782
+ }
80634
80783
  if (block.pageSize) next.pendingPageSize = { w: block.pageSize.w, h: block.pageSize.h };
80635
80784
  if (block.orientation) next.pendingOrientation = block.orientation;
80636
80785
  const sectionType = block.type ?? "continuous";
@@ -81397,6 +81546,49 @@ const hashParagraphBorders = (borders) => {
81397
81546
  if (borders.left) parts.push(`l:[${hashParagraphBorder(borders.left)}]`);
81398
81547
  return parts.join(";");
81399
81548
  };
81549
+ function isNoneBorder(value) {
81550
+ return typeof value === "object" && value !== null && "none" in value && value.none === true;
81551
+ }
81552
+ function isBorderSpec(value) {
81553
+ return typeof value === "object" && value !== null && !("none" in value);
81554
+ }
81555
+ const hashBorderSpec = (border) => {
81556
+ const parts = [];
81557
+ if (border.style !== void 0) parts.push(`s:${border.style}`);
81558
+ if (border.width !== void 0) parts.push(`w:${border.width}`);
81559
+ if (border.color !== void 0) parts.push(`c:${border.color}`);
81560
+ if (border.space !== void 0) parts.push(`sp:${border.space}`);
81561
+ return parts.join(",");
81562
+ };
81563
+ const hashTableBorderValue = (borderValue) => {
81564
+ if (borderValue === void 0) return "";
81565
+ if (borderValue === null) return "null";
81566
+ if (isNoneBorder(borderValue)) return "none";
81567
+ if (isBorderSpec(borderValue)) {
81568
+ return hashBorderSpec(borderValue);
81569
+ }
81570
+ return "";
81571
+ };
81572
+ const hashTableBorders = (borders) => {
81573
+ if (!borders) return "";
81574
+ const parts = [];
81575
+ if (borders.top !== void 0) parts.push(`t:[${hashTableBorderValue(borders.top)}]`);
81576
+ if (borders.right !== void 0) parts.push(`r:[${hashTableBorderValue(borders.right)}]`);
81577
+ if (borders.bottom !== void 0) parts.push(`b:[${hashTableBorderValue(borders.bottom)}]`);
81578
+ if (borders.left !== void 0) parts.push(`l:[${hashTableBorderValue(borders.left)}]`);
81579
+ if (borders.insideH !== void 0) parts.push(`ih:[${hashTableBorderValue(borders.insideH)}]`);
81580
+ if (borders.insideV !== void 0) parts.push(`iv:[${hashTableBorderValue(borders.insideV)}]`);
81581
+ return parts.join(";");
81582
+ };
81583
+ const hashCellBorders = (borders) => {
81584
+ if (!borders) return "";
81585
+ const parts = [];
81586
+ if (borders.top) parts.push(`t:[${hashBorderSpec(borders.top)}]`);
81587
+ if (borders.right) parts.push(`r:[${hashBorderSpec(borders.right)}]`);
81588
+ if (borders.bottom) parts.push(`b:[${hashBorderSpec(borders.bottom)}]`);
81589
+ if (borders.left) parts.push(`l:[${hashBorderSpec(borders.left)}]`);
81590
+ return parts.join(";");
81591
+ };
81400
81592
  const MAX_CACHE_SIZE$1 = 1e4;
81401
81593
  const BYTES_PER_ENTRY_ESTIMATE = 5e3;
81402
81594
  const NORMALIZED_WHITESPACE = /\s+/g;
@@ -81424,6 +81616,26 @@ const hashRuns = (block) => {
81424
81616
  continue;
81425
81617
  }
81426
81618
  for (const cell of row.cells) {
81619
+ if (cell.attrs) {
81620
+ const cellAttrs = cell.attrs;
81621
+ const cellAttrParts = [];
81622
+ if (cellAttrs.borders) {
81623
+ cellAttrParts.push(`cb:${hashCellBorders(cellAttrs.borders)}`);
81624
+ }
81625
+ if (cellAttrs.padding) {
81626
+ const p = cellAttrs.padding;
81627
+ cellAttrParts.push(`cp:${p.top ?? 0}:${p.right ?? 0}:${p.bottom ?? 0}:${p.left ?? 0}`);
81628
+ }
81629
+ if (cellAttrs.verticalAlign) {
81630
+ cellAttrParts.push(`va:${cellAttrs.verticalAlign}`);
81631
+ }
81632
+ if (cellAttrs.background) {
81633
+ cellAttrParts.push(`bg:${cellAttrs.background}`);
81634
+ }
81635
+ if (cellAttrParts.length > 0) {
81636
+ cellHashes.push(`ca:${cellAttrParts.join(":")}`);
81637
+ }
81638
+ }
81427
81639
  const cellBlocks = cell.blocks ?? (cell.paragraph ? [cell.paragraph] : []);
81428
81640
  for (const cellBlock of cellBlocks) {
81429
81641
  const paragraphBlock = cellBlock;
@@ -81490,8 +81702,25 @@ const hashRuns = (block) => {
81490
81702
  }
81491
81703
  }
81492
81704
  }
81705
+ let tableAttrsKey = "";
81706
+ if (tableBlock.attrs) {
81707
+ const tblAttrs = tableBlock.attrs;
81708
+ const tableAttrParts = [];
81709
+ if (tblAttrs.borders) {
81710
+ tableAttrParts.push(`tb:${hashTableBorders(tblAttrs.borders)}`);
81711
+ }
81712
+ if (tblAttrs.borderCollapse) {
81713
+ tableAttrParts.push(`bc:${tblAttrs.borderCollapse}`);
81714
+ }
81715
+ if (tblAttrs.cellSpacing !== void 0) {
81716
+ tableAttrParts.push(`cs:${tblAttrs.cellSpacing}`);
81717
+ }
81718
+ if (tableAttrParts.length > 0) {
81719
+ tableAttrsKey = `|ta:${tableAttrParts.join(":")}`;
81720
+ }
81721
+ }
81493
81722
  const contentHash = cellHashes.join("|");
81494
- return `${block.id}:table:${contentHash}`;
81723
+ return `${block.id}:table:${contentHash}${tableAttrsKey}`;
81495
81724
  }
81496
81725
  if (block.kind !== "paragraph") return block.id;
81497
81726
  const trackedMode = block.attrs && "trackedChangesMode" in block.attrs && block.attrs.trackedChangesMode || "review";
@@ -83013,17 +83242,67 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
83013
83242
  for (const [type2, value] of Object.entries(preHeaderLayouts)) {
83014
83243
  if (!isValidHeaderType(type2)) continue;
83015
83244
  if (value?.layout && typeof value.layout.height === "number") {
83016
- headerContentHeights[type2] = value.layout.height;
83245
+ const height = value.layout.height;
83246
+ if (Number.isFinite(height) && height >= 0) {
83247
+ headerContentHeights[type2] = height;
83248
+ }
83017
83249
  }
83018
83250
  }
83019
83251
  const hfPreEnd = performance.now();
83020
83252
  perfLog(`[Perf] 4.1.5 Pre-layout headers for height: ${(hfPreEnd - hfPreStart).toFixed(2)}ms`);
83021
83253
  }
83254
+ let footerContentHeights;
83255
+ if (headerFooter?.constraints && headerFooter.footerBlocks) {
83256
+ const footerPreStart = performance.now();
83257
+ const measureFn = headerFooter.measure ?? measureBlock2;
83258
+ if (!headerFooter.headerBlocks) {
83259
+ invalidateHeaderFooterCache(
83260
+ headerMeasureCache,
83261
+ headerFooterCacheState,
83262
+ headerFooter.headerBlocks,
83263
+ headerFooter.footerBlocks,
83264
+ headerFooter.constraints,
83265
+ options.sectionMetadata
83266
+ );
83267
+ }
83268
+ const FOOTER_PRELAYOUT_PLACEHOLDER_PAGE_COUNT = 1;
83269
+ try {
83270
+ const preFooterLayouts = await layoutHeaderFooterWithCache(
83271
+ headerFooter.footerBlocks,
83272
+ headerFooter.constraints,
83273
+ measureFn,
83274
+ headerMeasureCache,
83275
+ FOOTER_PRELAYOUT_PLACEHOLDER_PAGE_COUNT,
83276
+ void 0
83277
+ // No page resolver needed for height calculation
83278
+ );
83279
+ const isValidFooterType = (key2) => {
83280
+ return ["default", "first", "even", "odd"].includes(key2);
83281
+ };
83282
+ footerContentHeights = {};
83283
+ for (const [type2, value] of Object.entries(preFooterLayouts)) {
83284
+ if (!isValidFooterType(type2)) continue;
83285
+ if (value?.layout && typeof value.layout.height === "number") {
83286
+ const height = value.layout.height;
83287
+ if (Number.isFinite(height) && height >= 0) {
83288
+ footerContentHeights[type2] = height;
83289
+ }
83290
+ }
83291
+ }
83292
+ } catch (error) {
83293
+ console.error("[Layout] Footer pre-layout failed:", error);
83294
+ footerContentHeights = void 0;
83295
+ }
83296
+ const footerPreEnd = performance.now();
83297
+ perfLog(`[Perf] 4.1.6 Pre-layout footers for height: ${(footerPreEnd - footerPreStart).toFixed(2)}ms`);
83298
+ }
83022
83299
  const layoutStart = performance.now();
83023
83300
  let layout = layoutDocument(nextBlocks, measures, {
83024
83301
  ...options,
83025
83302
  headerContentHeights,
83026
83303
  // Pass header heights to prevent overlap
83304
+ footerContentHeights,
83305
+ // Pass footer heights to prevent overlap
83027
83306
  remeasureParagraph: (block, maxWidth, firstLineIndent) => remeasureParagraph(block, maxWidth, firstLineIndent)
83028
83307
  });
83029
83308
  const layoutEnd = performance.now();
@@ -83072,6 +83351,8 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
83072
83351
  ...options,
83073
83352
  headerContentHeights,
83074
83353
  // Pass header heights to prevent overlap
83354
+ footerContentHeights,
83355
+ // Pass footer heights to prevent overlap
83075
83356
  remeasureParagraph: (block, maxWidth, firstLineIndent) => remeasureParagraph(block, maxWidth, firstLineIndent)
83076
83357
  });
83077
83358
  const relayoutEnd = performance.now();
@@ -83238,6 +83519,285 @@ async function remeasureAffectedBlocks(blocks, measures, affectedBlockIds, const
83238
83519
  }
83239
83520
  return updatedMeasures;
83240
83521
  }
83522
+ class PageGeometryHelper {
83523
+ /**
83524
+ * Creates a new PageGeometryHelper instance.
83525
+ *
83526
+ * @param config - Page geometry configuration
83527
+ */
83528
+ constructor(config2) {
83529
+ this.cache = null;
83530
+ this.config = config2;
83531
+ }
83532
+ /**
83533
+ * Updates the layout and invalidates the cache.
83534
+ *
83535
+ * Call this whenever the layout changes (new pages, different heights, etc.)
83536
+ *
83537
+ * @param layout - New layout data
83538
+ * @param pageGap - Optional new page gap (if not provided, uses current gap)
83539
+ */
83540
+ updateLayout(layout, pageGap) {
83541
+ this.config.layout = layout;
83542
+ if (pageGap !== void 0) {
83543
+ this.config.pageGap = pageGap;
83544
+ }
83545
+ this.cache = null;
83546
+ }
83547
+ /**
83548
+ * Updates the page gap and invalidates the cache.
83549
+ *
83550
+ * @param pageGap - New gap between pages in pixels
83551
+ */
83552
+ updatePageGap(pageGap) {
83553
+ if (this.config.pageGap !== pageGap) {
83554
+ this.config.pageGap = pageGap;
83555
+ this.cache = null;
83556
+ }
83557
+ }
83558
+ /**
83559
+ * Gets the cumulative Y position (top edge) of a page in container space.
83560
+ *
83561
+ * The returned value is the distance from the top of the container to the
83562
+ * top of the specified page, accounting for all previous pages and gaps.
83563
+ *
83564
+ * @param pageIndex - Zero-based page index
83565
+ * @returns Y position in pixels, or 0 if page index is invalid
83566
+ *
83567
+ * @example
83568
+ * ```typescript
83569
+ * // Get Y position of page 0 (first page)
83570
+ * const y0 = helper.getPageTop(0); // Returns 0
83571
+ *
83572
+ * // Get Y position of page 2 (third page)
83573
+ * // Assumes page 0 height = 1000, page 1 height = 1200, gap = 24
83574
+ * const y2 = helper.getPageTop(2); // Returns 1000 + 24 + 1200 + 24 = 2248
83575
+ * ```
83576
+ */
83577
+ getPageTop(pageIndex) {
83578
+ this.ensureCache();
83579
+ if (pageIndex < 0 || pageIndex >= this.cache.cumulativeY.length) {
83580
+ return 0;
83581
+ }
83582
+ return this.cache.cumulativeY[pageIndex];
83583
+ }
83584
+ /**
83585
+ * Gets the height of a specific page.
83586
+ *
83587
+ * Uses per-page height if available (from layout.pages[i].size?.h),
83588
+ * otherwise falls back to layout.pageSize.h.
83589
+ *
83590
+ * @param pageIndex - Zero-based page index
83591
+ * @returns Page height in pixels, or 0 if page index is invalid
83592
+ *
83593
+ * @example
83594
+ * ```typescript
83595
+ * const height = helper.getPageHeight(0); // Returns page-specific height
83596
+ * ```
83597
+ */
83598
+ getPageHeight(pageIndex) {
83599
+ this.ensureCache();
83600
+ if (pageIndex < 0 || pageIndex >= this.cache.pageHeights.length) {
83601
+ return 0;
83602
+ }
83603
+ return this.cache.pageHeights[pageIndex];
83604
+ }
83605
+ /**
83606
+ * Gets the gap between pages.
83607
+ *
83608
+ * @returns Gap in pixels
83609
+ *
83610
+ * @example
83611
+ * ```typescript
83612
+ * const gap = helper.getPageGap(); // Returns 24
83613
+ * ```
83614
+ */
83615
+ getPageGap() {
83616
+ this.ensureCache();
83617
+ return this.cache.pageGap;
83618
+ }
83619
+ /**
83620
+ * Gets the total height of all pages including gaps.
83621
+ *
83622
+ * Total height = sum of all page heights + (pageCount - 1) * gap
83623
+ *
83624
+ * @returns Total height in pixels
83625
+ *
83626
+ * @example
83627
+ * ```typescript
83628
+ * // 3 pages: heights [1000, 1200, 1000], gap = 24
83629
+ * const total = helper.getTotalHeight();
83630
+ * // Returns 1000 + 24 + 1200 + 24 + 1000 = 3248
83631
+ * ```
83632
+ */
83633
+ getTotalHeight() {
83634
+ this.ensureCache();
83635
+ return this.cache.totalHeight;
83636
+ }
83637
+ /**
83638
+ * Gets the number of pages in the layout.
83639
+ *
83640
+ * @returns Page count
83641
+ */
83642
+ getPageCount() {
83643
+ return this.config.layout.pages.length;
83644
+ }
83645
+ /**
83646
+ * Finds the page index containing a given Y coordinate.
83647
+ *
83648
+ * This performs a linear search through cached cumulative positions.
83649
+ * For large documents, consider adding binary search optimization.
83650
+ *
83651
+ * @param containerY - Y coordinate in container space
83652
+ * @returns Page index, or null if Y is outside all pages
83653
+ *
83654
+ * @example
83655
+ * ```typescript
83656
+ * // Find which page contains Y = 1500
83657
+ * const pageIndex = helper.getPageIndexAtY(1500);
83658
+ * // Returns 1 (second page) if first page ends at Y=1024
83659
+ * ```
83660
+ */
83661
+ getPageIndexAtY(containerY) {
83662
+ this.ensureCache();
83663
+ const cache2 = this.cache;
83664
+ for (let i = 0; i < cache2.cumulativeY.length; i++) {
83665
+ const pageTop = cache2.cumulativeY[i];
83666
+ const pageBottom = pageTop + cache2.pageHeights[i];
83667
+ if (containerY >= pageTop && containerY < pageBottom) {
83668
+ return i;
83669
+ }
83670
+ }
83671
+ return null;
83672
+ }
83673
+ /**
83674
+ * Finds the nearest page index to a given Y coordinate (snap-to-nearest).
83675
+ *
83676
+ * Returns the page containing Y when inside a page; otherwise returns the
83677
+ * closest page based on distance to page center. Useful for dragging through
83678
+ * page gaps where getPageIndexAtY would return null.
83679
+ *
83680
+ * @param containerY - Y coordinate in container space
83681
+ * @returns Nearest page index, or null if there are no pages
83682
+ */
83683
+ getNearestPageIndex(containerY) {
83684
+ this.ensureCache();
83685
+ const cache2 = this.cache;
83686
+ const pageCount = cache2.pageHeights.length;
83687
+ if (pageCount === 0) return null;
83688
+ const direct = this.getPageIndexAtY(containerY);
83689
+ if (direct !== null) return direct;
83690
+ let nearestIndex = 0;
83691
+ let nearestDistance = Infinity;
83692
+ for (let i = 0; i < pageCount; i++) {
83693
+ const top2 = cache2.cumulativeY[i];
83694
+ const height = cache2.pageHeights[i];
83695
+ const center = top2 + height / 2;
83696
+ const distance = Math.abs(containerY - center);
83697
+ if (distance < nearestDistance) {
83698
+ nearestDistance = distance;
83699
+ nearestIndex = i;
83700
+ }
83701
+ }
83702
+ return nearestIndex;
83703
+ }
83704
+ /**
83705
+ * Ensures the cache is built and up-to-date.
83706
+ * Validates cache state and rebuilds if needed.
83707
+ * @private
83708
+ * @throws Never throws - handles errors gracefully with fallback values
83709
+ */
83710
+ ensureCache() {
83711
+ if (this.cache !== null) {
83712
+ if (!Array.isArray(this.cache.cumulativeY) || !Array.isArray(this.cache.pageHeights)) {
83713
+ console.warn("[PageGeometryHelper] Cache corruption detected, rebuilding cache");
83714
+ this.cache = null;
83715
+ } else {
83716
+ return;
83717
+ }
83718
+ }
83719
+ this.buildCache();
83720
+ }
83721
+ /**
83722
+ * Builds the geometry cache from current layout data.
83723
+ * Handles errors gracefully by providing fallback values.
83724
+ * @private
83725
+ * @throws Never throws - catches all errors and provides safe defaults
83726
+ */
83727
+ buildCache() {
83728
+ try {
83729
+ const layout = this.config.layout;
83730
+ if (!layout || !Array.isArray(layout.pages)) {
83731
+ throw new Error("Invalid layout: missing or invalid pages array");
83732
+ }
83733
+ const pageGap = this.config.pageGap ?? layout.pageGap ?? 0;
83734
+ const pageCount = layout.pages.length;
83735
+ if (!Number.isFinite(pageGap) || pageGap < 0) {
83736
+ throw new Error(`Invalid pageGap: ${pageGap} (must be non-negative finite number)`);
83737
+ }
83738
+ const cumulativeY = new Array(pageCount);
83739
+ const pageHeights = new Array(pageCount);
83740
+ let currentY = 0;
83741
+ for (let i = 0; i < pageCount; i++) {
83742
+ const page = layout.pages[i];
83743
+ if (!page) {
83744
+ throw new Error(`Invalid page at index ${i}: page is null or undefined`);
83745
+ }
83746
+ const pageHeight = page.size?.h ?? layout.pageSize.h;
83747
+ if (!Number.isFinite(pageHeight) || pageHeight < 0) {
83748
+ throw new Error(`Invalid page height at index ${i}: ${pageHeight} (must be non-negative finite number)`);
83749
+ }
83750
+ cumulativeY[i] = currentY;
83751
+ pageHeights[i] = pageHeight;
83752
+ currentY += pageHeight;
83753
+ if (i < pageCount - 1) {
83754
+ currentY += pageGap;
83755
+ }
83756
+ }
83757
+ const totalHeight = currentY;
83758
+ this.cache = {
83759
+ cumulativeY,
83760
+ pageHeights,
83761
+ pageGap,
83762
+ totalHeight,
83763
+ layoutVersion: 0
83764
+ // Placeholder for future version tracking
83765
+ };
83766
+ } catch (error) {
83767
+ const errorMessage = error instanceof Error ? error.message : String(error);
83768
+ console.error(`[PageGeometryHelper] Cache build failed: ${errorMessage}. Using fallback empty cache.`);
83769
+ this.cache = {
83770
+ cumulativeY: [],
83771
+ pageHeights: [],
83772
+ pageGap: 0,
83773
+ totalHeight: 0,
83774
+ layoutVersion: 0
83775
+ };
83776
+ }
83777
+ }
83778
+ /**
83779
+ * Clears the cache, forcing recalculation on next access.
83780
+ * Useful for testing or manual cache invalidation.
83781
+ */
83782
+ clearCache() {
83783
+ this.cache = null;
83784
+ }
83785
+ /**
83786
+ * Gets debug information about the current cache state.
83787
+ * @internal
83788
+ */
83789
+ getDebugInfo() {
83790
+ this.ensureCache();
83791
+ return {
83792
+ isCached: this.cache !== null,
83793
+ pageCount: this.config.layout.pages.length,
83794
+ pageGap: this.cache.pageGap,
83795
+ totalHeight: this.cache.totalHeight,
83796
+ cumulativeY: [...this.cache.cumulativeY],
83797
+ pageHeights: [...this.cache.pageHeights]
83798
+ };
83799
+ }
83800
+ }
83241
83801
  var Priority = /* @__PURE__ */ ((Priority2) => {
83242
83802
  Priority2[Priority2["P0"] = 0] = "P0";
83243
83803
  Priority2[Priority2["P1"] = 1] = "P1";
@@ -83531,18 +84091,41 @@ const rangesOverlap = (startA, endA, startB, endB) => {
83531
84091
  const effectiveEndA = endA ?? startA + 1;
83532
84092
  return effectiveEndA > startB && startA < endB;
83533
84093
  };
83534
- function hitTestPage(layout, point) {
84094
+ function hitTestPage(layout, point, geometryHelper) {
84095
+ if (geometryHelper) {
84096
+ const pageIndex = geometryHelper.getPageIndexAtY(point.y);
84097
+ if (pageIndex !== null) {
84098
+ return { pageIndex, page: layout.pages[pageIndex] };
84099
+ }
84100
+ const nearest = geometryHelper.getNearestPageIndex(point.y);
84101
+ if (nearest !== null) {
84102
+ return { pageIndex: nearest, page: layout.pages[nearest] };
84103
+ }
84104
+ return null;
84105
+ }
83535
84106
  const pageGap = layout.pageGap ?? 0;
83536
84107
  let cursorY = 0;
84108
+ let nearestIndex = null;
84109
+ let nearestDistance = Infinity;
83537
84110
  for (let pageIndex = 0; pageIndex < layout.pages.length; pageIndex += 1) {
83538
84111
  const page = layout.pages[pageIndex];
84112
+ const pageHeight = page.size?.h ?? layout.pageSize.h;
83539
84113
  const top2 = cursorY;
83540
- const bottom2 = top2 + layout.pageSize.h;
84114
+ const bottom2 = top2 + pageHeight;
83541
84115
  if (point.y >= top2 && point.y < bottom2) {
83542
84116
  return { pageIndex, page };
83543
84117
  }
84118
+ const center = top2 + pageHeight / 2;
84119
+ const distance = Math.abs(point.y - center);
84120
+ if (distance < nearestDistance) {
84121
+ nearestDistance = distance;
84122
+ nearestIndex = pageIndex;
84123
+ }
83544
84124
  cursorY = bottom2 + pageGap;
83545
84125
  }
84126
+ if (nearestIndex !== null) {
84127
+ return { pageIndex: nearestIndex, page: layout.pages[nearestIndex] };
84128
+ }
83546
84129
  return null;
83547
84130
  }
83548
84131
  function hitTestFragment(layout, pageHit, blocks, measures, point) {
@@ -83703,7 +84286,7 @@ const hitTestTableFragment = (pageHit, blocks, measures, point) => {
83703
84286
  }
83704
84287
  return null;
83705
84288
  };
83706
- function clickToPosition(layout, blocks, measures, containerPoint, domContainer, clientX, clientY) {
84289
+ function clickToPosition(layout, blocks, measures, containerPoint, domContainer, clientX, clientY, geometryHelper) {
83707
84290
  logClickStage("log", "entry", {
83708
84291
  pages: layout.pages.length
83709
84292
  });
@@ -83746,75 +84329,132 @@ function clickToPosition(layout, blocks, measures, containerPoint, domContainer,
83746
84329
  return { pos: domPos, blockId: "", pageIndex: 0, column: 0, lineIndex: -1 };
83747
84330
  }
83748
84331
  }
83749
- const pageHit = hitTestPage(layout, containerPoint);
84332
+ const pageHit = hitTestPage(layout, containerPoint, geometryHelper);
83750
84333
  if (!pageHit) {
83751
84334
  return null;
83752
84335
  }
83753
- const pageGap = layout.pageGap ?? 0;
84336
+ const pageTopY = geometryHelper ? geometryHelper.getPageTop(pageHit.pageIndex) : calculatePageTopFallback(layout, pageHit.pageIndex);
83754
84337
  const pageRelativePoint = {
83755
84338
  x: containerPoint.x,
83756
- y: containerPoint.y - pageHit.pageIndex * (layout.pageSize.h + pageGap)
84339
+ y: containerPoint.y - pageTopY
83757
84340
  };
83758
84341
  logClickStage("log", "page-hit", {
83759
84342
  pageIndex: pageHit.pageIndex
83760
84343
  });
83761
- const fragmentHit = hitTestFragment(layout, pageHit, blocks, measures, pageRelativePoint);
84344
+ let fragmentHit = hitTestFragment(layout, pageHit, blocks, measures, pageRelativePoint);
84345
+ if (!fragmentHit) {
84346
+ const page = pageHit.page;
84347
+ const fragments = page.fragments.filter(
84348
+ (f2) => f2 != null && typeof f2 === "object"
84349
+ );
84350
+ if (fragments.length > 0) {
84351
+ let nearest = null;
84352
+ let nearestDist = Infinity;
84353
+ for (const frag of fragments) {
84354
+ const top2 = frag.y;
84355
+ const bottom2 = frag.y + frag.height;
84356
+ let dist2;
84357
+ if (pageRelativePoint.y < top2) {
84358
+ dist2 = top2 - pageRelativePoint.y;
84359
+ } else if (pageRelativePoint.y > bottom2) {
84360
+ dist2 = pageRelativePoint.y - bottom2;
84361
+ } else {
84362
+ dist2 = 0;
84363
+ }
84364
+ if (dist2 < nearestDist) {
84365
+ nearestDist = dist2;
84366
+ nearest = frag;
84367
+ }
84368
+ }
84369
+ if (nearest) {
84370
+ const blockIndex = findBlockIndexByFragmentId(blocks, nearest.blockId);
84371
+ if (blockIndex !== -1) {
84372
+ const block = blocks[blockIndex];
84373
+ const measure = measures[blockIndex];
84374
+ if (block && measure) {
84375
+ fragmentHit = {
84376
+ fragment: nearest,
84377
+ block,
84378
+ measure,
84379
+ pageIndex: pageHit.pageIndex,
84380
+ pageY: 0
84381
+ };
84382
+ }
84383
+ }
84384
+ }
84385
+ }
84386
+ }
83762
84387
  if (fragmentHit) {
83763
84388
  const { fragment, block, measure, pageIndex, pageY } = fragmentHit;
83764
- if (fragment.kind !== "para" || measure.kind !== "paragraph" || block.kind !== "paragraph") {
83765
- logClickStage("warn", "fragment-type-mismatch", {
83766
- fragmentKind: fragment.kind,
83767
- measureKind: measure.kind,
83768
- blockKind: block.kind
84389
+ if (fragment.kind === "para" && measure.kind === "paragraph" && block.kind === "paragraph") {
84390
+ const lineIndex = findLineIndexAtY(measure, pageY, fragment.fromLine, fragment.toLine);
84391
+ if (lineIndex == null) {
84392
+ logClickStage("warn", "no-line", {
84393
+ blockId: fragment.blockId
84394
+ });
84395
+ return null;
84396
+ }
84397
+ const line = measure.lines[lineIndex];
84398
+ const isRTL = isRtlBlock(block);
84399
+ const indentLeft = typeof block.attrs?.indent?.left === "number" ? block.attrs.indent.left : 0;
84400
+ const indentRight = typeof block.attrs?.indent?.right === "number" ? block.attrs.indent.right : 0;
84401
+ const paraIndentLeft = Number.isFinite(indentLeft) ? indentLeft : 0;
84402
+ const paraIndentRight = Number.isFinite(indentRight) ? indentRight : 0;
84403
+ const totalIndent = paraIndentLeft + paraIndentRight;
84404
+ const availableWidth = Math.max(0, fragment.width - totalIndent);
84405
+ if (totalIndent > fragment.width) {
84406
+ console.warn(
84407
+ `[clickToPosition] Paragraph indents (${totalIndent}px) exceed fragment width (${fragment.width}px) for block ${fragment.blockId}. This may indicate a layout miscalculation. Available width clamped to 0.`
84408
+ );
84409
+ }
84410
+ const markerWidth = fragment.markerWidth ?? measure.marker?.markerWidth ?? 0;
84411
+ const isListItem3 = markerWidth > 0;
84412
+ const alignmentOverride = isListItem3 ? "left" : void 0;
84413
+ const pos = mapPointToPm(block, line, pageRelativePoint.x - fragment.x, isRTL, availableWidth, alignmentOverride);
84414
+ if (pos == null) {
84415
+ logClickStage("warn", "no-position", {
84416
+ blockId: fragment.blockId
84417
+ });
84418
+ return null;
84419
+ }
84420
+ const column = determineColumn(layout, fragment.x);
84421
+ logPositionDebug({
84422
+ blockId: fragment.blockId,
84423
+ x: pageRelativePoint.x - fragment.x
83769
84424
  });
83770
- return null;
83771
- }
83772
- const lineIndex = findLineIndexAtY(measure, pageY, fragment.fromLine, fragment.toLine);
83773
- if (lineIndex == null) {
83774
- logClickStage("warn", "no-line", {
84425
+ logClickStage("log", "success", {
83775
84426
  blockId: fragment.blockId
83776
84427
  });
83777
- return null;
83778
- }
83779
- const line = measure.lines[lineIndex];
83780
- const isRTL = isRtlBlock(block);
83781
- const indentLeft = typeof block.attrs?.indent?.left === "number" ? block.attrs.indent.left : 0;
83782
- const indentRight = typeof block.attrs?.indent?.right === "number" ? block.attrs.indent.right : 0;
83783
- const paraIndentLeft = Number.isFinite(indentLeft) ? indentLeft : 0;
83784
- const paraIndentRight = Number.isFinite(indentRight) ? indentRight : 0;
83785
- const totalIndent = paraIndentLeft + paraIndentRight;
83786
- const availableWidth = Math.max(0, fragment.width - totalIndent);
83787
- if (totalIndent > fragment.width) {
83788
- console.warn(
83789
- `[clickToPosition] Paragraph indents (${totalIndent}px) exceed fragment width (${fragment.width}px) for block ${fragment.blockId}. This may indicate a layout miscalculation. Available width clamped to 0.`
83790
- );
84428
+ return {
84429
+ pos,
84430
+ blockId: fragment.blockId,
84431
+ pageIndex,
84432
+ column,
84433
+ lineIndex
84434
+ // lineIndex is now already absolute (within measure.lines), no need to add fragment.fromLine
84435
+ };
83791
84436
  }
83792
- const markerWidth = fragment.markerWidth ?? measure.marker?.markerWidth ?? 0;
83793
- const isListItem3 = markerWidth > 0;
83794
- const alignmentOverride = isListItem3 ? "left" : void 0;
83795
- const pos = mapPointToPm(block, line, pageRelativePoint.x - fragment.x, isRTL, availableWidth, alignmentOverride);
83796
- if (pos == null) {
83797
- logClickStage("warn", "no-position", {
83798
- blockId: fragment.blockId
84437
+ if (isAtomicFragment(fragment)) {
84438
+ const pmRange = getAtomicPmRange(fragment, block);
84439
+ const pos = pmRange.pmStart ?? pmRange.pmEnd ?? null;
84440
+ if (pos == null) {
84441
+ logClickStage("warn", "atomic-without-range", {
84442
+ fragmentId: fragment.blockId
84443
+ });
84444
+ return null;
84445
+ }
84446
+ logClickStage("log", "success", {
84447
+ blockId: fragment.blockId,
84448
+ column: determineColumn(layout, fragment.x)
83799
84449
  });
83800
- return null;
84450
+ return {
84451
+ pos,
84452
+ blockId: fragment.blockId,
84453
+ pageIndex,
84454
+ column: determineColumn(layout, fragment.x),
84455
+ lineIndex: -1
84456
+ };
83801
84457
  }
83802
- const column = determineColumn(layout, fragment.x);
83803
- logPositionDebug({
83804
- blockId: fragment.blockId,
83805
- x: pageRelativePoint.x - fragment.x
83806
- });
83807
- logClickStage("log", "success", {
83808
- blockId: fragment.blockId
83809
- });
83810
- return {
83811
- pos,
83812
- blockId: fragment.blockId,
83813
- pageIndex,
83814
- column,
83815
- lineIndex
83816
- // lineIndex is now already absolute (within measure.lines), no need to add fragment.fromLine
83817
- };
83818
84458
  }
83819
84459
  const tableHit = hitTestTableFragment(pageHit, blocks, measures, pageRelativePoint);
83820
84460
  if (tableHit) {
@@ -83964,12 +84604,22 @@ const sumLineHeights = (measure, fromLine, toLine) => {
83964
84604
  }
83965
84605
  return height;
83966
84606
  };
83967
- function selectionToRects(layout, blocks, measures, from2, to) {
84607
+ const calculatePageTopFallback = (layout, pageIndex) => {
84608
+ const pageGap = layout.pageGap ?? 0;
84609
+ let y2 = 0;
84610
+ for (let i = 0; i < pageIndex; i++) {
84611
+ const pageHeight = layout.pages[i]?.size?.h ?? layout.pageSize.h;
84612
+ y2 += pageHeight + pageGap;
84613
+ }
84614
+ return y2;
84615
+ };
84616
+ function selectionToRects(layout, blocks, measures, from2, to, geometryHelper) {
83968
84617
  if (from2 === to) {
83969
84618
  return [];
83970
84619
  }
83971
84620
  const rects = [];
83972
84621
  layout.pages.forEach((page, pageIndex) => {
84622
+ const pageTopY = geometryHelper ? geometryHelper.getPageTop(pageIndex) : calculatePageTopFallback(layout, pageIndex);
83973
84623
  page.fragments.forEach((fragment) => {
83974
84624
  if (fragment.kind === "para") {
83975
84625
  const blockIndex = findBlockIndexByFragmentId(blocks, fragment.blockId, { from: from2, to });
@@ -84011,12 +84661,16 @@ function selectionToRects(layout, blocks, measures, from2, to) {
84011
84661
  wordLayout
84012
84662
  });
84013
84663
  const rectX = fragment.x + indentAdjust + Math.min(startX, endX);
84014
- const rectWidth = Math.max(1, Math.abs(endX - startX));
84664
+ const rectWidth = Math.max(
84665
+ 1,
84666
+ Math.min(Math.abs(endX - startX), line.width)
84667
+ // clamp to line width to prevent runaway widths
84668
+ );
84015
84669
  const lineOffset = lineHeightBeforeIndex(measure, index2) - lineHeightBeforeIndex(measure, fragment.fromLine);
84016
84670
  const rectY = fragment.y + lineOffset;
84017
84671
  rects.push({
84018
84672
  x: rectX,
84019
- y: rectY + pageIndex * (layout.pageSize.h + (layout.pageGap ?? 0)),
84673
+ y: rectY + pageTopY,
84020
84674
  width: rectWidth,
84021
84675
  height: line.lineHeight,
84022
84676
  pageIndex
@@ -84144,12 +84798,16 @@ function selectionToRects(layout, blocks, measures, from2, to) {
84144
84798
  wordLayout: cellWordLayout
84145
84799
  });
84146
84800
  const rectX = fragment.x + cellX + padding.left + textIndentAdjust + Math.min(startX, endX);
84147
- const rectWidth = Math.max(1, Math.abs(endX - startX));
84801
+ const rectWidth = Math.max(
84802
+ 1,
84803
+ Math.min(Math.abs(endX - startX), line.width)
84804
+ // clamp to line width to prevent runaway widths
84805
+ );
84148
84806
  const lineOffset = lineHeightBeforeIndex(info.measure, index2) - lineHeightBeforeIndex(info.measure, info.startLine);
84149
84807
  const rectY = fragment.y + rowOffset + blockTopCursor + lineOffset;
84150
84808
  rects.push({
84151
84809
  x: rectX,
84152
- y: rectY + pageIndex * (layout.pageSize.h + (layout.pageGap ?? 0)),
84810
+ y: rectY + pageTopY,
84153
84811
  width: rectWidth,
84154
84812
  height: line.lineHeight,
84155
84813
  pageIndex
@@ -84178,7 +84836,7 @@ function selectionToRects(layout, blocks, measures, from2, to) {
84178
84836
  if (!rangesOverlap(pmRange.pmStart, pmRange.pmEnd, from2, to)) return;
84179
84837
  rects.push({
84180
84838
  x: fragment.x,
84181
- y: fragment.y + pageIndex * (layout.pageSize.h + (layout.pageGap ?? 0)),
84839
+ y: fragment.y + pageTopY,
84182
84840
  width: fragment.width,
84183
84841
  height: fragment.height,
84184
84842
  pageIndex
@@ -85294,7 +85952,7 @@ async function measureParagraphBlock(block, maxWidth) {
85294
85952
  const wordEndWithSpace = charPosInRun + (isLastWord ? word.length : word.length + 1);
85295
85953
  const effectiveMaxWidth = currentLine ? currentLine.maxWidth : getEffectiveWidth(lines.length === 0 ? initialAvailableWidth : contentWidth);
85296
85954
  if (wordOnlyWidth > effectiveMaxWidth && word.length > 1) {
85297
- if (currentLine && currentLine.width > 0 && currentLine.segments.length > 0) {
85955
+ if (currentLine && currentLine.width > 0 && currentLine.segments && currentLine.segments.length > 0) {
85298
85956
  const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing, currentLine.maxFontInfo);
85299
85957
  const { spaceCount: _sc, ...lineBase } = currentLine;
85300
85958
  const completedLine = { ...lineBase, ...metrics };
@@ -85305,7 +85963,7 @@ async function measureParagraphBlock(block, maxWidth) {
85305
85963
  currentLine = null;
85306
85964
  }
85307
85965
  const lineMaxWidth = getEffectiveWidth(lines.length === 0 ? initialAvailableWidth : contentWidth);
85308
- const hasTabOnlyLine = currentLine && currentLine.segments.length === 0 && currentLine.width > 0;
85966
+ const hasTabOnlyLine = currentLine && currentLine.segments && currentLine.segments.length === 0 && currentLine.width > 0;
85309
85967
  const remainingWidthAfterTab = hasTabOnlyLine ? currentLine.maxWidth - currentLine.width : lineMaxWidth;
85310
85968
  const chunkWidth = hasTabOnlyLine ? Math.max(remainingWidthAfterTab, lineMaxWidth * 0.25) : lineMaxWidth;
85311
85969
  const chunks = breakWordIntoChunks(word, chunkWidth - WIDTH_FUDGE_PX2, font, ctx2, run2);
@@ -85316,7 +85974,7 @@ async function measureParagraphBlock(block, maxWidth) {
85316
85974
  const chunkEndChar = chunkCharOffset + chunk.text.length;
85317
85975
  const isLastChunk = chunkIndex === chunks.length - 1;
85318
85976
  const isFirstChunk = chunkIndex === 0;
85319
- if (isFirstChunk && hasTabOnlyLine && currentLine) {
85977
+ if (isFirstChunk && hasTabOnlyLine && currentLine && currentLine.segments) {
85320
85978
  currentLine.toRun = runIndex;
85321
85979
  currentLine.toChar = chunkEndChar;
85322
85980
  currentLine.width = roundValue(currentLine.width + chunk.width);
@@ -86149,6 +86807,7 @@ const createHeaderFooterEditor = ({
86149
86807
  const fontSizeInPixles = fontSizePt * 1.3333;
86150
86808
  const lineHeight2 = fontSizeInPixles * 1.2;
86151
86809
  applyStyleIsolationClass(editorContainer);
86810
+ const isFooter = type2 === "footer";
86152
86811
  Object.assign(editorContainer.style, {
86153
86812
  padding: "0",
86154
86813
  margin: "0",
@@ -86163,7 +86822,7 @@ const createHeaderFooterEditor = ({
86163
86822
  fontFamily: fontFamilyCss || typeface,
86164
86823
  fontSize: `${fontSizeInPixles}px`,
86165
86824
  lineHeight: `${lineHeight2}px`,
86166
- overflow: "hidden",
86825
+ overflow: isFooter ? "visible" : "hidden",
86167
86826
  pointerEvents: "auto",
86168
86827
  // Critical: enables click interaction
86169
86828
  backgroundColor: "white"
@@ -87242,6 +87901,7 @@ class EditorOverlayManager {
87242
87901
  const editorContainer = __privateGet$1(this, _activeEditorHost).querySelector(".super-editor");
87243
87902
  if (editorContainer instanceof HTMLElement) {
87244
87903
  editorContainer.style.top = "0";
87904
+ editorContainer.style.transform = "";
87245
87905
  }
87246
87906
  }
87247
87907
  }
@@ -87417,6 +88077,7 @@ const DEFAULT_PAGE_SIZE = { w: 612, h: 792 };
87417
88077
  const DEFAULT_MARGINS = { top: 72, right: 72, bottom: 72, left: 72 };
87418
88078
  const DEFAULT_VIRTUALIZED_PAGE_GAP = 72;
87419
88079
  const DEFAULT_PAGE_GAP = 24;
88080
+ const DEFAULT_HORIZONTAL_PAGE_GAP = 20;
87420
88081
  const WORD_CHARACTER_REGEX = /[\p{L}\p{N}''_~-]/u;
87421
88082
  const MULTI_CLICK_TIME_THRESHOLD_MS = 400;
87422
88083
  const MULTI_CLICK_DISTANCE_THRESHOLD_PX = 5;
@@ -87440,6 +88101,7 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
87440
88101
  __privateAdd$1(this, _layoutOptions);
87441
88102
  __privateAdd$1(this, _layoutState, { blocks: [], measures: [], layout: null, bookmarks: /* @__PURE__ */ new Map() });
87442
88103
  __privateAdd$1(this, _domPainter, null);
88104
+ __privateAdd$1(this, _pageGeometryHelper, null);
87443
88105
  __privateAdd$1(this, _dragHandlerCleanup, null);
87444
88106
  __privateAdd$1(this, _layoutError, null);
87445
88107
  __privateAdd$1(this, _layoutErrorState, "healthy");
@@ -87592,7 +88254,8 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
87592
88254
  { x: x2, y: y2 },
87593
88255
  __privateGet$1(this, _viewportHost),
87594
88256
  event.clientX,
87595
- event.clientY
88257
+ event.clientY,
88258
+ __privateGet$1(this, _pageGeometryHelper) ?? void 0
87596
88259
  );
87597
88260
  const doc22 = __privateGet$1(this, _editor3).state?.doc;
87598
88261
  const hit = rawHit && doc22 ? { ...rawHit, pos: Math.max(0, Math.min(rawHit.pos, doc22.content.size)) } : rawHit;
@@ -87791,7 +88454,8 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
87791
88454
  { x: normalized.x, y: normalized.y },
87792
88455
  __privateGet$1(this, _viewportHost),
87793
88456
  event.clientX,
87794
- event.clientY
88457
+ event.clientY,
88458
+ __privateGet$1(this, _pageGeometryHelper) ?? void 0
87795
88459
  );
87796
88460
  if (!hit) return;
87797
88461
  const currentTableHit = __privateMethod$1(this, _PresentationEditor_instances, hitTestTable_fn).call(this, normalized.x, normalized.y);
@@ -88638,7 +89302,14 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
88638
89302
  return __privateMethod$1(this, _PresentationEditor_instances, computeHeaderFooterSelectionRects_fn).call(this, start2, end2);
88639
89303
  }
88640
89304
  if (!__privateGet$1(this, _layoutState).layout) return [];
88641
- const rects = selectionToRects(__privateGet$1(this, _layoutState).layout, __privateGet$1(this, _layoutState).blocks, __privateGet$1(this, _layoutState).measures, start2, end2) ?? [];
89305
+ const rects = selectionToRects(
89306
+ __privateGet$1(this, _layoutState).layout,
89307
+ __privateGet$1(this, _layoutState).blocks,
89308
+ __privateGet$1(this, _layoutState).measures,
89309
+ start2,
89310
+ end2,
89311
+ __privateGet$1(this, _pageGeometryHelper) ?? void 0
89312
+ ) ?? [];
88642
89313
  return rects;
88643
89314
  };
88644
89315
  const rawRects = layoutRectSource();
@@ -88903,6 +89574,7 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
88903
89574
  };
88904
89575
  }
88905
89576
  __privateSet(this, _domPainter, null);
89577
+ __privateSet(this, _pageGeometryHelper, null);
88906
89578
  __privateSet(this, _pendingDocChange, true);
88907
89579
  __privateMethod$1(this, _PresentationEditor_instances, scheduleRerender_fn).call(this);
88908
89580
  }
@@ -88935,7 +89607,16 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
88935
89607
  x: localX,
88936
89608
  y: headerPageIndex * headerPageHeight + (localY - headerPageIndex * headerPageHeight)
88937
89609
  };
88938
- const hit2 = clickToPosition(context.layout, context.blocks, context.measures, headerPoint) ?? null;
89610
+ const hit2 = clickToPosition(
89611
+ context.layout,
89612
+ context.blocks,
89613
+ context.measures,
89614
+ headerPoint,
89615
+ void 0,
89616
+ void 0,
89617
+ void 0,
89618
+ void 0
89619
+ ) ?? null;
88939
89620
  return hit2;
88940
89621
  }
88941
89622
  if (!__privateGet$1(this, _layoutState).layout) {
@@ -88948,7 +89629,8 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
88948
89629
  normalized,
88949
89630
  __privateGet$1(this, _viewportHost),
88950
89631
  clientX,
88951
- clientY
89632
+ clientY,
89633
+ __privateGet$1(this, _pageGeometryHelper) ?? void 0
88952
89634
  ) ?? null;
88953
89635
  return hit;
88954
89636
  }
@@ -89171,6 +89853,7 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
89171
89853
  __privateSet(this, _session, { mode: "body" });
89172
89854
  __privateSet(this, _activeHeaderFooterEditor, null);
89173
89855
  __privateSet(this, _domPainter, null);
89856
+ __privateSet(this, _pageGeometryHelper, null);
89174
89857
  (_a2 = __privateGet$1(this, _dragHandlerCleanup)) == null ? void 0 : _a2.call(this);
89175
89858
  __privateSet(this, _dragHandlerCleanup, null);
89176
89859
  __privateGet$1(this, _selectionOverlay2)?.remove();
@@ -89224,7 +89907,14 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
89224
89907
  if (!normalized) return false;
89225
89908
  const pmPos = __privateGet$1(this, _layoutState).bookmarks.get(normalized);
89226
89909
  if (pmPos == null) return false;
89227
- const rects = selectionToRects(layout, __privateGet$1(this, _layoutState).blocks, __privateGet$1(this, _layoutState).measures, pmPos, pmPos + 1) ?? [];
89910
+ const rects = selectionToRects(
89911
+ layout,
89912
+ __privateGet$1(this, _layoutState).blocks,
89913
+ __privateGet$1(this, _layoutState).measures,
89914
+ pmPos,
89915
+ pmPos + 1,
89916
+ __privateGet$1(this, _pageGeometryHelper) ?? void 0
89917
+ ) ?? [];
89228
89918
  const rect = rects[0];
89229
89919
  let pageIndex = rect?.pageIndex ?? null;
89230
89920
  if (pageIndex == null) {
@@ -89288,6 +89978,7 @@ _hiddenHost = /* @__PURE__ */ new WeakMap();
89288
89978
  _layoutOptions = /* @__PURE__ */ new WeakMap();
89289
89979
  _layoutState = /* @__PURE__ */ new WeakMap();
89290
89980
  _domPainter = /* @__PURE__ */ new WeakMap();
89981
+ _pageGeometryHelper = /* @__PURE__ */ new WeakMap();
89291
89982
  _dragHandlerCleanup = /* @__PURE__ */ new WeakMap();
89292
89983
  _layoutError = /* @__PURE__ */ new WeakMap();
89293
89984
  _layoutErrorState = /* @__PURE__ */ new WeakMap();
@@ -89520,18 +90211,19 @@ normalizeAwarenessStates_fn = function() {
89520
90211
  const normalized = /* @__PURE__ */ new Map();
89521
90212
  states?.forEach((aw, clientId) => {
89522
90213
  if (clientId === provider.awareness?.clientID) return;
89523
- if (!aw.cursor) return;
90214
+ const awState = aw;
90215
+ if (!awState.cursor) return;
89524
90216
  try {
89525
90217
  const anchor = relativePositionToAbsolutePosition(
89526
90218
  ystate.doc,
89527
90219
  ystate.type,
89528
- Y__namespace.createRelativePositionFromJSON(aw.cursor.anchor),
90220
+ Y__namespace.createRelativePositionFromJSON(awState.cursor.anchor),
89529
90221
  ystate.binding.mapping
89530
90222
  );
89531
90223
  const head = relativePositionToAbsolutePosition(
89532
90224
  ystate.doc,
89533
90225
  ystate.type,
89534
- Y__namespace.createRelativePositionFromJSON(aw.cursor.head),
90226
+ Y__namespace.createRelativePositionFromJSON(awState.cursor.head),
89535
90227
  ystate.binding.mapping
89536
90228
  );
89537
90229
  if (anchor === null || head === null) return;
@@ -89543,9 +90235,9 @@ normalizeAwarenessStates_fn = function() {
89543
90235
  normalized.set(clientId, {
89544
90236
  clientId,
89545
90237
  user: {
89546
- name: aw.user?.name,
89547
- email: aw.user?.email,
89548
- color: aw.user?.color || __privateMethod$1(this, _PresentationEditor_instances, getFallbackColor_fn).call(this, clientId)
90238
+ name: awState.user?.name,
90239
+ email: awState.user?.email,
90240
+ color: awState.user?.color || __privateMethod$1(this, _PresentationEditor_instances, getFallbackColor_fn).call(this, clientId)
89549
90241
  },
89550
90242
  anchor: clampedAnchor,
89551
90243
  head: clampedHead,
@@ -89746,7 +90438,7 @@ renderRemoteSelection_fn = function(cursor) {
89746
90438
  if (!layout || !blocks || !measures) return;
89747
90439
  const start2 = Math.min(cursor.anchor, cursor.head);
89748
90440
  const end2 = Math.max(cursor.anchor, cursor.head);
89749
- const rects = selectionToRects(layout, blocks, measures, start2, end2) ?? [];
90441
+ const rects = selectionToRects(layout, blocks, measures, start2, end2, __privateGet$1(this, _pageGeometryHelper) ?? void 0) ?? [];
89750
90442
  const color = __privateMethod$1(this, _PresentationEditor_instances, getValidatedColor_fn).call(this, cursor);
89751
90443
  const opacity = __privateGet$1(this, _layoutOptions).presence?.highlightOpacity ?? 0.35;
89752
90444
  const pageHeight = layout.pageSize?.h ?? __privateGet$1(this, _layoutOptions).pageSize?.h ?? DEFAULT_PAGE_SIZE.h;
@@ -90106,15 +90798,25 @@ hitTestTable_fn = function(normalizedX, normalizedY) {
90106
90798
  const configuredPageSize = __privateGet$1(this, _layoutOptions).pageSize ?? DEFAULT_PAGE_SIZE;
90107
90799
  let pageY = 0;
90108
90800
  let pageHit = null;
90109
- for (let i = 0; i < layout.pages.length; i++) {
90110
- const page = layout.pages[i];
90111
- const pageHeight = page.size?.h ?? configuredPageSize.h;
90112
- const gap = __privateGet$1(this, _layoutOptions).virtualization?.gap ?? DEFAULT_PAGE_GAP;
90113
- if (normalizedY >= pageY && normalizedY < pageY + pageHeight) {
90114
- pageHit = { pageIndex: i, page };
90115
- break;
90801
+ const geometryHelper = __privateGet$1(this, _pageGeometryHelper);
90802
+ if (geometryHelper) {
90803
+ const idx = geometryHelper.getPageIndexAtY(normalizedY) ?? geometryHelper.getNearestPageIndex(normalizedY);
90804
+ if (idx != null && layout.pages[idx]) {
90805
+ pageHit = { pageIndex: idx, page: layout.pages[idx] };
90806
+ pageY = geometryHelper.getPageTop(idx);
90807
+ }
90808
+ }
90809
+ if (!pageHit) {
90810
+ const gap = layout.pageGap ?? __privateMethod$1(this, _PresentationEditor_instances, getEffectivePageGap_fn).call(this);
90811
+ for (let i = 0; i < layout.pages.length; i++) {
90812
+ const page = layout.pages[i];
90813
+ const pageHeight = page.size?.h ?? configuredPageSize.h;
90814
+ if (normalizedY >= pageY && normalizedY < pageY + pageHeight) {
90815
+ pageHit = { pageIndex: i, page };
90816
+ break;
90817
+ }
90818
+ pageY += pageHeight + gap;
90116
90819
  }
90117
- pageY += pageHeight + gap;
90118
90820
  }
90119
90821
  if (!pageHit) {
90120
90822
  return null;
@@ -90366,12 +91068,7 @@ rerender_fn = async function() {
90366
91068
  return;
90367
91069
  }
90368
91070
  ({ layout, measures } = result);
90369
- if (__privateGet$1(this, _layoutOptions).virtualization?.enabled) {
90370
- const gap = __privateGet$1(this, _layoutOptions).virtualization.gap ?? DEFAULT_VIRTUALIZED_PAGE_GAP;
90371
- layout.pageGap = Math.max(0, gap);
90372
- } else {
90373
- layout.pageGap = DEFAULT_PAGE_GAP;
90374
- }
91071
+ layout.pageGap = __privateMethod$1(this, _PresentationEditor_instances, getEffectivePageGap_fn).call(this);
90375
91072
  headerLayouts = result.headers;
90376
91073
  footerLayouts = result.footers;
90377
91074
  } catch (error) {
@@ -90388,6 +91085,17 @@ rerender_fn = async function() {
90388
91085
  __privateSet(this, _layoutState, { blocks, measures, layout, bookmarks, anchorMap });
90389
91086
  __privateSet(this, _headerLayoutResults, headerLayouts ?? null);
90390
91087
  __privateSet(this, _footerLayoutResults, footerLayouts ?? null);
91088
+ if (__privateGet$1(this, _layoutState).layout) {
91089
+ const pageGap = __privateGet$1(this, _layoutState).layout.pageGap ?? __privateMethod$1(this, _PresentationEditor_instances, getEffectivePageGap_fn).call(this);
91090
+ if (!__privateGet$1(this, _pageGeometryHelper)) {
91091
+ __privateSet(this, _pageGeometryHelper, new PageGeometryHelper({
91092
+ layout: __privateGet$1(this, _layoutState).layout,
91093
+ pageGap
91094
+ }));
91095
+ } else {
91096
+ __privateGet$1(this, _pageGeometryHelper).updateLayout(__privateGet$1(this, _layoutState).layout, pageGap);
91097
+ }
91098
+ }
90391
91099
  await __privateMethod$1(this, _PresentationEditor_instances, layoutPerRIdHeaderFooters_fn).call(this, headerFooterInput, layout, sectionMetadata);
90392
91100
  __privateMethod$1(this, _PresentationEditor_instances, updateDecorationProviders_fn).call(this, layout);
90393
91101
  const painter = __privateMethod$1(this, _PresentationEditor_instances, ensurePainter_fn).call(this, blocks, measures);
@@ -90457,7 +91165,8 @@ ensurePainter_fn = function(blocks, measures) {
90457
91165
  pageStyles: __privateGet$1(this, _layoutOptions).pageStyles,
90458
91166
  headerProvider: __privateGet$1(this, _headerDecorationProvider),
90459
91167
  footerProvider: __privateGet$1(this, _footerDecorationProvider),
90460
- ruler: __privateGet$1(this, _layoutOptions).ruler
91168
+ ruler: __privateGet$1(this, _layoutOptions).ruler,
91169
+ pageGap: __privateGet$1(this, _layoutState).layout?.pageGap ?? __privateMethod$1(this, _PresentationEditor_instances, getEffectivePageGap_fn).call(this)
90461
91170
  }));
90462
91171
  }
90463
91172
  return __privateGet$1(this, _domPainter);
@@ -90545,7 +91254,14 @@ updateSelection_fn = function() {
90545
91254
  }
90546
91255
  return;
90547
91256
  }
90548
- const rects = selectionToRects(layout, __privateGet$1(this, _layoutState).blocks, __privateGet$1(this, _layoutState).measures, from2, to) ?? [];
91257
+ const rects = selectionToRects(
91258
+ layout,
91259
+ __privateGet$1(this, _layoutState).blocks,
91260
+ __privateGet$1(this, _layoutState).measures,
91261
+ from2,
91262
+ to,
91263
+ __privateGet$1(this, _pageGeometryHelper) ?? void 0
91264
+ ) ?? [];
90549
91265
  let domStart = null;
90550
91266
  let domEnd = null;
90551
91267
  try {
@@ -90559,7 +91275,9 @@ updateSelection_fn = function() {
90559
91275
  const correctedRects = __privateMethod$1(this, _PresentationEditor_instances, applyDomCorrectionToRects_fn).call(this, rects, domStart, domEnd);
90560
91276
  try {
90561
91277
  __privateGet$1(this, _localSelectionLayer).innerHTML = "";
90562
- __privateMethod$1(this, _PresentationEditor_instances, renderSelectionRects_fn).call(this, correctedRects);
91278
+ if (correctedRects.length > 0) {
91279
+ __privateMethod$1(this, _PresentationEditor_instances, renderSelectionRects_fn).call(this, correctedRects);
91280
+ }
90563
91281
  } catch (error) {
90564
91282
  if (process$1$1.env.NODE_ENV === "development") {
90565
91283
  console.warn("[PresentationEditor] Failed to render selection rects:", error);
@@ -90751,8 +91469,10 @@ createDecorationProvider_fn = function(kind, layout) {
90751
91469
  const pageHeight2 = page?.size?.h ?? layout.pageSize?.h ?? __privateGet$1(this, _layoutOptions).pageSize?.h ?? DEFAULT_PAGE_SIZE.h;
90752
91470
  const margins2 = pageMargins ?? layout.pages[0]?.margins ?? __privateGet$1(this, _layoutOptions).margins ?? DEFAULT_MARGINS;
90753
91471
  const box2 = __privateMethod$1(this, _PresentationEditor_instances, computeDecorationBox_fn).call(this, kind, margins2, pageHeight2);
91472
+ const layoutMinY2 = rIdLayout.layout.minY ?? 0;
91473
+ const normalizedFragments2 = layoutMinY2 < 0 ? fragments2.map((f2) => ({ ...f2, y: f2.y - layoutMinY2 })) : fragments2;
90754
91474
  return {
90755
- fragments: fragments2,
91475
+ fragments: normalizedFragments2,
90756
91476
  height: box2.height,
90757
91477
  contentHeight: rIdLayout.layout.height ?? box2.height,
90758
91478
  offset: box2.offset,
@@ -90760,6 +91480,7 @@ createDecorationProvider_fn = function(kind, layout) {
90760
91480
  contentWidth: box2.width,
90761
91481
  headerId: sectionRId,
90762
91482
  sectionType: headerFooterType,
91483
+ minY: layoutMinY2,
90763
91484
  box: {
90764
91485
  x: box2.x,
90765
91486
  y: box2.offset,
@@ -90792,8 +91513,10 @@ createDecorationProvider_fn = function(kind, layout) {
90792
91513
  const box = __privateMethod$1(this, _PresentationEditor_instances, computeDecorationBox_fn).call(this, kind, margins, pageHeight);
90793
91514
  const fallbackId = __privateGet$1(this, _headerFooterManager)?.getVariantId(kind, headerFooterType);
90794
91515
  const finalHeaderId = sectionRId ?? fallbackId ?? void 0;
91516
+ const layoutMinY = variant.layout.minY ?? 0;
91517
+ const normalizedFragments = layoutMinY < 0 ? fragments.map((f2) => ({ ...f2, y: f2.y - layoutMinY })) : fragments;
90795
91518
  return {
90796
- fragments,
91519
+ fragments: normalizedFragments,
90797
91520
  height: box.height,
90798
91521
  contentHeight: variant.layout.height ?? box.height,
90799
91522
  offset: box.offset,
@@ -90801,6 +91524,7 @@ createDecorationProvider_fn = function(kind, layout) {
90801
91524
  contentWidth: box.width,
90802
91525
  headerId: finalHeaderId,
90803
91526
  sectionType: headerFooterType,
91527
+ minY: layoutMinY,
90804
91528
  box: {
90805
91529
  x: box.x,
90806
91530
  y: box.offset,
@@ -90915,7 +91639,9 @@ rebuildHeaderFooterRegions_fn = function(layout) {
90915
91639
  localX: footerPayload?.hitRegion?.x ?? footerBox.x,
90916
91640
  localY: footerPayload?.hitRegion?.y ?? footerBox.offset,
90917
91641
  width: footerPayload?.hitRegion?.width ?? footerBox.width,
90918
- height: footerPayload?.hitRegion?.height ?? footerBox.height
91642
+ height: footerPayload?.hitRegion?.height ?? footerBox.height,
91643
+ contentHeight: footerPayload?.contentHeight,
91644
+ minY: footerPayload?.minY
90919
91645
  });
90920
91646
  });
90921
91647
  };
@@ -91045,6 +91771,18 @@ enterHeaderFooterMode_fn = async function(region) {
91045
91771
  });
91046
91772
  return;
91047
91773
  }
91774
+ if (region.kind === "footer") {
91775
+ const editorContainer = editorHost.firstElementChild;
91776
+ if (editorContainer instanceof HTMLElement) {
91777
+ editorContainer.style.overflow = "visible";
91778
+ if (region.minY != null && region.minY < 0) {
91779
+ const shiftDown = Math.abs(region.minY);
91780
+ editorContainer.style.transform = `translateY(${shiftDown}px)`;
91781
+ } else {
91782
+ editorContainer.style.transform = "";
91783
+ }
91784
+ }
91785
+ }
91048
91786
  try {
91049
91787
  editor.setEditable(true);
91050
91788
  editor.setOptions({ documentMode: "editing" });
@@ -91327,6 +92065,15 @@ waitForPageMount_fn = async function(pageIndex, options = {}) {
91327
92065
  checkPage();
91328
92066
  });
91329
92067
  };
92068
+ getEffectivePageGap_fn = function() {
92069
+ if (__privateGet$1(this, _layoutOptions).virtualization?.enabled) {
92070
+ return Math.max(0, __privateGet$1(this, _layoutOptions).virtualization.gap ?? DEFAULT_VIRTUALIZED_PAGE_GAP);
92071
+ }
92072
+ if (__privateGet$1(this, _layoutOptions).layoutMode === "horizontal") {
92073
+ return DEFAULT_HORIZONTAL_PAGE_GAP;
92074
+ }
92075
+ return DEFAULT_PAGE_GAP;
92076
+ };
91330
92077
  getBodyPageHeight_fn = function() {
91331
92078
  return __privateGet$1(this, _layoutState).layout?.pageSize?.h ?? __privateGet$1(this, _layoutOptions).pageSize?.h ?? DEFAULT_PAGE_SIZE.h;
91332
92079
  };
@@ -91350,7 +92097,7 @@ applyDomCorrectionToRects_fn = function(rects, domStart, domEnd) {
91350
92097
  dy: domStart.y - layoutY
91351
92098
  };
91352
92099
  }
91353
- return rects.map((rect, idx) => {
92100
+ const corrected = rects.map((rect, idx) => {
91354
92101
  const delta = pageDelta[rect.pageIndex];
91355
92102
  let adjustedX = delta ? rect.x + delta.dx : rect.x;
91356
92103
  let adjustedY = delta ? rect.y + delta.dy : rect.y;
@@ -91365,6 +92112,7 @@ applyDomCorrectionToRects_fn = function(rects, domStart, domEnd) {
91365
92112
  }
91366
92113
  if (isLastRect && domEnd && rect.pageIndex === domEnd.pageIndex) {
91367
92114
  const endX = domEnd.x;
92115
+ adjustedX = Math.min(adjustedX, endX);
91368
92116
  adjustedWidth = Math.max(1, endX - adjustedX);
91369
92117
  }
91370
92118
  return {
@@ -91374,6 +92122,29 @@ applyDomCorrectionToRects_fn = function(rects, domStart, domEnd) {
91374
92122
  width: adjustedWidth
91375
92123
  };
91376
92124
  });
92125
+ const MAX_DELTA_PX = 12;
92126
+ let invalid = false;
92127
+ if (domStart && corrected[0]) {
92128
+ const dx = Math.abs(corrected[0].x - domStart.x);
92129
+ const dy = Math.abs(corrected[0].y - domStart.y);
92130
+ if (dx > MAX_DELTA_PX || dy > MAX_DELTA_PX) invalid = true;
92131
+ }
92132
+ if (domEnd && corrected[corrected.length - 1]) {
92133
+ const last = corrected[corrected.length - 1];
92134
+ const dx = Math.abs(last.x + last.width - domEnd.x);
92135
+ const dy = Math.abs(last.y - domEnd.y);
92136
+ if (dx > MAX_DELTA_PX || dy > MAX_DELTA_PX) invalid = true;
92137
+ }
92138
+ if (invalid) {
92139
+ console.warn("[SelectionOverlay] Suppressing selection render due to large DOM/Layout mismatch", {
92140
+ domStart,
92141
+ domEnd,
92142
+ rectStart: corrected[0],
92143
+ rectEnd: corrected[corrected.length - 1]
92144
+ });
92145
+ return [];
92146
+ }
92147
+ return corrected;
91377
92148
  };
91378
92149
  renderCellSelectionOverlay_fn = function(selection, layout) {
91379
92150
  const localSelectionLayer = __privateGet$1(this, _localSelectionLayer);
@@ -91657,7 +92428,7 @@ computeHeaderFooterSelectionRects_fn = function(from2, to) {
91657
92428
  return [];
91658
92429
  }
91659
92430
  if (!bodyLayout) return [];
91660
- const rects = selectionToRects(context.layout, context.blocks, context.measures, from2, to) ?? [];
92431
+ const rects = selectionToRects(context.layout, context.blocks, context.measures, from2, to, void 0) ?? [];
91661
92432
  const headerPageHeight = context.layout.pageSize?.h ?? context.region.height ?? 1;
91662
92433
  const bodyPageHeight = __privateMethod$1(this, _PresentationEditor_instances, getBodyPageHeight_fn).call(this);
91663
92434
  return rects.map((rect) => {
@@ -91940,8 +92711,8 @@ computeCaretLayoutRectGeometry_fn = function(pos, includeDomFallback = true) {
91940
92711
  const zoom2 = __privateGet$1(this, _layoutOptions).zoom ?? 1;
91941
92712
  let domCaretX2 = null;
91942
92713
  let domCaretY2 = null;
91943
- const spanEls2 = pageEl2?.querySelectorAll("span[data-pm-start][data-pm-end]") ?? [];
91944
- for (const spanEl of spanEls2) {
92714
+ const spanEls2 = pageEl2?.querySelectorAll("span[data-pm-start][data-pm-end]");
92715
+ for (const spanEl of Array.from(spanEls2 ?? [])) {
91945
92716
  const pmStart = Number(spanEl.dataset.pmStart);
91946
92717
  const pmEnd = Number(spanEl.dataset.pmEnd);
91947
92718
  if (pos >= pmStart && pos <= pmEnd && spanEl.firstChild?.nodeType === Node.TEXT_NODE) {
@@ -91993,8 +92764,8 @@ computeCaretLayoutRectGeometry_fn = function(pos, includeDomFallback = true) {
91993
92764
  const zoom = __privateGet$1(this, _layoutOptions).zoom ?? 1;
91994
92765
  let domCaretX = null;
91995
92766
  let domCaretY = null;
91996
- const spanEls = pageEl?.querySelectorAll("span[data-pm-start][data-pm-end]") ?? [];
91997
- for (const spanEl of spanEls) {
92767
+ const spanEls = pageEl?.querySelectorAll("span[data-pm-start][data-pm-end]");
92768
+ for (const spanEl of Array.from(spanEls ?? [])) {
91998
92769
  const pmStart = Number(spanEl.dataset.pmStart);
91999
92770
  const pmEnd = Number(spanEl.dataset.pmEnd);
92000
92771
  if (pos >= pmStart && pos <= pmEnd && spanEl.firstChild?.nodeType === Node.TEXT_NODE) {
@@ -92124,7 +92895,14 @@ getCurrentPageIndex_fn = function() {
92124
92895
  if (!layout || !selection) {
92125
92896
  return 0;
92126
92897
  }
92127
- const rects = selectionToRects(layout, __privateGet$1(this, _layoutState).blocks, __privateGet$1(this, _layoutState).measures, selection.from, selection.to) ?? [];
92898
+ const rects = selectionToRects(
92899
+ layout,
92900
+ __privateGet$1(this, _layoutState).blocks,
92901
+ __privateGet$1(this, _layoutState).measures,
92902
+ selection.from,
92903
+ selection.to,
92904
+ __privateGet$1(this, _pageGeometryHelper) ?? void 0
92905
+ ) ?? [];
92128
92906
  if (rects.length > 0) {
92129
92907
  return rects[0]?.pageIndex ?? 0;
92130
92908
  }
@@ -97556,14 +98334,19 @@ const createCell = (cellType, cellContent = null) => {
97556
98334
  }
97557
98335
  return cellType.createAndFill();
97558
98336
  };
97559
- const createTableBorders = ({ size: size2 = 0.66665, color = "#000000" } = {}) => {
98337
+ const createTableBorders = (borderSpec = {}) => {
98338
+ borderSpec = {
98339
+ size: 0.66665,
98340
+ color: "#000000",
98341
+ ...borderSpec
98342
+ };
97560
98343
  return {
97561
- top: { size: size2, color },
97562
- left: { size: size2, color },
97563
- bottom: { size: size2, color },
97564
- right: { size: size2, color },
97565
- insideH: { size: size2, color },
97566
- insideV: { size: size2, color }
98344
+ top: borderSpec,
98345
+ left: borderSpec,
98346
+ bottom: borderSpec,
98347
+ right: borderSpec,
98348
+ insideH: borderSpec,
98349
+ insideV: borderSpec
97567
98350
  };
97568
98351
  };
97569
98352
  const createTable = (schema, rowsCount, colsCount, withHeaderRow, cellContent = null) => {
@@ -97691,12 +98474,17 @@ const deleteTableWhenSelected = ({ editor }) => {
97691
98474
  editor.commands.deleteTable();
97692
98475
  return true;
97693
98476
  };
97694
- const createCellBorders = ({ size: size2 = 0.66665, color = "#000000" } = {}) => {
98477
+ const createCellBorders = (borderSpec = {}) => {
98478
+ borderSpec = {
98479
+ size: 0.66665,
98480
+ color: "#000000",
98481
+ ...borderSpec
98482
+ };
97695
98483
  return {
97696
- top: { size: size2, color },
97697
- left: { size: size2, color },
97698
- bottom: { size: size2, color },
97699
- right: { size: size2, color }
98484
+ top: borderSpec,
98485
+ left: borderSpec,
98486
+ bottom: borderSpec,
98487
+ right: borderSpec
97700
98488
  };
97701
98489
  };
97702
98490
  function cellAround($pos) {
@@ -98463,13 +99251,20 @@ const Table = Node$1.create({
98463
99251
  if (["tableCell", "tableHeader"].includes(node.type.name)) {
98464
99252
  tr.setNodeMarkup(pos, void 0, {
98465
99253
  ...node.attrs,
98466
- borders: createCellBorders({ size: 0 })
99254
+ borders: createCellBorders({ size: 0, space: 0, val: "none", color: "auto" })
98467
99255
  });
98468
99256
  }
98469
99257
  });
98470
99258
  tr.setNodeMarkup(table.pos, void 0, {
98471
99259
  ...table.node.attrs,
98472
- borders: createTableBorders({ size: 0 })
99260
+ borders: createTableBorders({ size: 0 }),
99261
+ // TODO: This works around the issue that table borders are duplicated between
99262
+ // the attributes of the table and the tableProperties attribute.
99263
+ // This can be removed when the redundancy is eliminated.
99264
+ tableProperties: {
99265
+ ...table.node.attrs.tableProperties,
99266
+ borders: createTableBorders({ size: 0, space: 0, val: "none", color: "auto" })
99267
+ }
98473
99268
  });
98474
99269
  return true;
98475
99270
  }
@@ -122471,7 +123266,7 @@ const makeDefaultItems = ({
122471
123266
  }
122472
123267
  },
122473
123268
  {
122474
- label: toolbarTexts2.transparentBorders,
123269
+ label: toolbarTexts2.removeBorders,
122475
123270
  command: "deleteCellAndTableBorders",
122476
123271
  icon: toolbarIcons2.deleteBorders,
122477
123272
  bottomBorder: true,
@@ -123052,7 +123847,7 @@ const toolbarTexts = {
123052
123847
  deleteRow: "Delete row",
123053
123848
  deleteColumn: "Delete column",
123054
123849
  deleteTable: "Delete table",
123055
- transparentBorders: "Transparent borders",
123850
+ removeBorders: "Remove borders",
123056
123851
  mergeCells: "Merge cells",
123057
123852
  splitCell: "Split cell",
123058
123853
  fixTables: "Fix tables",
@@ -124090,7 +124885,7 @@ const TEXTS = {
124090
124885
  deleteRow: "Delete row",
124091
124886
  deleteColumn: "Delete column",
124092
124887
  deleteTable: "Delete table",
124093
- transparentBorders: "Transparent borders",
124888
+ removeBorders: "Remove borders",
124094
124889
  mergeCells: "Merge cells",
124095
124890
  splitCell: "Split cell",
124096
124891
  fixTables: "Fix tables",
@@ -124173,7 +124968,7 @@ const tableActionsOptions = [
124173
124968
  }
124174
124969
  },
124175
124970
  {
124176
- label: TEXTS.transparentBorders,
124971
+ label: TEXTS.removeBorders,
124177
124972
  command: "deleteCellAndTableBorders",
124178
124973
  icon: ICONS.deleteBorders,
124179
124974
  bottomBorder: true,