@stll/folio-core 0.44.0 → 0.46.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 (263) hide show
  1. package/dist/ai-edits/__fixtures__/paragraphs.js +2 -2
  2. package/dist/ai-edits/apply.js +59 -19
  3. package/dist/ai-edits/headless.js +2 -1
  4. package/dist/compare/compare.js +2 -5
  5. package/dist/compare/content-alignment.js +78 -53
  6. package/dist/compare/inline-atoms.js +34 -20
  7. package/dist/compare/scenario.js +2 -5
  8. package/dist/compare/types.d.ts +9 -1
  9. package/dist/compare/types.js +12 -1
  10. package/dist/compat/eigenpal.d.ts +2 -1
  11. package/dist/compat/eigenpal.js +2 -1
  12. package/dist/content-controls/checkboxDisplay.d.ts +11 -0
  13. package/dist/content-controls/checkboxDisplay.js +40 -0
  14. package/dist/content-controls/findContentControls.js +3 -1
  15. package/dist/content-controls/mutateContentControls.js +21 -4
  16. package/dist/controller/contentControlWidgetController.d.ts +1 -0
  17. package/dist/controller/contentControlWidgetController.js +3 -0
  18. package/dist/controller/hiddenEditorApi.js +3 -1
  19. package/dist/controller/hiddenEditorManager.d.ts +1 -1
  20. package/dist/controller/hiddenEditorManager.js +6 -3
  21. package/dist/display-list/build/buildDisplayList.js +20 -1
  22. package/dist/display-list/build/imagePrimitives.d.ts +1 -1
  23. package/dist/display-list/build/imagePrimitives.js +3 -1
  24. package/dist/display-list/build/paragraphPrimitives.js +21 -2
  25. package/dist/display-list/dom/renderDisplayListToDom.js +18 -10
  26. package/dist/display-list/types.d.ts +17 -0
  27. package/dist/document-operations.js +14 -3
  28. package/dist/docx/attributeRemainder.d.ts +43 -0
  29. package/dist/docx/attributeRemainder.js +65 -0
  30. package/dist/docx/blockContentParser.d.ts +1 -1
  31. package/dist/docx/blockContentParser.js +87 -63
  32. package/dist/docx/blockPlainText.d.ts +3 -4
  33. package/dist/docx/blockPlainText.js +1 -0
  34. package/dist/docx/bookmarkPlacement.js +2 -0
  35. package/dist/docx/borderParser.js +5 -5
  36. package/dist/docx/commentAnchorIndex.d.ts +30 -0
  37. package/dist/docx/commentAnchorIndex.js +50 -0
  38. package/dist/docx/commentParser.d.ts +1 -1
  39. package/dist/docx/commentParser.js +78 -50
  40. package/dist/docx/commentRangeIntegrity.d.ts +16 -1
  41. package/dist/docx/commentRangeIntegrity.js +42 -1
  42. package/dist/docx/commentRangeJoin.d.ts +9 -0
  43. package/dist/docx/commentRangeJoin.js +33 -0
  44. package/dist/docx/commentReferenceCompletion.d.ts +9 -0
  45. package/dist/docx/commentReferenceCompletion.js +47 -0
  46. package/dist/docx/commentReferenceNormalization.js +1 -0
  47. package/dist/docx/commentReplyMarkers.js +11 -19
  48. package/dist/docx/commentThreadKey.d.ts +18 -0
  49. package/dist/docx/commentThreadKey.js +22 -0
  50. package/dist/docx/compatibility.js +1 -0
  51. package/dist/docx/containerChildren.d.ts +111 -0
  52. package/dist/docx/containerChildren.gen.d.ts +28 -0
  53. package/dist/docx/containerChildren.gen.js +246 -0
  54. package/dist/docx/containerChildren.js +103 -0
  55. package/dist/docx/diagramPreview.js +87 -27
  56. package/dist/docx/documentParser.d.ts +1 -1
  57. package/dist/docx/documentParser.js +3 -3
  58. package/dist/docx/ensureParaIds.js +17 -7
  59. package/dist/docx/fieldParser.d.ts +1 -1
  60. package/dist/docx/fieldParser.js +4 -4
  61. package/dist/docx/fieldState.d.ts +26 -0
  62. package/dist/docx/fieldState.js +53 -0
  63. package/dist/docx/footnoteParser.d.ts +1 -1
  64. package/dist/docx/graphicFrameLocks.d.ts +16 -4
  65. package/dist/docx/graphicFrameLocks.js +19 -6
  66. package/dist/docx/groupDrawingParser.js +3 -3
  67. package/dist/docx/headerFooterParser.js +1 -1
  68. package/dist/docx/headerFooterReferenceNormalization.js +1 -0
  69. package/dist/docx/hyperlinkParser.d.ts +27 -8
  70. package/dist/docx/hyperlinkParser.js +78 -20
  71. package/dist/docx/imageParser.d.ts +9 -1
  72. package/dist/docx/imageParser.js +91 -20
  73. package/dist/docx/imageRawXml.d.ts +14 -1
  74. package/dist/docx/imageRawXml.js +30 -6
  75. package/dist/docx/inlineWrapperContent.d.ts +85 -0
  76. package/dist/docx/inlineWrapperContent.js +84 -0
  77. package/dist/docx/mathToMathml.js +12 -14
  78. package/dist/docx/nonVisualDrawingProps.d.ts +34 -0
  79. package/dist/docx/nonVisualDrawingProps.js +46 -0
  80. package/dist/docx/normalizeBaseDirection.js +10 -1
  81. package/dist/docx/paraIdAttribute.d.ts +21 -0
  82. package/dist/docx/paraIdAttribute.js +64 -0
  83. package/dist/docx/paragraphParser.d.ts +1 -1
  84. package/dist/docx/paragraphParser.js +277 -168
  85. package/dist/docx/paragraphPropertySource.js +5 -1
  86. package/dist/docx/paragraphTextBoxEnrichment.d.ts +1 -1
  87. package/dist/docx/paragraphTextBoxEnrichment.js +9 -52
  88. package/dist/docx/paragraphTraversal.js +7 -4
  89. package/dist/docx/parseWarningMessage.js +2 -1
  90. package/dist/docx/parser.js +2 -2
  91. package/dist/docx/preservedRunContent.d.ts +32 -0
  92. package/dist/docx/preservedRunContent.js +86 -0
  93. package/dist/docx/previewBudget.d.ts +64 -0
  94. package/dist/docx/previewBudget.js +88 -0
  95. package/dist/docx/renderedPageBreakNormalization.js +2 -4
  96. package/dist/docx/revisionIdNormalization.js +17 -5
  97. package/dist/docx/rezip.js +91 -36
  98. package/dist/docx/runParser.d.ts +1 -1
  99. package/dist/docx/runParser.js +16 -12
  100. package/dist/docx/sdtPropertiesPatch.js +24 -18
  101. package/dist/docx/sectionParser.js +8 -1
  102. package/dist/docx/sectionReferenceHistory.js +2 -2
  103. package/dist/docx/selectiveSave.js +6 -6
  104. package/dist/docx/selectiveXmlPatch.d.ts +46 -2
  105. package/dist/docx/selectiveXmlPatch.js +86 -39
  106. package/dist/docx/serializer/blockSdtSerializer.js +38 -26
  107. package/dist/docx/serializer/borderSerializer.d.ts +1 -1
  108. package/dist/docx/serializer/borderSerializer.js +15 -14
  109. package/dist/docx/serializer/commentSerializer.d.ts +41 -16
  110. package/dist/docx/serializer/commentSerializer.js +87 -92
  111. package/dist/docx/serializer/documentSerializer.js +8 -11
  112. package/dist/docx/serializer/fontTableSerializer.js +6 -6
  113. package/dist/docx/serializer/headerFooterSerializer.js +12 -14
  114. package/dist/docx/serializer/markupRangeAttributes.js +2 -2
  115. package/dist/docx/serializer/noteSerializer.js +8 -8
  116. package/dist/docx/serializer/numberingSerializer.js +7 -6
  117. package/dist/docx/serializer/paragraphSerializer.js +93 -72
  118. package/dist/docx/serializer/partNamespaces.js +2 -2
  119. package/dist/docx/serializer/runSerializer.js +73 -44
  120. package/dist/docx/serializer/sectionPropertiesSerializer.js +19 -14
  121. package/dist/docx/serializer/settingsSerializer.js +4 -3
  122. package/dist/docx/serializer/stylesSerializer.js +6 -6
  123. package/dist/docx/serializer/tableSerializer.js +28 -17
  124. package/dist/docx/serializer/textFormattingSerializer.js +29 -28
  125. package/dist/docx/serializer/themeSerializer.js +6 -6
  126. package/dist/docx/serializer/trackedChangeAttributes.js +2 -2
  127. package/dist/docx/serializer/xmlUtils.d.ts +1 -2
  128. package/dist/docx/serializer/xmlUtils.js +1 -13
  129. package/dist/docx/server/boundedArchive.d.ts +12 -0
  130. package/dist/docx/server/boundedArchive.js +20 -1
  131. package/dist/docx/server/createBilingualDocument.js +3 -1
  132. package/dist/docx/server/materializeYjsDocx.d.ts +1 -1
  133. package/dist/docx/server/materializeYjsDocx.js +9 -1
  134. package/dist/docx/server/migrateYjsAttrSchema.d.ts +55 -0
  135. package/dist/docx/server/migrateYjsAttrSchema.js +95 -0
  136. package/dist/docx/server/validateDocxConformance.js +22 -1
  137. package/dist/docx/shapeParser.js +12 -10
  138. package/dist/docx/tableParser.d.ts +1 -1
  139. package/dist/docx/tableParser.js +206 -85
  140. package/dist/docx/textBoxParser.d.ts +25 -2
  141. package/dist/docx/textBoxParser.js +59 -4
  142. package/dist/docx/unzip.d.ts +23 -0
  143. package/dist/docx/unzip.js +37 -26
  144. package/dist/docx/verbatimCapture.js +1 -1
  145. package/dist/docx/vmlImageParser.d.ts +17 -1
  146. package/dist/docx/vmlImageParser.js +20 -3
  147. package/dist/docx/vmlPreview.d.ts +1 -3
  148. package/dist/docx/vmlPreview.js +2 -30
  149. package/dist/docx/xmlEncoding.d.ts +5 -0
  150. package/dist/docx/xmlEncoding.js +12 -0
  151. package/dist/docx/xmlParser.d.ts +26 -2
  152. package/dist/docx/xmlParser.js +70 -27
  153. package/dist/docx/xmlResourceLimits.d.ts +89 -9
  154. package/dist/docx/xmlResourceLimits.js +105 -24
  155. package/dist/headless-layout.js +10 -1
  156. package/dist/index.d.ts +2 -1
  157. package/dist/index.js +2 -1
  158. package/dist/internal/pageBreakRunSourceDescendantIndex.js +5 -2
  159. package/dist/internal/paragraphFormattingSerialization.js +3 -2
  160. package/dist/layout-bridge/convert/toFlowBlocks.js +102 -12
  161. package/dist/layout-engine/measure/tableCellFloating.d.ts +2 -0
  162. package/dist/layout-engine/measure/tableCellFloating.js +2 -0
  163. package/dist/layout-engine/types.d.ts +23 -1
  164. package/dist/layout-painter/renderImage.d.ts +5 -1
  165. package/dist/layout-painter/renderImage.js +14 -6
  166. package/dist/layout-painter/renderPage.d.ts +2 -0
  167. package/dist/layout-painter/renderPage.js +4 -0
  168. package/dist/layout-painter/renderParagraph.d.ts +13 -1
  169. package/dist/layout-painter/renderParagraph.js +26 -6
  170. package/dist/managers/autoSaveCodec.d.ts +9 -1
  171. package/dist/managers/autoSaveCodec.js +14 -12
  172. package/dist/markdown/images.js +1 -4
  173. package/dist/markdown/renderBlock.js +1 -0
  174. package/dist/markdown/renderRuns.d.ts +1 -1
  175. package/dist/markdown/renderRuns.js +28 -5
  176. package/dist/markdown/renderTable.js +22 -5
  177. package/dist/markdown/trailers.js +4 -1
  178. package/dist/pdf/images.js +142 -6
  179. package/dist/prosemirror/attrs/index.d.ts +14 -3
  180. package/dist/prosemirror/attrs/index.js +224 -2
  181. package/dist/prosemirror/authoredTransformAttrs.d.ts +28 -0
  182. package/dist/prosemirror/authoredTransformAttrs.js +64 -0
  183. package/dist/prosemirror/commands/contentControls.js +10 -2
  184. package/dist/prosemirror/commands/image.d.ts +9 -2
  185. package/dist/prosemirror/commands/image.js +43 -28
  186. package/dist/prosemirror/commands/pageBreak.js +1 -1
  187. package/dist/prosemirror/commentReferenceAttrs.d.ts +8 -0
  188. package/dist/prosemirror/commentReferenceAttrs.js +33 -0
  189. package/dist/prosemirror/commentReferenceIntegrity.d.ts +47 -0
  190. package/dist/prosemirror/commentReferenceIntegrity.js +43 -0
  191. package/dist/prosemirror/conversion/fromProseDoc.d.ts +2 -13
  192. package/dist/prosemirror/conversion/fromProseDoc.js +338 -99
  193. package/dist/prosemirror/conversion/index.d.ts +2 -2
  194. package/dist/prosemirror/conversion/toProseDoc.d.ts +7 -9
  195. package/dist/prosemirror/conversion/toProseDoc.js +551 -327
  196. package/dist/prosemirror/extensions/StarterKit.js +8 -58
  197. package/dist/prosemirror/extensions/core/DocExtension.js +1 -1
  198. package/dist/prosemirror/extensions/core/ParagraphExtension.js +2 -1
  199. package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +45 -27
  200. package/dist/prosemirror/extensions/features/EmptyParagraphFormatExtension.js +3 -1
  201. package/dist/prosemirror/extensions/features/ImagePasteExtension.js +5 -3
  202. package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +1 -0
  203. package/dist/prosemirror/extensions/markRegistry.d.ts +41 -0
  204. package/dist/prosemirror/extensions/markRegistry.js +75 -0
  205. package/dist/prosemirror/extensions/marks/HyperlinkExtension.js +2 -3
  206. package/dist/prosemirror/extensions/marks/InlineWrapperExtension.d.ts +18 -0
  207. package/dist/prosemirror/extensions/marks/InlineWrapperExtension.js +63 -0
  208. package/dist/prosemirror/extensions/marks/markUtils.d.ts +2 -1
  209. package/dist/prosemirror/extensions/marks/markUtils.js +47 -4
  210. package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.d.ts +11 -0
  211. package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.js +87 -0
  212. package/dist/prosemirror/extensions/nodes/FieldExtension.js +9 -7
  213. package/dist/prosemirror/extensions/nodes/ImageExtension.js +20 -0
  214. package/dist/prosemirror/extensions/nodes/PreservedBlockExtension.d.ts +32 -0
  215. package/dist/prosemirror/extensions/nodes/PreservedBlockExtension.js +67 -0
  216. package/dist/prosemirror/extensions/nodes/PreservedXmlExtension.d.ts +16 -0
  217. package/dist/prosemirror/extensions/nodes/PreservedXmlExtension.js +60 -0
  218. package/dist/prosemirror/extensions/nodes/ShapeExtension.js +10 -2
  219. package/dist/prosemirror/extensions/nodes/TableExtension.js +3 -2
  220. package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +13 -5
  221. package/dist/prosemirror/inlineWrapperStack.d.ts +39 -0
  222. package/dist/prosemirror/inlineWrapperStack.js +75 -0
  223. package/dist/prosemirror/pageBreakRunProjection.d.ts +17 -7
  224. package/dist/prosemirror/pageBreakRunProjection.js +19 -9
  225. package/dist/prosemirror/paragraphFormattingProvenance.d.ts +6 -3
  226. package/dist/prosemirror/paragraphFormattingProvenance.js +12 -3
  227. package/dist/prosemirror/replacedAnnotations.d.ts +59 -0
  228. package/dist/prosemirror/replacedAnnotations.js +165 -0
  229. package/dist/prosemirror/runFormattingInlineCarriers.d.ts +3 -1
  230. package/dist/prosemirror/runFormattingInlineCarriers.js +5 -1
  231. package/dist/prosemirror/schema/index.d.ts +3 -3
  232. package/dist/prosemirror/schema/marks.d.ts +25 -1
  233. package/dist/prosemirror/schema/nodes.d.ts +139 -3
  234. package/dist/prosemirror/schema/nodes.js +16 -1
  235. package/dist/prosemirror/trackedRunInlineAtoms.d.ts +2 -0
  236. package/dist/prosemirror/trackedRunInlineAtoms.js +2 -0
  237. package/dist/prosemirror/validation.js +16 -2
  238. package/dist/prosemirror/yjsDocumentMetadata.d.ts +73 -0
  239. package/dist/prosemirror/yjsDocumentMetadata.js +171 -0
  240. package/dist/prosemirror/zeroWidthAnchors.js +2 -0
  241. package/dist/render-dom/commentAnchorAttributes.d.ts +37 -0
  242. package/dist/render-dom/commentAnchorAttributes.js +54 -0
  243. package/dist/server.d.ts +3 -1
  244. package/dist/server.js +3 -1
  245. package/dist/types/content.d.ts +2 -2
  246. package/dist/utils/base64.d.ts +36 -0
  247. package/dist/utils/base64.js +40 -0
  248. package/dist/utils/clipboard.d.ts +9 -1
  249. package/dist/utils/clipboard.js +29 -2
  250. package/dist/utils/findReplace.js +1 -1
  251. package/dist/utils/imageLuminance.d.ts +15 -0
  252. package/dist/utils/imageLuminance.js +32 -0
  253. package/dist/utils/mergeDocumentContent.js +7 -17
  254. package/dist/utils/replaceText.js +1 -0
  255. package/dist/utils/units.d.ts +10 -1
  256. package/dist/utils/units.js +12 -1
  257. package/dist/utils/urlSecurity.d.ts +8 -2
  258. package/dist/utils/urlSecurity.js +21 -3
  259. package/package.json +2 -2
  260. package/dist/docx/blockRangeMarkers.d.ts +0 -36
  261. package/dist/docx/blockRangeMarkers.js +0 -59
  262. package/dist/prosemirror/yjsParagraphSourceContract.d.ts +0 -9
  263. package/dist/prosemirror/yjsParagraphSourceContract.js +0 -26
@@ -37,7 +37,8 @@ import { fromMarkdown } from "../markdown/fromMarkdown.js";
37
37
  import { toMarkdown, toMarkdownResult } from "../markdown/index.js";
38
38
  import { EmbeddedFont, EmbeddedFontParts, buildEmbeddedFontFamilyMap, extractEmbeddedFonts, getEmbeddedFontFaces, scopeEmbeddedFontFamily } from "../fonts/embeddedFonts.js";
39
39
  import { getGoogleFontsEnabled, setEmbeddedFontFamilyMap, setGoogleFontsEnabled } from "../utils/fontResolver.js";
40
+ import { FOLIO_YJS_ATTR_SCHEMA_VERSION, FolioYjsAttrSchemaVersion, FolioYjsAttrSchemaVersionError } from "../prosemirror/yjsDocumentMetadata.js";
40
41
  import { DOCX_CONFORMANCE_CLASSES } from "../index.js";
41
42
  type Document = document_d_exports.Document;
42
43
  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 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 };
44
+ 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, FOLIO_YJS_ATTR_SCHEMA_VERSION, 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 FolioYjsAttrSchemaVersion, FolioYjsAttrSchemaVersionError, 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 };
@@ -26,6 +26,7 @@ import { DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, acceptAutocompleteSuggestion, acc
26
26
  import { getTemplateDirectives, scanDirectives } from "../prosemirror/plugins/templateDirectives.js";
27
27
  import { setTemplatePreviewValues } from "../prosemirror/plugins/templatePreviewValues.js";
28
28
  import { clearTemplateSlashMenu, consumeTemplateSlashQuery, getTemplateSlashMenu, resetTemplateSlashQuery, templateSlashMenuKey } from "../prosemirror/plugins/templateSlashMenu.js";
29
+ import { FOLIO_YJS_ATTR_SCHEMA_VERSION, FolioYjsAttrSchemaVersionError } from "../prosemirror/yjsDocumentMetadata.js";
29
30
  import { extractDocumentStyleSet, extractDocumentStyleSetFromDocx, inspectDocumentStyles, inspectDocumentStylesFromDocx } from "../style-sets/extract.js";
30
31
  import { STELLA_STYLE_SET_NAME, createStellaStyleDocumentPreset, createStellaStyleSet } from "../style-sets/stellaStyle.js";
31
32
  import { DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION } from "../style-sets/types.js";
@@ -33,4 +34,4 @@ import { currentFolioBlockId, deriveBlockId, getFolioParaIdFromBlockId, isFolioB
33
34
  import { createEmptyDocument } from "../utils/createDocument.js";
34
35
  import { getGoogleFontsEnabled, setEmbeddedFontFamilyMap, setGoogleFontsEnabled } from "../utils/fontResolver.js";
35
36
  import { mergeDocumentContent } from "../utils/mergeDocumentContent.js";
36
- export { COMPARE_REVISION_FORMATS, COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, CompareDocxApplyError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, DRAWING_SAFETY_CLASSES, 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, FolioContentComparisonLimitError, FolioContentInlinePresentationProjectionError, InvalidCompareDocxOptionsError, InvalidFolioContentComparisonError, InvalidFolioDocumentOperationBatchError, MAX_COMPARE_OPERATIONS, STELLA_STYLE_SET_NAME, UnsupportedFolioDocumentOperationVersionError, WORD_DIFF_GRANULARITIES, 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 };
37
+ export { COMPARE_REVISION_FORMATS, COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, CompareDocxApplyError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, DRAWING_SAFETY_CLASSES, 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, FOLIO_YJS_ATTR_SCHEMA_VERSION, FolioContentComparisonLimitError, FolioContentInlinePresentationProjectionError, FolioYjsAttrSchemaVersionError, InvalidCompareDocxOptionsError, InvalidFolioContentComparisonError, InvalidFolioDocumentOperationBatchError, MAX_COMPARE_OPERATIONS, STELLA_STYLE_SET_NAME, UnsupportedFolioDocumentOperationVersionError, WORD_DIFF_GRANULARITIES, 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 };
@@ -0,0 +1,11 @@
1
+ import { document_d_exports } from "../types/document.js";
2
+ //#region src/content-controls/checkboxDisplay.d.ts
3
+ type CheckboxDisplayContent = Extract<document_d_exports.RunContent, {
4
+ type: "symbol";
5
+ } | {
6
+ type: "text";
7
+ }>;
8
+ /** Resolve the authored checkbox state into the run payload Word expects. */
9
+ declare const checkboxDisplayContent: (rawPropertiesXml: string | undefined, checked: boolean) => CheckboxDisplayContent;
10
+ //#endregion
11
+ export { checkboxDisplayContent };
@@ -0,0 +1,40 @@
1
+ import { NAMESPACES, OOXML_NAMESPACE_SCOPE, WORDPROCESSINGML_NAMESPACE_URIS, findChildByNamespaceUri, getAttributeByNamespaceUri, parseXml } from "../docx/xmlParser.js";
2
+ //#region src/content-controls/checkboxDisplay.ts
3
+ const CHECKBOX_NAMESPACE_URIS = /* @__PURE__ */ new Set([NAMESPACES.w14, ...WORDPROCESSINGML_NAMESPACE_URIS]);
4
+ const DEFAULT_CHECKED_CHARACTER = "2612";
5
+ const DEFAULT_UNCHECKED_CHARACTER = "2610";
6
+ const DEFAULT_CHECKBOX_FONT = "MS Gothic";
7
+ const HEX_CODE_POINT = /^[\dA-Fa-f]{1,6}$/u;
8
+ const MAX_CHECKBOX_PROPERTIES_CHARACTERS = 65536;
9
+ const defaultDisplay = (checked) => ({
10
+ type: "symbol",
11
+ char: checked ? DEFAULT_CHECKED_CHARACTER : DEFAULT_UNCHECKED_CHARACTER,
12
+ font: DEFAULT_CHECKBOX_FONT
13
+ });
14
+ /** Resolve the authored checkbox state into the run payload Word expects. */
15
+ const checkboxDisplayContent = (rawPropertiesXml, checked) => {
16
+ if (!rawPropertiesXml || rawPropertiesXml.length > MAX_CHECKBOX_PROPERTIES_CHARACTERS) return defaultDisplay(checked);
17
+ let root;
18
+ try {
19
+ root = parseXml(rawPropertiesXml, OOXML_NAMESPACE_SCOPE);
20
+ } catch {
21
+ return defaultDisplay(checked);
22
+ }
23
+ const state = findChildByNamespaceUri(findChildByNamespaceUri(findChildByNamespaceUri(root, WORDPROCESSINGML_NAMESPACE_URIS, "sdtPr"), CHECKBOX_NAMESPACE_URIS, "checkbox"), CHECKBOX_NAMESPACE_URIS, checked ? "checkedState" : "uncheckedState");
24
+ const rawCharacter = getAttributeByNamespaceUri(state, CHECKBOX_NAMESPACE_URIS, "val");
25
+ if (!rawCharacter || !HEX_CODE_POINT.test(rawCharacter)) return defaultDisplay(checked);
26
+ const codePoint = Number.parseInt(rawCharacter, 16);
27
+ if (!Number.isInteger(codePoint) || codePoint > 1114111 || codePoint >= 55296 && codePoint <= 57343) return defaultDisplay(checked);
28
+ const font = getAttributeByNamespaceUri(state, CHECKBOX_NAMESPACE_URIS, "font") ?? DEFAULT_CHECKBOX_FONT;
29
+ if (codePoint <= 65535) return {
30
+ type: "symbol",
31
+ char: codePoint.toString(16).toUpperCase().padStart(4, "0"),
32
+ font
33
+ };
34
+ return {
35
+ type: "text",
36
+ text: String.fromCodePoint(codePoint)
37
+ };
38
+ };
39
+ //#endregion
40
+ export { checkboxDisplayContent };
@@ -1,3 +1,4 @@
1
+ import { decodeOoxmlSymbolCharacter } from "../utils/ooxmlSymbol.js";
1
2
  //#region src/content-controls/findContentControls.ts
2
3
  function matches(control, filter) {
3
4
  if (filter.pmPos !== void 0) return false;
@@ -63,10 +64,11 @@ function getContentControlText(control) {
63
64
  const paraText = [];
64
65
  for (const item of block.content) if (item.type === "run") {
65
66
  for (const child of item.content) if (child.type === "text") paraText.push(child.text);
67
+ else if (child.type === "symbol") paraText.push(decodeOoxmlSymbolCharacter(child.char) ?? "");
66
68
  }
67
69
  parts.push(paraText.join(""));
68
70
  } else if (block.type === "table") for (const row of block.rows) for (const cell of row.cells) visit(cell.content);
69
- else visit(block.content);
71
+ else if (block.type === "blockSdt") visit(block.content);
70
72
  };
71
73
  visit(control.content);
72
74
  return parts.join("\n");
@@ -1,5 +1,8 @@
1
1
  import { formatDate } from "../docx/fieldParser.js";
2
+ import { cloneParagraphWithPropertySource } from "../docx/paragraphPropertySource.js";
3
+ import { checkboxDisplayContent } from "./checkboxDisplay.js";
2
4
  import { ContentControlBoundError, ContentControlLockedError, ContentControlTypeError } from "./errors.js";
5
+ import { sanitizeXmlCharacters } from "@stll/docx-core";
3
6
  //#region src/content-controls/mutateContentControls.ts
4
7
  /**
5
8
  * Pure (immutable) write helpers for block-level content controls.
@@ -220,7 +223,8 @@ function controlMatchesFilter(control, filter) {
220
223
  if (filter.sdtType !== void 0 && control.properties.sdtType !== filter.sdtType) return false;
221
224
  return true;
222
225
  }
223
- function makeParagraphFromText(text) {
226
+ function makeParagraphFromText(rawText) {
227
+ const text = sanitizeXmlCharacters(rawText);
224
228
  return {
225
229
  type: "paragraph",
226
230
  content: text.length === 0 ? [] : [{
@@ -232,6 +236,20 @@ function makeParagraphFromText(text) {
232
236
  }]
233
237
  };
234
238
  }
239
+ function makeCheckboxParagraph(control, checked) {
240
+ const paragraph = control.content.find((block) => block.type === "paragraph");
241
+ const run = paragraph?.content.find((item) => item.type === "run");
242
+ const content = [{
243
+ type: "run",
244
+ ...run?.formatting !== void 0 ? { formatting: run.formatting } : {},
245
+ content: [checkboxDisplayContent(control.properties.rawPropertiesXml, checked)]
246
+ }];
247
+ if (!paragraph) return {
248
+ type: "paragraph",
249
+ content
250
+ };
251
+ return cloneParagraphWithPropertySource(paragraph, { content });
252
+ }
235
253
  function cloneBlock(block) {
236
254
  return structuredClone(block);
237
255
  }
@@ -300,7 +318,7 @@ function setContentControlValue(doc, filter, input, options = {}) {
300
318
  ...control,
301
319
  properties: {
302
320
  ...control.properties,
303
- dropdownLastValue: input.value,
321
+ dropdownLastValue: sanitizeXmlCharacters(input.value),
304
322
  showingPlaceholder: false,
305
323
  ...strippedRawPropertiesXml !== void 0 ? { rawPropertiesXml: strippedRawPropertiesXml } : {}
306
324
  },
@@ -315,7 +333,6 @@ function setContentControlValue(doc, filter, input, options = {}) {
315
333
  ...control.properties.tag !== void 0 ? { tag: control.properties.tag } : {},
316
334
  ...control.properties.alias !== void 0 ? { alias: control.properties.alias } : {}
317
335
  });
318
- const glyph = input.checked ? "☒" : "☐";
319
336
  return {
320
337
  ...control,
321
338
  properties: {
@@ -324,7 +341,7 @@ function setContentControlValue(doc, filter, input, options = {}) {
324
341
  showingPlaceholder: false,
325
342
  ...strippedRawPropertiesXml !== void 0 ? { rawPropertiesXml: strippedRawPropertiesXml } : {}
326
343
  },
327
- content: [makeParagraphFromText(glyph)]
344
+ content: [makeCheckboxParagraph(control, input.checked)]
328
345
  };
329
346
  }
330
347
  if (sdtType !== "date") throw new ContentControlTypeError({
@@ -46,6 +46,7 @@ declare class ContentControlWidgetController extends Subscribable<ContentControl
46
46
  private readonly onPaintedClick;
47
47
  private readonly onKeyDown;
48
48
  private readonly onScroll;
49
+ private readonly onPointerDown;
49
50
  private open;
50
51
  private removeDismissListeners;
51
52
  private unbindView;
@@ -113,15 +113,18 @@ var ContentControlWidgetController = class extends Subscribable {
113
113
  if (event.key === "Escape") this.close();
114
114
  };
115
115
  onScroll = () => this.close();
116
+ onPointerDown = () => this.close();
116
117
  open(snapshot) {
117
118
  this.removeDismissListeners();
118
119
  this.ownerWindow = this.viewDom?.ownerDocument.defaultView ?? null;
119
120
  this.ownerWindow?.addEventListener("keydown", this.onKeyDown);
121
+ this.ownerWindow?.addEventListener("pointerdown", this.onPointerDown);
120
122
  this.ownerWindow?.addEventListener("scroll", this.onScroll, true);
121
123
  this.setSnapshot(snapshot);
122
124
  }
123
125
  removeDismissListeners() {
124
126
  this.ownerWindow?.removeEventListener("keydown", this.onKeyDown);
127
+ this.ownerWindow?.removeEventListener("pointerdown", this.onPointerDown);
125
128
  this.ownerWindow?.removeEventListener("scroll", this.onScroll, true);
126
129
  this.ownerWindow = null;
127
130
  }
@@ -45,7 +45,9 @@ const createHiddenEditorApi = (deps) => {
45
45
  return stateToDocument(view.state, deps.getDocumentContext());
46
46
  },
47
47
  focus: () => {
48
- deps.getView()?.focus();
48
+ const view = deps.getView();
49
+ if (!view || view.hasFocus()) return;
50
+ view.focus();
49
51
  },
50
52
  blur: () => {
51
53
  const view = deps.getView();
@@ -5,9 +5,9 @@ import { RemoteSelection } from "../types/remote-selection.js";
5
5
  import { HiddenEditorApi } from "./hiddenEditorApi.js";
6
6
  import { EditorState, Plugin, Transaction } from "prosemirror-state";
7
7
  import { EditorView } from "prosemirror-view";
8
- import * as YProseMirror from "y-prosemirror";
9
8
  import * as Yjs from "yjs";
10
9
  import { XmlFragment } from "yjs";
10
+ import * as YProseMirror from "y-prosemirror";
11
11
  //#region src/controller/hiddenEditorManager.d.ts
12
12
  type YProseMirrorModule = typeof YProseMirror;
13
13
  type YjsModule = typeof Yjs;
@@ -8,7 +8,7 @@ import { createDocumentNumberingPlugin } from "../prosemirror/plugins/documentNu
8
8
  import { createDocumentStylesPlugin } from "../prosemirror/plugins/documentStyles.js";
9
9
  import { schema } from "../prosemirror/schema/index.js";
10
10
  import { createTextInputPlugin } from "../prosemirror/textInput.js";
11
- import { proseDocumentParagraphSourceContract, readYjsParagraphSourceContract, withParagraphSourceContract, writeYjsParagraphSourceContract } from "../prosemirror/yjsParagraphSourceContract.js";
11
+ import { applyAttrSchemaMigrations, proseDocumentParagraphSourceContract, readYjsAttrSchemaVersion, readYjsParagraphSourceContract, withParagraphSourceContract, writeYjsDocumentMetadata } from "../prosemirror/yjsDocumentMetadata.js";
12
12
  import { createHiddenEditorApi } from "./hiddenEditorApi.js";
13
13
  import { panic } from "better-result";
14
14
  import { EditorState } from "prosemirror-state";
@@ -129,12 +129,15 @@ function createHiddenEditorState(options) {
129
129
  collaborationModules.yProseMirror.prosemirrorToYXmlFragment(seedState.doc, collaboration.yXmlFragment);
130
130
  const collaborationDocument = collaboration.yXmlFragment.doc;
131
131
  if (!collaborationDocument) panic("A collaboration fragment must belong to a Yjs document before seeding.");
132
- if (proseDocumentParagraphSourceContract(seedState.doc)) writeYjsParagraphSourceContract(collaborationDocument, seedState.doc);
132
+ writeYjsDocumentMetadata(collaborationDocument, seedState.doc);
133
133
  collaboration.onSeeded?.();
134
134
  }
135
- let { doc } = collaborationModules.yProseMirror.initProseMirrorDoc(collaboration.yXmlFragment, activeSchema);
136
135
  const collaborationDocument = collaboration.yXmlFragment.doc;
137
136
  if (!collaborationDocument) panic("A collaboration fragment must belong to a Yjs document before loading.");
137
+ const attrSchemaVersion = readYjsAttrSchemaVersion(collaborationDocument);
138
+ if (attrSchemaVersion.isErr()) throw attrSchemaVersion.error;
139
+ applyAttrSchemaMigrations(collaborationDocument, collaboration.yXmlFragment, attrSchemaVersion.value);
140
+ let { doc } = collaborationModules.yProseMirror.initProseMirrorDoc(collaboration.yXmlFragment, activeSchema);
138
141
  const collaborationContract = readYjsParagraphSourceContract(collaborationDocument);
139
142
  const localContract = proseDocumentParagraphSourceContract(localDoc);
140
143
  if (localContract && collaborationContract !== localContract) panic("The collaboration state belongs to a different paragraph-property source.");
@@ -1,3 +1,4 @@
1
+ import { isHeadingOutlineLevel } from "../../docx/builtInStyles.js";
1
2
  import { HIT_REGION_KINDS } from "../primitives.js";
2
3
  import { AuthorColorTable } from "./buildContext.js";
3
4
  import { DOC_CANVAS } from "./colors.js";
@@ -12,6 +13,19 @@ import { paintTableFragment } from "./tablePrimitives.js";
12
13
  import { paintTextBoxFragment } from "./textBoxPrimitives.js";
13
14
  import { UNSUPPORTED_CONSTRUCT, UnsupportedCollector } from "./unsupported.js";
14
15
  //#region src/display-list/build/buildDisplayList.ts
16
+ /**
17
+ * `Layout` + `BlockLookup` → `DisplayList`.
18
+ *
19
+ * The single source of truth for painting. Two backends consume the result and
20
+ * neither may look behind it, so anything missing here is painted nowhere.
21
+ *
22
+ * Purity is a hard requirement, not a preference: no clock, no randomness, no
23
+ * `globalThis.document`. The font and image tables intern in first-use page
24
+ * order, and author colours are assigned per build, so two builds of one layout
25
+ * are deeply equal. The one impure edge is the measure provider, which the
26
+ * composition root installs and which is deterministic for a given font set;
27
+ * that is the same seam line breaking already ran through, which is the point.
28
+ */
15
29
  /** Document-wide gaps are attributed to the first page, the only one certain to exist. */
16
30
  const FIRST_PAGE_INDEX = 0;
17
31
  /**
@@ -60,6 +74,11 @@ const paragraphTextOf = (block) => block.runs.map((run) => run.kind === "text" ?
60
74
  * Resolve everything that needs the whole document before any page is painted:
61
75
  * where each bookmark lands (a `#name` hyperlink cannot become a page target
62
76
  * until then) and the heading outline.
77
+ *
78
+ * The outline takes the levels {@link isHeadingOutlineLevel} accepts and no
79
+ * others: `w:outlineLvl` 9 is the reserved body-text value, not a tenth level,
80
+ * and a `TOC Heading` paragraph carrying it would otherwise become a PDF
81
+ * bookmark nested nine deep.
63
82
  */
64
83
  const collectDocumentTargets = (layout, blockLookup) => {
65
84
  const bookmarkTargets = /* @__PURE__ */ new Map();
@@ -74,7 +93,7 @@ const collectDocumentTargets = (layout, blockLookup) => {
74
93
  yPx: fragment.y
75
94
  });
76
95
  const level = block.attrs?.outlineLevel;
77
- if (level !== void 0 && fragment.continuesFromPrev !== true) {
96
+ if (isHeadingOutlineLevel(level) && fragment.continuesFromPrev !== true) {
78
97
  const title = paragraphTextOf(block);
79
98
  if (title.length > 0) outline.push({
80
99
  title,
@@ -15,7 +15,7 @@ declare class ImageTable {
15
15
  failureFor(src: string): string | undefined;
16
16
  snapshot(): readonly DisplayImageSource[];
17
17
  }
18
- type ImageVisualSource = Pick<ImageBlock, "src" | "opacity" | "cropTop" | "cropRight" | "cropBottom" | "cropLeft" | "borderWidth" | "borderColor" | "borderStyle" | "transform">;
18
+ type ImageVisualSource = Pick<ImageBlock, "src" | "opacity" | "brightness" | "contrast" | "cropTop" | "cropRight" | "cropBottom" | "cropLeft" | "borderWidth" | "borderColor" | "borderStyle" | "transform">;
19
19
  type PaintImageOptions = {
20
20
  readonly source: ImageVisualSource;
21
21
  readonly rect: DisplayRect;
@@ -213,7 +213,9 @@ const paintImage = ({ source, rect, context, label }) => {
213
213
  image: ref,
214
214
  rect,
215
215
  ...crop === void 0 ? {} : { crop },
216
- opacity: source.opacity == null ? 1 : Math.min(1, Math.max(0, source.opacity))
216
+ opacity: source.opacity == null ? 1 : Math.min(1, Math.max(0, source.opacity)),
217
+ ...source.brightness == null ? {} : { brightness: source.brightness },
218
+ ...source.contrast == null ? {} : { contrast: source.contrast }
217
219
  };
218
220
  const degrees = parseRotationDegrees(source.transform);
219
221
  if (degrees === 0) primitives.push(image);
@@ -6,7 +6,7 @@ import { countCompressibleSpaces, toPaintedText } from "../../layout-engine/meas
6
6
  import { isFloatingImageRun } from "../../layout-engine/types.js";
7
7
  import { resolveParagraphBorderHorizontalOutsets } from "../../layout-painter/borderStroke.js";
8
8
  import { getAutomaticTextColorForBackground } from "../../layout-painter/documentColors.js";
9
- import { getLeaderChar, getRenderableTextColor, sliceRunsForLine, splitCollapsibleLineEdgeSpaces, splitTextRunsByEastAsia, startsAfterSoftWrap } from "../../layout-painter/renderParagraph.js";
9
+ import { UNICODE_BIDI_BY_WRAPPER_CONTROL, getLeaderChar, getRenderableTextColor, sliceRunsForLine, splitCollapsibleLineEdgeSpaces, splitTextRunsByEastAsia, startsAfterSoftWrap } from "../../layout-painter/renderParagraph.js";
10
10
  import { getHorizontalScaleFactor } from "../../utils/horizontalScale.js";
11
11
  import { resolvePhysicalParagraphInlineLayout } from "../../utils/paragraphInlineLayout.js";
12
12
  import { inlineImageBoundingBox } from "../../utils/rotationBoundingBox.js";
@@ -278,6 +278,23 @@ const modelRangeOf = (run, context) => run.pmStart === void 0 || run.pmEnd === v
278
278
  story: context.story
279
279
  };
280
280
  /**
281
+ * The base direction one run's glyphs are laid out in.
282
+ *
283
+ * A bidirectional wrapper the author wrote around the run states it, and is
284
+ * nearer than the paragraph's own base direction: an override (`w:bdo`) lays
285
+ * every character out that way, and an embedding (`w:dir`) opens a level in
286
+ * that direction. A wrapper with no `w:val` states nothing, and the paragraph
287
+ * decides as before.
288
+ */
289
+ const runGlyphDirection = (run, paragraphIsRtl) => run.bidiWrapper?.direction ?? (paragraphIsRtl ? "rtl" : "ltr");
290
+ /**
291
+ * The wrapper's control, for the backend that resolves the order itself.
292
+ *
293
+ * The direction alone does not separate the two: an override forces the
294
+ * order, an embedding leaves the algorithm to resolve within it.
295
+ */
296
+ const runUnicodeBidi = (run) => run.bidiWrapper === void 0 ? void 0 : UNICODE_BIDI_BY_WRAPPER_CONTROL[run.bidiWrapper.control];
297
+ /**
281
298
  * One `glyphRun` plus everything painted around it: the run's background rect
282
299
  * first, then the glyphs, then the decorations whose geometry CSS would have
283
300
  * derived from the font.
@@ -342,6 +359,7 @@ const emitGlyphRun = ({ sink, context, run, glyphs, style, paintXPx, baselineYPx
342
359
  thicknessPx: 1,
343
360
  pattern: "solid"
344
361
  } : void 0;
362
+ const unicodeBidi = runUnicodeBidi(run);
345
363
  sink.glyphs.push({
346
364
  kind: "glyphRun",
347
365
  font,
@@ -350,7 +368,8 @@ const emitGlyphRun = ({ sink, context, run, glyphs, style, paintXPx, baselineYPx
350
368
  xPx: paintXPx,
351
369
  baselineYPx: runBaselineYPx,
352
370
  ...glyphRunText(glyphs),
353
- direction: isRtl ? "rtl" : "ltr",
371
+ direction: runGlyphDirection(run, isRtl),
372
+ ...unicodeBidi === void 0 ? {} : { unicodeBidi },
354
373
  ...stroke === void 0 ? {} : { stroke },
355
374
  ...pmRange === void 0 ? {} : { pmRange },
356
375
  ...collapsedEdge === void 0 ? {} : { collapsedEdge }
@@ -1,3 +1,7 @@
1
+ import { writeCommentAnchorIds } from "../../render-dom/commentAnchorAttributes.js";
2
+ import { bytesToDataUrl } from "../../utils/base64.js";
3
+ import { imageLuminanceFilter } from "../../utils/imageLuminance.js";
4
+ import { anchorTargetAttrs } from "../../utils/urlSecurity.js";
1
5
  import { STROKE_DASH_FACTORS, walkRegions } from "../primitives.js";
2
6
  import { panic } from "better-result";
3
7
  //#region src/display-list/dom/renderDisplayListToDom.ts
@@ -42,7 +46,6 @@ const PAGE_CLASS_NAME = "layout-page";
42
46
  */
43
47
  const PAGE_ELEMENT_ID_PREFIX = "page-";
44
48
  const DEGREES_PER_RADIAN = 180 / Math.PI;
45
- const BASE64_CHUNK_SIZE = 32768;
46
49
  const IMAGE_MIME_TYPES = {
47
50
  png: "image/png",
48
51
  jpeg: "image/jpeg"
@@ -98,17 +101,11 @@ const resolveImage = (ref, images) => {
98
101
  if (source === void 0) panic(`renderDisplayListToDom: image ref ${ref} is out of range (${images.length} images)`);
99
102
  return source;
100
103
  };
101
- const toBase64 = (bytes) => {
102
- let binary = "";
103
- for (let offset = 0; offset < bytes.length; offset += BASE64_CHUNK_SIZE) binary += String.fromCharCode(...bytes.subarray(offset, offset + BASE64_CHUNK_SIZE));
104
- return btoa(binary);
105
- };
106
104
  /** A `Blob` part cannot be backed by shared memory, so prove it is not. */
107
105
  const isBlobPart = (bytes) => bytes.buffer instanceof ArrayBuffer;
108
106
  const binarySrc = (bytes, mimeType) => {
109
107
  if (isBlobPart(bytes) && typeof Blob === "function" && typeof URL !== "undefined" && typeof URL.createObjectURL === "function") return URL.createObjectURL(new Blob([bytes], { type: mimeType }));
110
- if (typeof btoa === "function") return `data:${mimeType};base64,${toBase64(bytes)}`;
111
- panic("renderDisplayListToDom: no Blob or btoa to build a binary source from");
108
+ return bytesToDataUrl(bytes, mimeType);
112
109
  };
113
110
  const fontFaceRule = (face, embedded, src) => `@font-face { font-family: ${quoteFontFamily(embedded.id)}; src: url("${src}"); font-weight: ${face.weight}; font-style: ${face.italic ? "italic" : "normal"}; }`;
114
111
  /**
@@ -315,6 +312,7 @@ const paintGlyphRun = (run, context) => {
315
312
  span.style.fontStyle = face.italic ? "italic" : "normal";
316
313
  span.style.color = cssColor(run.color);
317
314
  span.style.direction = run.direction;
315
+ if (run.unicodeBidi !== void 0) span.style.unicodeBidi = run.unicodeBidi;
318
316
  if (run.stroke !== void 0) span.style.webkitTextStroke = `${px(run.stroke.thicknessPx)} ${cssColor(run.stroke.color)}`;
319
317
  span.style.fontKerning = run.kerning ? "normal" : "none";
320
318
  if (run.smallCaps) span.style.fontVariant = "small-caps";
@@ -392,13 +390,18 @@ const paintRect = ({ rect, fill, stroke }, context) => {
392
390
  default: panic(`renderDisplayListToDom: unhandled rect stroke painter ${JSON.stringify(painter)}`);
393
391
  }
394
392
  };
395
- const paintImage = ({ image, rect, crop, opacity }, context) => {
393
+ const paintImage = ({ image, rect, crop, opacity, brightness, contrast }, context) => {
396
394
  const source = resolveImage(image, context.images);
397
395
  const clip = createAbsoluteDiv(context, rect);
398
396
  clip.style.overflow = "hidden";
399
397
  const element = context.doc.createElement("img");
400
398
  element.style.position = "absolute";
401
399
  element.style.opacity = String(opacity);
400
+ const filter = imageLuminanceFilter({
401
+ ...brightness === void 0 ? {} : { brightness },
402
+ ...contrast === void 0 ? {} : { contrast }
403
+ });
404
+ if (filter !== void 0) element.style.filter = filter;
402
405
  element.style.left = "0px";
403
406
  element.style.top = "0px";
404
407
  element.style.width = px(rect.widthPx);
@@ -489,6 +492,11 @@ const paintLink = ({ rect, target, tooltip }, context) => {
489
492
  element.style.width = px(rect.widthPx);
490
493
  element.style.height = px(rect.heightPx);
491
494
  element.href = linkHref(target);
495
+ if (target.kind !== "page") {
496
+ const anchor = anchorTargetAttrs(void 0);
497
+ element.target = anchor.target;
498
+ element.rel = anchor.rel;
499
+ }
492
500
  if (tooltip !== void 0) element.title = tooltip;
493
501
  context.parent.append(element);
494
502
  };
@@ -549,7 +557,7 @@ const applyRegionModel = (element, region) => {
549
557
  element.dataset["pmEnd"] = String(model.pmRange.end);
550
558
  }
551
559
  if (model.blockId !== void 0) element.dataset["blockId"] = model.blockId;
552
- if (model.commentIds !== void 0 && model.commentIds.length > 0) element.dataset["commentId"] = String(model.commentIds[0]);
560
+ if (model.commentIds !== void 0) writeCommentAnchorIds(element, model.commentIds);
553
561
  if (model.rowIndex !== void 0) element.dataset["rowIndex"] = String(model.rowIndex);
554
562
  if (model.columnIndex !== void 0) element.dataset["columnIndex"] = String(model.columnIndex);
555
563
  const story = model.story ?? model.pmRange?.story;
@@ -215,6 +215,19 @@ type DisplayGlyphRun = {
215
215
  readonly text: string;
216
216
  readonly advancesPx: readonly number[];
217
217
  readonly direction: "ltr" | "rtl";
218
+ /**
219
+ * How a backend that resolves bidirectional text itself must treat the run.
220
+ *
221
+ * `direction` alone is the base direction, and a backend that hands the text
222
+ * to such a resolver gets the ordinary algorithm: a Latin word inside an
223
+ * `rtl` run reads forwards. That is an embedding, and it is wrong for the
224
+ * run the author wrapped in an override (`w:bdo`), where every character is
225
+ * laid out in `direction` whatever its own script. Absent is the ordinary
226
+ * run, whose base direction the paragraph or the run itself decided; a
227
+ * backend that positions every glyph from `advancesPx` reorders nothing and
228
+ * ignores this.
229
+ */
230
+ readonly unicodeBidi?: "embed" | "bidi-override";
218
231
  /**
219
232
  * Whether the glyphs kern.
220
233
  *
@@ -299,6 +312,10 @@ type DisplayImagePrimitive = {
299
312
  readonly b: number;
300
313
  };
301
314
  readonly opacity: number;
315
+ /** DrawingML picture brightness as a signed percentage. */
316
+ readonly brightness?: number;
317
+ /** DrawingML picture contrast as a signed percentage. */
318
+ readonly contrast?: number;
302
319
  };
303
320
  /** Clips its children to `rect`. Used for cropped images and cell overflow. */
304
321
  type DisplayClipGroup = {
@@ -1,6 +1,7 @@
1
1
  import { applyFolioAIEditOperations, previewFolioAIEditOperations } from "./ai-edits/apply.js";
2
2
  import { LINE_SPACING_RULE_VALUES, PARAGRAPH_ALIGNMENT_VALUES } from "./types/documentEnumValues.js";
3
3
  import { TaggedError } from "better-result";
4
+ import { sanitizeXmlCharacters } from "@stll/docx-core";
4
5
  //#region src/document-operations.ts
5
6
  const FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION = 1;
6
7
  /** Direct paragraph-alignment values accepted by the operation contract. */
@@ -138,15 +139,25 @@ const assertAllowedKeys = (value, path, allowedKeys) => {
138
139
  const unexpected = Object.keys(value).find((key) => !allowedKeys.includes(key));
139
140
  if (unexpected !== void 0) invalidBatch(`${path}.${unexpected}`, "unexpected property");
140
141
  };
142
+ /**
143
+ * Every string in a batch passes through here, so this is where a value an
144
+ * agent sent stops being able to corrupt the package it lands in: XML 1.0
145
+ * admits none of the C0 controls but tab, LF and CR, and no escape can carry
146
+ * one into a document. The batch is otherwise held to exactly what it says, so
147
+ * the rule is the narrowest one that keeps the request usable — drop what
148
+ * cannot be written, map an unpaired surrogate to U+FFFD — rather than
149
+ * rejecting a whole edit over a stray control character. The parsed batch is
150
+ * both what folio applies and what the receipt reports, so the two agree.
151
+ */
141
152
  const readString = (value, key, path) => {
142
153
  const candidate = value[key];
143
- if (typeof candidate === "string") return candidate;
154
+ if (typeof candidate === "string") return sanitizeXmlCharacters(candidate);
144
155
  return invalidBatch(`${path}.${key}`, "expected a string");
145
156
  };
146
157
  const readOptionalString = (value, key, path) => {
147
158
  const candidate = value[key];
148
159
  if (candidate === void 0) return;
149
- if (typeof candidate === "string") return candidate;
160
+ if (typeof candidate === "string") return sanitizeXmlCharacters(candidate);
150
161
  return invalidBatch(`${path}.${key}`, "expected a string when provided");
151
162
  };
152
163
  const readOptionalBoolean = (value, key, path) => {
@@ -184,7 +195,7 @@ const readOptionalStringArray = (value, key, path) => {
184
195
  if (candidate === void 0) return;
185
196
  if (!Array.isArray(candidate)) return invalidBatch(`${path}.${key}`, "expected an array when provided");
186
197
  return candidate.map((item, index) => {
187
- if (typeof item === "string") return item;
198
+ if (typeof item === "string") return sanitizeXmlCharacters(item);
188
199
  return invalidBatch(`${path}.${key}[${index}]`, "expected a string");
189
200
  });
190
201
  };
@@ -0,0 +1,43 @@
1
+ import { XmlElement } from "./xmlParser.js";
2
+ import { PreservedAttribute } from "@stll/docx-core/model";
3
+ //#region src/docx/attributeRemainder.d.ts
4
+ /**
5
+ * The modelled set of an element whose serializer writes no attribute at all.
6
+ *
7
+ * `w:r`, `w:tr` and `w:sectPr` are rebuilt as bare start tags, so everything
8
+ * their source wrote is the remainder. Named rather than spelled `new Set()`
9
+ * at each call site, so the claim is visible and one place has to change when
10
+ * one of them gains a modelled attribute.
11
+ */
12
+ declare const NO_MODELLED_ATTRIBUTES: ReadonlySet<string>;
13
+ type AttributeRemainderOptions = {
14
+ /** The element, as the source wrote it. */
15
+ element: XmlElement;
16
+ /**
17
+ * Local names this element's own parser reads.
18
+ *
19
+ * Local names rather than qualified ones, because folio's attribute readers
20
+ * fall back to a local-name match across prefixes: an attribute the parser
21
+ * would read under any binding has to be out of the remainder, or the save
22
+ * writes the value twice under two spellings.
23
+ */
24
+ modelled: ReadonlySet<string>;
25
+ };
26
+ /**
27
+ * Every attribute on the element the model has no field for.
28
+ *
29
+ * @returns the remainder, or `undefined` when the parser read them all — an
30
+ * empty list is never written, so a fully modelled element stays identical
31
+ * in the model.
32
+ */
33
+ declare const attributeRemainder: ({ element, modelled }: AttributeRemainderOptions) => PreservedAttribute[] | undefined;
34
+ /**
35
+ * The element's attributes, modelled first and the remainder after them.
36
+ *
37
+ * @param modelled the fragments the serializer is about to emit, already
38
+ * spelled — they win a collision, because the model is the editable copy
39
+ * @returns the fragments to write, so an element with neither writes nothing
40
+ */
41
+ declare const serializePreservedAttributes: (modelled: readonly string[], preserved: readonly PreservedAttribute[] | undefined) => string[];
42
+ //#endregion
43
+ export { NO_MODELLED_ATTRIBUTES, attributeRemainder, serializePreservedAttributes };