@stll/folio-core 0.42.0 → 0.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/compat/eigenpal.d.ts +2 -2
  2. package/dist/controller/layoutPipeline.d.ts +2 -1
  3. package/dist/controller/layoutPipeline.js +5 -2
  4. package/dist/controller/layoutSession.d.ts +2 -1
  5. package/dist/controller/layoutSession.js +1 -0
  6. package/dist/docx/blockContentParser.js +2 -1
  7. package/dist/docx/commentIdNormalization.d.ts +8 -0
  8. package/dist/docx/commentIdNormalization.js +16 -0
  9. package/dist/docx/defaultParagraphStyle.d.ts +22 -0
  10. package/dist/docx/defaultParagraphStyle.js +32 -0
  11. package/dist/docx/footnoteParser.js +2 -0
  12. package/dist/docx/headerFooterRefParser.d.ts +12 -1
  13. package/dist/docx/headerFooterRefParser.js +9 -2
  14. package/dist/docx/numberingParser.js +2 -1
  15. package/dist/docx/numberingReference.d.ts +21 -0
  16. package/dist/docx/numberingReference.js +21 -0
  17. package/dist/docx/numberingReferenceNormalization.d.ts +11 -2
  18. package/dist/docx/numberingReferenceNormalization.js +32 -9
  19. package/dist/docx/paragraphParser.js +3 -2
  20. package/dist/docx/parser.js +10 -2
  21. package/dist/docx/rezip.js +22 -5
  22. package/dist/docx/server/createBilingualDocument.js +5 -4
  23. package/dist/docx/styleParser.js +2 -2
  24. package/dist/index.d.ts +2 -2
  25. package/dist/internal/pageBreakRunSourceDescendantIndex.d.ts +2 -0
  26. package/dist/internal/pageBreakRunSourceDescendantIndex.js +7 -5
  27. package/dist/layout-bridge/convert/templatePreviewFlow.d.ts +19 -11
  28. package/dist/layout-bridge/convert/templatePreviewFlow.js +103 -38
  29. package/dist/layout-bridge/convert/toFlowBlocks.js +12 -3
  30. package/dist/prosemirror/commands/pageBreak.js +12 -1
  31. package/dist/prosemirror/conversion/fromProseDoc.js +2 -1
  32. package/dist/prosemirror/conversion/toProseDoc.js +27 -12
  33. package/dist/prosemirror/extensions/features/ListExtension.js +42 -4
  34. package/dist/prosemirror/listMarker.js +2 -1
  35. package/dist/prosemirror/numberedRefFields.js +2 -1
  36. package/dist/prosemirror/pageBreakRunProjection.d.ts +11 -3
  37. package/dist/prosemirror/pageBreakRunProjection.js +16 -8
  38. package/dist/prosemirror/plugins/templatePreviewValues.d.ts +42 -1
  39. package/dist/prosemirror/plugins/templatePreviewValues.js +217 -14
  40. package/dist/prosemirror/styles/resolvedStyleAttrs.js +2 -1
  41. package/dist/prosemirror/styles/styleResolver.js +3 -6
  42. package/dist/prosemirror/utils/visualLineNavigation.d.ts +22 -2
  43. package/dist/prosemirror/utils/visualLineNavigation.js +80 -63
  44. package/dist/style-engine/styleEngine.d.ts +1 -1
  45. package/dist/style-sets/extract.js +57 -11
  46. package/package.json +2 -1
@@ -29,7 +29,7 @@ import { getFolioCaretViewportRect, getFolioSelectionViewportRect } from "../pag
29
29
  import { AICitationRange, createAICitationDecorationsPlugin, setAICitationsMeta, setActiveCitationMeta } from "../prosemirror/plugins/aiCitationDecorations.js";
30
30
  import { AnonymizationMatch, AnonymizationTerm, anonymizationDecorationsKey, getAnonymizationMatches, setAnonymizationTermsMeta } from "../prosemirror/plugins/anonymizationDecorations.js";
31
31
  import { DirectiveKind, DirectiveRange, getTemplateDirectives, scanDirectives } from "../prosemirror/plugins/templateDirectives.js";
32
- import { TemplatePreviewSpan, TemplatePreviewValue, TemplatePreviewValues, setTemplatePreviewValues } from "../prosemirror/plugins/templatePreviewValues.js";
32
+ import { TemplatePreviewHiddenRange, TemplatePreviewSpan, TemplatePreviewValue, TemplatePreviewValues, setTemplatePreviewValues } from "../prosemirror/plugins/templatePreviewValues.js";
33
33
  import { TemplateSlashMenuKeyAction, TemplateSlashMenuState, clearTemplateSlashMenu, consumeTemplateSlashQuery, getTemplateSlashMenu, resetTemplateSlashQuery, templateSlashMenuKey } from "../prosemirror/plugins/templateSlashMenu.js";
34
34
  import { AcceptAutocompleteResult, AutocompleteSuggestionPluginOptions, AutocompleteSuggestionState, AutocompleteSuggestionStatus, AutocompleteTriggerCheck, AutocompleteTriggerOptions, AutocompleteTriggerSkipReason, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, acceptAutocompleteSuggestion, acceptAutocompleteWord, appendAutocompleteToken, autocompleteSuggestionKey, autocompleteSuggestionPlugin, clearAutocompleteSuggestion, finishAutocompleteSuggestion, getAutocompleteSuggestion, shouldTriggerAutocomplete, startAutocompleteSuggestion } from "../prosemirror/plugins/autocompleteSuggestion.js";
35
35
  import { ImageMeta, ImageRef, MarkdownOptions, MarkdownResult } from "../markdown/types.js";
@@ -40,4 +40,4 @@ import { getGoogleFontsEnabled, setEmbeddedFontFamilyMap, setGoogleFontsEnabled
40
40
  import { DOCX_CONFORMANCE_CLASSES } from "../index.js";
41
41
  type Document = document_d_exports.Document;
42
42
  type DocxConformanceClass = document_d_exports.DocxConformanceClass;
43
- export { type AIBarStatus, type AIChatMode, type AICitation, type AICitationRange, type AICitationSource, type AIGenerateInput, type AISuggestion, type AISuggestionApplyMode, type AISuggestionPreset, type AISuggestionSeverity, type AISuggestionStatus, type AcceptAutocompleteResult, type AnonymizationMatch, type AnonymizationTerm, type ApplyFolioDocumentOperationsOptions, type ApplyResult, type AutocompleteSuggestionPluginOptions, type AutocompleteSuggestionState, type AutocompleteSuggestionStatus, type AutocompleteTriggerCheck, type AutocompleteTriggerOptions, type AutocompleteTriggerSkipReason, type BlockRect, COMPARE_REVISION_FORMATS, COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, type CompareChange, type CompareChangeLocation, type CompareCompatibility, type CompareContentOptions, CompareDocxApplyError, type CompareDocxError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, type CompareDocxOptions, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, type CompareFolioRequirement, type CompareResult, type CompareRevisionFormat, type CompareUnsupportedPart, type CompareUnsupportedReason, type CompareVerification, type CompareVerificationCause, type CompareVerificationFailure, type CompareVerificationInvariant, type CreateEmptyDocumentOptions, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, DRAWING_SAFETY_CLASSES, type DeriveBlockIdInput, type DirectiveKind, type DirectiveRange, type Document, type DocumentPreset, type DocumentPropertiesOptions, type DocumentStyleCatalog, type DocumentStyleCatalogEntry, type DocumentStyleSet, type DocxCompatibility, type DocxCompatibilityContext, type DocxCompatibilityIssue, type DocxCompatibilityLocation, type DocxCompatibilityPart, type DocxConformanceClass, type DocxDrawingClassification, type DrawingSafetyClass, type EmbeddedFont, type EmbeddedFontParts, type ExtractDocumentStyleSetOptions, FOLIO_CONTENT_COMPARISON_LIMITS, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_LINE_SPACING_RULE_VALUES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, type FinalParagraphMarkRevision, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIBlockStructuralBoundary, type FolioAIBlockTableLocation, type FolioAIComment, type FolioAIEditAppliedOperation, type FolioAIEditApplyMode, type FolioAIEditApplyOutcome, type FolioAIEditApplyResult, type FolioAIEditNormalization, type FolioAIEditNormalizationCode, type FolioAIEditOperation, type FolioAIEditPrecondition, type FolioAIEditReviewMeta, type FolioAIEditSeverity, type FolioAIEditSkipReason, type FolioAIEditSkippedOperation, type FolioAIEditSnapshot, type FolioAIInlineBooleanProperty, type FolioAIInlineFormatting, type FolioAIInlineFormattingPatch, type FolioAIParagraphSpacing, type FolioAISignatureParty, type FolioBlockId, type FolioContentBlock, type FolioContentBlockProperty, type FolioContentComparison, type FolioContentComparisonError, type FolioContentComparisonEvent, type FolioContentComparisonLimit, FolioContentComparisonLimitError, type FolioContentContainerPathEntry, type FolioContentFormatRange, type FolioContentFormattingChange, type FolioContentIdStability, type FolioContentInlineBooleanProperty, type FolioContentInlineComparisonResult, type FolioContentInlineFormatting, type FolioContentInlineFormattingPatch, FolioContentInlinePresentationProjectionError, type FolioContentLineSpacingRule, type FolioContentParagraphAlignment, type FolioContentParagraphFormattingPatch, type FolioContentParagraphKind, type FolioContentParagraphSpacing, type FolioContentRun, type FolioContentSnapshot, type FolioContentStructuralChange, type FolioContentTableLocation, type FolioContentTextSegment, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationResultBase, type FolioDocumentOperationStatus, type FolioDocumentOperationStory, type FolioDocumentOperationType, type FolioDocumentOperationUndoFailureReason, type FolioDocumentOperationUndoHandle, type FolioDocumentOperationUndoResult, type FolioDocxCompatibilityHost, type FolioDocxCompatibilityProfile, type FolioRevisionStamp, type FolioWordDiffOptions, type ImageMeta, type ImageRef, type InspectDocxCompatibilityOptions, InvalidCompareDocxOptionsError, InvalidFolioContentComparisonError, InvalidFolioDocumentOperationBatchError, MAX_COMPARE_OPERATIONS, type MarkdownOptions, type MarkdownResult, type PositionalText, type ResolvedAnchor, STELLA_STYLE_SET_NAME, type TemplatePreviewSpan, type TemplatePreviewValue, type TemplatePreviewValues, type TemplateSlashMenuKeyAction, type TemplateSlashMenuState, UnsupportedFolioDocumentOperationVersionError, WORD_DIFF_GRANULARITIES, type WordDiffGranularity, type WordDiffNormalization, type WordDiffOptions, type WordDiffSegment, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, compareContent, compareDocx, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, currentFolioBlockId, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioAIContentBlock, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, mergeDocumentContent, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
43
+ export { type AIBarStatus, type AIChatMode, type AICitation, type AICitationRange, type AICitationSource, type AIGenerateInput, type AISuggestion, type AISuggestionApplyMode, type AISuggestionPreset, type AISuggestionSeverity, type AISuggestionStatus, type AcceptAutocompleteResult, type AnonymizationMatch, type AnonymizationTerm, type ApplyFolioDocumentOperationsOptions, type ApplyResult, type AutocompleteSuggestionPluginOptions, type AutocompleteSuggestionState, type AutocompleteSuggestionStatus, type AutocompleteTriggerCheck, type AutocompleteTriggerOptions, type AutocompleteTriggerSkipReason, type BlockRect, COMPARE_REVISION_FORMATS, COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, type CompareChange, type CompareChangeLocation, type CompareCompatibility, type CompareContentOptions, CompareDocxApplyError, type CompareDocxError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, type CompareDocxOptions, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, type CompareFolioRequirement, type CompareResult, type CompareRevisionFormat, type CompareUnsupportedPart, type CompareUnsupportedReason, type CompareVerification, type CompareVerificationCause, type CompareVerificationFailure, type CompareVerificationInvariant, type CreateEmptyDocumentOptions, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, DRAWING_SAFETY_CLASSES, type DeriveBlockIdInput, type DirectiveKind, type DirectiveRange, type Document, type DocumentPreset, type DocumentPropertiesOptions, type DocumentStyleCatalog, type DocumentStyleCatalogEntry, type DocumentStyleSet, type DocxCompatibility, type DocxCompatibilityContext, type DocxCompatibilityIssue, type DocxCompatibilityLocation, type DocxCompatibilityPart, type DocxConformanceClass, type DocxDrawingClassification, type DrawingSafetyClass, type EmbeddedFont, type EmbeddedFontParts, type ExtractDocumentStyleSetOptions, FOLIO_CONTENT_COMPARISON_LIMITS, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_LINE_SPACING_RULE_VALUES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, type FinalParagraphMarkRevision, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIBlockStructuralBoundary, type FolioAIBlockTableLocation, type FolioAIComment, type FolioAIEditAppliedOperation, type FolioAIEditApplyMode, type FolioAIEditApplyOutcome, type FolioAIEditApplyResult, type FolioAIEditNormalization, type FolioAIEditNormalizationCode, type FolioAIEditOperation, type FolioAIEditPrecondition, type FolioAIEditReviewMeta, type FolioAIEditSeverity, type FolioAIEditSkipReason, type FolioAIEditSkippedOperation, type FolioAIEditSnapshot, type FolioAIInlineBooleanProperty, type FolioAIInlineFormatting, type FolioAIInlineFormattingPatch, type FolioAIParagraphSpacing, type FolioAISignatureParty, type FolioBlockId, type FolioContentBlock, type FolioContentBlockProperty, type FolioContentComparison, type FolioContentComparisonError, type FolioContentComparisonEvent, type FolioContentComparisonLimit, FolioContentComparisonLimitError, type FolioContentContainerPathEntry, type FolioContentFormatRange, type FolioContentFormattingChange, type FolioContentIdStability, type FolioContentInlineBooleanProperty, type FolioContentInlineComparisonResult, type FolioContentInlineFormatting, type FolioContentInlineFormattingPatch, FolioContentInlinePresentationProjectionError, type FolioContentLineSpacingRule, type FolioContentParagraphAlignment, type FolioContentParagraphFormattingPatch, type FolioContentParagraphKind, type FolioContentParagraphSpacing, type FolioContentRun, type FolioContentSnapshot, type FolioContentStructuralChange, type FolioContentTableLocation, type FolioContentTextSegment, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationResultBase, type FolioDocumentOperationStatus, type FolioDocumentOperationStory, type FolioDocumentOperationType, type FolioDocumentOperationUndoFailureReason, type FolioDocumentOperationUndoHandle, type FolioDocumentOperationUndoResult, type FolioDocxCompatibilityHost, type FolioDocxCompatibilityProfile, type FolioRevisionStamp, type FolioWordDiffOptions, type ImageMeta, type ImageRef, type InspectDocxCompatibilityOptions, InvalidCompareDocxOptionsError, InvalidFolioContentComparisonError, InvalidFolioDocumentOperationBatchError, MAX_COMPARE_OPERATIONS, type MarkdownOptions, type MarkdownResult, type PositionalText, type ResolvedAnchor, STELLA_STYLE_SET_NAME, type TemplatePreviewHiddenRange, type TemplatePreviewSpan, type TemplatePreviewValue, type TemplatePreviewValues, type TemplateSlashMenuKeyAction, type TemplateSlashMenuState, UnsupportedFolioDocumentOperationVersionError, WORD_DIFF_GRANULARITIES, type WordDiffGranularity, type WordDiffNormalization, type WordDiffOptions, type WordDiffSegment, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, compareContent, compareDocx, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, currentFolioBlockId, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioAIContentBlock, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, mergeDocumentContent, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
@@ -1,5 +1,5 @@
1
1
  import { document_d_exports } from "../types/document.js";
2
- import { TemplatePreviewEntry } from "../prosemirror/plugins/templatePreviewValues.js";
2
+ import { TemplatePreviewEntry, TemplatePreviewHiddenRange } from "../prosemirror/plugins/templatePreviewValues.js";
3
3
  import { ColumnLayout, FlowBlock, FootnoteContent, HeaderFooterContent, Layout, Measure, PageHeaderFooterRefs, PageMargins } from "../layout-engine/types.js";
4
4
  import { LayoutRunReason } from "../layout-engine/layoutInstrumentation.js";
5
5
  import { DirtyRange } from "../paged-layout/incrementalMeasure.js";
@@ -73,6 +73,7 @@ type LayoutPipelineDeps<THfPMs> = {
73
73
  */
74
74
  pageRenderer?: PageRendererName;
75
75
  emptyTemplatePreviewEntries: readonly TemplatePreviewEntry[];
76
+ emptyTemplatePreviewHidden: readonly TemplatePreviewHiddenRange[];
76
77
  };
77
78
  declare function runLayoutPipeline<THfPMs>(deps: LayoutPipelineDeps<THfPMs>, state: EditorState, options?: LayoutRunOptions): LayoutOutcome;
78
79
  //#endregion
@@ -100,7 +100,7 @@ function attachAuthoredMarginsToLayoutPages(layout, options) {
100
100
  } : layout;
101
101
  }
102
102
  function runLayoutPipeline(deps, state, options = {}) {
103
- const { contentWidth, columns, pageSize, margins, pageGap, showMarginGuides, marginGuideColor, syncCoordinator, headerContent, footerContent, firstPageHeaderContent, firstPageFooterContent, headerContentRId, footerContentRId, firstPageHeaderContentRId, firstPageFooterContentRId, sectionHeaderFooterRefs, theme: _theme, sectionProperties, document, defaultTabStop, mirrorMargins, styles, layout, hfPMs, painter, pagesContainer, session, renderHfFromContentOrPm, renderHeaderFooterContentByRId, documentFontsAreLoaded, buildFootnoteRenderItems, describeInvalidHighlightMarks, pageRenderer = PAGE_RENDERER.legacy, emptyTemplatePreviewEntries: EMPTY_TEMPLATE_PREVIEW_ENTRIES } = deps;
103
+ const { contentWidth, columns, pageSize, margins, pageGap, showMarginGuides, marginGuideColor, syncCoordinator, headerContent, footerContent, firstPageHeaderContent, firstPageFooterContent, headerContentRId, footerContentRId, firstPageHeaderContentRId, firstPageFooterContentRId, sectionHeaderFooterRefs, theme: _theme, sectionProperties, document, defaultTabStop, mirrorMargins, styles, layout, hfPMs, painter, pagesContainer, session, renderHfFromContentOrPm, renderHeaderFooterContentByRId, documentFontsAreLoaded, buildFootnoteRenderItems, describeInvalidHighlightMarks, pageRenderer = PAGE_RENDERER.legacy, emptyTemplatePreviewEntries: EMPTY_TEMPLATE_PREVIEW_ENTRIES, emptyTemplatePreviewHidden: EMPTY_TEMPLATE_PREVIEW_HIDDEN } = deps;
104
104
  let outcome = {};
105
105
  let pendingArtifacts;
106
106
  let pendingTemplatePreview;
@@ -144,13 +144,16 @@ function runLayoutPipeline(deps, state, options = {}) {
144
144
  }, state.doc.content, state.doc.marks) : state.doc, flowOpts);
145
145
  const previewState = templatePreviewValuesKey.getState(state);
146
146
  const previewEntries = previewState?.entries ?? EMPTY_TEMPLATE_PREVIEW_ENTRIES;
147
+ const previewHidden = previewState?.hidden ?? EMPTY_TEMPLATE_PREVIEW_HIDDEN;
147
148
  const previewMode = previewState?.preview?.mode ?? "plain";
148
- if (previewEntries.length > 0) newBlocks = applyTemplatePreviewToBlocks(newBlocks, {
149
+ if (previewEntries.length > 0 || previewHidden.length > 0) newBlocks = applyTemplatePreviewToBlocks(newBlocks, {
149
150
  entries: previewEntries,
151
+ hidden: previewHidden,
150
152
  mode: previewMode
151
153
  });
152
154
  pendingTemplatePreview = {
153
155
  entries: previewEntries,
156
+ hidden: previewHidden,
154
157
  mode: previewMode
155
158
  };
156
159
  outcome.blocks = newBlocks;
@@ -1,4 +1,4 @@
1
- import { TemplatePreviewEntry, TemplatePreviewValues } from "../prosemirror/plugins/templatePreviewValues.js";
1
+ import { TemplatePreviewEntry, TemplatePreviewHiddenRange, TemplatePreviewValues } from "../prosemirror/plugins/templatePreviewValues.js";
2
2
  import { FlowBlock, Measure } from "../layout-engine/types.js";
3
3
  import { EditorState } from "prosemirror-state";
4
4
  //#region src/controller/layoutSession.d.ts
@@ -9,6 +9,7 @@ type LayoutArtifacts = {
9
9
  };
10
10
  type LayoutTemplatePreview = {
11
11
  entries: readonly TemplatePreviewEntry[];
12
+ hidden: readonly TemplatePreviewHiddenRange[];
12
13
  mode: TemplatePreviewValues["mode"];
13
14
  };
14
15
  type LayoutSession = {
@@ -6,6 +6,7 @@ const createLayoutSession = () => ({
6
6
  usedLoadedFonts: false,
7
7
  lastTemplatePreview: {
8
8
  entries: [],
9
+ hidden: [],
9
10
  mode: "plain"
10
11
  }
11
12
  });
@@ -1,6 +1,7 @@
1
1
  import { parseBookmarkEnd, parseBookmarkStart } from "./bookmarkParser.js";
2
2
  import { appendBookmarkMarkerToLastParagraphInBlocks, prependBookmarkMarkersToFirstParagraphInBlocks } from "./bookmarkPlacement.js";
3
3
  import { convertBulletToUnicode } from "./bulletMarkers.js";
4
+ import { isNumberingReference } from "./numberingReference.js";
4
5
  import { formatOoxmlCounter } from "./ooxmlCounterFormatter.js";
5
6
  import { parseParagraph } from "./paragraphParser.js";
6
7
  import { enrichParagraphTextBoxes } from "./paragraphTextBoxEnrichment.js";
@@ -18,7 +19,7 @@ const computeListMarker = (paragraph, { numbering, listCounters, abstractCounter
18
19
  return;
19
20
  }
20
21
  const { numId, level } = listRendering;
21
- if (numId === 0) {
22
+ if (!isNumberingReference(numId)) {
22
23
  previousList.abstractNumId = null;
23
24
  previousList.fromStyle = false;
24
25
  previousList.numId = null;
@@ -0,0 +1,8 @@
1
+ import { document_d_exports } from "../types/document.js";
2
+ //#region src/docx/commentIdNormalization.d.ts
3
+ type NormalizeCommentIdsResult = {
4
+ droppedDuplicateComments: number;
5
+ };
6
+ declare const normalizeCommentIds: (comments: document_d_exports.Comment[]) => NormalizeCommentIdsResult;
7
+ //#endregion
8
+ export { NormalizeCommentIdsResult, normalizeCommentIds };
@@ -0,0 +1,16 @@
1
+ //#region src/docx/commentIdNormalization.ts
2
+ const normalizeCommentIds = (comments) => {
3
+ const seen = /* @__PURE__ */ new Set();
4
+ let kept = 0;
5
+ for (const comment of comments) {
6
+ if (seen.has(comment.id)) continue;
7
+ seen.add(comment.id);
8
+ comments[kept] = comment;
9
+ kept += 1;
10
+ }
11
+ const droppedDuplicateComments = comments.length - kept;
12
+ comments.length = kept;
13
+ return { droppedDuplicateComments };
14
+ };
15
+ //#endregion
16
+ export { normalizeCommentIds };
@@ -0,0 +1,22 @@
1
+ import { document_d_exports } from "../types/document.js";
2
+ //#region src/docx/defaultParagraphStyle.d.ts
3
+ /** The name Word's built-in default paragraph style always carries in the file. */
4
+ declare const BUILT_IN_DEFAULT_PARAGRAPH_STYLE_NAME = "Normal";
5
+ /** The id English Word gives it, kept as the last resort for the reverse case. */
6
+ declare const BUILT_IN_DEFAULT_PARAGRAPH_STYLE_ID = "Normal";
7
+ /**
8
+ * The formatting Word's default template gives Normal: 8pt (160 twips) after
9
+ * spacing, 1.08x line spacing.
10
+ *
11
+ * A package that declares neither a default paragraph style nor `w:docDefaults`
12
+ * renders as though it declared this, so anything that mints the missing
13
+ * default has to mint the formatting with it.
14
+ */
15
+ declare const BUILT_IN_DEFAULT_PARAGRAPH_FORMATTING: {
16
+ spaceAfter: number;
17
+ lineSpacing: number;
18
+ lineSpacingRule: "auto";
19
+ };
20
+ declare const resolveDefaultParagraphStyle: (styles: Iterable<document_d_exports.Style>) => document_d_exports.Style | undefined;
21
+ //#endregion
22
+ export { BUILT_IN_DEFAULT_PARAGRAPH_FORMATTING, BUILT_IN_DEFAULT_PARAGRAPH_STYLE_ID, BUILT_IN_DEFAULT_PARAGRAPH_STYLE_NAME, resolveDefaultParagraphStyle };
@@ -0,0 +1,32 @@
1
+ //#region src/docx/defaultParagraphStyle.ts
2
+ /** The name Word's built-in default paragraph style always carries in the file. */
3
+ const BUILT_IN_DEFAULT_PARAGRAPH_STYLE_NAME = "Normal";
4
+ /** The id English Word gives it, kept as the last resort for the reverse case. */
5
+ const BUILT_IN_DEFAULT_PARAGRAPH_STYLE_ID = "Normal";
6
+ /**
7
+ * The formatting Word's default template gives Normal: 8pt (160 twips) after
8
+ * spacing, 1.08x line spacing.
9
+ *
10
+ * A package that declares neither a default paragraph style nor `w:docDefaults`
11
+ * renders as though it declared this, so anything that mints the missing
12
+ * default has to mint the formatting with it.
13
+ */
14
+ const BUILT_IN_DEFAULT_PARAGRAPH_FORMATTING = {
15
+ spaceAfter: 160,
16
+ lineSpacing: 259,
17
+ lineSpacingRule: "auto"
18
+ };
19
+ const resolveDefaultParagraphStyle = (styles) => {
20
+ let flagged;
21
+ let namedBuiltIn;
22
+ let idBuiltIn;
23
+ for (const style of styles) {
24
+ if (style.type !== "paragraph") continue;
25
+ if (style.default) flagged = style;
26
+ if (namedBuiltIn === void 0 && style.name === "Normal") namedBuiltIn = style;
27
+ if (idBuiltIn === void 0 && style.styleId === "Normal") idBuiltIn = style;
28
+ }
29
+ return flagged ?? namedBuiltIn ?? idBuiltIn;
30
+ };
31
+ //#endregion
32
+ export { BUILT_IN_DEFAULT_PARAGRAPH_FORMATTING, BUILT_IN_DEFAULT_PARAGRAPH_STYLE_ID, BUILT_IN_DEFAULT_PARAGRAPH_STYLE_NAME, resolveDefaultParagraphStyle };
@@ -78,6 +78,7 @@ function parseFootnotes(footnotesXml, styles = null, theme = null, numbering = n
78
78
  const footnoteElements = findChildren(rootElement, "w", "footnote");
79
79
  for (const fnEl of footnoteElements) {
80
80
  const footnote = parseFootnote(fnEl, styles, theme, numbering, rels, media);
81
+ if (byId.has(footnote.id)) continue;
81
82
  byId.set(footnote.id, footnote);
82
83
  footnotes.push(footnote);
83
84
  }
@@ -138,6 +139,7 @@ function parseEndnotes(endnotesXml, styles = null, theme = null, numbering = nul
138
139
  const endnoteElements = findChildren(rootElement, "w", "endnote");
139
140
  for (const enEl of endnoteElements) {
140
141
  const endnote = parseEndnote(enEl, styles, theme, numbering, rels, media);
142
+ if (byId.has(endnote.id)) continue;
141
143
  byId.set(endnote.id, endnote);
142
144
  endnotes.push(endnote);
143
145
  }
@@ -1,6 +1,17 @@
1
1
  import { document_d_exports } from "../types/document.js";
2
2
  import { XmlElement } from "./xmlParser.js";
3
3
  //#region src/docx/headerFooterRefParser.d.ts
4
+ /**
5
+ * Read a `w:type` attribute as one of ECMA-376's three `ST_HdrFtr` values.
6
+ *
7
+ * The enumeration is `even`, `default` and `first` (17.18.36); `default` is
8
+ * the odd-page header, which is why a producer writing `odd` means the same
9
+ * thing. Word opens such a package, so anything outside the enumeration reads
10
+ * as the default the schema itself defaults to. Everything that compares
11
+ * header/footer reference types has to read them through here, or a
12
+ * normalisation at this boundary looks like a lost reference downstream.
13
+ */
14
+ declare function parseHeaderFooterType(typeAttr: string | null): document_d_exports.HeaderFooterType;
4
15
  /**
5
16
  * Parse a header reference from sectPr (w:headerReference)
6
17
  */
@@ -18,4 +29,4 @@ declare function parseHeaderReferences(sectPr: XmlElement): document_d_exports.H
18
29
  */
19
30
  declare function parseFooterReferences(sectPr: XmlElement): document_d_exports.FooterReference[];
20
31
  //#endregion
21
- export { parseFooterReference, parseFooterReferences, parseHeaderReference, parseHeaderReferences };
32
+ export { parseFooterReference, parseFooterReferences, parseHeaderFooterType, parseHeaderReference, parseHeaderReferences };
@@ -1,7 +1,14 @@
1
1
  import { findChildren, getAttribute } from "./xmlParser.js";
2
2
  //#region src/docx/headerFooterRefParser.ts
3
3
  /**
4
- * Parse header type attribute
4
+ * Read a `w:type` attribute as one of ECMA-376's three `ST_HdrFtr` values.
5
+ *
6
+ * The enumeration is `even`, `default` and `first` (17.18.36); `default` is
7
+ * the odd-page header, which is why a producer writing `odd` means the same
8
+ * thing. Word opens such a package, so anything outside the enumeration reads
9
+ * as the default the schema itself defaults to. Everything that compares
10
+ * header/footer reference types has to read them through here, or a
11
+ * normalisation at this boundary looks like a lost reference downstream.
5
12
  */
6
13
  function parseHeaderFooterType(typeAttr) {
7
14
  switch (typeAttr) {
@@ -49,4 +56,4 @@ function parseFooterReferences(sectPr) {
49
56
  return refs;
50
57
  }
51
58
  //#endregion
52
- export { parseFooterReference, parseFooterReferences, parseHeaderReference, parseHeaderReferences };
59
+ export { parseFooterReference, parseFooterReferences, parseHeaderFooterType, parseHeaderReference, parseHeaderReferences };
@@ -1,3 +1,4 @@
1
+ import { isNumberingReference } from "./numberingReference.js";
1
2
  import { formatOoxmlCounter, padDecimal } from "./ooxmlCounterFormatter.js";
2
3
  import { LevelSuffixSchema, narrowEnum } from "./parserEnums.js";
3
4
  import { parseRunProperties } from "./runParser.js";
@@ -529,7 +530,7 @@ function createNumberingMap(definitions) {
529
530
  */
530
531
  function computeListRendering(numPr, numbering) {
531
532
  const { numId, ilvl = 0 } = numPr;
532
- if (numId === void 0 || numId === 0) return null;
533
+ if (!isNumberingReference(numId)) return null;
533
534
  const level = numbering.getLevel(numId, ilvl);
534
535
  if (!level) return null;
535
536
  const levelNumFmts = [];
@@ -0,0 +1,21 @@
1
+ //#region src/docx/numberingReference.d.ts
2
+ /**
3
+ * The reserved `w:numId` value that means "no numbering".
4
+ *
5
+ * ECMA-376 (17.9.18 `numId`, 17.9.19 `numPr`) reserves 0: it names no `w:num`,
6
+ * it switches numbering off, and on a style it cancels the numbering the style
7
+ * would otherwise inherit through `w:basedOn` (Word writes it on, for example,
8
+ * a heading-based style that must not be numbered). It must therefore survive a
9
+ * round trip: dropping the `w:numPr` would hand the numbering back.
10
+ */
11
+ declare const NO_NUMBERING_NUM_ID = 0;
12
+ /**
13
+ * Whether a `w:numId` names a numbering definition to resolve.
14
+ *
15
+ * Every lookup or validation against `numbering.nums` goes through this: an
16
+ * absent id has nothing to resolve, and {@link NO_NUMBERING_NUM_ID} is the
17
+ * "none" sentinel, never a dangling reference.
18
+ */
19
+ declare const isNumberingReference: (numId: number | undefined) => numId is number;
20
+ //#endregion
21
+ export { NO_NUMBERING_NUM_ID, isNumberingReference };
@@ -0,0 +1,21 @@
1
+ //#region src/docx/numberingReference.ts
2
+ /**
3
+ * The reserved `w:numId` value that means "no numbering".
4
+ *
5
+ * ECMA-376 (17.9.18 `numId`, 17.9.19 `numPr`) reserves 0: it names no `w:num`,
6
+ * it switches numbering off, and on a style it cancels the numbering the style
7
+ * would otherwise inherit through `w:basedOn` (Word writes it on, for example,
8
+ * a heading-based style that must not be numbered). It must therefore survive a
9
+ * round trip: dropping the `w:numPr` would hand the numbering back.
10
+ */
11
+ const NO_NUMBERING_NUM_ID = 0;
12
+ /**
13
+ * Whether a `w:numId` names a numbering definition to resolve.
14
+ *
15
+ * Every lookup or validation against `numbering.nums` goes through this: an
16
+ * absent id has nothing to resolve, and {@link NO_NUMBERING_NUM_ID} is the
17
+ * "none" sentinel, never a dangling reference.
18
+ */
19
+ const isNumberingReference = (numId) => numId !== void 0 && numId !== 0;
20
+ //#endregion
21
+ export { NO_NUMBERING_NUM_ID, isNumberingReference };
@@ -10,8 +10,17 @@ type NormalizeNumberingReferencesInput = {
10
10
  endnotes?: readonly document_d_exports.Endnote[];
11
11
  };
12
12
  type NormalizeNumberingReferencesResult = {
13
- removedMissingNumberingReferences: number;
13
+ unnumberedDanglingReferences: number;
14
14
  };
15
15
  declare const normalizeNumberingReferences: ({ documentBody, numbering, headers, footers, footnotes, endnotes }: NormalizeNumberingReferencesInput) => NormalizeNumberingReferencesResult;
16
+ type NormalizeStyleNumberingReferencesInput = {
17
+ styles: readonly document_d_exports.Style[];
18
+ numbering: NumberingMap | undefined;
19
+ };
20
+ type NormalizeStyleNumberingReferencesResult = {
21
+ /** Style ids whose dangling reference became the "no numbering" sentinel. */
22
+ unnumberedStyleIds: string[];
23
+ };
24
+ declare const normalizeStyleNumberingReferences: ({ styles, numbering }: NormalizeStyleNumberingReferencesInput) => NormalizeStyleNumberingReferencesResult;
16
25
  //#endregion
17
- export { normalizeNumberingReferences };
26
+ export { normalizeNumberingReferences, normalizeStyleNumberingReferences };
@@ -1,7 +1,18 @@
1
+ import { isNumberingReference } from "./numberingReference.js";
1
2
  import { visitDocxParagraphs } from "./paragraphTraversal.js";
2
3
  //#region src/docx/numberingReferenceNormalization.ts
4
+ /**
5
+ * Whether a `w:numId` still reaches a level definition: a `w:num` that names a
6
+ * `w:abstractNum` the numbering part defines. Both hops can dangle, and a
7
+ * `w:num` with no `w:abstractNum` numbers nothing just as a missing one does.
8
+ */
9
+ const resolvesNumbering = (numId, numbering) => {
10
+ if (!numbering) return false;
11
+ const abstractNumId = numbering.getAbstractNumId(numId);
12
+ return abstractNumId !== null && numbering.getAbstract(abstractNumId) !== null;
13
+ };
3
14
  const normalizeNumberingReferences = ({ documentBody, numbering, headers, footers, footnotes, endnotes }) => {
4
- let removedMissingNumberingReferences = 0;
15
+ let unnumberedDanglingReferences = 0;
5
16
  visitDocxParagraphs({
6
17
  documentBody,
7
18
  headers,
@@ -9,14 +20,26 @@ const normalizeNumberingReferences = ({ documentBody, numbering, headers, footer
9
20
  footnotes,
10
21
  endnotes
11
22
  }, (paragraph) => {
12
- const numId = paragraph.formatting?.numPr?.numId;
13
- if (numId !== void 0 && numId !== 0 && !numbering.hasNumbering(numId)) {
14
- delete paragraph.formatting?.numPr;
15
- delete paragraph.listRendering;
16
- removedMissingNumberingReferences += 1;
17
- }
23
+ const formatting = paragraph.formatting;
24
+ const numId = formatting?.numPr?.numId;
25
+ if (!formatting || !isNumberingReference(numId) || resolvesNumbering(numId, numbering)) return;
26
+ formatting.numPr = { numId: 0 };
27
+ delete formatting.numPrFromStyle;
28
+ delete paragraph.listRendering;
29
+ unnumberedDanglingReferences += 1;
18
30
  });
19
- return { removedMissingNumberingReferences };
31
+ return { unnumberedDanglingReferences };
32
+ };
33
+ const normalizeStyleNumberingReferences = ({ styles, numbering }) => {
34
+ const unnumberedStyleIds = [];
35
+ for (const style of styles) {
36
+ const pPr = style.pPr;
37
+ const numId = pPr?.numPr?.numId;
38
+ if (!pPr || !isNumberingReference(numId) || resolvesNumbering(numId, numbering)) continue;
39
+ pPr.numPr = { numId: 0 };
40
+ unnumberedStyleIds.push(style.styleId);
41
+ }
42
+ return { unnumberedStyleIds };
20
43
  };
21
44
  //#endregion
22
- export { normalizeNumberingReferences };
45
+ export { normalizeNumberingReferences, normalizeStyleNumberingReferences };
@@ -4,6 +4,7 @@ import { parseBookmarkEnd as parseBookmarkEnd$1, parseBookmarkStart as parseBook
4
4
  import { parseFieldType } from "./fieldParser.js";
5
5
  import { parseHyperlink as parseHyperlink$1, parseHyperlinkChild } from "./hyperlinkParser.js";
6
6
  import { markerFormattingFromLevel, numberingLevelHasMarkerSlot } from "./numberingParser.js";
7
+ import { isNumberingReference } from "./numberingReference.js";
7
8
  import { paraIdInRange } from "./paraIdRangeNormalization.js";
8
9
  import { assignParagraphPropertySource } from "./paragraphPropertySource.js";
9
10
  import { BorderStyleSchema, FrameWrapSchema, FrameXAlignSchema, FrameYAlignSchema, LineSpacingRuleSchema, ParagraphAlignmentSchema, ShadingPatternSchema, TabLeaderSchema, TabStopAlignmentSchema, ThemeColorSlotSchema, narrowEnum } from "./parserEnums.js";
@@ -1114,7 +1115,7 @@ function parseParagraph(node, styles, theme, numbering, rels = null, media = nul
1114
1115
  }
1115
1116
  if (effectiveNumPr && numbering) {
1116
1117
  const { numId, ilvl = 0 } = effectiveNumPr;
1117
- if (numId !== void 0 && numId !== 0) {
1118
+ if (isNumberingReference(numId)) {
1118
1119
  const level = numbering.getLevel(numId, ilvl);
1119
1120
  if (level) {
1120
1121
  const levelNumFmts = [];
@@ -1310,7 +1311,7 @@ function isEmptyParagraph(paragraph) {
1310
1311
  * @returns true if paragraph has numbering properties
1311
1312
  */
1312
1313
  function isListItem(paragraph) {
1313
- return paragraph.formatting?.numPr !== void 0 && paragraph.formatting.numPr.numId !== void 0 && paragraph.formatting.numPr.numId !== 0;
1314
+ return isNumberingReference(paragraph.formatting?.numPr?.numId);
1314
1315
  }
1315
1316
  /**
1316
1317
  * Get the list level of a paragraph (0-8)
@@ -1,6 +1,7 @@
1
1
  import { toArrayBuffer } from "../utils/docxInput.js";
2
2
  import { loadFontsWithMapping } from "../utils/fontLoader.js";
3
3
  import { MAX_PACKAGE_TIFF_PIXELS, convertTiffToPngDataUrl, isTiffMimeType } from "../utils/tiffConverter.js";
4
+ import { normalizeCommentIds } from "./commentIdNormalization.js";
4
5
  import { parseComments } from "./commentParser.js";
5
6
  import { normalizeCommentReferences } from "./commentReferenceNormalization.js";
6
7
  import { detectDocxConformanceClass } from "./conformance.js";
@@ -17,7 +18,7 @@ import { extractMetafileRaster, isMetafileMimeType } from "./metafileRaster.js";
17
18
  import { renderEmfSvg } from "./metafileSvg.js";
18
19
  import { DocxModelValidationError, formatDocumentModelIssues, validateFolioDocumentModel } from "./modelValidation.js";
19
20
  import { parseNumbering } from "./numberingParser.js";
20
- import { normalizeNumberingReferences } from "./numberingReferenceNormalization.js";
21
+ import { normalizeNumberingReferences, normalizeStyleNumberingReferences } from "./numberingReferenceNormalization.js";
21
22
  import { assignDocumentParagraphPropertySourceContract } from "./paragraphPropertySource.js";
22
23
  import { RELATIONSHIP_TYPES, parseRelationships, resolveRelativePath } from "./relsParser.js";
23
24
  import { normalizeRenderedPageBreakHints } from "./renderedPageBreakNormalization.js";
@@ -137,6 +138,8 @@ async function parseDocx(input, options = {}) {
137
138
  } else onProgress("Skipping footnotes/endnotes", 75);
138
139
  onProgress("Parsing comments...", 75);
139
140
  const comments = timeStage("comments", () => parseComments(raw.commentsXml, styles, theme, rels, media, raw.commentsExtensibleXml, raw.commentsExtendedXml));
141
+ const commentIdNormalization = normalizeCommentIds(comments);
142
+ if (commentIdNormalization.droppedDuplicateComments > 0) warnings.push(`Dropped ${commentIdNormalization.droppedDuplicateComments} comment(s) repeating a w:id another comment already defines.`);
140
143
  if (comments.length > 0) documentBody.comments = comments;
141
144
  normalizeDrawingIds({
142
145
  documentBody,
@@ -179,7 +182,12 @@ async function parseDocx(input, options = {}) {
179
182
  ...footnotes !== void 0 ? { footnotes } : {},
180
183
  ...endnotes !== void 0 ? { endnotes } : {}
181
184
  });
182
- if (numberingReferenceNormalization.removedMissingNumberingReferences > 0) warnings.push(`Removed ${numberingReferenceNormalization.removedMissingNumberingReferences} numbering reference(s) whose numbering definitions are missing.`);
185
+ if (numberingReferenceNormalization.unnumberedDanglingReferences > 0) warnings.push(`Unnumbered ${numberingReferenceNormalization.unnumberedDanglingReferences} paragraph(s) whose numbering definitions are missing.`);
186
+ const styleNumberingNormalization = normalizeStyleNumberingReferences({
187
+ styles: styleDefinitions?.styles ?? [],
188
+ numbering
189
+ });
190
+ for (const styleId of styleNumberingNormalization.unnumberedStyleIds) warnings.push(`Unnumbered style "${styleId}" whose numbering definition is missing.`);
183
191
  const trackedMoveRangeNormalization = normalizeTrackedMoveRanges({
184
192
  documentBody,
185
193
  ...headers !== void 0 ? { headers } : {},
@@ -7,9 +7,11 @@ import { applyReplyThreadMarkers } from "./commentReplyMarkers.js";
7
7
  import { normalizeDrawingIds } from "./drawingIdNormalization.js";
8
8
  import { rebindDrawingImageRelationship } from "./drawingRelationships.js";
9
9
  import { parseEndnotes, parseFootnotes } from "./footnoteParser.js";
10
+ import { parseHeaderFooterType } from "./headerFooterRefParser.js";
10
11
  import { assertValidFolioDocumentModel } from "./modelValidation.js";
11
12
  import { isNewDataUrlDrawing } from "./newImage.js";
12
13
  import { parseNumbering } from "./numberingParser.js";
14
+ import { isNumberingReference } from "./numberingReference.js";
13
15
  import { isUnsafePackagePath, reconcilePackageReferences, removeUnsafeEntries } from "./packageParts.js";
14
16
  import { normalizeParaIdRangeInXmlParts } from "./paraIdRangeNormalization.js";
15
17
  import { RELATIONSHIP_TYPES, parseRelationships, resolveRelativePath } from "./relsParser.js";
@@ -113,7 +115,7 @@ const extractHeaderFooterReferences = (xml) => {
113
115
  const rId = getAttributeByNamespaceUri(node, OFFICE_RELATIONSHIP_NAMESPACE_URIS, "id");
114
116
  if (rId) references.push({
115
117
  element,
116
- type: getAttributeByNamespaceUri(node, WORDPROCESSINGML_NAMESPACE_URIS, "type") ?? "default",
118
+ type: parseHeaderFooterType(getAttributeByNamespaceUri(node, WORDPROCESSINGML_NAMESPACE_URIS, "type")),
117
119
  rId
118
120
  });
119
121
  }
@@ -1684,17 +1686,32 @@ const createDocumentSeedZip = async (doc, properties) => {
1684
1686
  };
1685
1687
  const relationshipXml = (id, type, target) => `<Relationship Id="rId${id}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/${type}" Target="${target}"/>`;
1686
1688
  const overrideXml = (partName, contentType) => `<Override PartName="${partName}" ContentType="${contentType}"/>`;
1689
+ /**
1690
+ * A package this build assembles from a Document must define the numbering its
1691
+ * styles name: Word reads a styles.xml reference nothing resolves as no
1692
+ * numbering at all, silently dropping the style's list.
1693
+ *
1694
+ * The panic is an invariant over Folio's own output, not input validation. A
1695
+ * source file can carry a dangling style reference, and it never arrives here:
1696
+ * `normalizeStyleNumberingReferences` rewrites one to the "no numbering"
1697
+ * sentinel at every boundary that mints a Document from user styles (`parseDocx`
1698
+ * and the style-set extraction entry points). What reaches this point is what
1699
+ * Folio itself put in the model, so a miss is a defect in Folio.
1700
+ */
1687
1701
  const assertStyleNumberingReferences = (doc) => {
1688
1702
  const referenced = /* @__PURE__ */ new Set();
1689
1703
  for (const style of doc.package.styles?.styles ?? []) {
1690
1704
  const numId = style.pPr?.numPr?.numId;
1691
- if (numId !== void 0) referenced.add(numId);
1705
+ if (isNumberingReference(numId)) referenced.add(numId);
1692
1706
  }
1693
1707
  if (referenced.size === 0) return;
1694
- const available = new Set(doc.package.numbering?.nums.map((numbering) => numbering.numId) ?? []);
1695
- for (const numId of referenced) if (!available.has(numId)) panic(`Style references missing numbering definition ${numId}`);
1708
+ const available = new Map(doc.package.numbering?.nums.map((numbering) => [numbering.numId, numbering]) ?? []);
1696
1709
  const availableAbstract = new Set(doc.package.numbering?.abstractNums.map((numbering) => numbering.abstractNumId) ?? []);
1697
- for (const numbering of doc.package.numbering?.nums ?? []) if (!availableAbstract.has(numbering.abstractNumId)) panic(`Numbering definition ${numbering.numId} references missing abstract numbering`);
1710
+ for (const numId of referenced) {
1711
+ const numbering = available.get(numId);
1712
+ if (!numbering) panic(`Style references missing numbering definition ${numId}`);
1713
+ if (!availableAbstract.has(numbering.abstractNumId)) panic(`Numbering definition ${numbering.numId} references missing abstract numbering`);
1714
+ }
1698
1715
  };
1699
1716
  //#endregion
1700
1717
  export { COMMENTS_CONTENT_TYPE, COMMENTS_EXTENDED_CONTENT_TYPE, COMMENTS_EXTENDED_PART, COMMENTS_EXTENDED_PART_LOWER, DocxPackageFidelityError, addCommentsExtendedOverride, addCommentsExtendedRelationship, addMedia, addRelationship, applyUpdatesToZip, collectHeaderFooterUpdates, collectHyperlinksWithoutRId, createDocx, createEmptyDocx, findMaxRId, hasModelDrivenPictureWatermark, hasUnmaterializedHeaderFooter, hasUnmaterializedInlineResources, isDocxBuffer, notePartRelsPath, removeCommentsExtendedOverride, removeCommentsExtendedRelationship, repackDocx, repackDocxFromRaw, updateCoreProperties, updateDocumentXml, updateMultipleFiles, updateXmlFile, validateDocx, withoutAttachedTemplate };
@@ -1,4 +1,5 @@
1
1
  import { deterministicHexId } from "../../utils/hexId.js";
2
+ import { isNumberingReference } from "../numberingReference.js";
2
3
  import { getParagraphText } from "../paragraphParser.js";
3
4
  import { cloneParagraphWithoutPropertySource } from "../paragraphPropertySource.js";
4
5
  import { getRunText } from "../runParser.js";
@@ -257,7 +258,7 @@ const resolveInheritedOutlineLevel = (style, styleById) => {
257
258
  /** The numbering a paragraph renders with: direct `numPr`, else the style chain's. */
258
259
  const effectiveNumPr = (paragraph, styleById) => {
259
260
  const direct = paragraph.formatting?.numPr;
260
- if (direct?.numId !== void 0) return direct.numId === 0 ? void 0 : direct;
261
+ if (direct?.numId !== void 0) return isNumberingReference(direct.numId) ? direct : void 0;
261
262
  const styleId = paragraph.formatting?.styleId;
262
263
  return styleId ? styleNumPr(styleById.get(styleId), styleById) : void 0;
263
264
  };
@@ -267,7 +268,7 @@ const styleNumPr = (style, styleById) => {
267
268
  while (current && !seen.has(current.styleId)) {
268
269
  seen.add(current.styleId);
269
270
  const numPr = current.pPr?.numPr;
270
- if (numPr?.numId !== void 0) return numPr.numId === 0 ? void 0 : numPr;
271
+ if (numPr?.numId !== void 0) return isNumberingReference(numPr.numId) ? numPr : void 0;
271
272
  current = current.basedOn ? styleById.get(current.basedOn) : void 0;
272
273
  }
273
274
  };
@@ -396,11 +397,11 @@ const cloneParagraphForTarget = (paragraph, targetParaId, styleCloner, cloner, b
396
397
  const nextFormatting = formatting && {
397
398
  ...formatting,
398
399
  ...formatting.styleId !== void 0 && { styleId: styleCloner.styleIdFor(formatting.styleId) },
399
- ...formatting.numPr?.numId !== void 0 && formatting.numPr.numId !== 0 && { numPr: {
400
+ ...formatting.numPr !== void 0 && isNumberingReference(formatting.numPr.numId) && { numPr: {
400
401
  ...formatting.numPr,
401
402
  numId: cloner.cloneNumId(formatting.numPr.numId)
402
403
  } },
403
- ...formatting.numPrFromStyle?.numId !== void 0 && formatting.numPrFromStyle.numId !== 0 && { numPrFromStyle: {
404
+ ...formatting.numPrFromStyle !== void 0 && isNumberingReference(formatting.numPrFromStyle.numId) && { numPrFromStyle: {
404
405
  ...formatting.numPrFromStyle,
405
406
  numId: cloner.cloneNumId(formatting.numPrFromStyle.numId)
406
407
  } }
@@ -2,6 +2,7 @@ import { isValidHexColor } from "../utils/colorResolver.js";
2
2
  import { parseHorizontalScalePercent } from "../utils/horizontalScale.js";
3
3
  import { mergeParagraphFormatting } from "../utils/paragraphFormattingMerge.js";
4
4
  import { mergeStyleTextFormatting } from "../utils/textFormattingMerge.js";
5
+ import { resolveDefaultParagraphStyle } from "./defaultParagraphStyle.js";
5
6
  import { BorderStyleSchema, ConditionalStyleTypeSchema, EmphasisMarkSchema, FontHintSchema, FontThemeSchema, HighlightColorSchema, LineSpacingRuleSchema, ParagraphAlignmentSchema, ShadingPatternSchema, StyleTypeSchema, TabLeaderSchema, TabStopAlignmentSchema, TableCellTextDirectionSchema, TableRowHeightRuleSchema, TableWidthTypeSchema, TextEffectSchema, ThemeColorSlotSchema, UnderlineStyleSchema, narrowEnum } from "./parserEnums.js";
6
7
  import { resolveThemeFontRef } from "./themeParser.js";
7
8
  import { findChild, findChildren, getAttribute, getLocalName, parseBooleanElement, parseNumberingLevelAttribute, parseNumericAttribute, parseOnOffValue, parseTableMeasurementValue, parseXmlDocument } from "./xmlParser.js";
@@ -916,8 +917,7 @@ function getResolvedStyle(styleId, styleMap) {
916
917
  * Get the default paragraph style
917
918
  */
918
919
  function getDefaultParagraphStyle(styleMap) {
919
- for (const style of styleMap.values()) if (style.type === "paragraph" && style.default) return style;
920
- return styleMap.get("Normal");
920
+ return resolveDefaultParagraphStyle(styleMap.values());
921
921
  }
922
922
  /**
923
923
  * Get the default character style