@harbour-enterprises/superdoc 1.0.0-beta.30 → 1.0.0-beta.32

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 (27) hide show
  1. package/dist/chunks/{PdfViewer-BADCvUNL.cjs → PdfViewer-CTKbqDWv.cjs} +1 -1
  2. package/dist/chunks/{PdfViewer-C2nY5qD8.es.js → PdfViewer-edjIRb_p.es.js} +1 -1
  3. package/dist/chunks/{index-DTgPk1zO.cjs → index-Cajp7-Xa.cjs} +3 -3
  4. package/dist/chunks/{index-DmelLGEj.es.js → index-Pwv0a9G5.es.js} +3 -3
  5. package/dist/chunks/{index-DUzV7kkk-BvBMF_lo.es.js → index-SGV4U12y-BPGxOtvI.es.js} +1 -1
  6. package/dist/chunks/{index-DUzV7kkk-CM3uwGCb.cjs → index-SGV4U12y-Dh5jaROA.cjs} +1 -1
  7. package/dist/chunks/{super-editor.es-463G9jKM.cjs → super-editor.es-BbbbKgEs.cjs} +1729 -105
  8. package/dist/chunks/{super-editor.es-Be9785LD.es.js → super-editor.es-CdGsYGU1.es.js} +1729 -105
  9. package/dist/super-editor/ai-writer.es.js +2 -2
  10. package/dist/super-editor/chunks/{converter-U59bT3FO.js → converter-CpuOoAUa.js} +1 -1
  11. package/dist/super-editor/chunks/{docx-zipper-DSnoGkju.js → docx-zipper-Dk99r397.js} +1 -1
  12. package/dist/super-editor/chunks/{editor-DRHVtMIR.js → editor-CFv-RJI-.js} +1776 -90
  13. package/dist/super-editor/chunks/{index-DUzV7kkk.js → index-SGV4U12y.js} +1 -1
  14. package/dist/super-editor/chunks/{toolbar-DbBLxo6N.js → toolbar-CQr3Xnx9.js} +2 -2
  15. package/dist/super-editor/converter.es.js +1 -1
  16. package/dist/super-editor/docx-zipper.es.js +2 -2
  17. package/dist/super-editor/editor.es.js +3 -3
  18. package/dist/super-editor/file-zipper.es.js +1 -1
  19. package/dist/super-editor/super-editor.es.js +6 -6
  20. package/dist/super-editor/toolbar.es.js +2 -2
  21. package/dist/super-editor.cjs +1 -1
  22. package/dist/super-editor.es.js +1 -1
  23. package/dist/superdoc.cjs +2 -2
  24. package/dist/superdoc.es.js +2 -2
  25. package/dist/superdoc.umd.js +1715 -91
  26. package/dist/superdoc.umd.js.map +1 -1
  27. package/package.json +1 -1
@@ -9323,14 +9323,14 @@ function requireSax() {
9323
9323
  var nameBody = /[:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u00B7\u0300-\u036F\u203F-\u2040.\d-]/;
9324
9324
  var entityStart = /[#:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/;
9325
9325
  var entityBody = /[#:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u00B7\u0300-\u036F\u203F-\u2040.\d-]/;
9326
- function isWhitespace(c2) {
9326
+ function isWhitespace2(c2) {
9327
9327
  return c2 === " " || c2 === "\n" || c2 === "\r" || c2 === " ";
9328
9328
  }
9329
9329
  function isQuote(c2) {
9330
9330
  return c2 === '"' || c2 === "'";
9331
9331
  }
9332
9332
  function isAttribEnd(c2) {
9333
- return c2 === ">" || isWhitespace(c2);
9333
+ return c2 === ">" || isWhitespace2(c2);
9334
9334
  }
9335
9335
  function isMatch(regex, c2) {
9336
9336
  return regex.test(c2);
@@ -9955,7 +9955,7 @@ function requireSax() {
9955
9955
  if (c2 === "<") {
9956
9956
  parser.state = S2.OPEN_WAKA;
9957
9957
  parser.startTagPosition = parser.position;
9958
- } else if (!isWhitespace(c2)) {
9958
+ } else if (!isWhitespace2(c2)) {
9959
9959
  strictFail(parser, "Non-whitespace before first tag.");
9960
9960
  parser.textNode = c2;
9961
9961
  parser.state = S2.TEXT;
@@ -10034,7 +10034,7 @@ function requireSax() {
10034
10034
  parser.state = S2.OPEN_WAKA;
10035
10035
  parser.startTagPosition = parser.position;
10036
10036
  } else {
10037
- if (!isWhitespace(c2) && (!parser.sawRoot || parser.closedRoot)) {
10037
+ if (!isWhitespace2(c2) && (!parser.sawRoot || parser.closedRoot)) {
10038
10038
  strictFail(parser, "Text data outside of root node.");
10039
10039
  }
10040
10040
  if (c2 === "&") {
@@ -10063,7 +10063,7 @@ function requireSax() {
10063
10063
  if (c2 === "!") {
10064
10064
  parser.state = S2.SGML_DECL;
10065
10065
  parser.sgmlDecl = "";
10066
- } else if (isWhitespace(c2)) ;
10066
+ } else if (isWhitespace2(c2)) ;
10067
10067
  else if (isMatch(nameStart, c2)) {
10068
10068
  parser.state = S2.OPEN_TAG;
10069
10069
  parser.tagName = c2;
@@ -10247,14 +10247,14 @@ function requireSax() {
10247
10247
  case S2.PROC_INST:
10248
10248
  if (c2 === "?") {
10249
10249
  parser.state = S2.PROC_INST_ENDING;
10250
- } else if (isWhitespace(c2)) {
10250
+ } else if (isWhitespace2(c2)) {
10251
10251
  parser.state = S2.PROC_INST_BODY;
10252
10252
  } else {
10253
10253
  parser.procInstName += c2;
10254
10254
  }
10255
10255
  continue;
10256
10256
  case S2.PROC_INST_BODY:
10257
- if (!parser.procInstBody && isWhitespace(c2)) {
10257
+ if (!parser.procInstBody && isWhitespace2(c2)) {
10258
10258
  continue;
10259
10259
  } else if (c2 === "?") {
10260
10260
  parser.state = S2.PROC_INST_ENDING;
@@ -10285,7 +10285,7 @@ function requireSax() {
10285
10285
  } else if (c2 === "/") {
10286
10286
  parser.state = S2.OPEN_TAG_SLASH;
10287
10287
  } else {
10288
- if (!isWhitespace(c2)) {
10288
+ if (!isWhitespace2(c2)) {
10289
10289
  strictFail(parser, "Invalid character in tag name");
10290
10290
  }
10291
10291
  parser.state = S2.ATTRIB;
@@ -10305,7 +10305,7 @@ function requireSax() {
10305
10305
  }
10306
10306
  continue;
10307
10307
  case S2.ATTRIB:
10308
- if (isWhitespace(c2)) {
10308
+ if (isWhitespace2(c2)) {
10309
10309
  continue;
10310
10310
  } else if (c2 === ">") {
10311
10311
  openTag(parser);
@@ -10327,7 +10327,7 @@ function requireSax() {
10327
10327
  parser.attribValue = parser.attribName;
10328
10328
  attrib(parser);
10329
10329
  openTag(parser);
10330
- } else if (isWhitespace(c2)) {
10330
+ } else if (isWhitespace2(c2)) {
10331
10331
  parser.state = S2.ATTRIB_NAME_SAW_WHITE;
10332
10332
  } else if (isMatch(nameBody, c2)) {
10333
10333
  parser.attribName += c2;
@@ -10338,7 +10338,7 @@ function requireSax() {
10338
10338
  case S2.ATTRIB_NAME_SAW_WHITE:
10339
10339
  if (c2 === "=") {
10340
10340
  parser.state = S2.ATTRIB_VALUE;
10341
- } else if (isWhitespace(c2)) {
10341
+ } else if (isWhitespace2(c2)) {
10342
10342
  continue;
10343
10343
  } else {
10344
10344
  strictFail(parser, "Attribute without value");
@@ -10361,7 +10361,7 @@ function requireSax() {
10361
10361
  }
10362
10362
  continue;
10363
10363
  case S2.ATTRIB_VALUE:
10364
- if (isWhitespace(c2)) {
10364
+ if (isWhitespace2(c2)) {
10365
10365
  continue;
10366
10366
  } else if (isQuote(c2)) {
10367
10367
  parser.q = c2;
@@ -10388,7 +10388,7 @@ function requireSax() {
10388
10388
  parser.state = S2.ATTRIB_VALUE_CLOSED;
10389
10389
  continue;
10390
10390
  case S2.ATTRIB_VALUE_CLOSED:
10391
- if (isWhitespace(c2)) {
10391
+ if (isWhitespace2(c2)) {
10392
10392
  parser.state = S2.ATTRIB;
10393
10393
  } else if (c2 === ">") {
10394
10394
  openTag(parser);
@@ -10421,7 +10421,7 @@ function requireSax() {
10421
10421
  continue;
10422
10422
  case S2.CLOSE_TAG:
10423
10423
  if (!parser.tagName) {
10424
- if (isWhitespace(c2)) {
10424
+ if (isWhitespace2(c2)) {
10425
10425
  continue;
10426
10426
  } else if (notMatch(nameStart, c2)) {
10427
10427
  if (parser.script) {
@@ -10442,14 +10442,14 @@ function requireSax() {
10442
10442
  parser.tagName = "";
10443
10443
  parser.state = S2.SCRIPT;
10444
10444
  } else {
10445
- if (!isWhitespace(c2)) {
10445
+ if (!isWhitespace2(c2)) {
10446
10446
  strictFail(parser, "Invalid tagname in closing tag");
10447
10447
  }
10448
10448
  parser.state = S2.CLOSE_TAG_SAW_WHITE;
10449
10449
  }
10450
10450
  continue;
10451
10451
  case S2.CLOSE_TAG_SAW_WHITE:
10452
- if (isWhitespace(c2)) {
10452
+ if (isWhitespace2(c2)) {
10453
10453
  continue;
10454
10454
  }
10455
10455
  if (c2 === ">") {
@@ -41841,7 +41841,7 @@ const _SuperConverter = class _SuperConverter2 {
41841
41841
  static getStoredSuperdocVersion(docx) {
41842
41842
  return _SuperConverter2.getStoredCustomProperty(docx, "SuperdocVersion");
41843
41843
  }
41844
- static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.0-beta.30") {
41844
+ static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.0-beta.32") {
41845
41845
  return _SuperConverter2.setStoredCustomProperty(docx, "SuperdocVersion", version2, false);
41846
41846
  }
41847
41847
  /**
@@ -45147,7 +45147,7 @@ var __privateGet$1 = (obj, member, getter) => (__accessCheck$1(obj, member, "rea
45147
45147
  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);
45148
45148
  var __privateSet = (obj, member, value, setter) => (__accessCheck$1(obj, member, "write to private field"), member.set(obj, value), value);
45149
45149
  var __privateMethod$1 = (obj, member, method) => (__accessCheck$1(obj, member, "access private method"), method);
45150
- 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, _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, _remoteCursorState, _remoteCursorDirty, _remoteCursorOverlay, _localSelectionLayer, _awarenessCleanup, _scrollCleanup, _remoteCursorRafHandle, _scrollTimeout, _PresentationEditor_instances, aggregateLayoutBounds_fn, safeCleanup_fn, setupEditorListeners_fn, setupCollaborationCursors_fn, normalizeAwarenessStates_fn, getFallbackColor_fn, getValidatedColor_fn, scheduleRemoteCursorUpdate_fn, scheduleRemoteCursorReRender_fn, updateRemoteCursors_fn, renderRemoteCursors_fn, renderRemoteCaret_fn, renderRemoteCursorLabel_fn, renderRemoteSelection_fn, setupPointerHandlers_fn, setupInputBridge_fn, initHeaderFooterRegistry_fn, _handlePointerDown, getFirstTextPosition_fn, registerPointerClick_fn, selectWordAt_fn, selectParagraphAt_fn, isWordCharacter_fn, _handlePointerMove, _handlePointerLeave, _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, 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, waitForPageMount_fn, getBodyPageHeight_fn, getHeaderFooterPageHeight_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, convertPageLocalToOverlayCoords_fn, normalizeClientPoint_fn, computeCaretLayoutRect_fn, computeCaretLayoutRectFromDOM_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;
45150
+ 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, _remoteCursorState, _remoteCursorDirty, _remoteCursorOverlay, _localSelectionLayer, _awarenessCleanup, _scrollCleanup, _remoteCursorRafHandle, _scrollTimeout, _PresentationEditor_instances, aggregateLayoutBounds_fn, safeCleanup_fn, setupEditorListeners_fn, setupCollaborationCursors_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, setupInputBridge_fn, initHeaderFooterRegistry_fn, _handlePointerDown, getFirstTextPosition_fn, registerPointerClick_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, 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, waitForPageMount_fn, getBodyPageHeight_fn, getHeaderFooterPageHeight_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, convertPageLocalToOverlayCoords_fn, normalizeClientPoint_fn, computeCaretLayoutRect_fn, computeCaretLayoutRectFromDOM_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;
45151
45151
  var GOOD_LEAF_SIZE = 200;
45152
45152
  var RopeSequence = function RopeSequence2() {
45153
45153
  };
@@ -59014,7 +59014,7 @@ const isHeadless = (editor) => {
59014
59014
  const shouldSkipNodeView = (editor) => {
59015
59015
  return isHeadless(editor);
59016
59016
  };
59017
- const summaryVersion = "1.0.0-beta.30";
59017
+ const summaryVersion = "1.0.0-beta.32";
59018
59018
  const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
59019
59019
  const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
59020
59020
  function mapAttributes(attrs) {
@@ -59803,7 +59803,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
59803
59803
  { default: remarkStringify },
59804
59804
  { default: remarkGfm }
59805
59805
  ] = await Promise.all([
59806
- import("./index-DUzV7kkk-BvBMF_lo.es.js"),
59806
+ import("./index-SGV4U12y-BPGxOtvI.es.js"),
59807
59807
  import("./index-DRCvimau-Cw339678.es.js"),
59808
59808
  import("./index-C_x_N6Uh-DJn8hIEt.es.js"),
59809
59809
  import("./index-D_sWOSiG-DE96TaT5.es.js"),
@@ -60008,7 +60008,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
60008
60008
  * Process collaboration migrations
60009
60009
  */
60010
60010
  processCollaborationMigrations() {
60011
- console.debug("[checkVersionMigrations] Current editor version", "1.0.0-beta.30");
60011
+ console.debug("[checkVersionMigrations] Current editor version", "1.0.0-beta.32");
60012
60012
  if (!this.options.ydoc) return;
60013
60013
  const metaMap = this.options.ydoc.getMap("meta");
60014
60014
  let docVersion = metaMap.get("version");
@@ -62045,9 +62045,11 @@ const applyMarksToRun = (run2, marks, hyperlinkConfig = DEFAULT_HYPERLINK_CONFIG
62045
62045
  case TRACK_INSERT_MARK:
62046
62046
  case TRACK_DELETE_MARK:
62047
62047
  case TRACK_FORMAT_MARK: {
62048
- const tracked = buildTrackedChangeMetaFromMark(mark);
62049
- if (tracked) {
62050
- run2.trackedChange = selectTrackedChangeMeta(run2.trackedChange, tracked);
62048
+ if (!isTabRun2) {
62049
+ const tracked = buildTrackedChangeMetaFromMark(mark);
62050
+ if (tracked) {
62051
+ run2.trackedChange = selectTrackedChangeMeta(run2.trackedChange, tracked);
62052
+ }
62051
62053
  }
62052
62054
  break;
62053
62055
  }
@@ -65148,7 +65150,27 @@ function handleStructuredContentBlockNode(node, context) {
65148
65150
  blocks.push(block);
65149
65151
  recordBlockKind(block.kind);
65150
65152
  });
65151
- } else if (child.type === "table") ;
65153
+ } else if (child.type === "table") {
65154
+ const tableNodeToBlock2 = converters?.tableNodeToBlock;
65155
+ if (tableNodeToBlock2) {
65156
+ const tableBlock = tableNodeToBlock2(
65157
+ child,
65158
+ nextBlockId,
65159
+ positions,
65160
+ defaultFont,
65161
+ defaultSize,
65162
+ styleContext,
65163
+ trackedChangesConfig,
65164
+ bookmarks,
65165
+ hyperlinkConfig
65166
+ );
65167
+ if (tableBlock) {
65168
+ applySdtMetadataToTableBlock(tableBlock, structuredContentMetadata);
65169
+ blocks.push(tableBlock);
65170
+ recordBlockKind(tableBlock.kind);
65171
+ }
65172
+ }
65173
+ }
65152
65174
  });
65153
65175
  }
65154
65176
  function processParagraphChild(child, sectionMetadata, context, output, converters) {
@@ -65618,6 +65640,65 @@ function imageNodeToRun(node, positions, activeSdt) {
65618
65640
  }
65619
65641
  return run2;
65620
65642
  }
65643
+ function fieldAnnotationNodeToRun(node, positions, fieldMetadata) {
65644
+ const attrs = node.attrs ?? {};
65645
+ const rawVariant = attrs.type ?? fieldMetadata?.variant ?? "text";
65646
+ const validVariants = ["text", "image", "signature", "checkbox", "html", "link"];
65647
+ const variant = validVariants.includes(rawVariant) ? rawVariant : "text";
65648
+ const displayLabel = (typeof attrs.displayLabel === "string" ? attrs.displayLabel : void 0) || (typeof attrs.defaultDisplayLabel === "string" ? attrs.defaultDisplayLabel : void 0) || (typeof fieldMetadata?.displayLabel === "string" ? fieldMetadata.displayLabel : void 0) || (typeof fieldMetadata?.defaultDisplayLabel === "string" ? fieldMetadata.defaultDisplayLabel : void 0) || (typeof attrs.alias === "string" ? attrs.alias : void 0) || (typeof fieldMetadata?.alias === "string" ? fieldMetadata.alias : void 0) || "";
65649
+ const run2 = {
65650
+ kind: "fieldAnnotation",
65651
+ variant,
65652
+ displayLabel
65653
+ };
65654
+ const fieldId = typeof attrs.fieldId === "string" ? attrs.fieldId : fieldMetadata?.fieldId;
65655
+ if (fieldId) run2.fieldId = fieldId;
65656
+ const fieldType = typeof attrs.fieldType === "string" ? attrs.fieldType : fieldMetadata?.fieldType;
65657
+ if (fieldType) run2.fieldType = fieldType;
65658
+ const fieldColor = typeof attrs.fieldColor === "string" ? attrs.fieldColor : fieldMetadata?.fieldColor;
65659
+ if (fieldColor) run2.fieldColor = fieldColor;
65660
+ const borderColor = typeof attrs.borderColor === "string" ? attrs.borderColor : fieldMetadata?.borderColor;
65661
+ if (borderColor) run2.borderColor = borderColor;
65662
+ const highlighted = attrs.highlighted ?? fieldMetadata?.highlighted;
65663
+ if (highlighted === false) run2.highlighted = false;
65664
+ if (attrs.hidden === true || fieldMetadata?.hidden === true) run2.hidden = true;
65665
+ const visibility = attrs.visibility ?? fieldMetadata?.visibility;
65666
+ if (visibility === "hidden") run2.visibility = "hidden";
65667
+ const imageSrc = typeof attrs.imageSrc === "string" ? attrs.imageSrc : fieldMetadata?.imageSrc;
65668
+ if (imageSrc) run2.imageSrc = imageSrc;
65669
+ const linkUrl = typeof attrs.linkUrl === "string" ? attrs.linkUrl : fieldMetadata?.linkUrl;
65670
+ if (linkUrl) run2.linkUrl = linkUrl;
65671
+ const rawHtml = attrs.rawHtml ?? fieldMetadata?.rawHtml;
65672
+ if (typeof rawHtml === "string") run2.rawHtml = rawHtml;
65673
+ const size2 = attrs.size ?? fieldMetadata?.size;
65674
+ if (size2 && (typeof size2.width === "number" || typeof size2.height === "number")) {
65675
+ run2.size = {
65676
+ width: typeof size2.width === "number" ? size2.width : void 0,
65677
+ height: typeof size2.height === "number" ? size2.height : void 0
65678
+ };
65679
+ }
65680
+ const fontFamily2 = attrs.fontFamily ?? fieldMetadata?.fontFamily;
65681
+ if (typeof fontFamily2 === "string") run2.fontFamily = fontFamily2;
65682
+ const fontSize2 = attrs.fontSize ?? fieldMetadata?.fontSize;
65683
+ if (typeof fontSize2 === "string" || typeof fontSize2 === "number") run2.fontSize = fontSize2;
65684
+ const textColor = attrs.textColor ?? fieldMetadata?.textColor;
65685
+ if (typeof textColor === "string") run2.textColor = textColor;
65686
+ const textHighlight = attrs.textHighlight ?? fieldMetadata?.textHighlight;
65687
+ if (typeof textHighlight === "string") run2.textHighlight = textHighlight;
65688
+ const formatting = fieldMetadata?.formatting;
65689
+ if (attrs.bold === true || formatting?.bold === true) run2.bold = true;
65690
+ if (attrs.italic === true || formatting?.italic === true) run2.italic = true;
65691
+ if (attrs.underline === true || formatting?.underline === true) run2.underline = true;
65692
+ const pos = positions.get(node);
65693
+ if (pos) {
65694
+ run2.pmStart = pos.start;
65695
+ run2.pmEnd = pos.end;
65696
+ }
65697
+ if (fieldMetadata) {
65698
+ run2.sdt = fieldMetadata;
65699
+ }
65700
+ return run2;
65701
+ }
65621
65702
  const isTextRun$1 = (run2) => run2.kind !== "tab";
65622
65703
  const dataAttrsCompatible = (a, b2) => {
65623
65704
  const aAttrs = a.dataAttrs;
@@ -65913,28 +65994,20 @@ function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defa
65913
65994
  }
65914
65995
  if (node.type === "fieldAnnotation") {
65915
65996
  const fieldMetadata = resolveNodeSdtMetadata(node, "fieldAnnotation");
65997
+ let contentText;
65916
65998
  if (Array.isArray(node.content) && node.content.length > 0) {
65917
- node.content.forEach((child) => visitNode(child, inheritedMarks, fieldMetadata ?? activeSdt, activeRunStyleId));
65918
- } else {
65919
- const nodeAttrs = typeof node.attrs === "object" && node.attrs !== null ? node.attrs : {};
65920
- const label = (typeof nodeAttrs.displayLabel === "string" ? nodeAttrs.displayLabel : void 0) || (typeof nodeAttrs.defaultDisplayLabel === "string" ? nodeAttrs.defaultDisplayLabel : void 0) || (typeof nodeAttrs.alias === "string" ? nodeAttrs.alias : void 0) || "";
65921
- if (label && typeof label === "string") {
65922
- const run2 = textNodeToRun(
65923
- { type: "text", text: label },
65924
- positions,
65925
- defaultFont,
65926
- defaultSize,
65927
- inheritedMarks,
65928
- fieldMetadata ?? activeSdt,
65929
- hyperlinkConfig,
65930
- themeColors
65931
- );
65932
- const inlineStyleId = getInlineStyleId(inheritedMarks);
65933
- applyRunStyles2(run2, inlineStyleId, activeRunStyleId);
65934
- applyBaseRunDefaults(run2, baseRunDefaults, defaultFont, defaultSize);
65935
- currentRuns.push(run2);
65936
- }
65999
+ const extractText = (n) => {
66000
+ if (n.type === "text" && typeof n.text === "string") return n.text;
66001
+ if (Array.isArray(n.content)) {
66002
+ return n.content.map(extractText).join("");
66003
+ }
66004
+ return "";
66005
+ };
66006
+ contentText = node.content.map(extractText).join("");
65937
66007
  }
66008
+ const nodeForRun = contentText && contentText.length > 0 ? { ...node, attrs: { ...node.attrs ?? {}, displayLabel: contentText } } : node;
66009
+ const run2 = fieldAnnotationNodeToRun(nodeForRun, positions, fieldMetadata);
66010
+ currentRuns.push(run2);
65938
66011
  return;
65939
66012
  }
65940
66013
  if (node.type === "pageReference") {
@@ -66771,9 +66844,9 @@ const extractTableStyleParagraphProps = (styleId, docx) => {
66771
66844
  }
66772
66845
  const attrs = spacingEl.attributes;
66773
66846
  const spacing = {};
66774
- const before = parseIntSafe(attrs["w:before"]);
66775
- const after = parseIntSafe(attrs["w:after"]);
66776
- const line = parseIntSafe(attrs["w:line"]);
66847
+ const before = parseIntSafe$1(attrs["w:before"]);
66848
+ const after = parseIntSafe$1(attrs["w:after"]);
66849
+ const line = parseIntSafe$1(attrs["w:line"]);
66777
66850
  const rawLineRule = attrs["w:lineRule"];
66778
66851
  const lineRule = rawLineRule === "auto" || rawLineRule === "exact" || rawLineRule === "atLeast" ? rawLineRule : void 0;
66779
66852
  if (before != null) spacing.before = twipsToPx$1(before);
@@ -66788,11 +66861,11 @@ const extractTableStyleParagraphProps = (styleId, docx) => {
66788
66861
  if (lineRule) spacing.lineRule = lineRule;
66789
66862
  const result = Object.keys(spacing).length > 0 ? { spacing } : void 0;
66790
66863
  return result;
66791
- } catch (err) {
66864
+ } catch {
66792
66865
  return void 0;
66793
66866
  }
66794
66867
  };
66795
- const parseIntSafe = (value) => {
66868
+ const parseIntSafe$1 = (value) => {
66796
66869
  if (value == null) return void 0;
66797
66870
  const num = typeof value === "number" ? value : parseInt(String(value), 10);
66798
66871
  return Number.isFinite(num) ? num : void 0;
@@ -67444,7 +67517,7 @@ function getMeasurementContext() {
67444
67517
  return measurementCtx;
67445
67518
  }
67446
67519
  function getRunFontString(run2) {
67447
- if (run2.kind === "tab" || run2.kind === "lineBreak" || run2.kind === "break" || "src" in run2) {
67520
+ if (run2.kind === "tab" || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation" || "src" in run2) {
67448
67521
  return "normal normal 16px Arial";
67449
67522
  }
67450
67523
  const style2 = run2.italic ? "italic" : "normal";
@@ -67475,6 +67548,10 @@ function sliceRunsForLine$1(block, line) {
67475
67548
  result.push(run2);
67476
67549
  continue;
67477
67550
  }
67551
+ if (run2.kind === "fieldAnnotation") {
67552
+ result.push(run2);
67553
+ continue;
67554
+ }
67478
67555
  const text = run2.text ?? "";
67479
67556
  const isFirstRun = runIndex === line.fromRun;
67480
67557
  const isLastRun = runIndex === line.toRun;
@@ -67508,7 +67585,8 @@ function measureCharacterX(block, line, charOffset) {
67508
67585
  1,
67509
67586
  runs2.reduce((sum, run2) => {
67510
67587
  if (isTabRun$1(run2)) return sum + TAB_CHAR_LENGTH;
67511
- if ("src" in run2 || run2.kind === "lineBreak" || run2.kind === "break") return sum;
67588
+ if ("src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation")
67589
+ return sum;
67512
67590
  return sum + (run2.text ?? "").length;
67513
67591
  }, 0)
67514
67592
  );
@@ -67529,7 +67607,7 @@ function measureCharacterX(block, line, charOffset) {
67529
67607
  currentCharOffset += runLength2;
67530
67608
  continue;
67531
67609
  }
67532
- const text = "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" ? "" : run2.text ?? "";
67610
+ const text = "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation" ? "" : run2.text ?? "";
67533
67611
  const runLength = text.length;
67534
67612
  if (currentCharOffset + runLength >= charOffset) {
67535
67613
  const offsetInRun = charOffset - currentCharOffset;
@@ -67572,7 +67650,7 @@ function measureCharacterXSegmentBased(block, line, charOffset, ctx2) {
67572
67650
  if (isTabRun$1(run2)) {
67573
67651
  return segmentBaseX + (offsetInSegment > 0 ? segment.width ?? 0 : 0);
67574
67652
  }
67575
- if ("src" in run2 || run2.kind === "lineBreak" || run2.kind === "break") {
67653
+ if ("src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation") {
67576
67654
  return segmentBaseX + (offsetInSegment >= segmentChars ? segment.width ?? 0 : 0);
67577
67655
  }
67578
67656
  const text = run2.text ?? "";
@@ -67587,6 +67665,38 @@ function measureCharacterXSegmentBased(block, line, charOffset, ctx2) {
67587
67665
  }
67588
67666
  return line.width;
67589
67667
  }
67668
+ function charOffsetToPm(block, line, charOffset, fallbackPmStart) {
67669
+ if (!Number.isFinite(charOffset) || !Number.isFinite(fallbackPmStart)) {
67670
+ console.warn("[charOffsetToPm] Invalid input:", { charOffset, fallbackPmStart });
67671
+ return fallbackPmStart;
67672
+ }
67673
+ const safeCharOffset = Math.max(0, charOffset);
67674
+ if (block.kind !== "paragraph") {
67675
+ return fallbackPmStart + safeCharOffset;
67676
+ }
67677
+ const runs = sliceRunsForLine$1(block, line);
67678
+ let cursor = 0;
67679
+ let lastPm = fallbackPmStart;
67680
+ for (const run2 of runs) {
67681
+ const isTab = isTabRun$1(run2);
67682
+ const text = "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation" ? "" : run2.text ?? "";
67683
+ const runLength = isTab ? TAB_CHAR_LENGTH : text.length;
67684
+ const runPmStart = typeof run2.pmStart === "number" ? run2.pmStart : null;
67685
+ const runPmEnd = typeof run2.pmEnd === "number" ? run2.pmEnd : runPmStart != null ? runPmStart + runLength : null;
67686
+ if (runPmStart != null) {
67687
+ lastPm = runPmStart;
67688
+ }
67689
+ if (safeCharOffset <= cursor + runLength) {
67690
+ const offsetInRun = Math.max(0, safeCharOffset - cursor);
67691
+ return runPmStart != null ? runPmStart + Math.min(offsetInRun, runLength) : fallbackPmStart + safeCharOffset;
67692
+ }
67693
+ if (runPmEnd != null) {
67694
+ lastPm = runPmEnd;
67695
+ }
67696
+ cursor += runLength;
67697
+ }
67698
+ return lastPm;
67699
+ }
67590
67700
  function findCharacterAtX(block, line, x2, pmStart) {
67591
67701
  const ctx2 = getMeasurementContext();
67592
67702
  if (!ctx2) {
@@ -67595,15 +67705,17 @@ function findCharacterAtX(block, line, x2, pmStart) {
67595
67705
  1,
67596
67706
  runs2.reduce((sum, run2) => {
67597
67707
  if (isTabRun$1(run2)) return sum + TAB_CHAR_LENGTH;
67598
- if ("src" in run2 || run2.kind === "lineBreak" || run2.kind === "break") return sum;
67708
+ if ("src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation")
67709
+ return sum;
67599
67710
  return sum + (run2.text ?? "").length;
67600
67711
  }, 0)
67601
67712
  );
67602
67713
  const ratio = Math.max(0, Math.min(1, x2 / line.width));
67603
67714
  const charOffset = Math.round(ratio * charsInLine);
67715
+ const pmPosition2 = charOffsetToPm(block, line, charOffset, pmStart);
67604
67716
  return {
67605
67717
  charOffset,
67606
- pmPosition: pmStart + charOffset
67718
+ pmPosition: pmPosition2
67607
67719
  };
67608
67720
  }
67609
67721
  const runs = sliceRunsForLine$1(block, line);
@@ -67619,18 +67731,17 @@ function findCharacterAtX(block, line, x2, pmStart) {
67619
67731
  const midpoint = startX + tabWidth / 2;
67620
67732
  const offsetInRun = safeX < midpoint ? 0 : TAB_CHAR_LENGTH;
67621
67733
  const charOffset = currentCharOffset + offsetInRun;
67622
- const pmBase = run2.pmStart ?? pmStart + currentCharOffset;
67623
- const pmPosition = pmBase + offsetInRun;
67734
+ const pmPosition2 = charOffsetToPm(block, line, charOffset, pmStart);
67624
67735
  return {
67625
67736
  charOffset,
67626
- pmPosition
67737
+ pmPosition: pmPosition2
67627
67738
  };
67628
67739
  }
67629
67740
  currentX = endX;
67630
67741
  currentCharOffset += TAB_CHAR_LENGTH;
67631
67742
  continue;
67632
67743
  }
67633
- const text = "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" ? "" : run2.text ?? "";
67744
+ const text = "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation" ? "" : run2.text ?? "";
67634
67745
  const runLength = text.length;
67635
67746
  if (runLength === 0) continue;
67636
67747
  ctx2.font = getRunFontString(run2);
@@ -67640,9 +67751,10 @@ function findCharacterAtX(block, line, x2, pmStart) {
67640
67751
  const charX = currentX + measured2.width + computeLetterSpacingWidth(run2, i, runLength);
67641
67752
  if (charX >= safeX) {
67642
67753
  if (i === 0) {
67754
+ const pmPosition3 = charOffsetToPm(block, line, currentCharOffset, pmStart);
67643
67755
  return {
67644
67756
  charOffset: currentCharOffset,
67645
- pmPosition: pmStart + currentCharOffset
67757
+ pmPosition: pmPosition3
67646
67758
  };
67647
67759
  }
67648
67760
  const prevText = text.slice(0, i - 1);
@@ -67651,9 +67763,10 @@ function findCharacterAtX(block, line, x2, pmStart) {
67651
67763
  const distToPrev = Math.abs(safeX - prevX);
67652
67764
  const distToCurrent = Math.abs(safeX - charX);
67653
67765
  const charOffset = distToPrev < distToCurrent ? currentCharOffset + i - 1 : currentCharOffset + i;
67766
+ const pmPosition2 = charOffsetToPm(block, line, charOffset, pmStart);
67654
67767
  return {
67655
67768
  charOffset,
67656
- pmPosition: pmStart + charOffset
67769
+ pmPosition: pmPosition2
67657
67770
  };
67658
67771
  }
67659
67772
  }
@@ -67661,13 +67774,14 @@ function findCharacterAtX(block, line, x2, pmStart) {
67661
67774
  currentX += measured.width + computeLetterSpacingWidth(run2, runLength, runLength);
67662
67775
  currentCharOffset += runLength;
67663
67776
  }
67777
+ const pmPosition = charOffsetToPm(block, line, currentCharOffset, pmStart);
67664
67778
  return {
67665
67779
  charOffset: currentCharOffset,
67666
- pmPosition: pmStart + currentCharOffset
67780
+ pmPosition
67667
67781
  };
67668
67782
  }
67669
67783
  const computeLetterSpacingWidth = (run2, precedingChars, runLength) => {
67670
- if (isTabRun$1(run2) || "src" in run2 || !("letterSpacing" in run2) || !run2.letterSpacing) {
67784
+ if (isTabRun$1(run2) || "src" in run2 || run2.kind === "fieldAnnotation" || !("letterSpacing" in run2) || !run2.letterSpacing) {
67671
67785
  return 0;
67672
67786
  }
67673
67787
  const maxGaps = Math.max(runLength - 1, 0);
@@ -67764,6 +67878,17 @@ function clickToPositionDom(domContainer, clientX, clientY) {
67764
67878
  pmStart: fragmentEl.dataset.pmStart,
67765
67879
  pmEnd: fragmentEl.dataset.pmEnd
67766
67880
  });
67881
+ const hitChainLine = hitChain.find(
67882
+ (el) => el.classList?.contains?.(CLASS_NAMES$1.line) && el.dataset?.pmStart !== void 0 && el.dataset?.pmEnd !== void 0
67883
+ );
67884
+ if (hitChainLine) {
67885
+ log("Using hit chain line directly:", {
67886
+ pmStart: hitChainLine.dataset.pmStart,
67887
+ pmEnd: hitChainLine.dataset.pmEnd
67888
+ });
67889
+ const result2 = processLineElement(hitChainLine, viewX);
67890
+ return result2;
67891
+ }
67767
67892
  const result = processFragment(fragmentEl, viewX, viewY);
67768
67893
  return result;
67769
67894
  }
@@ -67829,7 +67954,82 @@ function processFragment(fragmentEl, viewX, viewY) {
67829
67954
  if (!Number.isFinite(lineStart) || !Number.isFinite(lineEnd)) {
67830
67955
  return null;
67831
67956
  }
67832
- const spanEls = Array.from(lineEl.querySelectorAll("span, a"));
67957
+ const spanEls = Array.from(lineEl.querySelectorAll("span, a")).filter(
67958
+ (el) => el.dataset.pmStart !== void 0 && el.dataset.pmEnd !== void 0
67959
+ );
67960
+ log(
67961
+ "Spans/anchors in line:",
67962
+ spanEls.map((el, i) => {
67963
+ const rect = el.getBoundingClientRect();
67964
+ return {
67965
+ index: i,
67966
+ tag: el.tagName,
67967
+ pmStart: el.dataset.pmStart,
67968
+ pmEnd: el.dataset.pmEnd,
67969
+ text: el.textContent?.substring(0, 20) + (el.textContent && el.textContent.length > 20 ? "..." : ""),
67970
+ visibility: el.style.visibility,
67971
+ rect: { left: rect.left, right: rect.right, width: rect.width }
67972
+ };
67973
+ })
67974
+ );
67975
+ if (spanEls.length === 0) {
67976
+ return lineStart;
67977
+ }
67978
+ const firstRect = spanEls[0].getBoundingClientRect();
67979
+ if (viewX <= firstRect.left) {
67980
+ return lineStart;
67981
+ }
67982
+ const lastRect = spanEls[spanEls.length - 1].getBoundingClientRect();
67983
+ if (viewX >= lastRect.right) {
67984
+ return lineEnd;
67985
+ }
67986
+ const targetEl = findSpanAtX(spanEls, viewX);
67987
+ if (!targetEl) {
67988
+ return lineStart;
67989
+ }
67990
+ const spanStart = Number(targetEl.dataset.pmStart ?? "NaN");
67991
+ const spanEnd = Number(targetEl.dataset.pmEnd ?? "NaN");
67992
+ const targetRect = targetEl.getBoundingClientRect();
67993
+ log("Target element:", {
67994
+ tag: targetEl.tagName,
67995
+ pmStart: spanStart,
67996
+ pmEnd: spanEnd,
67997
+ text: targetEl.textContent?.substring(0, 30),
67998
+ visibility: targetEl.style.visibility,
67999
+ rect: { left: targetRect.left, right: targetRect.right, width: targetRect.width },
68000
+ pageX: viewX,
68001
+ pageY: viewY
68002
+ });
68003
+ if (!Number.isFinite(spanStart) || !Number.isFinite(spanEnd)) {
68004
+ return null;
68005
+ }
68006
+ const firstChild = targetEl.firstChild;
68007
+ if (!firstChild || firstChild.nodeType !== Node.TEXT_NODE || !firstChild.textContent) {
68008
+ const elRect = targetEl.getBoundingClientRect();
68009
+ const closerToLeft = Math.abs(viewX - elRect.left) <= Math.abs(viewX - elRect.right);
68010
+ const snapPos = closerToLeft ? spanStart : spanEnd;
68011
+ return snapPos;
68012
+ }
68013
+ const textNode = firstChild;
68014
+ const charIndex = findCharIndexAtX(textNode, targetEl, viewX);
68015
+ const pos = spanStart + charIndex;
68016
+ return pos;
68017
+ }
68018
+ function processLineElement(lineEl, viewX) {
68019
+ const lineStart = Number(lineEl.dataset.pmStart ?? "NaN");
68020
+ const lineEnd = Number(lineEl.dataset.pmEnd ?? "NaN");
68021
+ const lineRect = lineEl.getBoundingClientRect();
68022
+ log("processLineElement:", {
68023
+ pmStart: lineStart,
68024
+ pmEnd: lineEnd,
68025
+ rect: { top: lineRect.top, bottom: lineRect.bottom, left: lineRect.left, right: lineRect.right }
68026
+ });
68027
+ if (!Number.isFinite(lineStart) || !Number.isFinite(lineEnd)) {
68028
+ return null;
68029
+ }
68030
+ const spanEls = Array.from(lineEl.querySelectorAll("span, a")).filter(
68031
+ (el) => el.dataset.pmStart !== void 0 && el.dataset.pmEnd !== void 0
68032
+ );
67833
68033
  log(
67834
68034
  "Spans/anchors in line:",
67835
68035
  spanEls.map((el, i) => {
@@ -70776,7 +70976,7 @@ const hashRuns = (block) => {
70776
70976
  return `img:${srcHash}:${imgRun.width}x${imgRun.height}`;
70777
70977
  }
70778
70978
  const text = normalizeText(
70779
- "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" ? "" : run2.text ?? ""
70979
+ "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation" ? "" : run2.text ?? ""
70780
70980
  );
70781
70981
  const bold = "bold" in run2 ? run2.bold : false;
70782
70982
  const italic = "italic" in run2 ? run2.italic : false;
@@ -71435,6 +71635,88 @@ async function layoutHeaderFooterWithCache(sections, constraints, measureBlock2,
71435
71635
  }
71436
71636
  return result;
71437
71637
  }
71638
+ function findWordBoundaries(blocks, pos) {
71639
+ const blockInfo = findBlockAtPosition(blocks, pos);
71640
+ if (!blockInfo) return null;
71641
+ const { block, localPos } = blockInfo;
71642
+ if (block.kind !== "paragraph") return null;
71643
+ const { text, pmStart } = extractBlockText(block);
71644
+ if (text.length === 0) return null;
71645
+ const clampedPos = Math.max(0, Math.min(localPos, text.length));
71646
+ let wordStart = clampedPos;
71647
+ while (wordStart > 0 && isWordChar(text[wordStart - 1])) {
71648
+ wordStart--;
71649
+ }
71650
+ let wordEnd = clampedPos;
71651
+ while (wordEnd < text.length && isWordChar(text[wordEnd])) {
71652
+ wordEnd++;
71653
+ }
71654
+ if (wordStart === wordEnd) {
71655
+ while (wordStart > 0 && isWhitespace(text[wordStart - 1])) {
71656
+ wordStart--;
71657
+ }
71658
+ while (wordEnd < text.length && isWhitespace(text[wordEnd])) {
71659
+ wordEnd++;
71660
+ }
71661
+ if (wordStart === wordEnd) {
71662
+ return null;
71663
+ }
71664
+ }
71665
+ return {
71666
+ from: pmStart + wordStart,
71667
+ to: pmStart + wordEnd
71668
+ };
71669
+ }
71670
+ function findParagraphBoundaries(blocks, pos) {
71671
+ const blockInfo = findBlockAtPosition(blocks, pos);
71672
+ if (!blockInfo) return null;
71673
+ const { block } = blockInfo;
71674
+ if (block.kind === "paragraph") {
71675
+ const { pmStart, pmEnd } = extractBlockText(block);
71676
+ return { from: pmStart, to: pmEnd };
71677
+ }
71678
+ if (block.kind === "image") {
71679
+ return { from: pos, to: pos + 1 };
71680
+ }
71681
+ return null;
71682
+ }
71683
+ function extractBlockText(block) {
71684
+ if (block.kind !== "paragraph") {
71685
+ return { text: "", pmStart: 0, pmEnd: 0 };
71686
+ }
71687
+ let text = "";
71688
+ let pmStart = Infinity;
71689
+ let pmEnd = 0;
71690
+ for (const run2 of block.runs) {
71691
+ text += "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation" ? "" : run2.text;
71692
+ if (run2.pmStart !== void 0) {
71693
+ pmStart = Math.min(pmStart, run2.pmStart);
71694
+ }
71695
+ if (run2.pmEnd !== void 0) {
71696
+ pmEnd = Math.max(pmEnd, run2.pmEnd);
71697
+ }
71698
+ }
71699
+ if (pmStart === Infinity) pmStart = 0;
71700
+ if (pmEnd === 0 && text.length > 0) pmEnd = pmStart + text.length;
71701
+ return { text, pmStart, pmEnd };
71702
+ }
71703
+ function findBlockAtPosition(blocks, pos) {
71704
+ for (const block of blocks) {
71705
+ if (block.kind === "paragraph") {
71706
+ const { pmStart, pmEnd } = extractBlockText(block);
71707
+ if (pos >= pmStart && pos <= pmEnd) {
71708
+ return { block, localPos: pos - pmStart };
71709
+ }
71710
+ }
71711
+ }
71712
+ return null;
71713
+ }
71714
+ function isWordChar(char) {
71715
+ return /[\p{L}\p{N}_]/u.test(char);
71716
+ }
71717
+ function isWhitespace(char) {
71718
+ return /\s/.test(char);
71719
+ }
71438
71720
  let canvas = null;
71439
71721
  let ctx$1 = null;
71440
71722
  function getCtx() {
@@ -71456,7 +71738,7 @@ function fontString(run2) {
71456
71738
  return `${italic}${bold}${size2}px ${family}`.trim();
71457
71739
  }
71458
71740
  function runText(run2) {
71459
- return "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" ? "" : run2.text ?? "";
71741
+ return "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation" ? "" : run2.text ?? "";
71460
71742
  }
71461
71743
  function measureRunSliceWidth(run2, fromChar, toChar) {
71462
71744
  const context = getCtx();
@@ -71618,7 +71900,7 @@ const paragraphBlocksEqual = (a, b2) => {
71618
71900
  for (let i = 0; i < a.runs.length; i += 1) {
71619
71901
  const runA = a.runs[i];
71620
71902
  const runB = b2.runs[i];
71621
- if (("src" in runA || runA.kind === "lineBreak" || runA.kind === "break" ? "" : runA.text) !== ("src" in runB || runB.kind === "lineBreak" || runB.kind === "break" ? "" : runB.text) || ("bold" in runA ? runA.bold : false) !== ("bold" in runB ? runB.bold : false) || ("italic" in runA ? runA.italic : false) !== ("italic" in runB ? runB.italic : false) || ("color" in runA ? runA.color : void 0) !== ("color" in runB ? runB.color : void 0) || getTrackedChangeKey(runA) !== getTrackedChangeKey(runB)) {
71903
+ if (("src" in runA || runA.kind === "lineBreak" || runA.kind === "break" || runA.kind === "fieldAnnotation" ? "" : runA.text) !== ("src" in runB || runB.kind === "lineBreak" || runB.kind === "break" || runB.kind === "fieldAnnotation" ? "" : runB.text) || ("bold" in runA ? runA.bold : false) !== ("bold" in runB ? runB.bold : false) || ("italic" in runA ? runA.italic : false) !== ("italic" in runB ? runB.italic : false) || ("color" in runA ? runA.color : void 0) !== ("color" in runB ? runB.color : void 0) || getTrackedChangeKey(runA) !== getTrackedChangeKey(runB)) {
71622
71904
  return false;
71623
71905
  }
71624
71906
  }
@@ -71738,7 +72020,7 @@ function computeHeaderFooterContentHash(blocks) {
71738
72020
  parts.push(block.id);
71739
72021
  if (block.kind === "paragraph") {
71740
72022
  for (const run2 of block.runs) {
71741
- if (!("src" in run2) && run2.kind !== "lineBreak" && run2.kind !== "break") {
72023
+ if (!("src" in run2) && run2.kind !== "lineBreak" && run2.kind !== "break" && run2.kind !== "fieldAnnotation") {
71742
72024
  parts.push(run2.text ?? "");
71743
72025
  }
71744
72026
  if ("bold" in run2 && run2.bold) parts.push("b");
@@ -72223,11 +72505,266 @@ var Priority = /* @__PURE__ */ ((Priority2) => {
72223
72505
  /** P3: Heavy debounce for full document layout */
72224
72506
  [Priority.P3]: 150
72225
72507
  });
72508
+ const DEFAULT_MIME_TYPE$1 = "application/x-field-annotation";
72509
+ const LEGACY_MIME_TYPE = "fieldAnnotation";
72510
+ function parseIntSafe(value) {
72511
+ if (!value) return void 0;
72512
+ const parsed = parseInt(value, 10);
72513
+ return Number.isFinite(parsed) ? parsed : void 0;
72514
+ }
72515
+ function extractFieldAnnotationData(element) {
72516
+ const dataset = element.dataset;
72517
+ const attributes = {};
72518
+ for (const key2 in dataset) {
72519
+ const value = dataset[key2];
72520
+ if (value !== void 0) {
72521
+ attributes[key2] = value;
72522
+ }
72523
+ }
72524
+ return {
72525
+ fieldId: dataset.fieldId,
72526
+ fieldType: dataset.fieldType,
72527
+ variant: dataset.variant ?? dataset.type,
72528
+ displayLabel: dataset.displayLabel,
72529
+ pmStart: parseIntSafe(dataset.pmStart),
72530
+ pmEnd: parseIntSafe(dataset.pmEnd),
72531
+ attributes
72532
+ };
72533
+ }
72534
+ class DragHandler {
72535
+ /**
72536
+ * Creates a new DragHandler instance.
72537
+ *
72538
+ * @param container - The DOM container element (typically .superdoc-layout)
72539
+ * @param config - Configuration options and callbacks
72540
+ */
72541
+ constructor(container, config2 = {}) {
72542
+ this.container = container;
72543
+ this.config = config2;
72544
+ this.mimeType = config2.mimeType ?? DEFAULT_MIME_TYPE$1;
72545
+ this.boundHandlers = {
72546
+ dragstart: this.handleDragStart.bind(this),
72547
+ dragover: this.handleDragOver.bind(this),
72548
+ drop: this.handleDrop.bind(this),
72549
+ dragend: this.handleDragEnd.bind(this),
72550
+ dragleave: this.handleDragLeave.bind(this)
72551
+ };
72552
+ this.windowDragoverHandler = this.handleWindowDragOver.bind(this);
72553
+ this.windowDropHandler = this.handleWindowDrop.bind(this);
72554
+ this.attachListeners();
72555
+ }
72556
+ /**
72557
+ * Attaches event listeners to the container and window.
72558
+ */
72559
+ attachListeners() {
72560
+ this.container.addEventListener("dragstart", this.boundHandlers.dragstart);
72561
+ this.container.addEventListener("dragover", this.boundHandlers.dragover);
72562
+ this.container.addEventListener("drop", this.boundHandlers.drop);
72563
+ this.container.addEventListener("dragend", this.boundHandlers.dragend);
72564
+ this.container.addEventListener("dragleave", this.boundHandlers.dragleave);
72565
+ window.addEventListener("dragover", this.windowDragoverHandler, false);
72566
+ window.addEventListener("drop", this.windowDropHandler, false);
72567
+ }
72568
+ /**
72569
+ * Removes event listeners from the container and window.
72570
+ */
72571
+ removeListeners() {
72572
+ this.container.removeEventListener("dragstart", this.boundHandlers.dragstart);
72573
+ this.container.removeEventListener("dragover", this.boundHandlers.dragover);
72574
+ this.container.removeEventListener("drop", this.boundHandlers.drop);
72575
+ this.container.removeEventListener("dragend", this.boundHandlers.dragend);
72576
+ this.container.removeEventListener("dragleave", this.boundHandlers.dragleave);
72577
+ window.removeEventListener("dragover", this.windowDragoverHandler, false);
72578
+ window.removeEventListener("drop", this.windowDropHandler, false);
72579
+ }
72580
+ /**
72581
+ * Handles dragover at window level to allow drops on overlay elements.
72582
+ * This ensures preventDefault is called even when dragging over selection
72583
+ * highlights or other UI elements that sit on top of the layout content.
72584
+ */
72585
+ handleWindowDragOver(event) {
72586
+ if (this.hasFieldAnnotationData(event)) {
72587
+ event.preventDefault();
72588
+ if (event.dataTransfer) {
72589
+ event.dataTransfer.dropEffect = "move";
72590
+ }
72591
+ const target = event.target;
72592
+ if (!this.container.contains(target)) {
72593
+ this.config.onDragOver?.({
72594
+ event,
72595
+ clientX: event.clientX,
72596
+ clientY: event.clientY,
72597
+ hasFieldAnnotation: true
72598
+ });
72599
+ }
72600
+ }
72601
+ }
72602
+ /**
72603
+ * Handles drop at window level to catch drops on overlay elements.
72604
+ * If the drop target is outside the container, we process it here.
72605
+ */
72606
+ handleWindowDrop(event) {
72607
+ if (this.hasFieldAnnotationData(event)) {
72608
+ const target = event.target;
72609
+ if (!this.container.contains(target)) {
72610
+ this.handleDrop(event);
72611
+ }
72612
+ }
72613
+ }
72614
+ /**
72615
+ * Handles the dragstart event.
72616
+ * Sets up dataTransfer with field annotation data and drag image.
72617
+ */
72618
+ handleDragStart(event) {
72619
+ const target = event.target;
72620
+ if (!target?.dataset?.draggable || target.dataset.draggable !== "true") {
72621
+ return;
72622
+ }
72623
+ const data = extractFieldAnnotationData(target);
72624
+ if (event.dataTransfer) {
72625
+ const jsonData = JSON.stringify({
72626
+ attributes: data.attributes,
72627
+ sourceField: data
72628
+ });
72629
+ event.dataTransfer.setData(this.mimeType, jsonData);
72630
+ event.dataTransfer.setData(LEGACY_MIME_TYPE, jsonData);
72631
+ event.dataTransfer.setData("text/plain", data.displayLabel ?? "Field Annotation");
72632
+ event.dataTransfer.setDragImage(target, 0, 0);
72633
+ event.dataTransfer.effectAllowed = "move";
72634
+ }
72635
+ this.config.onDragStart?.({
72636
+ event,
72637
+ element: target,
72638
+ data
72639
+ });
72640
+ }
72641
+ /**
72642
+ * Handles the dragover event.
72643
+ * Provides visual feedback and determines if drop is allowed.
72644
+ */
72645
+ handleDragOver(event) {
72646
+ const hasFieldAnnotation = this.hasFieldAnnotationData(event);
72647
+ if (hasFieldAnnotation) {
72648
+ event.preventDefault();
72649
+ if (event.dataTransfer) {
72650
+ event.dataTransfer.dropEffect = "move";
72651
+ }
72652
+ this.container.classList.add("drag-over");
72653
+ }
72654
+ this.config.onDragOver?.({
72655
+ event,
72656
+ clientX: event.clientX,
72657
+ clientY: event.clientY,
72658
+ hasFieldAnnotation
72659
+ });
72660
+ }
72661
+ /**
72662
+ * Handles the dragleave event.
72663
+ * Removes visual feedback when drag leaves the container.
72664
+ */
72665
+ handleDragLeave(event) {
72666
+ const relatedTarget = event.relatedTarget;
72667
+ if (!relatedTarget || !this.container.contains(relatedTarget)) {
72668
+ this.container.classList.remove("drag-over");
72669
+ }
72670
+ }
72671
+ /**
72672
+ * Handles the drop event.
72673
+ * Maps drop coordinates to ProseMirror position and emits drop event.
72674
+ */
72675
+ handleDrop(event) {
72676
+ this.container.classList.remove("drag-over");
72677
+ if (!this.hasFieldAnnotationData(event)) {
72678
+ return;
72679
+ }
72680
+ event.preventDefault();
72681
+ const data = this.extractDragData(event);
72682
+ if (!data) {
72683
+ return;
72684
+ }
72685
+ const pmPosition = clickToPositionDom(this.container, event.clientX, event.clientY);
72686
+ this.config.onDrop?.({
72687
+ event,
72688
+ data,
72689
+ pmPosition,
72690
+ clientX: event.clientX,
72691
+ clientY: event.clientY
72692
+ });
72693
+ }
72694
+ /**
72695
+ * Handles the dragend event.
72696
+ * Cleans up drag state.
72697
+ */
72698
+ handleDragEnd(event) {
72699
+ this.container.classList.remove("drag-over");
72700
+ this.config.onDragEnd?.(event);
72701
+ }
72702
+ /**
72703
+ * Checks if a drag event contains field annotation data.
72704
+ */
72705
+ hasFieldAnnotationData(event) {
72706
+ if (!event.dataTransfer) {
72707
+ return false;
72708
+ }
72709
+ const types2 = event.dataTransfer.types;
72710
+ return types2.includes(this.mimeType) || types2.includes(LEGACY_MIME_TYPE);
72711
+ }
72712
+ /**
72713
+ * Extracts field annotation data from a drag event's dataTransfer.
72714
+ */
72715
+ extractDragData(event) {
72716
+ if (!event.dataTransfer) {
72717
+ return null;
72718
+ }
72719
+ let jsonData = event.dataTransfer.getData(this.mimeType);
72720
+ if (!jsonData) {
72721
+ jsonData = event.dataTransfer.getData(LEGACY_MIME_TYPE);
72722
+ }
72723
+ if (!jsonData) {
72724
+ return null;
72725
+ }
72726
+ try {
72727
+ const parsed = JSON.parse(jsonData);
72728
+ return parsed.sourceField ?? parsed.attributes ?? parsed;
72729
+ } catch {
72730
+ return null;
72731
+ }
72732
+ }
72733
+ /**
72734
+ * Updates the configuration options.
72735
+ *
72736
+ * @param config - New configuration options to merge
72737
+ */
72738
+ updateConfig(config2) {
72739
+ this.config = { ...this.config, ...config2 };
72740
+ if (config2.mimeType) {
72741
+ this.mimeType = config2.mimeType;
72742
+ }
72743
+ }
72744
+ /**
72745
+ * Destroys the drag handler and removes all event listeners.
72746
+ * Call this when the layout engine is unmounted or the container is removed.
72747
+ */
72748
+ destroy() {
72749
+ this.removeListeners();
72750
+ this.container.classList.remove("drag-over");
72751
+ }
72752
+ }
72753
+ function createDragHandler(container, config2 = {}) {
72754
+ const handler2 = new DragHandler(container, config2);
72755
+ return () => handler2.destroy();
72756
+ }
72226
72757
  const isAtomicFragment = (fragment) => {
72227
72758
  return fragment.kind === "drawing" || fragment.kind === "image";
72228
72759
  };
72229
72760
  const logClickStage = (_level, _stage, _payload) => {
72230
72761
  };
72762
+ const logPositionDebug = (payload) => {
72763
+ return;
72764
+ };
72765
+ const logSelectionMapDebug = (payload) => {
72766
+ return;
72767
+ };
72231
72768
  const blockPmRangeFromAttrs = (block) => {
72232
72769
  const attrs = block?.attrs;
72233
72770
  const pmStart = typeof attrs?.pmStart === "number" ? attrs.pmStart : void 0;
@@ -72497,6 +73034,10 @@ function clickToPosition(layout, blocks, measures, containerPoint, domContainer,
72497
73034
  return null;
72498
73035
  }
72499
73036
  const column = determineColumn(layout, fragment.x);
73037
+ logPositionDebug({
73038
+ blockId: fragment.blockId,
73039
+ x: pageRelativePoint.x - fragment.x
73040
+ });
72500
73041
  logClickStage("log", "success", {
72501
73042
  blockId: fragment.blockId
72502
73043
  });
@@ -72605,10 +73146,13 @@ function selectionToRects(layout, blocks, measures, from2, to) {
72605
73146
  const sliceFrom = Math.max(range2.pmStart, from2);
72606
73147
  const sliceTo = Math.min(range2.pmEnd, to);
72607
73148
  if (sliceFrom >= sliceTo) return;
72608
- const x1 = mapPmToX(block, line, sliceFrom - range2.pmStart, fragment.width);
72609
- const x2 = mapPmToX(block, line, sliceTo - range2.pmStart, fragment.width);
72610
- const rectX = fragment.x + Math.min(x1, x2);
72611
- const rectWidth = Math.max(1, Math.abs(x2 - x1));
73149
+ const charOffsetFrom = pmPosToCharOffset(block, line, sliceFrom);
73150
+ const charOffsetTo = pmPosToCharOffset(block, line, sliceTo);
73151
+ const startX = mapPmToX(block, line, charOffsetFrom, fragment.width);
73152
+ const endX = mapPmToX(block, line, charOffsetTo, fragment.width);
73153
+ const markerWidth = fragment.markerWidth ?? measure.marker?.markerWidth ?? 0;
73154
+ const rectX = fragment.x + markerWidth + Math.min(startX, endX);
73155
+ const rectWidth = Math.max(1, Math.abs(endX - startX));
72612
73156
  const lineOffset = lineHeightBeforeIndex(measure, index2) - lineHeightBeforeIndex(measure, fragment.fromLine);
72613
73157
  const rectY = fragment.y + lineOffset;
72614
73158
  rects.push({
@@ -72748,7 +73292,7 @@ function computeLinePmRange$1(block, line) {
72748
73292
  for (let runIndex = line.fromRun; runIndex <= line.toRun; runIndex += 1) {
72749
73293
  const run2 = block.runs[runIndex];
72750
73294
  if (!run2) continue;
72751
- const text = "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" ? "" : run2.text ?? "";
73295
+ const text = "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation" ? "" : run2.text ?? "";
72752
73296
  const runLength = text.length;
72753
73297
  const runPmStart = run2.pmStart ?? null;
72754
73298
  const runPmEnd = run2.pmEnd ?? (runPmStart != null ? runPmStart + runLength : null);
@@ -72766,6 +73310,57 @@ function computeLinePmRange$1(block, line) {
72766
73310
  }
72767
73311
  return { pmStart, pmEnd };
72768
73312
  }
73313
+ function pmPosToCharOffset(block, line, pmPos) {
73314
+ if (block.kind !== "paragraph") return 0;
73315
+ let charOffset = 0;
73316
+ for (let runIndex = line.fromRun; runIndex <= line.toRun; runIndex += 1) {
73317
+ const run2 = block.runs[runIndex];
73318
+ if (!run2) continue;
73319
+ const text = "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation" ? "" : run2.text ?? "";
73320
+ const runTextLength = text.length;
73321
+ const runPmStart = run2.pmStart ?? null;
73322
+ const runPmEnd = run2.pmEnd ?? (runPmStart != null ? runPmStart + runTextLength : null);
73323
+ if (runPmStart == null || runPmEnd == null || runTextLength === 0) continue;
73324
+ const isFirstRun = runIndex === line.fromRun;
73325
+ const isLastRun = runIndex === line.toRun;
73326
+ const lineStartChar = isFirstRun ? line.fromChar : 0;
73327
+ const lineEndChar = isLastRun ? line.toChar : runTextLength;
73328
+ const runSliceCharCount = lineEndChar - lineStartChar;
73329
+ const runPmRange = runPmEnd - runPmStart;
73330
+ const runSlicePmStart = runPmStart + lineStartChar / runTextLength * runPmRange;
73331
+ const runSlicePmEnd = runPmStart + lineEndChar / runTextLength * runPmRange;
73332
+ if (pmPos >= runSlicePmStart && pmPos <= runSlicePmEnd) {
73333
+ const runSlicePmRange = runSlicePmEnd - runSlicePmStart;
73334
+ if (runSlicePmRange > 0) {
73335
+ const pmOffsetInSlice = pmPos - runSlicePmStart;
73336
+ const charOffsetInSlice = Math.round(pmOffsetInSlice / runSlicePmRange * runSliceCharCount);
73337
+ const result = charOffset + Math.min(charOffsetInSlice, runSliceCharCount);
73338
+ const runText2 = text;
73339
+ const offsetInRun = result - charOffset - (isFirstRun ? 0 : 0);
73340
+ logSelectionMapDebug({
73341
+ blockId: block.id,
73342
+ lineFromRun: line.fromRun,
73343
+ lineToRun: line.toRun,
73344
+ runTextPreview: runText2.slice(Math.max(0, offsetInRun - 10), Math.min(runText2.length, offsetInRun + 10))
73345
+ });
73346
+ return result;
73347
+ }
73348
+ logSelectionMapDebug({
73349
+ blockId: block.id
73350
+ });
73351
+ return charOffset;
73352
+ }
73353
+ if (pmPos > runSlicePmEnd) {
73354
+ charOffset += runSliceCharCount;
73355
+ }
73356
+ }
73357
+ logSelectionMapDebug({
73358
+ blockId: block.id,
73359
+ lineFromRun: line.fromRun,
73360
+ lineToRun: line.toRun
73361
+ });
73362
+ return charOffset;
73363
+ }
72769
73364
  const determineColumn = (layout, fragmentX) => {
72770
73365
  const columns = layout.columns;
72771
73366
  if (!columns || columns.count <= 1) return 0;
@@ -72810,8 +73405,8 @@ const mapPointToPm = (block, line, x2, isRTL) => {
72810
73405
  if (isRTL) {
72811
73406
  const charOffset = result.charOffset;
72812
73407
  const charsInLine = Math.max(1, line.toChar - line.fromChar);
72813
- const reversedOffset = charsInLine - charOffset;
72814
- return range2.pmStart + reversedOffset;
73408
+ const reversedOffset = Math.max(0, Math.min(charsInLine, charsInLine - charOffset));
73409
+ return charOffsetToPm(block, line, reversedOffset, range2.pmStart);
72815
73410
  }
72816
73411
  return result.pmPosition;
72817
73412
  };
@@ -75254,9 +75849,227 @@ const TRACK_CHANGE_STYLES = `
75254
75849
  border-bottom: 2px solid gold;
75255
75850
  }
75256
75851
  `;
75852
+ const SDT_CONTAINER_STYLES = `
75853
+ /* Document Section - Block-level container with gray border and hover tooltip */
75854
+ .superdoc-document-section {
75855
+ background-color: #fafafa;
75856
+ border: 1px solid #ababab;
75857
+ border-radius: 4px;
75858
+ position: relative;
75859
+ box-sizing: border-box;
75860
+ }
75861
+
75862
+ /* Document section tooltip - positioned above the fragment */
75863
+ .superdoc-document-section__tooltip {
75864
+ position: absolute;
75865
+ top: -19px;
75866
+ left: -1px;
75867
+ max-width: 100px;
75868
+ min-width: 0;
75869
+ height: 18px;
75870
+ border: 1px solid #ababab;
75871
+ border-bottom: none;
75872
+ border-radius: 6px 6px 0 0;
75873
+ padding: 0 8px;
75874
+ align-items: center;
75875
+ font-size: 10px;
75876
+ display: none;
75877
+ z-index: 100;
75878
+ background-color: #fafafa;
75879
+ pointer-events: none;
75880
+ }
75881
+
75882
+ .superdoc-document-section__tooltip span {
75883
+ max-width: 100%;
75884
+ overflow: hidden;
75885
+ white-space: nowrap;
75886
+ text-overflow: ellipsis;
75887
+ }
75888
+
75889
+ /* Show tooltip on hover - adjust border radius to connect with tooltip tab */
75890
+ .superdoc-document-section:hover {
75891
+ border-radius: 0 4px 4px 4px;
75892
+ }
75893
+
75894
+ .superdoc-document-section:hover .superdoc-document-section__tooltip {
75895
+ display: flex;
75896
+ align-items: center;
75897
+ }
75898
+
75899
+ /* Continuation styling: first fragment has top corners, last has bottom corners */
75900
+ .superdoc-document-section[data-sdt-container-start="true"] {
75901
+ border-radius: 4px 4px 0 0;
75902
+ }
75903
+
75904
+ .superdoc-document-section[data-sdt-container-end="true"] {
75905
+ border-radius: 0 0 4px 4px;
75906
+ }
75907
+
75908
+ .superdoc-document-section[data-sdt-container-start="true"][data-sdt-container-end="true"] {
75909
+ border-radius: 4px;
75910
+ }
75911
+
75912
+ .superdoc-document-section[data-sdt-container-start="true"]:hover {
75913
+ border-radius: 0 4px 0 0;
75914
+ }
75915
+
75916
+ /* Middle fragments have no border radius */
75917
+ .superdoc-document-section:not([data-sdt-container-start="true"]):not([data-sdt-container-end="true"]) {
75918
+ border-radius: 0;
75919
+ border-top: none;
75920
+ }
75921
+
75922
+ /* Structured Content Block - Blue border container */
75923
+ .superdoc-structured-content-block {
75924
+ padding: 1px;
75925
+ box-sizing: border-box;
75926
+ border-radius: 4px;
75927
+ border: 1px solid #629be7;
75928
+ position: relative;
75929
+ }
75930
+
75931
+ /* Structured content drag handle/label - positioned above */
75932
+ .superdoc-structured-content__label {
75933
+ font-size: 10px;
75934
+ align-items: center;
75935
+ justify-content: center;
75936
+ position: absolute;
75937
+ left: 2px;
75938
+ top: -19px;
75939
+ width: calc(100% - 4px);
75940
+ max-width: 110px;
75941
+ min-width: 0;
75942
+ height: 18px;
75943
+ padding: 0 4px;
75944
+ border: 1px solid #629be7;
75945
+ border-bottom: none;
75946
+ border-radius: 6px 6px 0 0;
75947
+ background-color: #629be7dd;
75948
+ box-sizing: border-box;
75949
+ z-index: 10;
75950
+ display: none;
75951
+ pointer-events: none;
75952
+ }
75953
+
75954
+ .superdoc-structured-content__label span {
75955
+ max-width: 100%;
75956
+ overflow: hidden;
75957
+ white-space: nowrap;
75958
+ text-overflow: ellipsis;
75959
+ }
75960
+
75961
+ .superdoc-structured-content-block:hover .superdoc-structured-content__label {
75962
+ display: inline-flex;
75963
+ }
75964
+
75965
+ /* Continuation styling for structured content blocks */
75966
+ .superdoc-structured-content-block[data-sdt-container-start="true"] {
75967
+ border-radius: 4px 4px 0 0;
75968
+ }
75969
+
75970
+ .superdoc-structured-content-block[data-sdt-container-end="true"] {
75971
+ border-radius: 0 0 4px 4px;
75972
+ }
75973
+
75974
+ .superdoc-structured-content-block[data-sdt-container-start="true"][data-sdt-container-end="true"] {
75975
+ border-radius: 4px;
75976
+ }
75977
+
75978
+ .superdoc-structured-content-block:not([data-sdt-container-start="true"]):not([data-sdt-container-end="true"]) {
75979
+ border-radius: 0;
75980
+ border-top: none;
75981
+ }
75982
+
75983
+ /* Structured Content Inline - Inline wrapper with blue border */
75984
+ .superdoc-structured-content-inline {
75985
+ padding: 1px;
75986
+ box-sizing: border-box;
75987
+ border-radius: 4px;
75988
+ border: 1px solid #629be7;
75989
+ position: relative;
75990
+ display: inline;
75991
+ }
75992
+
75993
+ /* Hover effect for inline structured content */
75994
+ .superdoc-structured-content-inline:hover {
75995
+ background-color: rgba(98, 155, 231, 0.15);
75996
+ border-color: #4a8ad9;
75997
+ }
75998
+
75999
+ /* Inline structured content label - shown on hover */
76000
+ .superdoc-structured-content-inline__label {
76001
+ position: absolute;
76002
+ bottom: calc(100% + 2px);
76003
+ left: 50%;
76004
+ transform: translateX(-50%);
76005
+ font-size: 10px;
76006
+ padding: 2px 6px;
76007
+ background-color: #629be7dd;
76008
+ color: white;
76009
+ border-radius: 4px;
76010
+ white-space: nowrap;
76011
+ z-index: 100;
76012
+ display: none;
76013
+ pointer-events: none;
76014
+ }
76015
+
76016
+ .superdoc-structured-content-inline:hover .superdoc-structured-content-inline__label {
76017
+ display: block;
76018
+ }
76019
+
76020
+ /* Print mode: hide visual styling for SDT containers */
76021
+ @media print {
76022
+ .superdoc-document-section,
76023
+ .superdoc-structured-content-block,
76024
+ .superdoc-structured-content-inline {
76025
+ background: none;
76026
+ border: none;
76027
+ padding: 0;
76028
+ }
76029
+
76030
+ .superdoc-document-section__tooltip,
76031
+ .superdoc-structured-content__label,
76032
+ .superdoc-structured-content-inline__label {
76033
+ display: none !important;
76034
+ }
76035
+ }
76036
+ `;
76037
+ const FIELD_ANNOTATION_STYLES = `
76038
+ /* Field annotation draggable styles */
76039
+ .superdoc-layout .annotation[data-draggable="true"] {
76040
+ cursor: grab;
76041
+ user-select: none;
76042
+ -webkit-user-select: none;
76043
+ }
76044
+
76045
+ .superdoc-layout .annotation[data-draggable="true"]:hover {
76046
+ opacity: 0.9;
76047
+ }
76048
+
76049
+ .superdoc-layout .annotation[data-draggable="true"]:active {
76050
+ cursor: grabbing;
76051
+ }
76052
+
76053
+ /* Drag over indicator for drop targets */
76054
+ .superdoc-layout.drag-over {
76055
+ outline: 2px dashed #b015b3;
76056
+ outline-offset: -2px;
76057
+ }
76058
+
76059
+ /* Drop zone indicator */
76060
+ .superdoc-layout .superdoc-drop-indicator {
76061
+ position: absolute;
76062
+ width: 2px;
76063
+ background-color: #b015b3;
76064
+ pointer-events: none;
76065
+ z-index: 1000;
76066
+ }
76067
+ `;
75257
76068
  let printStylesInjected = false;
75258
76069
  let linkStylesInjected = false;
75259
76070
  let trackChangeStylesInjected = false;
76071
+ let sdtContainerStylesInjected = false;
76072
+ let fieldAnnotationStylesInjected = false;
75260
76073
  const ensurePrintStyles = (doc2) => {
75261
76074
  if (printStylesInjected || !doc2) return;
75262
76075
  const styleEl = doc2.createElement("style");
@@ -75281,6 +76094,22 @@ const ensureTrackChangeStyles = (doc2) => {
75281
76094
  doc2.head?.appendChild(styleEl);
75282
76095
  trackChangeStylesInjected = true;
75283
76096
  };
76097
+ const ensureSdtContainerStyles = (doc2) => {
76098
+ if (sdtContainerStylesInjected || !doc2) return;
76099
+ const styleEl = doc2.createElement("style");
76100
+ styleEl.setAttribute("data-superdoc-sdt-container-styles", "true");
76101
+ styleEl.textContent = SDT_CONTAINER_STYLES;
76102
+ doc2.head?.appendChild(styleEl);
76103
+ sdtContainerStylesInjected = true;
76104
+ };
76105
+ const ensureFieldAnnotationStyles = (doc2) => {
76106
+ if (fieldAnnotationStylesInjected || !doc2) return;
76107
+ const styleEl = doc2.createElement("style");
76108
+ styleEl.setAttribute("data-superdoc-field-annotation-styles", "true");
76109
+ styleEl.textContent = FIELD_ANNOTATION_STYLES;
76110
+ doc2.head?.appendChild(styleEl);
76111
+ fieldAnnotationStylesInjected = true;
76112
+ };
75284
76113
  const ALLOWED_BORDER_STYLES = /* @__PURE__ */ new Set([
75285
76114
  "none",
75286
76115
  "single",
@@ -75610,6 +76439,50 @@ const renderTableRow = (deps) => {
75610
76439
  container.appendChild(cellElement);
75611
76440
  }
75612
76441
  };
76442
+ function isStructuredContentMetadata(sdt) {
76443
+ return sdt !== null && sdt !== void 0 && typeof sdt === "object" && "type" in sdt && sdt.type === "structuredContent";
76444
+ }
76445
+ function isDocumentSectionMetadata(sdt) {
76446
+ return sdt !== null && sdt !== void 0 && typeof sdt === "object" && "type" in sdt && sdt.type === "documentSection";
76447
+ }
76448
+ function getSdtContainerConfig(sdt) {
76449
+ if (isDocumentSectionMetadata(sdt)) {
76450
+ return {
76451
+ className: "superdoc-document-section",
76452
+ labelText: sdt.title ?? "Document section",
76453
+ labelClassName: "superdoc-document-section__tooltip",
76454
+ isStart: true,
76455
+ isEnd: true
76456
+ };
76457
+ }
76458
+ if (isStructuredContentMetadata(sdt) && sdt.scope === "block") {
76459
+ return {
76460
+ className: "superdoc-structured-content-block",
76461
+ labelText: sdt.alias ?? "Structured content",
76462
+ labelClassName: "superdoc-structured-content__label",
76463
+ isStart: true,
76464
+ isEnd: true
76465
+ };
76466
+ }
76467
+ return null;
76468
+ }
76469
+ function applySdtContainerStyling(doc2, container, sdt, containerSdt) {
76470
+ let config2 = getSdtContainerConfig(sdt);
76471
+ if (!config2 && containerSdt) {
76472
+ config2 = getSdtContainerConfig(containerSdt);
76473
+ }
76474
+ if (!config2) return;
76475
+ container.classList.add(config2.className);
76476
+ container.dataset.sdtContainerStart = String(config2.isStart);
76477
+ container.dataset.sdtContainerEnd = String(config2.isEnd);
76478
+ container.style.overflow = "visible";
76479
+ const labelEl = doc2.createElement("div");
76480
+ labelEl.className = config2.labelClassName;
76481
+ const labelText = doc2.createElement("span");
76482
+ labelText.textContent = config2.labelText;
76483
+ labelEl.appendChild(labelText);
76484
+ container.appendChild(labelEl);
76485
+ }
75613
76486
  const renderTableFragment = (deps) => {
75614
76487
  const { doc: doc2, fragment, blockLookup, context, renderLine, applyFragmentFrame, applySdtDataset, applyStyles: applyStyles2 } = deps;
75615
76488
  if (!doc2) {
@@ -75646,6 +76519,7 @@ const renderTableFragment = (deps) => {
75646
76519
  applyFragmentFrame(container, fragment);
75647
76520
  container.style.height = `${fragment.height}px`;
75648
76521
  applySdtDataset(container, block.attrs?.sdt);
76522
+ applySdtContainerStyling(doc2, container, block.attrs?.sdt);
75649
76523
  container.classList.add("superdoc-table-fragment");
75650
76524
  if (fragment.metadata?.columnBoundaries) {
75651
76525
  const columnCount = measure.columnWidths.length;
@@ -76112,6 +76986,8 @@ const _DomPainter = class _DomPainter2 {
76112
76986
  ensurePrintStyles(doc2);
76113
76987
  ensureLinkStyles(doc2);
76114
76988
  ensureTrackChangeStyles(doc2);
76989
+ ensureFieldAnnotationStyles(doc2);
76990
+ ensureSdtContainerStyles(doc2);
76115
76991
  mount2.classList.add(CLASS_NAMES.container);
76116
76992
  if (this.mount && this.mount !== mount2) {
76117
76993
  this.resetState();
@@ -76634,7 +77510,8 @@ const _DomPainter = class _DomPainter2 {
76634
77510
  fragmentEl.classList.add(CLASS_NAMES.fragment);
76635
77511
  const isTocEntry = block.attrs?.isTocEntry;
76636
77512
  const hasMarker = !fragment.continuesFromPrev && fragment.markerWidth && wordLayout?.marker;
76637
- const styles = isTocEntry ? { ...fragmentStyles, whiteSpace: "nowrap" } : hasMarker ? { ...fragmentStyles, overflow: "visible" } : fragmentStyles;
77513
+ const hasSdtContainer = block.attrs?.sdt?.type === "documentSection" || block.attrs?.sdt?.type === "structuredContent" || block.attrs?.containerSdt?.type === "documentSection" || block.attrs?.containerSdt?.type === "structuredContent";
77514
+ const styles = isTocEntry ? { ...fragmentStyles, whiteSpace: "nowrap" } : hasMarker || hasSdtContainer ? { ...fragmentStyles, overflow: "visible" } : fragmentStyles;
76638
77515
  applyStyles$2(fragmentEl, styles);
76639
77516
  this.applyFragmentFrame(fragmentEl, fragment, context.section);
76640
77517
  if (isTocEntry) {
@@ -76654,6 +77531,7 @@ const _DomPainter = class _DomPainter2 {
76654
77531
  }
76655
77532
  this.applySdtDataset(fragmentEl, block.attrs?.sdt);
76656
77533
  this.applyContainerSdtDataset(fragmentEl, block.attrs?.containerSdt);
77534
+ applySdtContainerStyling(this.doc, fragmentEl, block.attrs?.sdt, block.attrs?.containerSdt);
76657
77535
  const dropCapDescriptor = block.attrs?.dropCapDescriptor;
76658
77536
  const dropCapMeasure = measure.dropCap;
76659
77537
  if (dropCapDescriptor && dropCapMeasure && !fragment.continuesFromPrev) {
@@ -76668,8 +77546,22 @@ const _DomPainter = class _DomPainter2 {
76668
77546
  const paraIndentRight = paraIndent?.right ?? 0;
76669
77547
  const suppressFirstLineIndent = block.attrs?.suppressFirstLineIndent === true;
76670
77548
  const firstLineOffset = suppressFirstLineIndent ? 0 : (paraIndent?.firstLine ?? 0) - (paraIndent?.hanging ?? 0);
77549
+ const isListParagraph = !!(fragment.markerWidth && wordLayout?.marker);
77550
+ const lastRun = block.runs.length > 0 ? block.runs[block.runs.length - 1] : null;
77551
+ const paragraphEndsWithLineBreak = lastRun?.kind === "lineBreak";
76671
77552
  lines.forEach((line, index2) => {
76672
- const lineEl = this.renderLine(block, line, context);
77553
+ const availableWidthOverride = Math.max(0, fragment.width - (paraIndentLeft + paraIndentRight));
77554
+ const isLastLineOfFragment = index2 === lines.length - 1;
77555
+ const isLastLineOfParagraph = isLastLineOfFragment && !fragment.continuesOnNext;
77556
+ const shouldSkipJustifyForLastLine = isLastLineOfParagraph && !paragraphEndsWithLineBreak;
77557
+ const lineEl = this.renderLine(
77558
+ block,
77559
+ line,
77560
+ context,
77561
+ availableWidthOverride,
77562
+ fragment.fromLine + index2,
77563
+ isListParagraph || shouldSkipJustifyForLastLine
77564
+ );
76673
77565
  const isListFirstLine = index2 === 0 && !fragment.continuesFromPrev && fragment.markerWidth && wordLayout?.marker;
76674
77566
  const hasExplicitSegmentPositioning = line.segments?.some((seg) => seg.x !== void 0);
76675
77567
  const isFirstLine = index2 === 0 && !fragment.continuesFromPrev;
@@ -76858,6 +77750,7 @@ const _DomPainter = class _DomPainter2 {
76858
77750
  fragmentEl.dataset.itemId = fragment.itemId;
76859
77751
  const paragraphMetadata = item.paragraph.attrs?.sdt;
76860
77752
  this.applySdtDataset(fragmentEl, paragraphMetadata);
77753
+ applySdtContainerStyling(this.doc, fragmentEl, paragraphMetadata, item.paragraph.attrs?.containerSdt);
76861
77754
  if (fragment.continuesFromPrev) {
76862
77755
  fragmentEl.dataset.continuesFromPrev = "true";
76863
77756
  }
@@ -76898,8 +77791,13 @@ const _DomPainter = class _DomPainter2 {
76898
77791
  const lines = itemMeasure.paragraph.lines.slice(fragment.fromLine, fragment.toLine);
76899
77792
  const contentAttrs = wordLayout ? item.paragraph.attrs : stripListIndent(item.paragraph.attrs);
76900
77793
  applyParagraphBlockStyles(contentEl, contentAttrs);
76901
- lines.forEach((line) => {
76902
- const lineEl = this.renderLine(item.paragraph, line, context);
77794
+ contentEl.style.textAlign = "left";
77795
+ const paraForList = {
77796
+ ...item.paragraph,
77797
+ attrs: { ...item.paragraph.attrs || {}, alignment: "left" }
77798
+ };
77799
+ lines.forEach((line, idx) => {
77800
+ const lineEl = this.renderLine(paraForList, line, context, fragment.width, fragment.fromLine + idx, true);
76903
77801
  contentEl.appendChild(lineEl);
76904
77802
  });
76905
77803
  fragmentEl.appendChild(contentEl);
@@ -77421,12 +78319,15 @@ const _DomPainter = class _DomPainter2 {
77421
78319
  const applyFragmentFrameWithSection = (el, frag) => {
77422
78320
  this.applyFragmentFrame(el, frag, context.section);
77423
78321
  };
78322
+ const renderLineForTableCell = (block, line, ctx2) => {
78323
+ return this.renderLine(block, line, ctx2, void 0, void 0, true);
78324
+ };
77424
78325
  return renderTableFragment({
77425
78326
  doc: this.doc,
77426
78327
  fragment,
77427
78328
  context,
77428
78329
  blockLookup: this.blockLookup,
77429
- renderLine: this.renderLine.bind(this),
78330
+ renderLine: renderLineForTableCell,
77430
78331
  applyFragmentFrame: applyFragmentFrameWithSection,
77431
78332
  applySdtDataset: this.applySdtDataset.bind(this),
77432
78333
  applyStyles: applyStyles$2
@@ -77621,10 +78522,19 @@ const _DomPainter = class _DomPainter2 {
77621
78522
  isBreakRun(run2) {
77622
78523
  return run2.kind === "break";
77623
78524
  }
78525
+ /**
78526
+ * Type guard to check if a run is a field annotation run.
78527
+ */
78528
+ isFieldAnnotationRun(run2) {
78529
+ return run2.kind === "fieldAnnotation";
78530
+ }
77624
78531
  renderRun(run2, context, trackedConfig) {
77625
78532
  if (this.isImageRun(run2)) {
77626
78533
  return this.renderImageRun(run2);
77627
78534
  }
78535
+ if (this.isFieldAnnotationRun(run2)) {
78536
+ return this.renderFieldAnnotationRun(run2);
78537
+ }
77628
78538
  if (this.isLineBreakRun(run2)) {
77629
78539
  return null;
77630
78540
  }
@@ -77761,7 +78671,212 @@ const _DomPainter = class _DomPainter2 {
77761
78671
  }
77762
78672
  return img;
77763
78673
  }
77764
- renderLine(block, line, context) {
78674
+ /**
78675
+ * Renders a FieldAnnotationRun as an inline "pill" element matching super-editor's visual appearance.
78676
+ *
78677
+ * Field annotations are styled inline elements that display form fields with:
78678
+ * - Outer span with border, border-radius, padding, and background color
78679
+ * - Inner span containing the displayLabel or type-specific content (image, link, etc.)
78680
+ *
78681
+ * @param run - The FieldAnnotationRun to render containing field configuration and styling
78682
+ * @returns HTMLElement (span) or null if document is not available
78683
+ *
78684
+ * @example
78685
+ * ```typescript
78686
+ * // Text variant
78687
+ * renderFieldAnnotationRun({ kind: 'fieldAnnotation', variant: 'text', displayLabel: 'Full Name', fieldColor: '#980043' })
78688
+ * // Returns: <span class="annotation" style="border: 2px solid #b015b3; ..."><span class="annotation-content">Full Name</span></span>
78689
+ *
78690
+ * // Image variant with imageSrc
78691
+ * renderFieldAnnotationRun({ kind: 'fieldAnnotation', variant: 'image', displayLabel: 'Photo', imageSrc: 'data:image/png;...' })
78692
+ * // Returns: <span class="annotation"><span class="annotation-content"><img src="..." /></span></span>
78693
+ *
78694
+ * // Link variant
78695
+ * renderFieldAnnotationRun({ kind: 'fieldAnnotation', variant: 'link', displayLabel: 'Website', linkUrl: 'https://example.com' })
78696
+ * // Returns: <span class="annotation"><span class="annotation-content"><a href="...">https://example.com</a></span></span>
78697
+ * ```
78698
+ */
78699
+ renderFieldAnnotationRun(run2) {
78700
+ if (!this.doc) {
78701
+ return null;
78702
+ }
78703
+ if (run2.hidden) {
78704
+ const hidden = this.doc.createElement("span");
78705
+ hidden.style.display = "none";
78706
+ if (run2.pmStart != null) hidden.dataset.pmStart = String(run2.pmStart);
78707
+ if (run2.pmEnd != null) hidden.dataset.pmEnd = String(run2.pmEnd);
78708
+ return hidden;
78709
+ }
78710
+ const defaultBorderColor = "#b015b3";
78711
+ const defaultFieldColor = "#980043";
78712
+ const annotation = this.doc.createElement("span");
78713
+ annotation.classList.add("annotation");
78714
+ annotation.setAttribute("aria-label", "Field annotation");
78715
+ const showHighlight = run2.highlighted !== false;
78716
+ if (showHighlight) {
78717
+ const borderColor = run2.borderColor || defaultBorderColor;
78718
+ annotation.style.border = `2px solid ${borderColor}`;
78719
+ annotation.style.borderRadius = "2px";
78720
+ annotation.style.padding = "1px 2px";
78721
+ annotation.style.boxSizing = "border-box";
78722
+ const fieldColor = run2.fieldColor || defaultFieldColor;
78723
+ const bgColor = fieldColor.length === 7 ? `${fieldColor}33` : fieldColor;
78724
+ if (run2.textHighlight) {
78725
+ annotation.style.backgroundColor = run2.textHighlight;
78726
+ } else {
78727
+ annotation.style.backgroundColor = bgColor;
78728
+ }
78729
+ }
78730
+ if (run2.visibility === "hidden") {
78731
+ annotation.style.visibility = "hidden";
78732
+ }
78733
+ if (run2.size) {
78734
+ if (run2.size.width) {
78735
+ annotation.style.width = `${run2.size.width}px`;
78736
+ annotation.style.display = "inline-block";
78737
+ annotation.style.overflow = "hidden";
78738
+ }
78739
+ if (run2.size.height) {
78740
+ annotation.style.height = `${run2.size.height}px`;
78741
+ }
78742
+ }
78743
+ if (run2.fontFamily) {
78744
+ annotation.style.fontFamily = run2.fontFamily;
78745
+ }
78746
+ if (run2.fontSize) {
78747
+ const fontSize2 = typeof run2.fontSize === "number" ? `${run2.fontSize}pt` : run2.fontSize;
78748
+ annotation.style.fontSize = fontSize2;
78749
+ }
78750
+ if (run2.textColor) {
78751
+ annotation.style.color = run2.textColor;
78752
+ }
78753
+ if (run2.bold) {
78754
+ annotation.style.fontWeight = "bold";
78755
+ }
78756
+ if (run2.italic) {
78757
+ annotation.style.fontStyle = "italic";
78758
+ }
78759
+ if (run2.underline) {
78760
+ annotation.style.textDecoration = "underline";
78761
+ }
78762
+ annotation.style.zIndex = "1";
78763
+ const content = this.doc.createElement("span");
78764
+ content.classList.add("annotation-content");
78765
+ content.style.pointerEvents = "none";
78766
+ content.setAttribute("contenteditable", "false");
78767
+ switch (run2.variant) {
78768
+ case "image":
78769
+ case "signature": {
78770
+ if (run2.imageSrc) {
78771
+ const img = this.doc.createElement("img");
78772
+ const isDataUrl = run2.imageSrc.startsWith("data:");
78773
+ if (isDataUrl) {
78774
+ if (run2.imageSrc.length <= MAX_DATA_URL_LENGTH && VALID_IMAGE_DATA_URL.test(run2.imageSrc)) {
78775
+ img.src = run2.imageSrc;
78776
+ } else {
78777
+ content.textContent = run2.displayLabel;
78778
+ break;
78779
+ }
78780
+ } else {
78781
+ const sanitized = sanitizeHref(run2.imageSrc);
78782
+ if (sanitized) {
78783
+ img.src = sanitized.href;
78784
+ } else {
78785
+ content.textContent = run2.displayLabel;
78786
+ break;
78787
+ }
78788
+ }
78789
+ img.alt = run2.displayLabel;
78790
+ img.style.height = "auto";
78791
+ img.style.maxWidth = "100%";
78792
+ img.style.pointerEvents = "none";
78793
+ img.style.verticalAlign = "middle";
78794
+ if (run2.variant === "signature") {
78795
+ img.style.maxHeight = "28px";
78796
+ }
78797
+ content.appendChild(img);
78798
+ annotation.style.display = "inline-block";
78799
+ content.style.display = "inline-block";
78800
+ } else {
78801
+ content.textContent = run2.displayLabel || (run2.variant === "signature" ? "Signature" : "");
78802
+ }
78803
+ break;
78804
+ }
78805
+ case "link": {
78806
+ if (run2.linkUrl) {
78807
+ const link = this.doc.createElement("a");
78808
+ const sanitized = sanitizeHref(run2.linkUrl);
78809
+ if (sanitized) {
78810
+ link.href = sanitized.href;
78811
+ link.target = "_blank";
78812
+ link.rel = "noopener noreferrer";
78813
+ link.textContent = run2.linkUrl;
78814
+ link.style.textDecoration = "none";
78815
+ content.style.pointerEvents = "all";
78816
+ content.appendChild(link);
78817
+ } else {
78818
+ content.textContent = run2.displayLabel;
78819
+ }
78820
+ } else {
78821
+ content.textContent = run2.displayLabel;
78822
+ }
78823
+ break;
78824
+ }
78825
+ case "html": {
78826
+ if (run2.rawHtml && typeof run2.rawHtml === "string") {
78827
+ content.textContent = run2.displayLabel;
78828
+ annotation.style.display = "inline-block";
78829
+ content.style.display = "inline-block";
78830
+ } else {
78831
+ content.textContent = run2.displayLabel;
78832
+ }
78833
+ break;
78834
+ }
78835
+ case "text":
78836
+ case "checkbox":
78837
+ default: {
78838
+ content.textContent = run2.displayLabel;
78839
+ break;
78840
+ }
78841
+ }
78842
+ annotation.appendChild(content);
78843
+ annotation.dataset.type = run2.variant;
78844
+ if (run2.fieldId) {
78845
+ annotation.dataset.fieldId = run2.fieldId;
78846
+ }
78847
+ if (run2.fieldType) {
78848
+ annotation.dataset.fieldType = run2.fieldType;
78849
+ }
78850
+ annotation.draggable = true;
78851
+ annotation.dataset.draggable = "true";
78852
+ if (run2.displayLabel) {
78853
+ annotation.dataset.displayLabel = run2.displayLabel;
78854
+ }
78855
+ if (run2.variant) {
78856
+ annotation.dataset.variant = run2.variant;
78857
+ }
78858
+ assertPmPositions(run2, "field annotation run");
78859
+ if (run2.pmStart != null) {
78860
+ annotation.dataset.pmStart = String(run2.pmStart);
78861
+ }
78862
+ if (run2.pmEnd != null) {
78863
+ annotation.dataset.pmEnd = String(run2.pmEnd);
78864
+ }
78865
+ this.applySdtDataset(annotation, run2.sdt);
78866
+ return annotation;
78867
+ }
78868
+ /**
78869
+ * Renders a single line of a paragraph block.
78870
+ *
78871
+ * @param block - The paragraph block containing the line
78872
+ * @param line - The line measurement data
78873
+ * @param context - Rendering context with fragment information
78874
+ * @param availableWidthOverride - Optional override for available width used in justification calculations
78875
+ * @param lineIndex - Optional zero-based index of the line within the fragment
78876
+ * @param skipJustify - When true, prevents justification even if alignment is 'justify'
78877
+ * @returns The rendered line element
78878
+ */
78879
+ renderLine(block, line, context, availableWidthOverride, lineIndex, skipJustify) {
77765
78880
  if (!this.doc) {
77766
78881
  throw new Error("DomPainter: document is not available");
77767
78882
  }
@@ -77773,8 +78888,10 @@ const _DomPainter = class _DomPainter2 {
77773
78888
  el.setAttribute("styleid", styleId);
77774
78889
  }
77775
78890
  const alignment2 = block.attrs?.alignment;
77776
- if (alignment2 === "center" || alignment2 === "right" || alignment2 === "justify") {
77777
- el.style.textAlign = alignment2 === "justify" ? "justify" : alignment2;
78891
+ if (alignment2 === "center" || alignment2 === "right") {
78892
+ el.style.textAlign = alignment2;
78893
+ } else if (alignment2 === "justify") {
78894
+ el.style.textAlign = "left";
77778
78895
  } else {
77779
78896
  el.style.textAlign = "left";
77780
78897
  }
@@ -77787,6 +78904,7 @@ const _DomPainter = class _DomPainter2 {
77787
78904
  }
77788
78905
  const runsForLine = sliceRunsForLine(block, line);
77789
78906
  const trackedConfig = this.resolveTrackedChangesConfig(block);
78907
+ const textSlices = runsForLine.length > 0 ? runsForLine.filter((r2) => (r2.kind === "text" || r2.kind === void 0) && "text" in r2 && r2.text != null).map((r2) => r2.text) : gatherTextSlicesForLine(block, line);
77790
78908
  if (runsForLine.length === 0) {
77791
78909
  const span = this.doc.createElement("span");
77792
78910
  span.innerHTML = "&nbsp;";
@@ -77833,6 +78951,19 @@ const _DomPainter = class _DomPainter2 {
77833
78951
  });
77834
78952
  }
77835
78953
  const hasExplicitPositioning = line.segments?.some((seg) => seg.x !== void 0);
78954
+ const availableWidth = availableWidthOverride ?? line.maxWidth ?? line.width;
78955
+ const shouldJustify = !skipJustify && alignment2 === "justify" && !hasExplicitPositioning;
78956
+ if (shouldJustify) {
78957
+ const spaceCount = textSlices.reduce(
78958
+ (sum, s2) => sum + Array.from(s2).filter((ch) => ch === " " || ch === " ").length,
78959
+ 0
78960
+ );
78961
+ const slack = Math.max(0, availableWidth - line.width);
78962
+ if (spaceCount > 0 && slack > 0) {
78963
+ const extraPerSpace = slack / spaceCount;
78964
+ el.style.wordSpacing = `${extraPerSpace}px`;
78965
+ }
78966
+ }
77836
78967
  if (hasExplicitPositioning && line.segments) {
77837
78968
  let cumulativeX = 0;
77838
78969
  const segmentsByRun = /* @__PURE__ */ new Map();
@@ -77911,6 +79042,22 @@ const _DomPainter = class _DomPainter2 {
77911
79042
  if (this.isBreakRun(baseRun)) {
77912
79043
  continue;
77913
79044
  }
79045
+ if (this.isFieldAnnotationRun(baseRun)) {
79046
+ const elem = this.renderRun(baseRun, context, trackedConfig);
79047
+ if (elem) {
79048
+ if (styleId) {
79049
+ elem.setAttribute("styleid", styleId);
79050
+ }
79051
+ const runSegments2 = segmentsByRun.get(runIndex);
79052
+ const segX = runSegments2 && runSegments2[0]?.x !== void 0 ? runSegments2[0].x : cumulativeX;
79053
+ const segWidth = (runSegments2 && runSegments2[0]?.width !== void 0 ? runSegments2[0].width : 0) ?? 0;
79054
+ elem.style.position = "absolute";
79055
+ elem.style.left = `${segX}px`;
79056
+ el.appendChild(elem);
79057
+ cumulativeX = segX + segWidth;
79058
+ }
79059
+ continue;
79060
+ }
77914
79061
  const runSegments = segmentsByRun.get(runIndex);
77915
79062
  if (!runSegments || runSegments.length === 0) {
77916
79063
  continue;
@@ -77956,7 +79103,22 @@ const _DomPainter = class _DomPainter2 {
77956
79103
  });
77957
79104
  }
77958
79105
  } else {
79106
+ let currentInlineSdtWrapper = null;
79107
+ let currentInlineSdtId = null;
79108
+ const closeCurrentWrapper = () => {
79109
+ if (currentInlineSdtWrapper) {
79110
+ el.appendChild(currentInlineSdtWrapper);
79111
+ currentInlineSdtWrapper = null;
79112
+ currentInlineSdtId = null;
79113
+ }
79114
+ };
77959
79115
  runsForLine.forEach((run2) => {
79116
+ const runSdt = run2.sdt;
79117
+ const isInlineSdt = runSdt?.type === "structuredContent" && runSdt?.scope === "inline";
79118
+ const runSdtId = isInlineSdt && runSdt?.id ? String(runSdt.id) : null;
79119
+ if (runSdtId !== currentInlineSdtId) {
79120
+ closeCurrentWrapper();
79121
+ }
77960
79122
  if (run2.kind === "tab") {
77961
79123
  const tabEl = this.doc.createElement("span");
77962
79124
  tabEl.classList.add("superdoc-tab");
@@ -77984,9 +79146,37 @@ const _DomPainter = class _DomPainter2 {
77984
79146
  if (styleId) {
77985
79147
  elem.setAttribute("styleid", styleId);
77986
79148
  }
77987
- el.appendChild(elem);
79149
+ if (isInlineSdt && runSdtId && this.doc) {
79150
+ if (!currentInlineSdtWrapper) {
79151
+ currentInlineSdtWrapper = this.doc.createElement("span");
79152
+ currentInlineSdtWrapper.className = "superdoc-structured-content-inline";
79153
+ currentInlineSdtId = runSdtId;
79154
+ this.applySdtDataset(currentInlineSdtWrapper, runSdt);
79155
+ const alias = runSdt?.alias || "Inline content";
79156
+ const labelEl = this.doc.createElement("span");
79157
+ labelEl.className = "superdoc-structured-content-inline__label";
79158
+ labelEl.textContent = alias;
79159
+ currentInlineSdtWrapper.appendChild(labelEl);
79160
+ }
79161
+ const wrapperPmStart = currentInlineSdtWrapper.dataset.pmStart;
79162
+ const wrapperPmEnd = currentInlineSdtWrapper.dataset.pmEnd;
79163
+ if (run2.pmStart != null) {
79164
+ if (!wrapperPmStart || run2.pmStart < parseInt(wrapperPmStart, 10)) {
79165
+ currentInlineSdtWrapper.dataset.pmStart = String(run2.pmStart);
79166
+ }
79167
+ }
79168
+ if (run2.pmEnd != null) {
79169
+ if (!wrapperPmEnd || run2.pmEnd > parseInt(wrapperPmEnd, 10)) {
79170
+ currentInlineSdtWrapper.dataset.pmEnd = String(run2.pmEnd);
79171
+ }
79172
+ }
79173
+ currentInlineSdtWrapper.appendChild(elem);
79174
+ } else {
79175
+ el.appendChild(elem);
79176
+ }
77988
79177
  }
77989
79178
  });
79179
+ closeCurrentWrapper();
77990
79180
  }
77991
79181
  const anchors = el.querySelectorAll("a[href]");
77992
79182
  anchors.forEach((anchor) => {
@@ -78494,7 +79684,7 @@ const deriveBlockVersion = (block) => {
78494
79684
  return block.id;
78495
79685
  };
78496
79686
  const applyRunStyles = (element, run2, _isLink = false) => {
78497
- if (run2.kind === "tab" || run2.kind === "image" || run2.kind === "lineBreak" || run2.kind === "break") {
79687
+ if (run2.kind === "tab" || run2.kind === "image" || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation") {
78498
79688
  return;
78499
79689
  }
78500
79690
  element.style.fontFamily = run2.fontFamily;
@@ -78616,6 +79806,23 @@ const applyParagraphShadingStyles = (element, shading) => {
78616
79806
  if (!shading?.fill) return;
78617
79807
  element.style.backgroundColor = shading.fill;
78618
79808
  };
79809
+ const gatherTextSlicesForLine = (block, line) => {
79810
+ const slices = [];
79811
+ const startRun = line.fromRun ?? 0;
79812
+ const endRun = line.toRun ?? startRun;
79813
+ for (let runIndex = startRun; runIndex <= endRun; runIndex += 1) {
79814
+ const run2 = block.runs[runIndex];
79815
+ if (!run2 || run2.kind !== "text" && run2.kind !== void 0 || !("text" in run2) || !run2.text) continue;
79816
+ const isFirst = runIndex === startRun;
79817
+ const isLast = runIndex === endRun;
79818
+ const start2 = isFirst ? line.fromChar ?? 0 : 0;
79819
+ const end2 = isLast ? line.toChar ?? run2.text.length : run2.text.length;
79820
+ if (start2 >= end2) continue;
79821
+ const slice2 = run2.text.slice(start2, end2);
79822
+ if (slice2) slices.push(slice2);
79823
+ }
79824
+ return slices;
79825
+ };
78619
79826
  const sliceRunsForLine = (block, line) => {
78620
79827
  const result = [];
78621
79828
  for (let runIndex = line.fromRun; runIndex <= line.toRun; runIndex += 1) {
@@ -78637,6 +79844,10 @@ const sliceRunsForLine = (block, line) => {
78637
79844
  result.push(run2);
78638
79845
  continue;
78639
79846
  }
79847
+ if (run2.kind === "fieldAnnotation") {
79848
+ result.push(run2);
79849
+ continue;
79850
+ }
78640
79851
  if (!("text" in run2)) {
78641
79852
  continue;
78642
79853
  }
@@ -78952,6 +80163,10 @@ const DEFAULT_TAB_INTERVAL_PX = twipsToPx(DEFAULT_TAB_INTERVAL_TWIPS);
78952
80163
  const TAB_EPSILON = 0.1;
78953
80164
  const DEFAULT_DECIMAL_SEPARATOR = ".";
78954
80165
  const ALLOWED_TAB_VALS = /* @__PURE__ */ new Set(["start", "center", "end", "decimal", "bar", "clear"]);
80166
+ const FIELD_ANNOTATION_PILL_PADDING = 8;
80167
+ const FIELD_ANNOTATION_LINE_HEIGHT_MULTIPLIER = 1.2;
80168
+ const FIELD_ANNOTATION_VERTICAL_PADDING = 6;
80169
+ const DEFAULT_FIELD_ANNOTATION_FONT_SIZE = 16;
78955
80170
  const roundValue = (value) => value;
78956
80171
  function getCanvasContext() {
78957
80172
  if (!canvasContext) {
@@ -79031,6 +80246,9 @@ function isImageRun(run2) {
79031
80246
  function isLineBreakRun(run2) {
79032
80247
  return run2.kind === "lineBreak";
79033
80248
  }
80249
+ function isFieldAnnotationRun(run2) {
80250
+ return run2.kind === "fieldAnnotation";
80251
+ }
79034
80252
  async function measureBlock(block, constraints) {
79035
80253
  const normalized = normalizeConstraints(constraints);
79036
80254
  if (block.kind === "drawing") {
@@ -79397,6 +80615,92 @@ async function measureParagraphBlock(block, maxWidth) {
79397
80615
  lastAppliedTabAlign = null;
79398
80616
  continue;
79399
80617
  }
80618
+ if (isFieldAnnotationRun(run2)) {
80619
+ const displayText = run2.displayLabel || "";
80620
+ const annotationFontSize = typeof run2.fontSize === "number" ? run2.fontSize : typeof run2.fontSize === "string" ? parseFloat(run2.fontSize) || DEFAULT_FIELD_ANNOTATION_FONT_SIZE : DEFAULT_FIELD_ANNOTATION_FONT_SIZE;
80621
+ const annotationFontFamily = run2.fontFamily || "Arial, sans-serif";
80622
+ const fontWeight = run2.bold ? "bold" : "normal";
80623
+ const fontStyle = run2.italic ? "italic" : "normal";
80624
+ const annotationFont = `${fontStyle} ${fontWeight} ${annotationFontSize}px ${annotationFontFamily}`;
80625
+ ctx2.font = annotationFont;
80626
+ const textWidth = displayText ? ctx2.measureText(displayText).width : 0;
80627
+ const annotationWidth = textWidth + FIELD_ANNOTATION_PILL_PADDING;
80628
+ const annotationHeight = annotationFontSize * FIELD_ANNOTATION_LINE_HEIGHT_MULTIPLIER + FIELD_ANNOTATION_VERTICAL_PADDING;
80629
+ let annotationStartX;
80630
+ if (pendingTabAlignment && currentLine) {
80631
+ annotationStartX = alignPendingTabForWidth(annotationWidth);
80632
+ }
80633
+ if (!currentLine) {
80634
+ currentLine = {
80635
+ fromRun: runIndex,
80636
+ fromChar: 0,
80637
+ toRun: runIndex,
80638
+ toChar: 1,
80639
+ // Field annotations are atomic units
80640
+ width: annotationWidth,
80641
+ maxFontSize: annotationHeight,
80642
+ maxWidth: getEffectiveWidth(initialAvailableWidth),
80643
+ segments: [
80644
+ {
80645
+ runIndex,
80646
+ fromChar: 0,
80647
+ toChar: 1,
80648
+ width: annotationWidth,
80649
+ ...annotationStartX !== void 0 ? { x: annotationStartX } : {}
80650
+ }
80651
+ ]
80652
+ };
80653
+ continue;
80654
+ }
80655
+ if (currentLine.width + annotationWidth > currentLine.maxWidth && currentLine.width > 0) {
80656
+ const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing, currentLine.maxFontInfo);
80657
+ const completedLine = {
80658
+ ...currentLine,
80659
+ ...metrics
80660
+ };
80661
+ addBarTabsToLine(completedLine);
80662
+ lines.push(completedLine);
80663
+ tabStopCursor = 0;
80664
+ pendingTabAlignment = null;
80665
+ lastAppliedTabAlign = null;
80666
+ currentLine = {
80667
+ fromRun: runIndex,
80668
+ fromChar: 0,
80669
+ toRun: runIndex,
80670
+ toChar: 1,
80671
+ width: annotationWidth,
80672
+ maxFontSize: annotationHeight,
80673
+ maxWidth: getEffectiveWidth(contentWidth),
80674
+ segments: [
80675
+ {
80676
+ runIndex,
80677
+ fromChar: 0,
80678
+ toChar: 1,
80679
+ width: annotationWidth
80680
+ }
80681
+ ]
80682
+ };
80683
+ } else {
80684
+ currentLine.toRun = runIndex;
80685
+ currentLine.toChar = 1;
80686
+ currentLine.width = roundValue(currentLine.width + annotationWidth);
80687
+ currentLine.maxFontSize = Math.max(currentLine.maxFontSize, annotationHeight);
80688
+ if (!currentLine.segments) currentLine.segments = [];
80689
+ currentLine.segments.push({
80690
+ runIndex,
80691
+ fromChar: 0,
80692
+ toChar: 1,
80693
+ width: annotationWidth,
80694
+ ...annotationStartX !== void 0 ? { x: annotationStartX } : {}
80695
+ });
80696
+ }
80697
+ const tabAlign = lastAppliedTabAlign;
80698
+ if (tabAlign && currentLine && tabAlign.val === "end") {
80699
+ currentLine.width = roundValue(tabAlign.target);
80700
+ }
80701
+ lastAppliedTabAlign = null;
80702
+ continue;
80703
+ }
79400
80704
  if (!("text" in run2) || !("fontSize" in run2)) {
79401
80705
  continue;
79402
80706
  }
@@ -81361,6 +82665,12 @@ function isInRegisteredSurface(event) {
81361
82665
  }
81362
82666
  return false;
81363
82667
  }
82668
+ function isValidFieldAnnotationAttributes(attrs) {
82669
+ if (!attrs || typeof attrs !== "object") return false;
82670
+ const a = attrs;
82671
+ return typeof a.fieldId === "string" && typeof a.fieldType === "string" && typeof a.displayLabel === "string" && typeof a.type === "string";
82672
+ }
82673
+ const FIELD_ANNOTATION_DATA_TYPE = "fieldAnnotation";
81364
82674
  const DEFAULT_PAGE_SIZE = { w: 612, h: 792 };
81365
82675
  const DEFAULT_MARGINS = { top: 72, right: 72, bottom: 72, left: 72 };
81366
82676
  const WORD_CHARACTER_REGEX = /[\p{L}\p{N}''_~-]/u;
@@ -81386,6 +82696,7 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
81386
82696
  __privateAdd$1(this, _layoutOptions);
81387
82697
  __privateAdd$1(this, _layoutState, { blocks: [], measures: [], layout: null });
81388
82698
  __privateAdd$1(this, _domPainter, null);
82699
+ __privateAdd$1(this, _dragHandlerCleanup, null);
81389
82700
  __privateAdd$1(this, _layoutError, null);
81390
82701
  __privateAdd$1(this, _layoutErrorState, "healthy");
81391
82702
  __privateAdd$1(this, _errorBanner, null);
@@ -81429,6 +82740,9 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
81429
82740
  __privateAdd$1(this, _lastClickTime, 0);
81430
82741
  __privateAdd$1(this, _lastClickPosition, { x: 0, y: 0 });
81431
82742
  __privateAdd$1(this, _lastSelectedImageBlockId, null);
82743
+ __privateAdd$1(this, _dragAnchor, null);
82744
+ __privateAdd$1(this, _isDragging, false);
82745
+ __privateAdd$1(this, _dragExtensionMode, "char");
81432
82746
  __privateAdd$1(this, _remoteCursorState, /* @__PURE__ */ new Map());
81433
82747
  __privateAdd$1(this, _remoteCursorDirty, false);
81434
82748
  __privateAdd$1(this, _remoteCursorOverlay, null);
@@ -81441,8 +82755,12 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
81441
82755
  if (event.button !== 0) {
81442
82756
  return;
81443
82757
  }
82758
+ const target = event.target;
82759
+ const isDraggableAnnotation = target?.closest?.('[data-draggable="true"]') != null;
81444
82760
  if (!__privateGet$1(this, _layoutState).layout) {
81445
- event.preventDefault();
82761
+ if (!isDraggableAnnotation) {
82762
+ event.preventDefault();
82763
+ }
81446
82764
  if (document.activeElement instanceof HTMLElement) {
81447
82765
  document.activeElement.blur();
81448
82766
  }
@@ -81451,10 +82769,10 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
81451
82769
  return;
81452
82770
  }
81453
82771
  const validPos = __privateMethod$1(this, _PresentationEditor_instances, getFirstTextPosition_fn).call(this);
81454
- const doc22 = __privateGet$1(this, _editor3)?.state?.doc;
81455
- if (doc22) {
82772
+ const doc222 = __privateGet$1(this, _editor3)?.state?.doc;
82773
+ if (doc222) {
81456
82774
  try {
81457
- const tr = __privateGet$1(this, _editor3).state.tr.setSelection(TextSelection$1.create(doc22, validPos));
82775
+ const tr = __privateGet$1(this, _editor3).state.tr.setSelection(TextSelection$1.create(doc222, validPos));
81458
82776
  __privateGet$1(this, _editor3).view?.dispatch(tr);
81459
82777
  } catch (error) {
81460
82778
  if (process$1$1.env.NODE_ENV === "development") {
@@ -81490,7 +82808,7 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
81490
82808
  if (headerFooterRegion) {
81491
82809
  return;
81492
82810
  }
81493
- const hit = clickToPosition(
82811
+ const rawHit = clickToPosition(
81494
82812
  __privateGet$1(this, _layoutState).layout,
81495
82813
  __privateGet$1(this, _layoutState).blocks,
81496
82814
  __privateGet$1(this, _layoutState).measures,
@@ -81499,7 +82817,11 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
81499
82817
  event.clientX,
81500
82818
  event.clientY
81501
82819
  );
81502
- event.preventDefault();
82820
+ const doc22 = __privateGet$1(this, _editor3).state?.doc;
82821
+ const hit = rawHit && doc22 ? { ...rawHit, pos: Math.max(0, Math.min(rawHit.pos, doc22.content.size)) } : rawHit;
82822
+ if (!isDraggableAnnotation) {
82823
+ event.preventDefault();
82824
+ }
81503
82825
  if (!hit) {
81504
82826
  if (document.activeElement instanceof HTMLElement) {
81505
82827
  document.activeElement.blur();
@@ -81507,10 +82829,10 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
81507
82829
  const editorDom2 = __privateGet$1(this, _editor3).view?.dom;
81508
82830
  if (editorDom2) {
81509
82831
  const validPos = __privateMethod$1(this, _PresentationEditor_instances, getFirstTextPosition_fn).call(this);
81510
- const doc22 = __privateGet$1(this, _editor3)?.state?.doc;
81511
- if (doc22) {
82832
+ const doc222 = __privateGet$1(this, _editor3)?.state?.doc;
82833
+ if (doc222) {
81512
82834
  try {
81513
- const tr = __privateGet$1(this, _editor3).state.tr.setSelection(TextSelection$1.create(doc22, validPos));
82835
+ const tr = __privateGet$1(this, _editor3).state.tr.setSelection(TextSelection$1.create(doc222, validPos));
81514
82836
  __privateGet$1(this, _editor3).view?.dispatch(tr);
81515
82837
  } catch (error) {
81516
82838
  if (process$1$1.env.NODE_ENV === "development") {
@@ -81531,9 +82853,9 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
81531
82853
  hit.pos
81532
82854
  );
81533
82855
  if (fragmentHit && (fragmentHit.fragment.kind === "image" || fragmentHit.fragment.kind === "drawing")) {
81534
- const doc22 = __privateGet$1(this, _editor3).state.doc;
82856
+ const doc222 = __privateGet$1(this, _editor3).state.doc;
81535
82857
  try {
81536
- const tr = __privateGet$1(this, _editor3).state.tr.setSelection(NodeSelection.create(doc22, hit.pos));
82858
+ const tr = __privateGet$1(this, _editor3).state.tr.setSelection(NodeSelection.create(doc222, hit.pos));
81537
82859
  __privateGet$1(this, _editor3).view?.dispatch(tr);
81538
82860
  if (__privateGet$1(this, _lastSelectedImageBlockId) && __privateGet$1(this, _lastSelectedImageBlockId) !== fragmentHit.fragment.blockId) {
81539
82861
  this.emit("imageDeselected", { blockId: __privateGet$1(this, _lastSelectedImageBlockId) });
@@ -81571,18 +82893,61 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
81571
82893
  this.emit("imageDeselected", { blockId: __privateGet$1(this, _lastSelectedImageBlockId) });
81572
82894
  __privateSet(this, _lastSelectedImageBlockId, null);
81573
82895
  }
82896
+ if (event.shiftKey && __privateGet$1(this, _editor3).state.selection.$anchor) {
82897
+ const anchor = __privateGet$1(this, _editor3).state.selection.anchor;
82898
+ const head = hit.pos;
82899
+ const { selAnchor, selHead } = __privateMethod$1(this, _PresentationEditor_instances, calculateExtendedSelection_fn).call(this, anchor, head, __privateGet$1(this, _dragExtensionMode));
82900
+ try {
82901
+ const tr = __privateGet$1(this, _editor3).state.tr.setSelection(TextSelection$1.create(__privateGet$1(this, _editor3).state.doc, selAnchor, selHead));
82902
+ __privateGet$1(this, _editor3).view?.dispatch(tr);
82903
+ __privateMethod$1(this, _PresentationEditor_instances, scheduleSelectionUpdate_fn).call(this);
82904
+ } catch (error) {
82905
+ console.warn("[SELECTION] Failed to extend selection on shift+click:", {
82906
+ error,
82907
+ anchor,
82908
+ head,
82909
+ selAnchor,
82910
+ selHead,
82911
+ mode: __privateGet$1(this, _dragExtensionMode)
82912
+ });
82913
+ }
82914
+ if (document.activeElement instanceof HTMLElement) {
82915
+ document.activeElement.blur();
82916
+ }
82917
+ const editorDom2 = __privateGet$1(this, _editor3).view?.dom;
82918
+ if (editorDom2) {
82919
+ editorDom2.focus();
82920
+ __privateGet$1(this, _editor3).view?.focus();
82921
+ }
82922
+ return;
82923
+ }
81574
82924
  const clickDepth = __privateMethod$1(this, _PresentationEditor_instances, registerPointerClick_fn).call(this, event);
82925
+ if (clickDepth === 1) {
82926
+ __privateSet(this, _dragAnchor, hit.pos);
82927
+ }
82928
+ __privateSet(this, _isDragging, true);
82929
+ if (clickDepth >= 3) {
82930
+ __privateSet(this, _dragExtensionMode, "para");
82931
+ } else if (clickDepth === 2) {
82932
+ __privateSet(this, _dragExtensionMode, "word");
82933
+ } else {
82934
+ __privateSet(this, _dragExtensionMode, "char");
82935
+ }
82936
+ if (typeof __privateGet$1(this, _viewportHost).setPointerCapture === "function") {
82937
+ __privateGet$1(this, _viewportHost).setPointerCapture(event.pointerId);
82938
+ }
81575
82939
  let handledByDepth = false;
81576
82940
  if (__privateGet$1(this, _session).mode === "body") {
82941
+ const selectionPos = clickDepth >= 2 && __privateGet$1(this, _dragAnchor) !== null ? __privateGet$1(this, _dragAnchor) : hit.pos;
81577
82942
  if (clickDepth >= 3) {
81578
- handledByDepth = __privateMethod$1(this, _PresentationEditor_instances, selectParagraphAt_fn).call(this, hit.pos);
82943
+ handledByDepth = __privateMethod$1(this, _PresentationEditor_instances, selectParagraphAt_fn).call(this, selectionPos);
81579
82944
  } else if (clickDepth === 2) {
81580
- handledByDepth = __privateMethod$1(this, _PresentationEditor_instances, selectWordAt_fn).call(this, hit.pos);
82945
+ handledByDepth = __privateMethod$1(this, _PresentationEditor_instances, selectWordAt_fn).call(this, selectionPos);
81581
82946
  }
81582
82947
  }
81583
82948
  if (!handledByDepth) {
81584
- const tr = __privateGet$1(this, _editor3).state.tr.setSelection(TextSelection$1.create(__privateGet$1(this, _editor3).state.doc, hit.pos));
81585
82949
  try {
82950
+ const tr = __privateGet$1(this, _editor3).state.tr.setSelection(TextSelection$1.create(__privateGet$1(this, _editor3).state.doc, hit.pos));
81586
82951
  __privateGet$1(this, _editor3).view?.dispatch(tr);
81587
82952
  } catch {
81588
82953
  }
@@ -81602,6 +82967,36 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
81602
82967
  if (!__privateGet$1(this, _layoutState).layout) return;
81603
82968
  const normalized = __privateMethod$1(this, _PresentationEditor_instances, normalizeClientPoint_fn).call(this, event.clientX, event.clientY);
81604
82969
  if (!normalized) return;
82970
+ if (__privateGet$1(this, _isDragging) && __privateGet$1(this, _dragAnchor) !== null && event.buttons & 1) {
82971
+ const hit = clickToPosition(
82972
+ __privateGet$1(this, _layoutState).layout,
82973
+ __privateGet$1(this, _layoutState).blocks,
82974
+ __privateGet$1(this, _layoutState).measures,
82975
+ { x: normalized.x, y: normalized.y },
82976
+ __privateGet$1(this, _viewportHost),
82977
+ event.clientX,
82978
+ event.clientY
82979
+ );
82980
+ if (!hit) return;
82981
+ const anchor = __privateGet$1(this, _dragAnchor);
82982
+ const head = hit.pos;
82983
+ const { selAnchor, selHead } = __privateMethod$1(this, _PresentationEditor_instances, calculateExtendedSelection_fn).call(this, anchor, head, __privateGet$1(this, _dragExtensionMode));
82984
+ try {
82985
+ const tr = __privateGet$1(this, _editor3).state.tr.setSelection(TextSelection$1.create(__privateGet$1(this, _editor3).state.doc, selAnchor, selHead));
82986
+ __privateGet$1(this, _editor3).view?.dispatch(tr);
82987
+ __privateMethod$1(this, _PresentationEditor_instances, scheduleSelectionUpdate_fn).call(this);
82988
+ } catch (error) {
82989
+ console.warn("[SELECTION] Failed to extend selection during drag:", {
82990
+ error,
82991
+ anchor,
82992
+ head,
82993
+ selAnchor,
82994
+ selHead,
82995
+ mode: __privateGet$1(this, _dragExtensionMode)
82996
+ });
82997
+ }
82998
+ return;
82999
+ }
81605
83000
  if (__privateGet$1(this, _session).mode !== "body") {
81606
83001
  __privateMethod$1(this, _PresentationEditor_instances, clearHoverRegion_fn).call(this);
81607
83002
  return;
@@ -81620,6 +83015,97 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
81620
83015
  __privateAdd$1(this, _handlePointerLeave, () => {
81621
83016
  __privateMethod$1(this, _PresentationEditor_instances, clearHoverRegion_fn).call(this);
81622
83017
  });
83018
+ __privateAdd$1(this, _handlePointerUp, (event) => {
83019
+ if (!__privateGet$1(this, _isDragging)) return;
83020
+ if (typeof __privateGet$1(this, _viewportHost).hasPointerCapture === "function" && typeof __privateGet$1(this, _viewportHost).releasePointerCapture === "function" && __privateGet$1(this, _viewportHost).hasPointerCapture(event.pointerId)) {
83021
+ __privateGet$1(this, _viewportHost).releasePointerCapture(event.pointerId);
83022
+ }
83023
+ __privateSet(this, _isDragging, false);
83024
+ });
83025
+ __privateAdd$1(this, _handleDragOver, (event) => {
83026
+ const activeEditor = this.getActiveEditor();
83027
+ if (!activeEditor?.isEditable) {
83028
+ return;
83029
+ }
83030
+ event.preventDefault();
83031
+ if (event.dataTransfer) {
83032
+ event.dataTransfer.dropEffect = "copy";
83033
+ }
83034
+ const dt = event.dataTransfer;
83035
+ const hasFieldAnnotation = dt?.types?.includes(FIELD_ANNOTATION_DATA_TYPE) || Boolean(dt?.getData?.(FIELD_ANNOTATION_DATA_TYPE));
83036
+ if (!hasFieldAnnotation) {
83037
+ return;
83038
+ }
83039
+ const hit = this.hitTest(event.clientX, event.clientY);
83040
+ const doc22 = activeEditor.state?.doc;
83041
+ if (!hit || !doc22) {
83042
+ return;
83043
+ }
83044
+ const pos = Math.min(Math.max(hit.pos, 1), doc22.content.size);
83045
+ const currentSelection = activeEditor.state.selection;
83046
+ const isSameCursor = currentSelection instanceof TextSelection$1 && currentSelection.from === pos && currentSelection.to === pos;
83047
+ if (isSameCursor) {
83048
+ return;
83049
+ }
83050
+ try {
83051
+ const tr = activeEditor.state.tr.setSelection(TextSelection$1.create(doc22, pos)).setMeta("addToHistory", false);
83052
+ activeEditor.view?.dispatch(tr);
83053
+ __privateMethod$1(this, _PresentationEditor_instances, scheduleSelectionUpdate_fn).call(this);
83054
+ } catch (error) {
83055
+ if (process$1$1.env.NODE_ENV === "development") {
83056
+ console.debug("[PresentationEditor] Drag position update skipped:", error);
83057
+ }
83058
+ }
83059
+ });
83060
+ __privateAdd$1(this, _handleDrop, (event) => {
83061
+ const activeEditor = this.getActiveEditor();
83062
+ if (!activeEditor?.isEditable) {
83063
+ return;
83064
+ }
83065
+ if (event.dataTransfer?.types?.includes("application/x-field-annotation")) {
83066
+ return;
83067
+ }
83068
+ event.preventDefault();
83069
+ event.stopPropagation();
83070
+ const fieldAnnotationData = event.dataTransfer?.getData(FIELD_ANNOTATION_DATA_TYPE);
83071
+ if (!fieldAnnotationData) {
83072
+ return;
83073
+ }
83074
+ const hit = this.hitTest(event.clientX, event.clientY);
83075
+ const selection = activeEditor.state?.selection;
83076
+ const fallbackPos = selection?.from ?? activeEditor.state?.doc?.content.size ?? null;
83077
+ const pos = hit?.pos ?? fallbackPos;
83078
+ if (pos == null) {
83079
+ return;
83080
+ }
83081
+ let parsedData = null;
83082
+ try {
83083
+ parsedData = JSON.parse(fieldAnnotationData);
83084
+ } catch {
83085
+ return;
83086
+ }
83087
+ const { attributes, sourceField } = parsedData ?? {};
83088
+ activeEditor.emit?.("fieldAnnotationDropped", {
83089
+ sourceField,
83090
+ editor: activeEditor,
83091
+ coordinates: hit,
83092
+ pos
83093
+ });
83094
+ if (attributes && isValidFieldAnnotationAttributes(attributes)) {
83095
+ activeEditor.commands?.addFieldAnnotation?.(pos, attributes, true);
83096
+ const posAfter = Math.min(pos + 1, activeEditor.state?.doc?.content.size ?? pos + 1);
83097
+ const tr = activeEditor.state?.tr.setSelection(TextSelection$1.create(activeEditor.state.doc, posAfter));
83098
+ if (tr) {
83099
+ activeEditor.view?.dispatch(tr);
83100
+ }
83101
+ __privateMethod$1(this, _PresentationEditor_instances, scheduleSelectionUpdate_fn).call(this);
83102
+ }
83103
+ const editorDom = activeEditor.view?.dom;
83104
+ if (editorDom) {
83105
+ editorDom.focus();
83106
+ activeEditor.view?.focus();
83107
+ }
83108
+ });
81623
83109
  __privateAdd$1(this, _handleDoubleClick, (event) => {
81624
83110
  if (event.button !== 0) return;
81625
83111
  if (!__privateGet$1(this, _layoutState).layout) return;
@@ -81809,6 +83295,7 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
81809
83295
  __privateMethod$1(this, _PresentationEditor_instances, applyZoom_fn).call(this);
81810
83296
  __privateMethod$1(this, _PresentationEditor_instances, setupEditorListeners_fn).call(this);
81811
83297
  __privateMethod$1(this, _PresentationEditor_instances, setupPointerHandlers_fn).call(this);
83298
+ __privateMethod$1(this, _PresentationEditor_instances, setupDragHandlers_fn).call(this);
81812
83299
  __privateMethod$1(this, _PresentationEditor_instances, setupInputBridge_fn).call(this);
81813
83300
  __privateMethod$1(this, _PresentationEditor_instances, syncTrackedChangesPreferences_fn).call(this);
81814
83301
  if (options.documentId) {
@@ -82520,6 +84007,7 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
82520
84007
  * Safe to call during partial initialization.
82521
84008
  */
82522
84009
  destroy() {
84010
+ var _a2;
82523
84011
  if (__privateGet$1(this, _rafHandle) != null) {
82524
84012
  __privateMethod$1(this, _PresentationEditor_instances, safeCleanup_fn).call(this, () => {
82525
84013
  const win = __privateGet$1(this, _visibleHost)?.ownerDocument?.defaultView ?? window;
@@ -82539,7 +84027,10 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
82539
84027
  __privateGet$1(this, _viewportHost)?.removeEventListener("pointerdown", __privateGet$1(this, _handlePointerDown));
82540
84028
  __privateGet$1(this, _viewportHost)?.removeEventListener("dblclick", __privateGet$1(this, _handleDoubleClick));
82541
84029
  __privateGet$1(this, _viewportHost)?.removeEventListener("pointermove", __privateGet$1(this, _handlePointerMove));
84030
+ __privateGet$1(this, _viewportHost)?.removeEventListener("pointerup", __privateGet$1(this, _handlePointerUp));
82542
84031
  __privateGet$1(this, _viewportHost)?.removeEventListener("pointerleave", __privateGet$1(this, _handlePointerLeave));
84032
+ __privateGet$1(this, _viewportHost)?.removeEventListener("dragover", __privateGet$1(this, _handleDragOver));
84033
+ __privateGet$1(this, _viewportHost)?.removeEventListener("drop", __privateGet$1(this, _handleDrop));
82543
84034
  __privateGet$1(this, _visibleHost)?.removeEventListener("keydown", __privateGet$1(this, _handleKeyDown));
82544
84035
  __privateGet$1(this, _inputBridge)?.notifyTargetChanged();
82545
84036
  __privateGet$1(this, _inputBridge)?.destroy();
@@ -82578,6 +84069,8 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
82578
84069
  __privateSet(this, _session, { mode: "body" });
82579
84070
  __privateSet(this, _activeHeaderFooterEditor, null);
82580
84071
  __privateSet(this, _domPainter, null);
84072
+ (_a2 = __privateGet$1(this, _dragHandlerCleanup)) == null ? void 0 : _a2.call(this);
84073
+ __privateSet(this, _dragHandlerCleanup, null);
82581
84074
  __privateGet$1(this, _selectionOverlay2)?.remove();
82582
84075
  __privateGet$1(this, _painterHost)?.remove();
82583
84076
  __privateGet$1(this, _hiddenHost)?.remove();
@@ -82605,6 +84098,7 @@ _hiddenHost = /* @__PURE__ */ new WeakMap();
82605
84098
  _layoutOptions = /* @__PURE__ */ new WeakMap();
82606
84099
  _layoutState = /* @__PURE__ */ new WeakMap();
82607
84100
  _domPainter = /* @__PURE__ */ new WeakMap();
84101
+ _dragHandlerCleanup = /* @__PURE__ */ new WeakMap();
82608
84102
  _layoutError = /* @__PURE__ */ new WeakMap();
82609
84103
  _layoutErrorState = /* @__PURE__ */ new WeakMap();
82610
84104
  _errorBanner = /* @__PURE__ */ new WeakMap();
@@ -82648,6 +84142,9 @@ _clickCount = /* @__PURE__ */ new WeakMap();
82648
84142
  _lastClickTime = /* @__PURE__ */ new WeakMap();
82649
84143
  _lastClickPosition = /* @__PURE__ */ new WeakMap();
82650
84144
  _lastSelectedImageBlockId = /* @__PURE__ */ new WeakMap();
84145
+ _dragAnchor = /* @__PURE__ */ new WeakMap();
84146
+ _isDragging = /* @__PURE__ */ new WeakMap();
84147
+ _dragExtensionMode = /* @__PURE__ */ new WeakMap();
82651
84148
  _remoteCursorState = /* @__PURE__ */ new WeakMap();
82652
84149
  _remoteCursorDirty = /* @__PURE__ */ new WeakMap();
82653
84150
  _remoteCursorOverlay = /* @__PURE__ */ new WeakMap();
@@ -82983,9 +84480,101 @@ setupPointerHandlers_fn = function() {
82983
84480
  __privateGet$1(this, _viewportHost).addEventListener("pointerdown", __privateGet$1(this, _handlePointerDown));
82984
84481
  __privateGet$1(this, _viewportHost).addEventListener("dblclick", __privateGet$1(this, _handleDoubleClick));
82985
84482
  __privateGet$1(this, _viewportHost).addEventListener("pointermove", __privateGet$1(this, _handlePointerMove));
84483
+ __privateGet$1(this, _viewportHost).addEventListener("pointerup", __privateGet$1(this, _handlePointerUp));
82986
84484
  __privateGet$1(this, _viewportHost).addEventListener("pointerleave", __privateGet$1(this, _handlePointerLeave));
84485
+ __privateGet$1(this, _viewportHost).addEventListener("dragover", __privateGet$1(this, _handleDragOver));
84486
+ __privateGet$1(this, _viewportHost).addEventListener("drop", __privateGet$1(this, _handleDrop));
82987
84487
  __privateGet$1(this, _visibleHost).addEventListener("keydown", __privateGet$1(this, _handleKeyDown));
82988
84488
  };
84489
+ setupDragHandlers_fn = function() {
84490
+ var _a2;
84491
+ (_a2 = __privateGet$1(this, _dragHandlerCleanup)) == null ? void 0 : _a2.call(this);
84492
+ __privateSet(this, _dragHandlerCleanup, null);
84493
+ __privateSet(this, _dragHandlerCleanup, createDragHandler(__privateGet$1(this, _painterHost), {
84494
+ onDragOver: (event) => {
84495
+ if (!event.hasFieldAnnotation || event.event.clientX === 0) {
84496
+ return;
84497
+ }
84498
+ const activeEditor = this.getActiveEditor();
84499
+ if (!activeEditor?.isEditable) {
84500
+ return;
84501
+ }
84502
+ const hit = this.hitTest(event.clientX, event.clientY);
84503
+ const doc2 = activeEditor.state?.doc;
84504
+ if (!hit || !doc2) {
84505
+ return;
84506
+ }
84507
+ const pos = Math.min(Math.max(hit.pos, 1), doc2.content.size);
84508
+ const currentSelection = activeEditor.state.selection;
84509
+ if (currentSelection instanceof TextSelection$1 && currentSelection.from === pos && currentSelection.to === pos) {
84510
+ return;
84511
+ }
84512
+ try {
84513
+ const tr = activeEditor.state.tr.setSelection(TextSelection$1.create(doc2, pos)).setMeta("addToHistory", false);
84514
+ activeEditor.view?.dispatch(tr);
84515
+ __privateMethod$1(this, _PresentationEditor_instances, scheduleSelectionUpdate_fn).call(this);
84516
+ } catch {
84517
+ }
84518
+ },
84519
+ onDrop: (event) => {
84520
+ event.event.preventDefault();
84521
+ event.event.stopPropagation();
84522
+ if (event.pmPosition === null) {
84523
+ return;
84524
+ }
84525
+ const activeEditor = this.getActiveEditor();
84526
+ const { state: state2, view } = activeEditor;
84527
+ if (!state2 || !view) {
84528
+ return;
84529
+ }
84530
+ const fieldId = event.data.fieldId;
84531
+ if (fieldId) {
84532
+ const targetPos = event.pmPosition;
84533
+ let sourceStart = null;
84534
+ let sourceEnd = null;
84535
+ let sourceNode = null;
84536
+ state2.doc.descendants((node, pos) => {
84537
+ if (node.type.name === "fieldAnnotation" && node.attrs.fieldId === fieldId) {
84538
+ sourceStart = pos;
84539
+ sourceEnd = pos + node.nodeSize;
84540
+ sourceNode = node;
84541
+ return false;
84542
+ }
84543
+ return true;
84544
+ });
84545
+ if (sourceStart === null || sourceEnd === null || !sourceNode) {
84546
+ return;
84547
+ }
84548
+ if (targetPos >= sourceStart && targetPos <= sourceEnd) {
84549
+ return;
84550
+ }
84551
+ const tr = state2.tr;
84552
+ tr.delete(sourceStart, sourceEnd);
84553
+ const mappedTarget = tr.mapping.map(targetPos);
84554
+ if (mappedTarget < 0 || mappedTarget > tr.doc.content.size) {
84555
+ return;
84556
+ }
84557
+ tr.insert(mappedTarget, sourceNode);
84558
+ tr.setMeta("uiEvent", "drop");
84559
+ view.dispatch(tr);
84560
+ return;
84561
+ }
84562
+ const attrs = event.data.attributes;
84563
+ if (attrs && isValidFieldAnnotationAttributes(attrs)) {
84564
+ const inserted = activeEditor.commands?.addFieldAnnotation?.(event.pmPosition, attrs, true);
84565
+ if (inserted) {
84566
+ __privateMethod$1(this, _PresentationEditor_instances, scheduleSelectionUpdate_fn).call(this);
84567
+ }
84568
+ return;
84569
+ }
84570
+ activeEditor.emit("fieldAnnotationDropped", {
84571
+ sourceField: event.data,
84572
+ editor: activeEditor,
84573
+ coordinates: { pos: event.pmPosition }
84574
+ });
84575
+ }
84576
+ }));
84577
+ };
82989
84578
  setupInputBridge_fn = function() {
82990
84579
  __privateGet$1(this, _inputBridge)?.destroy();
82991
84580
  const win = __privateGet$1(this, _visibleHost).ownerDocument?.defaultView ?? window;
@@ -83062,8 +84651,11 @@ getFirstTextPosition_fn = function() {
83062
84651
  registerPointerClick_fn = function(event) {
83063
84652
  const MAX_CLICK_COUNT = 3;
83064
84653
  const time2 = event.timeStamp ?? performance.now();
83065
- const withinTime = time2 - __privateGet$1(this, _lastClickTime) <= MULTI_CLICK_TIME_THRESHOLD_MS;
83066
- const withinDistance = Math.abs(event.clientX - __privateGet$1(this, _lastClickPosition).x) <= MULTI_CLICK_DISTANCE_THRESHOLD_PX && Math.abs(event.clientY - __privateGet$1(this, _lastClickPosition).y) <= MULTI_CLICK_DISTANCE_THRESHOLD_PX;
84654
+ const timeDelta = time2 - __privateGet$1(this, _lastClickTime);
84655
+ const withinTime = timeDelta <= MULTI_CLICK_TIME_THRESHOLD_MS;
84656
+ const distanceX = Math.abs(event.clientX - __privateGet$1(this, _lastClickPosition).x);
84657
+ const distanceY = Math.abs(event.clientY - __privateGet$1(this, _lastClickPosition).y);
84658
+ const withinDistance = distanceX <= MULTI_CLICK_DISTANCE_THRESHOLD_PX && distanceY <= MULTI_CLICK_DISTANCE_THRESHOLD_PX;
83067
84659
  if (withinTime && withinDistance) {
83068
84660
  __privateSet(this, _clickCount, Math.min(__privateGet$1(this, _clickCount) + 1, MAX_CLICK_COUNT));
83069
84661
  } else {
@@ -83078,6 +84670,9 @@ selectWordAt_fn = function(pos) {
83078
84670
  if (!state2?.doc) {
83079
84671
  return false;
83080
84672
  }
84673
+ if (pos < 0 || pos > state2.doc.content.size) {
84674
+ return false;
84675
+ }
83081
84676
  const $pos = state2.doc.resolve(pos);
83082
84677
  let textblockPos = $pos;
83083
84678
  while (textblockPos.depth > 0) {
@@ -83164,6 +84759,30 @@ selectParagraphAt_fn = function(pos) {
83164
84759
  return false;
83165
84760
  }
83166
84761
  };
84762
+ calculateExtendedSelection_fn = function(anchor, head, mode) {
84763
+ if (mode === "word") {
84764
+ const anchorBounds = findWordBoundaries(__privateGet$1(this, _layoutState).blocks, anchor);
84765
+ const headBounds = findWordBoundaries(__privateGet$1(this, _layoutState).blocks, head);
84766
+ if (anchorBounds && headBounds) {
84767
+ if (head >= anchor) {
84768
+ return { selAnchor: anchorBounds.from, selHead: headBounds.to };
84769
+ } else {
84770
+ return { selAnchor: anchorBounds.to, selHead: headBounds.from };
84771
+ }
84772
+ }
84773
+ } else if (mode === "para") {
84774
+ const anchorBounds = findParagraphBoundaries(__privateGet$1(this, _layoutState).blocks, anchor);
84775
+ const headBounds = findParagraphBoundaries(__privateGet$1(this, _layoutState).blocks, head);
84776
+ if (anchorBounds && headBounds) {
84777
+ if (head >= anchor) {
84778
+ return { selAnchor: anchorBounds.from, selHead: headBounds.to };
84779
+ } else {
84780
+ return { selAnchor: anchorBounds.to, selHead: headBounds.from };
84781
+ }
84782
+ }
84783
+ }
84784
+ return { selAnchor: anchor, selHead: head };
84785
+ };
83167
84786
  isWordCharacter_fn = function(char) {
83168
84787
  if (!char) {
83169
84788
  return false;
@@ -83172,6 +84791,9 @@ isWordCharacter_fn = function(char) {
83172
84791
  };
83173
84792
  _handlePointerMove = /* @__PURE__ */ new WeakMap();
83174
84793
  _handlePointerLeave = /* @__PURE__ */ new WeakMap();
84794
+ _handlePointerUp = /* @__PURE__ */ new WeakMap();
84795
+ _handleDragOver = /* @__PURE__ */ new WeakMap();
84796
+ _handleDrop = /* @__PURE__ */ new WeakMap();
83175
84797
  _handleDoubleClick = /* @__PURE__ */ new WeakMap();
83176
84798
  _handleKeyDown = /* @__PURE__ */ new WeakMap();
83177
84799
  focusHeaderFooterShortcut_fn = function(kind) {
@@ -84344,10 +85966,12 @@ convertPageLocalToOverlayCoords_fn = function(pageIndex, pageLocalX, pageLocalY)
84344
85966
  }
84345
85967
  const pageRect = pageEl.getBoundingClientRect();
84346
85968
  const overlayRect = __privateGet$1(this, _selectionOverlay2).getBoundingClientRect();
84347
- const zoom = __privateGet$1(this, _layoutOptions).zoom ?? 1;
85969
+ const layoutPageSize = __privateGet$1(this, _layoutState).layout?.pageSize;
85970
+ const scaleX = layoutPageSize && typeof layoutPageSize.w === "number" && layoutPageSize.w > 0 ? pageRect.width / layoutPageSize.w : 1;
85971
+ const scaleY = layoutPageSize && typeof layoutPageSize.h === "number" && layoutPageSize.h > 0 ? pageRect.height / layoutPageSize.h : 1;
84348
85972
  return {
84349
- x: pageRect.left - overlayRect.left + pageLocalX * zoom,
84350
- y: pageRect.top - overlayRect.top + pageLocalY * zoom
85973
+ x: pageRect.left - overlayRect.left + pageLocalX * scaleX,
85974
+ y: pageRect.top - overlayRect.top + pageLocalY * scaleY
84351
85975
  };
84352
85976
  };
84353
85977
  normalizeClientPoint_fn = function(clientX, clientY) {