@stll/folio-core 0.37.3 → 0.37.5
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.
- package/dist/ai-edits/index.d.ts +2 -1
- package/dist/ai-edits/types.d.ts +2 -2
- package/dist/compare/content-alignment.js +213 -135
- package/dist/compare/content-types.d.ts +3 -1
- package/dist/compat/eigenpal.d.ts +2 -2
- package/dist/docx/numberingParser.d.ts +1 -13
- package/dist/docx/numberingParser.js +1 -10
- package/dist/docx/paragraphParser.js +1 -5
- package/dist/docx/paragraphPropertySource.d.ts +8 -5
- package/dist/docx/paragraphPropertySource.js +16 -4
- package/dist/docx/serializer/borderSerializer.d.ts +4 -1
- package/dist/docx/serializer/borderSerializer.js +20 -18
- package/dist/docx/serializer/commentSerializer.js +1 -1
- package/dist/docx/serializer/numberingSerializer.js +1 -1
- package/dist/docx/serializer/paragraphSerializer.js +11 -177
- package/dist/docx/serializer/runSerializer.d.ts +1 -5
- package/dist/docx/serializer/runSerializer.js +2 -129
- package/dist/docx/serializer/stylesSerializer.js +1 -1
- package/dist/docx/serializer/textFormattingSerializer.d.ts +17 -0
- package/dist/docx/serializer/textFormattingSerializer.js +142 -0
- package/dist/index.d.ts +2 -2
- package/dist/internal/paragraphFormattingSerialization.d.ts +23 -0
- package/dist/internal/paragraphFormattingSerialization.js +157 -0
- package/dist/prosemirror/attrs/index.js +13 -0
- package/dist/prosemirror/conversion/fromProseDoc.js +28 -20
- package/dist/prosemirror/conversion/toProseDoc.js +1 -0
- package/dist/prosemirror/extensions/nodes/TextBoxExtension.d.ts +2 -63
- package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +9 -0
- package/dist/prosemirror/schema/nodes.d.ts +11 -1
- package/dist/prosemirror/schema/nodes.js +7 -0
- package/dist/server.d.ts +2 -1
- package/dist/version-comparison.js +23 -27
- package/package.json +1 -1
package/dist/ai-edits/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { FolioContentParagraphKind } from "../compare/content-types.js";
|
|
1
2
|
import { FolioAIBlock, FolioAIBlockAnchor, FolioAIBlockKind, FolioAIBlockPreviewRun, FolioAIBlockStructuralBoundary, FolioAIBlockTableLocation, FolioAIComment, FolioAIEditAppliedOperation, FolioAIEditApplyMode, FolioAIEditApplyResult, FolioAIEditNormalization, FolioAIEditNormalizationCode, FolioAIEditOperation, FolioAIEditPrecondition, FolioAIEditReviewMeta, FolioAIEditSeverity, FolioAIEditSkipReason, FolioAIEditSkippedOperation, FolioAIEditSnapshot, FolioAIInlineBooleanProperty, FolioAIInlineFormatting, FolioAIInlineFormattingPatch, FolioAIParagraphSpacing, FolioAISignatureParty, FolioAITextRangeHandle, FolioDocumentNavigationTarget, FolioDocumentOutline, FolioDocumentOutlineEntry, FolioDocumentSection, FolioDocumentSectionHandle, FolioDocumentSectionReadResult } from "./types.js";
|
|
2
3
|
import { WORD_DIFF_GRANULARITIES, WordDiffGranularity, WordDiffNormalization, WordDiffOptions, WordDiffSegment, diffWordSegments } from "./word-diff.js";
|
|
3
4
|
import { FolioAIEditApplyOutcome, FolioAIEditView, FolioRevisionStamp, FolioWordDiffOptions, applyFolioAIEditOperations } from "./apply.js";
|
|
@@ -9,4 +10,4 @@ import { createFolioAIEditSnapshot, createFolioAITextRangeHandle, hashFolioAIBlo
|
|
|
9
10
|
import { FOLIO_RESOLVED_REVIEWED_VIEWS, FOLIO_REVIEWED_VIEWS, FolioApplyDocumentOperationsToStoryOptions, FolioDocumentStory, FolioDocumentStoryHandle, FolioDocumentStoryNotFoundError, FolioEditableDocumentStoryHandle, FolioReadReviewedStoryOptions, FolioResolveReviewedStoryOptions, FolioResolvedReviewedView, FolioReviewedStory, FolioReviewedView, UnsupportedFolioReviewedViewError, isFolioResolvedReviewedView, isFolioReviewedView } from "./headless.js";
|
|
10
11
|
import { getFolioDocumentOutline, readFolioDocumentSection } from "./scoped-reading.js";
|
|
11
12
|
import { getFolioParaIdFromBlockId } from "../types/block-id.js";
|
|
12
|
-
export { type ApplyFolioDocumentOperationsOptions, type DocPositionRange, 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_RESOLVED_REVIEWED_VIEWS, FOLIO_REVIEWED_VIEWS, 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 FolioAIEditView, type FolioAIInlineBooleanProperty, type FolioAIInlineFormatting, type FolioAIInlineFormattingPatch, type FolioAIParagraphSpacing, type FolioAISignatureParty, type FolioAITextRangeHandle, type FolioApplyDocumentOperationsToStoryOptions, type FolioCommentAnchor, type FolioDocumentNavigationTarget, 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 FolioDocumentOutline, type FolioDocumentOutlineEntry, type FolioDocumentSection, type FolioDocumentSectionHandle, type FolioDocumentSectionReadResult, type FolioDocumentStory, type FolioDocumentStoryHandle, FolioDocumentStoryNotFoundError, type FolioEditableDocumentStoryHandle, type FolioReadReviewedStoryOptions, type FolioResolveReviewedStoryOptions, type FolioResolvedReviewedView, type FolioReviewChange, type FolioReviewChangeKind, type FolioReviewedStory, type FolioReviewedView, type FolioRevisionStamp, type FolioWordDiffOptions, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, UnsupportedFolioReviewedViewError, WORD_DIFF_GRANULARITIES, type WordDiffGranularity, type WordDiffNormalization, type WordDiffOptions, type WordDiffSegment, applyFolioAIEditOperations, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, buildAnnotatedBlockText, clampRangeToDocSize, createFolioAIEditSnapshot, createFolioAITextRangeHandle, diffWordSegments, getCommentAnchorsFromDoc, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioDocumentOutline, getFolioParaIdFromBlockId, getTrackedChangesFromDoc, hashFolioAIBlockText, isFolioAIContentBlock, isFolioDocumentOperationModeSupported, isFolioResolvedReviewedView, isFolioReviewedView, isSupportedFolioDocumentOperationVersion, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, readFolioDocumentSection, resolveFolioAIBlockRange, resolveFolioAITextRange, resolvePassageRange };
|
|
13
|
+
export { type ApplyFolioDocumentOperationsOptions, type DocPositionRange, 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_RESOLVED_REVIEWED_VIEWS, FOLIO_REVIEWED_VIEWS, 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 FolioAIEditView, type FolioAIInlineBooleanProperty, type FolioAIInlineFormatting, type FolioAIInlineFormattingPatch, type FolioAIParagraphSpacing, type FolioAISignatureParty, type FolioAITextRangeHandle, type FolioApplyDocumentOperationsToStoryOptions, type FolioCommentAnchor, type FolioContentParagraphKind, type FolioDocumentNavigationTarget, 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 FolioDocumentOutline, type FolioDocumentOutlineEntry, type FolioDocumentSection, type FolioDocumentSectionHandle, type FolioDocumentSectionReadResult, type FolioDocumentStory, type FolioDocumentStoryHandle, FolioDocumentStoryNotFoundError, type FolioEditableDocumentStoryHandle, type FolioReadReviewedStoryOptions, type FolioResolveReviewedStoryOptions, type FolioResolvedReviewedView, type FolioReviewChange, type FolioReviewChangeKind, type FolioReviewedStory, type FolioReviewedView, type FolioRevisionStamp, type FolioWordDiffOptions, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, UnsupportedFolioReviewedViewError, WORD_DIFF_GRANULARITIES, type WordDiffGranularity, type WordDiffNormalization, type WordDiffOptions, type WordDiffSegment, applyFolioAIEditOperations, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, buildAnnotatedBlockText, clampRangeToDocSize, createFolioAIEditSnapshot, createFolioAITextRangeHandle, diffWordSegments, getCommentAnchorsFromDoc, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioDocumentOutline, getFolioParaIdFromBlockId, getTrackedChangesFromDoc, hashFolioAIBlockText, isFolioAIContentBlock, isFolioDocumentOperationModeSupported, isFolioResolvedReviewedView, isFolioReviewedView, isSupportedFolioDocumentOperationVersion, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, readFolioDocumentSection, resolveFolioAIBlockRange, resolveFolioAITextRange, resolvePassageRange };
|
package/dist/ai-edits/types.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { document_d_exports } from "../types/document.js";
|
|
2
|
-
import { FolioContentBlock, FolioContentInlineBooleanProperty, FolioContentInlineFormatting, FolioContentInlineFormattingPatch, FolioContentParagraphSpacing, FolioContentRun, FolioContentSnapshot, FolioContentTableLocation } from "../compare/content-types.js";
|
|
2
|
+
import { FolioContentBlock, FolioContentInlineBooleanProperty, FolioContentInlineFormatting, FolioContentInlineFormattingPatch, FolioContentParagraphKind, FolioContentParagraphSpacing, FolioContentRun, FolioContentSnapshot, FolioContentTableLocation } from "../compare/content-types.js";
|
|
3
3
|
//#region src/ai-edits/types.d.ts
|
|
4
|
-
type FolioAIBlockKind =
|
|
4
|
+
type FolioAIBlockKind = FolioContentParagraphKind;
|
|
5
5
|
/** Boolean run properties supported by snapshots and range-formatting mutations. */
|
|
6
6
|
type FolioAIInlineBooleanProperty = FolioContentInlineBooleanProperty;
|
|
7
7
|
type FolioAIInlineFormatting = FolioContentInlineFormatting;
|
|
@@ -7,7 +7,8 @@ import { panic } from "better-result";
|
|
|
7
7
|
* The block walk is split by structural container before any textual
|
|
8
8
|
* alignment runs. Body blocks are compared with body blocks; tables are
|
|
9
9
|
* aligned table by table, then row by row and cell by cell. All quadratic
|
|
10
|
-
*
|
|
10
|
+
* structural candidate alignment in one caller-owned work session shares
|
|
11
|
+
* one hard budget; block exact-text anchors are gap-local and non-quadratic.
|
|
11
12
|
*/
|
|
12
13
|
const MAX_CONTENT_ALIGNMENT_LCS_CELLS = 4e6;
|
|
13
14
|
const MAX_CONTENT_STRUCTURE_TOKEN_LOOKUPS = 4e6;
|
|
@@ -28,6 +29,13 @@ const claimFolioContentAlignmentCells = (baseCount, revisedCount, workSession) =
|
|
|
28
29
|
workSession.remainingLcsCells -= baseCount * revisedCount;
|
|
29
30
|
return true;
|
|
30
31
|
};
|
|
32
|
+
const NON_WHITESPACE = /\S/u;
|
|
33
|
+
const PARAGRAPH_MARK_KIND_FAMILY = {
|
|
34
|
+
heading: "paragraphMark",
|
|
35
|
+
listItem: "paragraphMark",
|
|
36
|
+
paragraph: "paragraphMark"
|
|
37
|
+
};
|
|
38
|
+
const blockKindsCanPair = (baseKind, revisedKind) => baseKind === revisedKind || Object.hasOwn(PARAGRAPH_MARK_KIND_FAMILY, baseKind) && Object.hasOwn(PARAGRAPH_MARK_KIND_FAMILY, revisedKind);
|
|
31
39
|
const folioContentIdStability = (block) => block.idStability ?? "stable";
|
|
32
40
|
/**
|
|
33
41
|
* Longest strictly increasing subsequence by revised index.
|
|
@@ -91,20 +99,75 @@ const longestIncreasingFolioContentPairs = (pairs) => {
|
|
|
91
99
|
}
|
|
92
100
|
return ordered.toReversed();
|
|
93
101
|
};
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
102
|
+
const containerPathKeyOf = ({ containerPath }) => containerPath === void 0 || containerPath.length === 0 ? null : JSON.stringify(containerPath.map(({ kind, id }) => [kind, id]));
|
|
103
|
+
const blockPairingTableFactsOf = ({ table }) => {
|
|
104
|
+
if (!table) return { type: "body" };
|
|
105
|
+
return {
|
|
106
|
+
type: "table",
|
|
107
|
+
outerTableIndex: table.outerTableIndex,
|
|
108
|
+
tableIndex: table.tableIndex,
|
|
109
|
+
rowIndex: table.rowIndex,
|
|
110
|
+
cellIndex: table.cellIndex
|
|
111
|
+
};
|
|
112
|
+
};
|
|
113
|
+
const prepareAlignmentBlocks = ({ baseBlocks, revisedBlocks, idStability }) => {
|
|
114
|
+
const ROOT_CONTAINER_PATH_TOKEN = 0;
|
|
115
|
+
const containerPathTokens = /* @__PURE__ */ new Map();
|
|
116
|
+
let nextContainerPathToken = 1;
|
|
117
|
+
const containerPathTokenOf = (block) => {
|
|
118
|
+
const key = containerPathKeyOf(block);
|
|
119
|
+
if (key === null) return ROOT_CONTAINER_PATH_TOKEN;
|
|
120
|
+
const existing = containerPathTokens.get(key);
|
|
121
|
+
if (existing !== void 0) return existing;
|
|
122
|
+
const token = nextContainerPathToken++;
|
|
123
|
+
containerPathTokens.set(key, token);
|
|
124
|
+
return token;
|
|
125
|
+
};
|
|
126
|
+
const prepare = (blocks) => blocks.map((block, index) => ({
|
|
127
|
+
block,
|
|
128
|
+
index,
|
|
129
|
+
pairingFacts: {
|
|
130
|
+
containerPathToken: containerPathTokenOf(block),
|
|
131
|
+
id: block.id,
|
|
132
|
+
idStability: idStability(block),
|
|
133
|
+
kind: block.kind,
|
|
134
|
+
table: blockPairingTableFactsOf(block)
|
|
135
|
+
}
|
|
136
|
+
}));
|
|
137
|
+
return {
|
|
138
|
+
base: prepare(baseBlocks),
|
|
139
|
+
revised: prepare(revisedBlocks)
|
|
140
|
+
};
|
|
141
|
+
};
|
|
142
|
+
/** Every alignment pass shares this complete structural pairing policy. */
|
|
143
|
+
const blocksCanPair = ({ base, revised, stableIdMismatch, structuralScope }) => {
|
|
144
|
+
if (!blockKindsCanPair(base.kind, revised.kind) || base.containerPathToken !== revised.containerPathToken) return false;
|
|
145
|
+
if (base.table.type !== revised.table.type) return false;
|
|
146
|
+
if (structuralScope === "document" && base.table.type === "table" && revised.table.type === "table" && (base.table.outerTableIndex !== revised.table.outerTableIndex || base.table.tableIndex !== revised.table.tableIndex || base.table.rowIndex !== revised.table.rowIndex || base.table.cellIndex !== revised.table.cellIndex)) return false;
|
|
147
|
+
return !(stableIdMismatch === "separate" && base.idStability === "stable" && revised.idStability === "stable" && base.id !== revised.id);
|
|
148
|
+
};
|
|
149
|
+
const uniqueStableBlocks = (blocks) => {
|
|
150
|
+
const blocksById = /* @__PURE__ */ new Map();
|
|
151
|
+
for (const block of blocks) {
|
|
152
|
+
if (block.pairingFacts.idStability !== "stable") continue;
|
|
153
|
+
blocksById.set(block.pairingFacts.id, blocksById.has(block.pairingFacts.id) ? null : block);
|
|
154
|
+
}
|
|
155
|
+
return blocksById;
|
|
156
|
+
};
|
|
157
|
+
/** Stable identity is authoritative only when it is unique on both sides. */
|
|
158
|
+
const pairByStableId = ({ base, revised, canPair }) => {
|
|
159
|
+
const baseBlockById = uniqueStableBlocks(base);
|
|
160
|
+
const revisedBlockById = uniqueStableBlocks(revised);
|
|
99
161
|
const candidates = [];
|
|
100
|
-
|
|
101
|
-
if (
|
|
102
|
-
const
|
|
103
|
-
if (
|
|
104
|
-
|
|
105
|
-
|
|
162
|
+
for (const baseBlock of base) {
|
|
163
|
+
if (baseBlockById.get(baseBlock.pairingFacts.id) !== baseBlock) continue;
|
|
164
|
+
const revisedBlock = revisedBlockById.get(baseBlock.pairingFacts.id);
|
|
165
|
+
if (!revisedBlock) continue;
|
|
166
|
+
if (canPair(baseBlock, revisedBlock)) candidates.push({
|
|
167
|
+
baseIndex: baseBlock.index,
|
|
168
|
+
revisedIndex: revisedBlock.index
|
|
106
169
|
});
|
|
107
|
-
}
|
|
170
|
+
}
|
|
108
171
|
return longestIncreasingFolioContentPairs(candidates);
|
|
109
172
|
};
|
|
110
173
|
/**
|
|
@@ -116,180 +179,191 @@ const pairByStableId = (base, revised, idStability) => {
|
|
|
116
179
|
* already bounded by stable/exact anchors, so it cannot turn a positional id
|
|
117
180
|
* into a move or pull a block across an established correspondence.
|
|
118
181
|
*/
|
|
119
|
-
const pairByResidualIdContinuity = ({ baseBlocks, revisedBlocks, baseFrom, baseTo, revisedFrom, revisedTo,
|
|
120
|
-
const
|
|
121
|
-
const
|
|
182
|
+
const pairByResidualIdContinuity = ({ baseBlocks, revisedBlocks, baseFrom, baseTo, revisedFrom, revisedTo, canPair }) => {
|
|
183
|
+
const uniqueBlocksById = ({ blocks, from, to }) => {
|
|
184
|
+
const blocksById = /* @__PURE__ */ new Map();
|
|
122
185
|
for (let index = from; index < to; index++) {
|
|
123
|
-
const
|
|
124
|
-
if (
|
|
125
|
-
|
|
186
|
+
const block = blocks[index];
|
|
187
|
+
if (!block) continue;
|
|
188
|
+
blocksById.set(block.pairingFacts.id, blocksById.has(block.pairingFacts.id) ? null : block);
|
|
126
189
|
}
|
|
127
|
-
return
|
|
190
|
+
return blocksById;
|
|
128
191
|
};
|
|
129
|
-
const
|
|
192
|
+
const baseBlocksById = uniqueBlocksById({
|
|
130
193
|
blocks: baseBlocks,
|
|
131
194
|
from: baseFrom,
|
|
132
195
|
to: baseTo
|
|
133
196
|
});
|
|
134
|
-
const
|
|
197
|
+
const revisedBlocksById = uniqueBlocksById({
|
|
135
198
|
blocks: revisedBlocks,
|
|
136
199
|
from: revisedFrom,
|
|
137
200
|
to: revisedTo
|
|
138
201
|
});
|
|
139
202
|
const candidates = [];
|
|
140
|
-
for (const [id,
|
|
141
|
-
const
|
|
142
|
-
if (baseIndex === null || revisedIndex === void 0 || revisedIndex === null) continue;
|
|
143
|
-
const baseBlock = baseBlocks[baseIndex];
|
|
144
|
-
const revisedBlock = revisedBlocks[revisedIndex];
|
|
203
|
+
for (const [id, baseBlock] of baseBlocksById) {
|
|
204
|
+
const revisedBlock = revisedBlocksById.get(id);
|
|
145
205
|
if (!baseBlock || !revisedBlock) continue;
|
|
146
|
-
if (idStability
|
|
206
|
+
if (baseBlock.pairingFacts.idStability === revisedBlock.pairingFacts.idStability || !canPair(baseBlock, revisedBlock)) continue;
|
|
147
207
|
candidates.push({
|
|
148
|
-
baseIndex,
|
|
149
|
-
revisedIndex
|
|
208
|
+
baseIndex: baseBlock.index,
|
|
209
|
+
revisedIndex: revisedBlock.index
|
|
150
210
|
});
|
|
151
211
|
}
|
|
152
212
|
return longestIncreasingFolioContentPairs(candidates);
|
|
153
213
|
};
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
return key;
|
|
167
|
-
};
|
|
168
|
-
const baseTextKeys = base.map(({ block }) => internText(block.text));
|
|
169
|
-
const revisedTextKeys = revised.map(({ block }) => internText(block.text));
|
|
170
|
-
const entriesCanPair = (baseIndex, revisedIndex) => {
|
|
171
|
-
const baseBlock = base[baseIndex]?.block;
|
|
172
|
-
const revisedBlock = revised[revisedIndex]?.block;
|
|
173
|
-
if (!baseBlock || !revisedBlock || baseTextKeys[baseIndex] !== revisedTextKeys[revisedIndex]) return false;
|
|
174
|
-
return stableIdMismatch === "pair" || !(idStability(baseBlock) === "stable" && idStability(revisedBlock) === "stable" && baseBlock.id !== revisedBlock.id);
|
|
214
|
+
/** Exact anchors are gap-local; repeated or blank text is not identity evidence. */
|
|
215
|
+
const pairByUniqueExactText = ({ base, revised, baseFrom, baseTo, revisedFrom, revisedTo, canPair }) => {
|
|
216
|
+
const uniqueBlocks = (blocks, from, to) => {
|
|
217
|
+
const blocksByText = /* @__PURE__ */ new Map();
|
|
218
|
+
for (let index = from; index < to; index++) {
|
|
219
|
+
const block = blocks[index];
|
|
220
|
+
if (!block) continue;
|
|
221
|
+
const text = block.block.text;
|
|
222
|
+
if (!NON_WHITESPACE.test(text)) continue;
|
|
223
|
+
blocksByText.set(text, blocksByText.has(text) ? null : block);
|
|
224
|
+
}
|
|
225
|
+
return blocksByText;
|
|
175
226
|
};
|
|
176
|
-
const
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
const
|
|
181
|
-
|
|
227
|
+
const baseBlocksByText = uniqueBlocks(base, baseFrom, baseTo);
|
|
228
|
+
const revisedBlocksByText = uniqueBlocks(revised, revisedFrom, revisedTo);
|
|
229
|
+
const candidates = [];
|
|
230
|
+
for (const [text, baseBlock] of baseBlocksByText) {
|
|
231
|
+
const revisedBlock = revisedBlocksByText.get(text);
|
|
232
|
+
if (!baseBlock || !revisedBlock) continue;
|
|
233
|
+
if (canPair(baseBlock, revisedBlock)) candidates.push({
|
|
234
|
+
baseIndex: baseBlock.index,
|
|
235
|
+
revisedIndex: revisedBlock.index
|
|
236
|
+
});
|
|
182
237
|
}
|
|
183
|
-
const
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
baseIndex += 1;
|
|
196
|
-
revisedIndex += 1;
|
|
197
|
-
continue;
|
|
238
|
+
const orderedCandidates = candidates.toSorted((left, right) => left.baseIndex - right.baseIndex || left.revisedIndex - right.revisedIndex);
|
|
239
|
+
if (orderedCandidates.length === 0) return [];
|
|
240
|
+
const tailRevisedIndexes = [];
|
|
241
|
+
const tailCandidateIndexes = [];
|
|
242
|
+
const predecessors = new Int32Array(orderedCandidates.length).fill(-1);
|
|
243
|
+
orderedCandidates.forEach((candidate, candidateIndex) => {
|
|
244
|
+
let lower = 0;
|
|
245
|
+
let upper = tailRevisedIndexes.length;
|
|
246
|
+
while (lower < upper) {
|
|
247
|
+
const middle = lower + Math.floor((upper - lower) / 2);
|
|
248
|
+
if ((tailRevisedIndexes[middle] ?? Number.POSITIVE_INFINITY) < candidate.revisedIndex) lower = middle + 1;
|
|
249
|
+
else upper = middle;
|
|
198
250
|
}
|
|
199
|
-
|
|
200
|
-
|
|
251
|
+
predecessors[candidateIndex] = lower === 0 ? -1 : tailCandidateIndexes[lower - 1] ?? -1;
|
|
252
|
+
tailRevisedIndexes[lower] = candidate.revisedIndex;
|
|
253
|
+
tailCandidateIndexes[lower] = candidateIndex;
|
|
254
|
+
});
|
|
255
|
+
const pairs = [];
|
|
256
|
+
for (let candidateIndex = tailCandidateIndexes.at(-1) ?? -1; candidateIndex !== -1; candidateIndex = predecessors[candidateIndex] ?? -1) {
|
|
257
|
+
const candidate = orderedCandidates[candidateIndex];
|
|
258
|
+
if (candidate) pairs.push(candidate);
|
|
259
|
+
}
|
|
260
|
+
return pairs.toReversed();
|
|
261
|
+
};
|
|
262
|
+
const pairsInAnchorGaps = ({ baseLength, revisedLength, anchors, pairGap }) => {
|
|
263
|
+
const pairs = [];
|
|
264
|
+
let baseFrom = 0;
|
|
265
|
+
let revisedFrom = 0;
|
|
266
|
+
for (const anchor of [...anchors, {
|
|
267
|
+
baseIndex: baseLength,
|
|
268
|
+
revisedIndex: revisedLength
|
|
269
|
+
}]) {
|
|
270
|
+
pairs.push(...pairGap(baseFrom, anchor.baseIndex, revisedFrom, anchor.revisedIndex));
|
|
271
|
+
baseFrom = anchor.baseIndex + 1;
|
|
272
|
+
revisedFrom = anchor.revisedIndex + 1;
|
|
201
273
|
}
|
|
202
274
|
return pairs;
|
|
203
275
|
};
|
|
204
|
-
const
|
|
205
|
-
const workSession = options.workSession ?? createFolioContentAlignmentWorkSession();
|
|
276
|
+
const alignFolioContentBlocksInScope = (baseBlocks, revisedBlocks, options) => {
|
|
206
277
|
const stableIdMismatch = options.stableIdMismatch ?? "separate";
|
|
207
278
|
const idStability = options.idStability ?? folioContentIdStability;
|
|
208
|
-
const
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
}
|
|
219
|
-
const
|
|
220
|
-
|
|
279
|
+
const prepared = prepareAlignmentBlocks({
|
|
280
|
+
baseBlocks,
|
|
281
|
+
revisedBlocks,
|
|
282
|
+
idStability
|
|
283
|
+
});
|
|
284
|
+
const canPair = (baseBlock, revisedBlock) => blocksCanPair({
|
|
285
|
+
base: baseBlock.pairingFacts,
|
|
286
|
+
revised: revisedBlock.pairingFacts,
|
|
287
|
+
stableIdMismatch,
|
|
288
|
+
structuralScope: options.structuralScope
|
|
289
|
+
});
|
|
290
|
+
const stableIdAnchors = pairByStableId({
|
|
291
|
+
base: prepared.base,
|
|
292
|
+
revised: prepared.revised,
|
|
293
|
+
canPair
|
|
294
|
+
});
|
|
295
|
+
const exactTextAnchors = pairsInAnchorGaps({
|
|
296
|
+
baseLength: prepared.base.length,
|
|
297
|
+
revisedLength: prepared.revised.length,
|
|
298
|
+
anchors: stableIdAnchors,
|
|
299
|
+
pairGap: (baseFrom, baseTo, revisedFrom, revisedTo) => pairByUniqueExactText({
|
|
300
|
+
base: prepared.base,
|
|
301
|
+
revised: prepared.revised,
|
|
302
|
+
baseFrom,
|
|
303
|
+
baseTo,
|
|
304
|
+
revisedFrom,
|
|
305
|
+
revisedTo,
|
|
306
|
+
canPair
|
|
307
|
+
})
|
|
308
|
+
});
|
|
309
|
+
const exactAndStableAnchors = [...stableIdAnchors, ...exactTextAnchors].toSorted((left, right) => left.baseIndex - right.baseIndex || left.revisedIndex - right.revisedIndex);
|
|
310
|
+
const continuityAnchors = pairsInAnchorGaps({
|
|
311
|
+
baseLength: prepared.base.length,
|
|
312
|
+
revisedLength: prepared.revised.length,
|
|
313
|
+
anchors: exactAndStableAnchors,
|
|
314
|
+
pairGap: (baseFrom, baseTo, revisedFrom, revisedTo) => pairByResidualIdContinuity({
|
|
315
|
+
baseBlocks: prepared.base,
|
|
316
|
+
revisedBlocks: prepared.revised,
|
|
317
|
+
baseFrom,
|
|
318
|
+
baseTo,
|
|
319
|
+
revisedFrom,
|
|
320
|
+
revisedTo,
|
|
321
|
+
canPair
|
|
322
|
+
})
|
|
323
|
+
});
|
|
324
|
+
const anchors = [...exactAndStableAnchors, ...continuityAnchors].toSorted((left, right) => left.baseIndex - right.baseIndex || left.revisedIndex - right.revisedIndex);
|
|
221
325
|
const events = [];
|
|
222
326
|
const emitPositionalGap = (baseFrom, baseTo, revisedFrom, revisedTo) => {
|
|
223
327
|
const pairedCount = Math.min(baseTo - baseFrom, revisedTo - revisedFrom);
|
|
224
328
|
for (let offset = 0; offset < pairedCount; offset++) {
|
|
225
|
-
const baseBlock =
|
|
226
|
-
const revisedBlock =
|
|
227
|
-
if (baseBlock && revisedBlock) if (
|
|
329
|
+
const baseBlock = prepared.base[baseFrom + offset];
|
|
330
|
+
const revisedBlock = prepared.revised[revisedFrom + offset];
|
|
331
|
+
if (baseBlock && revisedBlock) if (!canPair(baseBlock, revisedBlock)) {
|
|
228
332
|
events.push({
|
|
229
333
|
type: "baseOnly",
|
|
230
|
-
block: baseBlock
|
|
334
|
+
block: baseBlock.block
|
|
231
335
|
});
|
|
232
336
|
events.push({
|
|
233
337
|
type: "revisedOnly",
|
|
234
|
-
block: revisedBlock
|
|
338
|
+
block: revisedBlock.block
|
|
235
339
|
});
|
|
236
340
|
} else events.push({
|
|
237
341
|
type: "pair",
|
|
238
|
-
baseBlock,
|
|
239
|
-
revisedBlock
|
|
342
|
+
baseBlock: baseBlock.block,
|
|
343
|
+
revisedBlock: revisedBlock.block
|
|
240
344
|
});
|
|
241
345
|
}
|
|
242
346
|
for (let index = baseFrom + pairedCount; index < baseTo; index++) {
|
|
243
|
-
const block =
|
|
347
|
+
const block = prepared.base[index]?.block;
|
|
244
348
|
if (block) events.push({
|
|
245
349
|
type: "baseOnly",
|
|
246
350
|
block
|
|
247
351
|
});
|
|
248
352
|
}
|
|
249
353
|
for (let index = revisedFrom + pairedCount; index < revisedTo; index++) {
|
|
250
|
-
const block =
|
|
354
|
+
const block = prepared.revised[index]?.block;
|
|
251
355
|
if (block) events.push({
|
|
252
356
|
type: "revisedOnly",
|
|
253
357
|
block
|
|
254
358
|
});
|
|
255
359
|
}
|
|
256
360
|
};
|
|
257
|
-
const emitGap = (baseFrom, baseTo, revisedFrom, revisedTo) => {
|
|
258
|
-
if (baseFrom === baseTo || revisedFrom === revisedTo) {
|
|
259
|
-
emitPositionalGap(baseFrom, baseTo, revisedFrom, revisedTo);
|
|
260
|
-
return;
|
|
261
|
-
}
|
|
262
|
-
const continuityPairs = pairByResidualIdContinuity({
|
|
263
|
-
baseBlocks,
|
|
264
|
-
revisedBlocks,
|
|
265
|
-
baseFrom,
|
|
266
|
-
baseTo,
|
|
267
|
-
revisedFrom,
|
|
268
|
-
revisedTo,
|
|
269
|
-
idStability
|
|
270
|
-
});
|
|
271
|
-
let baseCursor = baseFrom;
|
|
272
|
-
let revisedCursor = revisedFrom;
|
|
273
|
-
for (const pair of continuityPairs) {
|
|
274
|
-
emitPositionalGap(baseCursor, pair.baseIndex, revisedCursor, pair.revisedIndex);
|
|
275
|
-
const baseBlock = baseBlocks[pair.baseIndex];
|
|
276
|
-
const revisedBlock = revisedBlocks[pair.revisedIndex];
|
|
277
|
-
if (baseBlock && revisedBlock) events.push({
|
|
278
|
-
type: "pair",
|
|
279
|
-
baseBlock,
|
|
280
|
-
revisedBlock
|
|
281
|
-
});
|
|
282
|
-
baseCursor = pair.baseIndex + 1;
|
|
283
|
-
revisedCursor = pair.revisedIndex + 1;
|
|
284
|
-
}
|
|
285
|
-
emitPositionalGap(baseCursor, baseTo, revisedCursor, revisedTo);
|
|
286
|
-
};
|
|
287
361
|
let baseCursor = 0;
|
|
288
362
|
let revisedCursor = 0;
|
|
289
363
|
for (const anchor of anchors) {
|
|
290
|
-
|
|
291
|
-
const baseBlock =
|
|
292
|
-
const revisedBlock =
|
|
364
|
+
emitPositionalGap(baseCursor, anchor.baseIndex, revisedCursor, anchor.revisedIndex);
|
|
365
|
+
const baseBlock = prepared.base[anchor.baseIndex]?.block;
|
|
366
|
+
const revisedBlock = prepared.revised[anchor.revisedIndex]?.block;
|
|
293
367
|
if (baseBlock && revisedBlock) events.push({
|
|
294
368
|
type: "pair",
|
|
295
369
|
baseBlock,
|
|
@@ -298,9 +372,13 @@ const alignFolioContentBlocks = (baseBlocks, revisedBlocks, options = {}) => {
|
|
|
298
372
|
baseCursor = anchor.baseIndex + 1;
|
|
299
373
|
revisedCursor = anchor.revisedIndex + 1;
|
|
300
374
|
}
|
|
301
|
-
|
|
375
|
+
emitPositionalGap(baseCursor, prepared.base.length, revisedCursor, prepared.revised.length);
|
|
302
376
|
return events;
|
|
303
377
|
};
|
|
378
|
+
const alignFolioContentBlocks = (baseBlocks, revisedBlocks, options = {}) => alignFolioContentBlocksInScope(baseBlocks, revisedBlocks, {
|
|
379
|
+
...options,
|
|
380
|
+
structuralScope: "document"
|
|
381
|
+
});
|
|
304
382
|
const BODY_MOVE_BUCKET = 0;
|
|
305
383
|
const scopedAlignmentSteps = (events, context, bucketForBlock) => {
|
|
306
384
|
const steps = [];
|
|
@@ -321,7 +399,6 @@ const scopedAlignmentSteps = (events, context, bucketForBlock) => {
|
|
|
321
399
|
}
|
|
322
400
|
return steps;
|
|
323
401
|
};
|
|
324
|
-
const containerPathKeyOf = (block) => block.containerPath === void 0 || block.containerPath.length === 0 ? null : JSON.stringify(block.containerPath.map(({ kind, id }) => [kind, id]));
|
|
325
402
|
const contentBlocksShareContainerPath = (left, right) => containerPathKeyOf(left) === containerPathKeyOf(right);
|
|
326
403
|
const splitSegments = (blocks) => {
|
|
327
404
|
const segments = [];
|
|
@@ -839,10 +916,11 @@ const alignRowCells = ({ baseRow, revisedRow, workSession, moveScopeContext, sta
|
|
|
839
916
|
for (const cellIndex of cellIndexes) {
|
|
840
917
|
const baseBlocks = baseCells.get(cellIndex) ?? [];
|
|
841
918
|
const revisedBlocks = revisedCells.get(cellIndex) ?? [];
|
|
842
|
-
const aligned =
|
|
919
|
+
const aligned = alignFolioContentBlocksInScope(baseBlocks, revisedBlocks, {
|
|
843
920
|
workSession,
|
|
844
921
|
idStability,
|
|
845
|
-
stableIdMismatch
|
|
922
|
+
stableIdMismatch,
|
|
923
|
+
structuralScope: "pairedTableCell"
|
|
846
924
|
}).flatMap((event) => {
|
|
847
925
|
if (event.type === "pair" && !contentBlocksShareContainerPath(event.baseBlock, event.revisedBlock)) return [{
|
|
848
926
|
type: "baseOnly",
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
//#region src/compare/content-types.d.ts
|
|
2
2
|
/** How callers expect a block identifier to behave across document revisions. */
|
|
3
3
|
type FolioContentIdStability = "stable" | "positional";
|
|
4
|
+
/** Text-bearing block kinds that share one editable paragraph-mark structure. */
|
|
5
|
+
type FolioContentParagraphKind = "heading" | "listItem" | "paragraph";
|
|
4
6
|
/** One enclosing structural container, ordered outermost to innermost in a block path. */
|
|
5
7
|
type FolioContentContainerPathEntry = {
|
|
6
8
|
kind: string;
|
|
@@ -97,4 +99,4 @@ type FolioContentSnapshot<Block extends FolioContentBlock = FolioContentBlock> =
|
|
|
97
99
|
blocks: readonly Block[];
|
|
98
100
|
};
|
|
99
101
|
//#endregion
|
|
100
|
-
export { FolioContentBlock, FolioContentContainerPathEntry, FolioContentIdStability, FolioContentInlineBooleanProperty, FolioContentInlineFormatting, FolioContentInlineFormattingPatch, FolioContentLineSpacingRule, FolioContentParagraphAlignment, FolioContentParagraphSpacing, FolioContentRun, FolioContentSnapshot, FolioContentTableLocation };
|
|
102
|
+
export { FolioContentBlock, FolioContentContainerPathEntry, FolioContentIdStability, FolioContentInlineBooleanProperty, FolioContentInlineFormatting, FolioContentInlineFormattingPatch, FolioContentLineSpacingRule, FolioContentParagraphAlignment, FolioContentParagraphKind, FolioContentParagraphSpacing, FolioContentRun, FolioContentSnapshot, FolioContentTableLocation };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { document_d_exports } from "../types/document.js";
|
|
2
|
-
import { FolioContentBlock, FolioContentContainerPathEntry, FolioContentIdStability, FolioContentInlineBooleanProperty, FolioContentInlineFormatting, FolioContentInlineFormattingPatch, FolioContentLineSpacingRule, FolioContentParagraphAlignment, FolioContentParagraphSpacing, FolioContentRun, FolioContentSnapshot, FolioContentTableLocation } from "../compare/content-types.js";
|
|
2
|
+
import { FolioContentBlock, FolioContentContainerPathEntry, FolioContentIdStability, FolioContentInlineBooleanProperty, FolioContentInlineFormatting, FolioContentInlineFormattingPatch, FolioContentLineSpacingRule, FolioContentParagraphAlignment, FolioContentParagraphKind, FolioContentParagraphSpacing, FolioContentRun, FolioContentSnapshot, FolioContentTableLocation } from "../compare/content-types.js";
|
|
3
3
|
import { FolioAIBlock, FolioAIBlockAnchor, FolioAIBlockKind, FolioAIBlockPreviewRun, FolioAIBlockStructuralBoundary, FolioAIBlockTableLocation, FolioAIComment, FolioAIEditAppliedOperation, FolioAIEditApplyMode, FolioAIEditApplyResult, FolioAIEditNormalization, FolioAIEditNormalizationCode, FolioAIEditOperation, FolioAIEditPrecondition, FolioAIEditReviewMeta, FolioAIEditSeverity, FolioAIEditSkipReason, FolioAIEditSkippedOperation, FolioAIEditSnapshot, FolioAIInlineBooleanProperty, FolioAIInlineFormatting, FolioAIInlineFormattingPatch, FolioAIParagraphSpacing, FolioAISignatureParty } from "../ai-edits/types.js";
|
|
4
4
|
import { WORD_DIFF_GRANULARITIES, WordDiffGranularity, WordDiffNormalization, WordDiffOptions, WordDiffSegment, diffWordSegments } from "../ai-edits/word-diff.js";
|
|
5
5
|
import { FolioAIEditApplyOutcome, FolioRevisionStamp, FolioWordDiffOptions, applyFolioAIEditOperations } from "../ai-edits/apply.js";
|
|
@@ -39,4 +39,4 @@ import { getGoogleFontsEnabled, setEmbeddedFontFamilyMap, setGoogleFontsEnabled
|
|
|
39
39
|
import { DOCX_CONFORMANCE_CLASSES } from "../index.js";
|
|
40
40
|
type Document = document_d_exports.Document;
|
|
41
41
|
type DocxConformanceClass = document_d_exports.DocxConformanceClass;
|
|
42
|
-
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_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, type CompareChange, type CompareChangeLocation, type CompareContentOptions, CompareDocxApplyError, type CompareDocxError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, type CompareDocxOptions, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, type CompareFormatRange, type CompareResult, 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, type DeriveBlockIdInput, type DirectiveKind, type DirectiveRange, type Document, type DocumentPreset, type DocumentStyleCatalog, type DocumentStyleCatalogEntry, type DocumentStyleSet, type DocxCompatibility, type DocxCompatibilityContext, type DocxCompatibilityIssue, type DocxCompatibilityLocation, type DocxCompatibilityPart, type DocxConformanceClass, 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 FolioContentInlineFormatting, type FolioContentInlineFormattingPatch, type FolioContentLineSpacingRule, type FolioContentParagraphAlignment, type FolioContentParagraphFormattingPatch, 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 };
|
|
42
|
+
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_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, type CompareChange, type CompareChangeLocation, type CompareContentOptions, CompareDocxApplyError, type CompareDocxError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, type CompareDocxOptions, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, type CompareFormatRange, type CompareResult, 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, type DeriveBlockIdInput, type DirectiveKind, type DirectiveRange, type Document, type DocumentPreset, type DocumentStyleCatalog, type DocumentStyleCatalogEntry, type DocumentStyleSet, type DocxCompatibility, type DocxCompatibilityContext, type DocxCompatibilityIssue, type DocxCompatibilityLocation, type DocxCompatibilityPart, type DocxConformanceClass, 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 FolioContentInlineFormatting, type FolioContentInlineFormattingPatch, 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 };
|
|
@@ -48,18 +48,6 @@ declare function computeListRendering(numPr: {
|
|
|
48
48
|
}, numbering: NumberingMap): (document_d_exports.ListRendering & {
|
|
49
49
|
levelStarts: number[];
|
|
50
50
|
}) | null;
|
|
51
|
-
/**
|
|
52
|
-
* Compare two `numPr` references by value — `numId` plus `ilvl` (a missing
|
|
53
|
-
* `ilvl` is level 0). Used for the style-sourced-numbering provenance check;
|
|
54
|
-
* avoids JSON.stringify equality, which is sensitive to key order.
|
|
55
|
-
*/
|
|
56
|
-
declare function numPrEqual(a: {
|
|
57
|
-
numId?: number;
|
|
58
|
-
ilvl?: number;
|
|
59
|
-
} | null | undefined, b: {
|
|
60
|
-
numId?: number;
|
|
61
|
-
ilvl?: number;
|
|
62
|
-
} | null | undefined): boolean;
|
|
63
51
|
/**
|
|
64
52
|
* Render list marker text by replacing placeholders with formatted numbers
|
|
65
53
|
*
|
|
@@ -83,4 +71,4 @@ declare function isBulletLevel(level: document_d_exports.ListLevel): boolean;
|
|
|
83
71
|
/** Whether a numbering level reserves horizontal space for a visible marker. */
|
|
84
72
|
declare const numberingLevelHasMarkerSlot: (level: Pick<document_d_exports.ListLevel, "numFmt">) => boolean;
|
|
85
73
|
//#endregion
|
|
86
|
-
export { NumberingMap, computeListRendering, createNumberingMap, formatOoxmlCounter as formatNumber, getBulletCharacter, getCachedNumberingMap, isBulletLevel, markerFormattingFromLevel,
|
|
74
|
+
export { NumberingMap, computeListRendering, createNumberingMap, formatOoxmlCounter as formatNumber, getBulletCharacter, getCachedNumberingMap, isBulletLevel, markerFormattingFromLevel, numberingLevelHasMarkerSlot, padDecimal, parseNumbering, renderListMarker };
|
|
@@ -560,15 +560,6 @@ function computeListRendering(numPr, numbering) {
|
|
|
560
560
|
return rendering;
|
|
561
561
|
}
|
|
562
562
|
/**
|
|
563
|
-
* Compare two `numPr` references by value — `numId` plus `ilvl` (a missing
|
|
564
|
-
* `ilvl` is level 0). Used for the style-sourced-numbering provenance check;
|
|
565
|
-
* avoids JSON.stringify equality, which is sensitive to key order.
|
|
566
|
-
*/
|
|
567
|
-
function numPrEqual(a, b) {
|
|
568
|
-
if (a == null || b == null) return a == null && b == null;
|
|
569
|
-
return a.numId === b.numId && (a.ilvl ?? 0) === (b.ilvl ?? 0);
|
|
570
|
-
}
|
|
571
|
-
/**
|
|
572
563
|
* Render list marker text by replacing placeholders with formatted numbers
|
|
573
564
|
*
|
|
574
565
|
* @param lvlText - The level text pattern (e.g., "%1.", "%1.%2")
|
|
@@ -613,4 +604,4 @@ function isBulletLevel(level) {
|
|
|
613
604
|
/** Whether a numbering level reserves horizontal space for a visible marker. */
|
|
614
605
|
const numberingLevelHasMarkerSlot = (level) => level.numFmt !== "none";
|
|
615
606
|
//#endregion
|
|
616
|
-
export { computeListRendering, createNumberingMap, formatOoxmlCounter as formatNumber, getBulletCharacter, getCachedNumberingMap, isBulletLevel, markerFormattingFromLevel,
|
|
607
|
+
export { computeListRendering, createNumberingMap, formatOoxmlCounter as formatNumber, getBulletCharacter, getCachedNumberingMap, isBulletLevel, markerFormattingFromLevel, numberingLevelHasMarkerSlot, padDecimal, parseNumbering, renderListMarker };
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { canonicalJson } from "../utils/canonicalJson.js";
|
|
2
1
|
import { isValidHexColor } from "../utils/colorResolver.js";
|
|
3
2
|
import { isValidHexId } from "../utils/hexId.js";
|
|
4
3
|
import { parseBookmarkEnd as parseBookmarkEnd$1, parseBookmarkStart as parseBookmarkStart$1 } from "./bookmarkParser.js";
|
|
@@ -1195,10 +1194,7 @@ function parseParagraph(node, styles, theme, numbering, rels = null, media = nul
|
|
|
1195
1194
|
}
|
|
1196
1195
|
}
|
|
1197
1196
|
}
|
|
1198
|
-
if (pPr) assignParagraphPropertySource(paragraph,
|
|
1199
|
-
xml: captureParagraphPropertySource(pPr),
|
|
1200
|
-
formattingJson: canonicalJson(paragraph.formatting ?? {})
|
|
1201
|
-
});
|
|
1197
|
+
if (pPr) assignParagraphPropertySource(paragraph, captureParagraphPropertySource(pPr));
|
|
1202
1198
|
return paragraph;
|
|
1203
1199
|
}
|
|
1204
1200
|
/**
|