docx-diff-editor 1.0.52 → 1.0.53

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/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/services/nodeFingerprint.ts","../src/components/StructuralChangesPane.tsx","../src/constants.ts","../src/services/colorUtils.ts","../src/services/trackChangeInjector.ts","../src/services/runPropertiesSync.ts","../src/services/contentResolver.ts","../src/services/documentDiffer.ts","../src/services/changeContextExtractor.ts","../src/services/nodeAligner.ts","../src/services/mergeDocuments.ts","../src/services/attrComparer.ts","../src/services/tableBlockDiffer.ts","../src/services/listBlockDiffer.ts","../src/services/nonTextNodeDiffer.ts","../src/services/structuralMerger.ts","../src/DocxDiffEditor.tsx","../src/services/index.ts","../src/services/blockLevelMerger.ts","../src/blankTemplate.ts"],"names":["extractTextContent","useState","useEffect","useCallback","jsxs","jsx","Fragment","uuidv4","DiffMatchPatch","i","j","generateFingerprint","deepEqual","simpleHash","cloneNode","forwardRef","DocxDiffEditor","useRef","error","useImperativeHandle","markAllTextAsInserted","markAllTextAsDeleted","extractTextPreview"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Node Fingerprint Service\n * \n * Generates content-based fingerprints for ProseMirror nodes.\n * Fingerprints are used to match nodes between documents during diffing.\n * \n * Key principle: Two nodes with the same content (ignoring styles/attrs)\n * should produce the same or similar fingerprints.\n */\n\nimport type { ProseMirrorJSON, FingerprintedNode } from '../types';\n\n// ============================================================================\n// Fingerprint Generation\n// ============================================================================\n\n/**\n * Extract text content from a node recursively.\n * Used as the basis for fingerprint generation.\n */\nfunction extractTextContent(node: ProseMirrorJSON): string {\n if (!node) return '';\n\n if (node.type === 'text' && node.text) {\n return node.text;\n }\n\n if (node.content && Array.isArray(node.content)) {\n return node.content.map(extractTextContent).join('');\n }\n\n return '';\n}\n\n/**\n * Simple hash function for strings.\n * Uses djb2 algorithm - fast and produces reasonably distributed hashes.\n */\nfunction simpleHash(str: string): string {\n let hash = 5381;\n for (let i = 0; i < str.length; i++) {\n hash = ((hash << 5) + hash) ^ str.charCodeAt(i);\n }\n // Convert to unsigned 32-bit and then to hex\n return (hash >>> 0).toString(16);\n}\n\n/**\n * Normalize text for fingerprinting.\n * Removes extra whitespace, lowercases, trims.\n */\nfunction normalizeText(text: string): string {\n return text\n .toLowerCase()\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\n/**\n * Generate a fingerprint for a single node.\n * \n * Fingerprint format by node type:\n * - text: \"t:{hash}\"\n * - paragraph: \"p:{hash}\"\n * - heading: \"h{level}:{hash}\"\n * - table: \"table:{rowCount}:{hash}\"\n * - tableRow: \"tr:{cellCount}:{hash}\"\n * - tableCell: \"tc:{hash}\"\n * - listItem: \"li:{hash}\"\n * - image: \"img:{srcHash}\"\n * - hardBreak: \"br\"\n * - horizontalRule: \"hr\"\n * - other: \"{type}:{hash}\"\n */\nexport function generateFingerprint(node: ProseMirrorJSON): string {\n if (!node) return '';\n\n const type = node.type || 'unknown';\n\n switch (type) {\n case 'text': {\n const text = normalizeText(node.text || '');\n return `t:${simpleHash(text)}`;\n }\n\n case 'paragraph': {\n const text = normalizeText(extractTextContent(node));\n return `p:${simpleHash(text)}`;\n }\n\n case 'heading': {\n const level = node.attrs?.level || 1;\n const text = normalizeText(extractTextContent(node));\n return `h${level}:${simpleHash(text)}`;\n }\n\n case 'table': {\n const rowCount = node.content?.length || 0;\n // Include child fingerprints for more accurate matching\n const childFps = (node.content || [])\n .map((child: ProseMirrorJSON) => generateFingerprint(child))\n .join('|');\n return `table:${rowCount}:${simpleHash(childFps)}`;\n }\n\n case 'tableRow': {\n const cellCount = node.content?.length || 0;\n const childFps = (node.content || [])\n .map((child: ProseMirrorJSON) => generateFingerprint(child))\n .join('|');\n return `tr:${cellCount}:${simpleHash(childFps)}`;\n }\n\n case 'tableCell':\n case 'tableHeader': {\n const text = normalizeText(extractTextContent(node));\n return `tc:${simpleHash(text)}`;\n }\n\n case 'bulletList':\n case 'orderedList': {\n const itemCount = node.content?.length || 0;\n const childFps = (node.content || [])\n .map((child: ProseMirrorJSON) => generateFingerprint(child))\n .join('|');\n return `list:${itemCount}:${simpleHash(childFps)}`;\n }\n\n case 'listItem': {\n const text = normalizeText(extractTextContent(node));\n return `li:${simpleHash(text)}`;\n }\n\n case 'image': {\n // Use src attribute as the basis for image fingerprint\n const src = node.attrs?.src || '';\n return `img:${simpleHash(src)}`;\n }\n\n case 'hardBreak':\n return 'br';\n\n case 'horizontalRule':\n return 'hr';\n\n case 'codeBlock': {\n const text = normalizeText(extractTextContent(node));\n const lang = node.attrs?.language || '';\n return `code:${lang}:${simpleHash(text)}`;\n }\n\n case 'blockquote': {\n const text = normalizeText(extractTextContent(node));\n return `bq:${simpleHash(text)}`;\n }\n\n // For doc and other container types, fingerprint based on content\n case 'doc': {\n const childFps = (node.content || [])\n .map((child: ProseMirrorJSON) => generateFingerprint(child))\n .join('|');\n return `doc:${simpleHash(childFps)}`;\n }\n\n // Default: use type and text content\n default: {\n const text = normalizeText(extractTextContent(node));\n return `${type}:${simpleHash(text)}`;\n }\n }\n}\n\n// ============================================================================\n// Fingerprinted Node Tree\n// ============================================================================\n\n/**\n * Build a tree of fingerprinted nodes from a document.\n * Each node gets a fingerprint and path for later reference.\n */\nexport function buildFingerprintTree(\n node: ProseMirrorJSON,\n path: number[] = []\n): FingerprintedNode {\n const fingerprint = generateFingerprint(node);\n \n const result: FingerprintedNode = {\n node,\n fingerprint,\n path: [...path],\n };\n\n if (node.content && Array.isArray(node.content)) {\n result.children = node.content.map((child: ProseMirrorJSON, index: number) =>\n buildFingerprintTree(child, [...path, index])\n );\n }\n\n return result;\n}\n\n/**\n * Extract top-level block nodes with their fingerprints.\n * These are the nodes we'll align between documents.\n */\nexport function extractBlockFingerprints(doc: ProseMirrorJSON): FingerprintedNode[] {\n if (!doc || !doc.content || !Array.isArray(doc.content)) {\n return [];\n }\n\n return doc.content.map((child: ProseMirrorJSON, index: number) => ({\n node: child,\n fingerprint: generateFingerprint(child),\n path: [index],\n }));\n}\n\n// ============================================================================\n// Similarity Calculation\n// ============================================================================\n\n/**\n * Calculate similarity between two fingerprints.\n * Returns a value between 0.0 (completely different) and 1.0 (identical).\n * \n * For identical fingerprints, returns 1.0.\n * For fingerprints of the same type, calculates content similarity.\n */\nexport function calculateSimilarity(fpA: string, fpB: string): number {\n // Identical fingerprints = perfect match\n if (fpA === fpB) return 1.0;\n\n // Extract type prefix\n const typeA = fpA.split(':')[0];\n const typeB = fpB.split(':')[0];\n\n // Different types = no match\n if (typeA !== typeB) return 0.0;\n\n // Same type but different content = partial match\n // Use simple heuristic based on prefix length\n // This is a simplified approach - could be enhanced with actual content comparison\n \n // For now, same type gives a base similarity\n // The actual matching will use this along with content comparison\n return 0.3;\n}\n\n/**\n * Calculate text similarity using Levenshtein distance.\n * Returns a value between 0.0 and 1.0.\n */\nexport function calculateTextSimilarity(textA: string, textB: string): number {\n const a = normalizeText(textA);\n const b = normalizeText(textB);\n\n if (a === b) return 1.0;\n if (a.length === 0 || b.length === 0) return 0.0;\n\n // For very different lengths, quick reject\n const lenRatio = Math.min(a.length, b.length) / Math.max(a.length, b.length);\n if (lenRatio < 0.3) return lenRatio;\n\n // Calculate Levenshtein distance\n const distance = levenshteinDistance(a, b);\n const maxLen = Math.max(a.length, b.length);\n \n return 1 - (distance / maxLen);\n}\n\n/**\n * Levenshtein distance implementation.\n * Optimized for memory by only keeping two rows.\n */\nfunction levenshteinDistance(a: string, b: string): number {\n if (a.length === 0) return b.length;\n if (b.length === 0) return a.length;\n\n // Use two rows for memory efficiency\n let prevRow = Array.from({ length: b.length + 1 }, (_, i) => i);\n let currRow = new Array(b.length + 1);\n\n for (let i = 1; i <= a.length; i++) {\n currRow[0] = i;\n for (let j = 1; j <= b.length; j++) {\n const cost = a[i - 1] === b[j - 1] ? 0 : 1;\n currRow[j] = Math.min(\n prevRow[j] + 1, // deletion\n currRow[j - 1] + 1, // insertion\n prevRow[j - 1] + cost // substitution\n );\n }\n [prevRow, currRow] = [currRow, prevRow];\n }\n\n return prevRow[b.length];\n}\n\n/**\n * Get full text similarity between two nodes.\n */\nexport function getNodeTextSimilarity(nodeA: ProseMirrorJSON, nodeB: ProseMirrorJSON): number {\n const textA = extractTextContent(nodeA);\n const textB = extractTextContent(nodeB);\n return calculateTextSimilarity(textA, textB);\n}\n","/**\n * Structural Changes Pane Component\n * \n * A floating, collapsible panel that displays structural changes\n * (table rows, list items, images, etc.) with Accept/Reject controls.\n * \n * Uses SuperDoc's acceptTrackedChangeById/rejectTrackedChangeById commands\n * to handle accept/reject actions.\n */\n\nimport React, { useState, useCallback, useEffect } from 'react';\nimport type { StructuralChangeInfo, StructuralPanePosition } from '../types';\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface StructuralChangesPaneProps {\n /** Array of structural changes to display */\n changes: StructuralChangeInfo[];\n \n /** Position of the pane */\n position?: StructuralPanePosition;\n \n /** Start collapsed? */\n initiallyCollapsed?: boolean;\n \n /** Callback when a change is accepted */\n onAccept: (changeId: string) => void;\n \n /** Callback when a change is rejected */\n onReject: (changeId: string) => void;\n \n /** Callback when Accept All is clicked */\n onAcceptAll: () => void;\n \n /** Callback when Reject All is clicked */\n onRejectAll: () => void;\n \n /** Callback when a change is clicked (for navigation) */\n onNavigate?: (changeId: string) => void;\n \n /** Callback when pane is dismissed */\n onDismiss?: () => void;\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Get icon for change type\n */\nfunction getChangeIcon(type: StructuralChangeInfo['type']): string {\n switch (type) {\n case 'rowInsert':\n case 'columnInsert':\n case 'paragraphInsert':\n case 'listItemInsert':\n case 'imageInsert':\n return '➕';\n case 'rowDelete':\n case 'columnDelete':\n case 'paragraphDelete':\n case 'listItemDelete':\n case 'imageDelete':\n return '➖';\n case 'attrChange':\n return '✏️';\n default:\n return '•';\n }\n}\n\n/**\n * Get human-readable label for change type\n */\nfunction getChangeLabel(type: StructuralChangeInfo['type']): string {\n switch (type) {\n case 'rowInsert':\n return 'Row inserted';\n case 'rowDelete':\n return 'Row deleted';\n case 'columnInsert':\n return 'Column inserted';\n case 'columnDelete':\n return 'Column deleted';\n case 'paragraphInsert':\n return 'Paragraph inserted';\n case 'paragraphDelete':\n return 'Paragraph deleted';\n case 'listItemInsert':\n return 'List item inserted';\n case 'listItemDelete':\n return 'List item deleted';\n case 'imageInsert':\n return 'Image inserted';\n case 'imageDelete':\n return 'Image deleted';\n case 'attrChange':\n return 'Formatting changed';\n default:\n return 'Change';\n }\n}\n\n/**\n * Format date for display\n */\nfunction formatDate(isoDate: string): string {\n try {\n const date = new Date(isoDate);\n return date.toLocaleDateString(undefined, {\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n });\n } catch {\n return '';\n }\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport const StructuralChangesPane: React.FC<StructuralChangesPaneProps> = ({\n changes,\n position = 'bottom-right',\n initiallyCollapsed = false,\n onAccept,\n onReject,\n onAcceptAll,\n onRejectAll,\n onNavigate,\n onDismiss,\n}) => {\n const [isCollapsed, setIsCollapsed] = useState(initiallyCollapsed);\n const [isVisible, setIsVisible] = useState(true);\n const [isAnimatingOut, setIsAnimatingOut] = useState(false);\n\n // Auto-hide when no changes\n useEffect(() => {\n if (changes.length === 0) {\n setIsAnimatingOut(true);\n const timer = setTimeout(() => setIsVisible(false), 300);\n return () => clearTimeout(timer);\n } else {\n setIsVisible(true);\n setIsAnimatingOut(false);\n }\n }, [changes.length]);\n\n // Handle dismiss\n const handleDismiss = useCallback(() => {\n setIsAnimatingOut(true);\n setTimeout(() => {\n setIsVisible(false);\n onDismiss?.();\n }, 300);\n }, [onDismiss]);\n\n // Handle toggle collapse\n const handleToggleCollapse = useCallback(() => {\n setIsCollapsed((prev) => !prev);\n }, []);\n\n // Handle accept single change\n const handleAccept = useCallback((e: React.MouseEvent, changeId: string) => {\n e.stopPropagation();\n onAccept(changeId);\n }, [onAccept]);\n\n // Handle reject single change\n const handleReject = useCallback((e: React.MouseEvent, changeId: string) => {\n e.stopPropagation();\n onReject(changeId);\n }, [onReject]);\n\n // Handle navigate to change\n const handleNavigate = useCallback((changeId: string) => {\n onNavigate?.(changeId);\n }, [onNavigate]);\n\n // Don't render if not visible\n if (!isVisible) return null;\n\n // Position classes\n const positionClasses: Record<StructuralPanePosition, string> = {\n 'top-right': 'dde-pane--top-right',\n 'bottom-right': 'dde-pane--bottom-right',\n 'top-left': 'dde-pane--top-left',\n 'bottom-left': 'dde-pane--bottom-left',\n };\n\n return (\n <div\n className={`dde-structural-pane ${positionClasses[position]} ${\n isAnimatingOut ? 'dde-pane--animating-out' : ''\n } ${isCollapsed ? 'dde-pane--collapsed' : ''}`}\n role=\"region\"\n aria-label=\"Structural Changes\"\n >\n {/* Header */}\n <div className=\"dde-pane__header\" onClick={handleToggleCollapse}>\n <div className=\"dde-pane__title\">\n <span className=\"dde-pane__icon\">📋</span>\n <span className=\"dde-pane__label\">\n Structural Changes\n <span className=\"dde-pane__count\">{changes.length}</span>\n </span>\n </div>\n <div className=\"dde-pane__controls\">\n <button\n className=\"dde-pane__btn dde-pane__btn--collapse\"\n onClick={(e) => {\n e.stopPropagation();\n handleToggleCollapse();\n }}\n aria-label={isCollapsed ? 'Expand' : 'Collapse'}\n title={isCollapsed ? 'Expand' : 'Collapse'}\n >\n {isCollapsed ? '+' : '−'}\n </button>\n <button\n className=\"dde-pane__btn dde-pane__btn--close\"\n onClick={(e) => {\n e.stopPropagation();\n handleDismiss();\n }}\n aria-label=\"Close\"\n title=\"Close\"\n >\n ×\n </button>\n </div>\n </div>\n\n {/* Body - only visible when not collapsed */}\n {!isCollapsed && (\n <>\n <div className=\"dde-pane__body\">\n {changes.length === 0 ? (\n <div className=\"dde-pane__empty\">No structural changes</div>\n ) : (\n <ul className=\"dde-pane__list\">\n {changes.map((change) => (\n <li\n key={change.id}\n className=\"dde-pane__item\"\n onClick={() => handleNavigate(change.id)}\n >\n <div className=\"dde-pane__item-header\">\n <span className=\"dde-pane__item-icon\">\n {getChangeIcon(change.type)}\n </span>\n <span className=\"dde-pane__item-label\">\n {getChangeLabel(change.type)}\n </span>\n </div>\n <div className=\"dde-pane__item-location\">\n {change.location}\n </div>\n <div className=\"dde-pane__item-preview\">\n {change.preview}\n </div>\n <div className=\"dde-pane__item-meta\">\n <span className=\"dde-pane__item-author\">\n {change.author.name}\n </span>\n <span className=\"dde-pane__item-date\">\n {formatDate(change.date)}\n </span>\n </div>\n <div className=\"dde-pane__item-actions\">\n <button\n className=\"dde-pane__action dde-pane__action--accept\"\n onClick={(e) => handleAccept(e, change.id)}\n title=\"Accept change\"\n >\n Accept\n </button>\n <button\n className=\"dde-pane__action dde-pane__action--reject\"\n onClick={(e) => handleReject(e, change.id)}\n title=\"Reject change\"\n >\n Reject\n </button>\n </div>\n </li>\n ))}\n </ul>\n )}\n </div>\n\n {/* Footer with bulk actions */}\n {changes.length > 0 && (\n <div className=\"dde-pane__footer\">\n <button\n className=\"dde-pane__bulk-btn dde-pane__bulk-btn--accept\"\n onClick={onAcceptAll}\n >\n Accept All\n </button>\n <button\n className=\"dde-pane__bulk-btn dde-pane__bulk-btn--reject\"\n onClick={onRejectAll}\n >\n Reject All\n </button>\n </div>\n )}\n </>\n )}\n </div>\n );\n};\n\nexport default StructuralChangesPane;\n","/**\n * Constants for DocxDiffEditor\n */\n\nimport type { TrackChangeAuthor } from './types';\n\n/**\n * Default author for track changes\n */\nexport const DEFAULT_AUTHOR: TrackChangeAuthor = {\n name: 'DocxDiff Editor',\n email: 'editor@docxdiff.local',\n};\n\n/**\n * Default SuperDoc user (used for editor initialization)\n */\nexport const DEFAULT_SUPERDOC_USER = {\n name: 'DocxDiff User',\n email: 'user@docxdiff.local',\n};\n\n/**\n * Permissions allowed for track change resolution\n */\nexport const TRACK_CHANGE_PERMISSIONS = [\n 'RESOLVE_OWN',\n 'RESOLVE_OTHER',\n 'REJECT_OWN',\n 'REJECT_OTHER',\n];\n\n/**\n * CSS class prefix for all component styles\n */\nexport const CSS_PREFIX = 'dde';\n\n/**\n * Timeouts\n */\nexport const TIMEOUTS = {\n /** Timeout for document parsing (ms) */\n PARSE_TIMEOUT: 30000,\n /** Small delay for React settling (ms) */\n INIT_DELAY: 100,\n /** Cleanup delay (ms) */\n CLEANUP_DELAY: 100,\n};\n\n","/**\n * Color Utilities\n * \n * Shared color conversion utilities for consistent handling across the codebase.\n * Single source of truth for CSS named colors and color format conversions.\n */\n\n// ============================================================================\n// CSS Named Colors Map (Single Source of Truth)\n// ============================================================================\n\n/**\n * Map of CSS named colors to hex values WITHOUT the # prefix.\n * This is the canonical format - add # when needed for CSS, strip for DOCX.\n */\nexport const CSS_NAMED_COLORS: Record<string, string> = {\n // Basic colors\n black: '000000',\n white: 'ffffff',\n red: 'ff0000',\n green: '008000',\n blue: '0000ff',\n yellow: 'ffff00',\n cyan: '00ffff',\n magenta: 'ff00ff',\n \n // Extended colors\n orange: 'ffa500',\n pink: 'ffc0cb',\n purple: '800080',\n violet: 'ee82ee',\n brown: 'a52a2a',\n gray: '808080',\n grey: '808080',\n \n // Light variants\n lightblue: 'add8e6',\n lightgreen: '90ee90',\n lightgray: 'd3d3d3',\n lightgrey: 'd3d3d3',\n lightpink: 'ffb6c1',\n lightyellow: 'ffffe0',\n \n // Dark variants\n darkblue: '00008b',\n darkgreen: '006400',\n darkgray: 'a9a9a9',\n darkgrey: 'a9a9a9',\n darkred: '8b0000',\n \n // Other common colors\n navy: '000080',\n teal: '008080',\n maroon: '800000',\n olive: '808000',\n silver: 'c0c0c0',\n aqua: '00ffff',\n fuchsia: 'ff00ff',\n lime: '00ff00',\n coral: 'ff7f50',\n salmon: 'fa8072',\n gold: 'ffd700',\n indigo: '4b0082',\n crimson: 'dc143c',\n tomato: 'ff6347',\n chocolate: 'd2691e',\n tan: 'd2b48c',\n beige: 'f5f5dc',\n ivory: 'fffff0',\n khaki: 'f0e68c',\n lavender: 'e6e6fa',\n plum: 'dda0dd',\n orchid: 'da70d6',\n turquoise: '40e0d0',\n skyblue: '87ceeb',\n steelblue: '4682b4',\n slategray: '708090',\n slategrey: '708090',\n};\n\n// ============================================================================\n// Color Conversion Functions\n// ============================================================================\n\n/**\n * Convert a color value to hex format WITHOUT # prefix.\n * Used for DOCX runProperties.color.val which expects hex without #.\n * \n * Handles:\n * - Named colors: \"red\" → \"ff0000\"\n * - Hex with #: \"#ff0000\" → \"ff0000\"\n * - Hex without #: \"ff0000\" → \"ff0000\"\n * \n * @param color - The color value to convert\n * @returns Hex color without # prefix\n */\nexport function colorToHexWithoutHash(color: string): string {\n const trimmed = color.trim();\n const lowerColor = trimmed.toLowerCase();\n \n // Check if it's a named color\n if (CSS_NAMED_COLORS[lowerColor]) {\n return CSS_NAMED_COLORS[lowerColor];\n }\n \n // Strip # if present\n return trimmed.replace(/^#/, '');\n}\n\n/**\n * Ensure a color value is valid for CSS (with # prefix for hex).\n * Used for ProseMirror marks which need valid CSS colors.\n * \n * Handles:\n * - Named colors: \"red\" → \"#ff0000\"\n * - Hex without #: \"ff0000\" → \"#ff0000\"\n * - 3-char hex without #: \"f00\" → \"#f00\"\n * - Already valid: \"#ff0000\" → \"#ff0000\"\n * - RGB/HSL: \"rgb(255,0,0)\" → \"rgb(255,0,0)\" (unchanged)\n * \n * @param color - The color value to normalize\n * @returns Valid CSS color string, or undefined if invalid input\n */\nexport function ensureValidCssColor(color: unknown): string | undefined {\n if (typeof color !== 'string' || !color) {\n return undefined;\n }\n \n const trimmed = color.trim();\n const lowerColor = trimmed.toLowerCase();\n \n // If it's a named color, convert to hex with #\n if (CSS_NAMED_COLORS[lowerColor]) {\n return `#${CSS_NAMED_COLORS[lowerColor]}`;\n }\n \n // If it's a 6-character hex without #, add the #\n if (/^[0-9a-fA-F]{6}$/.test(trimmed)) {\n return `#${trimmed}`;\n }\n \n // If it's a 3-character hex without #, add the #\n if (/^[0-9a-fA-F]{3}$/.test(trimmed)) {\n return `#${trimmed}`;\n }\n \n // Already has # or is rgb/hsl/etc - return as-is\n return trimmed;\n}\n\n/**\n * Check if a string is a recognized named CSS color.\n * \n * @param color - The color value to check\n * @returns True if the color is a recognized named color\n */\nexport function isNamedColor(color: string): boolean {\n return CSS_NAMED_COLORS[color.toLowerCase().trim()] !== undefined;\n}\n","/**\n * Track Change Injector Service\n * Creates track change marks for insertions, deletions, and format changes.\n */\n\nimport { v4 as uuidv4 } from 'uuid';\nimport type { TrackChangeAuthor, ProseMirrorJSON, ProseMirrorMark } from '../types';\nimport { DEFAULT_AUTHOR } from '../constants';\nimport { ensureValidCssColor } from './colorUtils';\n\n/**\n * Check if a value is meaningful (not null, undefined, or empty string).\n */\nfunction isMeaningfulValue(value: unknown): boolean {\n return value !== null && value !== undefined && value !== '';\n}\n\n/**\n * Clean attrs by removing null, undefined, and empty string values.\n * This prevents SuperDoc's translateFormatChangesToEnglish from showing\n * \"Changed X from Y to undefined\" when properties don't exist in one side.\n */\nfunction cleanAttrs(attrs: Record<string, unknown>): Record<string, unknown> {\n const cleaned: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(attrs)) {\n if (isMeaningfulValue(value)) {\n cleaned[key] = value;\n }\n }\n return cleaned;\n}\n\n/**\n * Normalize a mark to ensure it has an `attrs` property and valid color format.\n * \n * SuperDoc requirements:\n * 1. parseFormatList filters out marks without `attrs`\n * 2. Color extension renderDOM uses attrs.color directly in CSS (needs # for hex)\n */\nfunction normalizeMark(mark: ProseMirrorMark): ProseMirrorMark {\n const attrs = { ...(mark.attrs || {}) };\n \n // Ensure color has valid CSS format (# prefix for hex colors)\n if (attrs.color !== undefined) {\n attrs.color = ensureValidCssColor(attrs.color);\n }\n \n return {\n type: mark.type,\n attrs,\n };\n}\n\n/**\n * Normalize a mark for use in trackFormat before/after arrays.\n * \n * This is stricter than normalizeMark - it also cleans attrs to remove\n * null/undefined/empty values. This prevents SuperDoc's bubble display from\n * showing \"Set font family to undefined\" when comparing marks with different\n * property sets.\n * \n * Example issue without cleaning:\n * - before: {fontFamily: \"Arial\", fontSize: \"12pt\"}\n * - after: {color: \"#ff0000\"} (no fontFamily property)\n * - Object.keys merge: [\"fontFamily\", \"fontSize\", \"color\"]\n * - afterValue for fontFamily = undefined → shows \"Changed font family from Arial to undefined\"\n */\nfunction normalizeMarkForTrackFormat(mark: ProseMirrorMark): ProseMirrorMark {\n let attrs = { ...(mark.attrs || {}) };\n \n // Ensure color has valid CSS format (# prefix for hex colors)\n if (attrs.color !== undefined) {\n attrs.color = ensureValidCssColor(attrs.color);\n }\n \n // Clean attrs to only include meaningful values\n attrs = cleanAttrs(attrs);\n \n return {\n type: mark.type,\n attrs,\n };\n}\n\n/**\n * Normalize an array of marks to ensure all have `attrs` property\n * and valid color formats.\n */\nfunction normalizeMarks(marks: ProseMirrorMark[]): ProseMirrorMark[] {\n return marks.map(normalizeMark);\n}\n\n/**\n * Normalize an array of marks for use in trackFormat before/after arrays.\n * Cleans attrs to remove null/undefined/empty values.\n */\nfunction normalizeMarksForTrackFormat(marks: ProseMirrorMark[]): ProseMirrorMark[] {\n return marks.map(normalizeMarkForTrackFormat);\n}\n\n/**\n * Normalize marks for DOM rendering.\n * Exported for use in other modules that apply marks to text nodes.\n */\nexport function normalizeMarksForRendering(marks: ProseMirrorMark[]): ProseMirrorMark[] {\n return normalizeMarks(marks);\n}\n\n/**\n * Create a trackInsert mark.\n * @param author - The author of the change\n * @param id - Optional ID to use (for linking with corresponding delete in replacements)\n */\nexport function createTrackInsertMark(\n author: TrackChangeAuthor = DEFAULT_AUTHOR,\n id?: string\n): ProseMirrorMark {\n return {\n type: 'trackInsert',\n attrs: {\n id: id ?? uuidv4(),\n author: author.name,\n authorEmail: author.email,\n authorImage: '',\n date: new Date().toISOString(),\n },\n };\n}\n\n/**\n * Create a trackDelete mark.\n * @param author - The author of the change\n * @param id - Optional ID to use (for linking with corresponding insert in replacements)\n */\nexport function createTrackDeleteMark(\n author: TrackChangeAuthor = DEFAULT_AUTHOR,\n id?: string\n): ProseMirrorMark {\n return {\n type: 'trackDelete',\n attrs: {\n id: id ?? uuidv4(),\n author: author.name,\n authorEmail: author.email,\n authorImage: '',\n date: new Date().toISOString(),\n },\n };\n}\n\n/**\n * Create a trackFormat mark.\n * \n * Note: SuperDoc's parseFormatList requires all marks in before/after arrays\n * to have both `type` and `attrs` properties. Marks without `attrs` get filtered out,\n * causing empty values in track change bubbles.\n * \n * We use normalizeMarksForTrackFormat which:\n * 1. Ensures all marks have `attrs` property (required by parseFormatList)\n * 2. Cleans attrs to remove null/undefined/empty values (prevents \"Set X to undefined\" bubbles)\n * 3. Normalizes color values to valid CSS format\n */\nexport function createTrackFormatMark(\n before: ProseMirrorMark[],\n after: ProseMirrorMark[],\n author: TrackChangeAuthor = DEFAULT_AUTHOR\n): ProseMirrorMark {\n // Normalize marks for trackFormat - cleans attrs to only include meaningful values\n // This prevents SuperDoc's translateFormatChangesToEnglish from showing\n // \"Changed X from Y to undefined\" when comparing marks with different property sets\n const normalizedBefore = normalizeMarksForTrackFormat(before);\n const normalizedAfter = normalizeMarksForTrackFormat(after);\n\n return {\n type: 'trackFormat',\n attrs: {\n id: uuidv4(),\n author: author.name,\n authorEmail: author.email,\n authorImage: '',\n date: new Date().toISOString(),\n before: normalizedBefore,\n after: normalizedAfter,\n },\n };\n}\n\n/**\n * Add a mark to a text node, preserving existing marks.\n */\nexport function addMarkToTextNode(\n node: ProseMirrorJSON,\n mark: ProseMirrorMark\n): ProseMirrorJSON {\n if (node.type !== 'text') {\n return node;\n }\n\n return {\n ...node,\n marks: [...(node.marks || []), mark],\n };\n}\n\n/**\n * Create a text node with specific marks.\n */\nexport function createTextNode(\n text: string,\n marks: ProseMirrorMark[] = []\n): ProseMirrorJSON {\n const node: ProseMirrorJSON = {\n type: 'text',\n text,\n };\n\n if (marks.length > 0) {\n node.marks = marks;\n }\n\n return node;\n}\n\n/**\n * Apply trackDelete mark to all text in a node (recursively).\n */\nexport function markAllAsDeleted(\n node: ProseMirrorJSON,\n author: TrackChangeAuthor = DEFAULT_AUTHOR\n): ProseMirrorJSON {\n if (node.type === 'text') {\n return addMarkToTextNode(node, createTrackDeleteMark(author));\n }\n\n if (node.content && Array.isArray(node.content)) {\n return {\n ...node,\n content: node.content.map((child: ProseMirrorJSON) =>\n markAllAsDeleted(child, author)\n ),\n };\n }\n\n return node;\n}\n\n/**\n * Apply trackInsert mark to all text in a node (recursively).\n */\nexport function markAllAsInserted(\n node: ProseMirrorJSON,\n author: TrackChangeAuthor = DEFAULT_AUTHOR\n): ProseMirrorJSON {\n if (node.type === 'text') {\n return addMarkToTextNode(node, createTrackInsertMark(author));\n }\n\n if (node.content && Array.isArray(node.content)) {\n return {\n ...node,\n content: node.content.map((child: ProseMirrorJSON) =>\n markAllAsInserted(child, author)\n ),\n };\n }\n\n return node;\n}\n\n/**\n * Clone a node deeply.\n */\nexport function cloneNode(node: ProseMirrorJSON): ProseMirrorJSON {\n return JSON.parse(JSON.stringify(node));\n}\n\n","/**\n * Run Properties Sync Service\n * \n * Ensures that ProseMirror marks on text nodes are synced to\n * runProperties on parent run nodes. This is required because\n * SuperDoc has a dual-layer architecture:\n * \n * - ProseMirror marks on text nodes → used for editing interactions\n * - runProperties on run nodes → used for actual DOCX rendering\n * \n * Both need to be in sync for styles to render correctly.\n * \n * Based on SuperDoc's decodeRPrFromMarks logic in converter-BavE2jnW.js\n */\n\nimport type { ProseMirrorJSON, ProseMirrorNode } from '../types';\nimport { normalizeMarksForRendering } from './trackChangeInjector';\nimport { colorToHexWithoutHash } from './colorUtils';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * A ProseMirror mark as it appears in JSON\n */\ninterface ProseMirrorMark {\n type: string;\n attrs?: Record<string, unknown>;\n}\n\n/**\n * SuperDoc's runProperties format\n */\ninterface RunProperties {\n bold?: boolean;\n italic?: boolean;\n strike?: boolean;\n underline?: {\n 'w:val'?: string;\n 'w:color'?: string;\n };\n highlight?: {\n 'w:val': string;\n };\n color?: {\n val: string;\n };\n fontSize?: number;\n fontFamily?: {\n ascii: string;\n eastAsia: string;\n hAnsi: string;\n cs: string;\n };\n letterSpacing?: number;\n textTransform?: string;\n [key: string]: unknown;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/**\n * Points to twips conversion (1 point = 20 twips)\n */\nconst PT_TO_TWIPS = 20;\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Convert points string to twips number.\n * Example: \"1pt\" → 20\n */\nfunction ptToTwips(ptValue: number): number {\n return Math.round(ptValue * PT_TO_TWIPS);\n}\n\n/**\n * Parse a font size string to points.\n * Handles: \"12pt\", \"12\", \"16px\" (approximates px to pt)\n */\nfunction parseFontSizeToPoints(fontSize: string | number): number | null {\n if (typeof fontSize === 'number') {\n return fontSize;\n }\n \n const value = parseFloat(fontSize);\n if (isNaN(value)) {\n return null;\n }\n \n // Check for px suffix and convert (approximate: 1px ≈ 0.75pt)\n if (fontSize.toLowerCase().includes('px')) {\n return value * 0.75;\n }\n \n // Assume pt or no suffix\n return value;\n}\n\n/**\n * Clean font family string - take first font from comma-separated list\n * and remove quotes.\n * Example: \"'Arial', sans-serif\" → \"Arial\"\n */\nfunction cleanFontFamily(fontFamily: string): string {\n return fontFamily\n .split(',')[0]\n .trim()\n .replace(/^[\"']|[\"']$/g, '');\n}\n\n// ============================================================================\n// Main Conversion Function\n// ============================================================================\n\n/**\n * Convert an array of ProseMirror marks to SuperDoc runProperties format.\n * \n * Based on SuperDoc's decodeRPrFromMarks logic.\n */\nexport function marksToRunProperties(marks: ProseMirrorMark[]): RunProperties {\n const runProperties: RunProperties = {};\n\n if (!marks || !Array.isArray(marks)) {\n return runProperties;\n }\n\n for (const mark of marks) {\n const type = mark.type;\n const attrs = mark.attrs || {};\n\n switch (type) {\n // Boolean marks: bold, italic, strike\n case 'bold':\n case 'italic':\n case 'strike': {\n // Check if mark is negated (value === \"0\" or false)\n const isNegated = attrs.value === '0' || attrs.value === false;\n runProperties[type] = !isNegated;\n break;\n }\n\n // Underline with optional type and color\n case 'underline': {\n const underlineAttrs: { 'w:val'?: string; 'w:color'?: string } = {};\n \n if (attrs.underlineType) {\n underlineAttrs['w:val'] = String(attrs.underlineType);\n } else {\n // Default underline type\n underlineAttrs['w:val'] = 'single';\n }\n \n if (attrs.underlineColor) {\n underlineAttrs['w:color'] = colorToHexWithoutHash(String(attrs.underlineColor));\n }\n \n if (Object.keys(underlineAttrs).length > 0) {\n runProperties.underline = underlineAttrs;\n }\n break;\n }\n\n // Highlight (background color)\n case 'highlight': {\n if (attrs.color) {\n const color = String(attrs.color).toLowerCase();\n if (color === 'transparent') {\n runProperties.highlight = { 'w:val': 'none' };\n } else {\n runProperties.highlight = { 'w:val': color };\n }\n }\n break;\n }\n\n // textStyle contains multiple style attributes\n case 'textStyle': {\n // Color - convert named colors to hex for SuperDoc compatibility\n if (attrs.color != null) {\n runProperties.color = {\n val: colorToHexWithoutHash(String(attrs.color)),\n };\n }\n\n // Font size (convert to half-points)\n if (attrs.fontSize != null) {\n const points = parseFontSizeToPoints(attrs.fontSize as string | number);\n if (points !== null) {\n runProperties.fontSize = points * 2; // Half-points\n }\n }\n\n // Font family (needs all 4 properties)\n if (attrs.fontFamily != null) {\n const cleanedFont = cleanFontFamily(String(attrs.fontFamily));\n runProperties.fontFamily = {\n ascii: cleanedFont,\n eastAsia: cleanedFont,\n hAnsi: cleanedFont,\n cs: cleanedFont,\n };\n }\n\n // Letter spacing (convert to twips)\n if (attrs.letterSpacing != null) {\n const ptValue = parseFloat(String(attrs.letterSpacing));\n if (!isNaN(ptValue)) {\n runProperties.letterSpacing = ptToTwips(ptValue);\n }\n }\n\n // Text transform (pass through)\n if (attrs.textTransform != null) {\n runProperties.textTransform = String(attrs.textTransform);\n }\n break;\n }\n\n // Unknown mark types are ignored\n default:\n break;\n }\n }\n\n return runProperties;\n}\n\n// ============================================================================\n// Document Normalization\n// ============================================================================\n\n/**\n * Recursively collect all marks from text nodes within a node.\n * This handles cases where text is nested within inline elements inside a run.\n */\nfunction collectMarksRecursively(node: ProseMirrorNode, allMarks: ProseMirrorMark[]): void {\n if (node.type === 'text' && node.marks && Array.isArray(node.marks)) {\n allMarks.push(...node.marks);\n }\n\n if (node.content && Array.isArray(node.content)) {\n for (const child of node.content) {\n collectMarksRecursively(child, allMarks);\n }\n }\n}\n\n/**\n * Collect all marks from text node descendants of a run node.\n * Recursively searches to handle nested inline content.\n */\nfunction collectMarksFromRunChildren(runNode: ProseMirrorNode): ProseMirrorMark[] {\n const allMarks: ProseMirrorMark[] = [];\n\n if (!runNode.content || !Array.isArray(runNode.content)) {\n return allMarks;\n }\n\n // Recursively collect marks from all text nodes\n for (const child of runNode.content) {\n collectMarksRecursively(child, allMarks);\n }\n\n // Deduplicate marks by type (keep last occurrence for each type)\n const marksByType = new Map<string, ProseMirrorMark>();\n for (const mark of allMarks) {\n marksByType.set(mark.type, mark);\n }\n\n return Array.from(marksByType.values());\n}\n\n/**\n * Recursively walk a node and:\n * 1. Normalize runProperties on run nodes from child text marks\n * 2. Normalize marks on text nodes to ensure valid CSS colors\n * \n * This ensures both the ProseMirror marks AND runProperties have valid values.\n */\nfunction normalizeNode(node: ProseMirrorNode): ProseMirrorNode {\n // If this is a text node with marks, normalize the marks\n if (node.type === 'text' && node.marks && Array.isArray(node.marks)) {\n const normalizedMarks = normalizeMarksForRendering(node.marks);\n return {\n ...node,\n marks: normalizedMarks,\n };\n }\n \n // If this is a run node, sync runProperties from child text marks\n if (node.type === 'run') {\n // First, recursively normalize children (including text node marks)\n const normalizedContent = node.content?.map(normalizeNode);\n \n // Then collect marks from the normalized children\n const normalizedNode = { ...node, content: normalizedContent };\n const marks = collectMarksFromRunChildren(normalizedNode);\n \n if (marks.length > 0) {\n const runPropsFromMarks = marksToRunProperties(marks);\n \n // Merge with existing runProperties (marks override)\n const existingRunProps = (node.attrs?.runProperties as RunProperties) || {};\n const mergedRunProps = {\n ...existingRunProps,\n ...runPropsFromMarks,\n };\n\n // Return node with updated runProperties\n return {\n ...normalizedNode,\n attrs: {\n ...normalizedNode.attrs,\n runProperties: mergedRunProps,\n },\n };\n }\n \n return normalizedNode;\n }\n\n // Recursively process children\n if (node.content && Array.isArray(node.content)) {\n return {\n ...node,\n content: node.content.map(normalizeNode),\n };\n }\n\n return node;\n}\n\n/**\n * Normalize a ProseMirror document by:\n * 1. Normalizing marks on text nodes (ensuring valid CSS colors, attrs property)\n * 2. Syncing runProperties on run nodes from child text node marks\n * \n * This ensures that styles set via marks (from HTML parsing, etc.) are:\n * - Properly formatted for SuperDoc's DOM rendering (valid CSS colors with #)\n * - Properly reflected in runProperties for DOCX export\n * \n * This function is idempotent - running it multiple times produces the same result.\n */\nexport function normalizeRunProperties(doc: ProseMirrorJSON): ProseMirrorJSON {\n // Deep clone to avoid mutating original\n const cloned = JSON.parse(JSON.stringify(doc)) as ProseMirrorJSON;\n \n return normalizeNode(cloned) as ProseMirrorJSON;\n}\n","/**\n * Content Resolver Service\n * Detects content type and parses DOCX files to ProseMirror JSON.\n *\n * Supports three input formats:\n * - File: DOCX file parsed by SuperDoc\n * - string: HTML content (handled directly by SuperDoc in the component)\n * - object: Direct ProseMirror JSON (passed through)\n */\n\nimport type { DocxContent, ProseMirrorJSON } from '../types';\nimport { TIMEOUTS } from '../constants';\nimport { normalizeRunProperties } from './runPropertiesSync';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype SuperDocConstructor = any;\n\n/**\n * Detect the type of content provided\n */\nexport function detectContentType(content: DocxContent): 'file' | 'html' | 'json' {\n if (content instanceof File) {\n return 'file';\n }\n if (typeof content === 'string') {\n return 'html';\n }\n // Assume it's JSON if it's an object\n return 'json';\n}\n\n/**\n * Validate that content looks like ProseMirror JSON\n */\nexport function isProseMirrorJSON(content: unknown): boolean {\n if (!content || typeof content !== 'object') return false;\n const obj = content as Record<string, unknown>;\n return typeof obj.type === 'string' && (obj.type === 'doc' || Array.isArray(obj.content));\n}\n\n/**\n * Parse an HTML string into ProseMirror JSON using a hidden SuperDoc instance.\n * \n * IMPORTANT: Uses the \"paste\" approach instead of the \"import\" approach.\n * SuperDoc's import path (via `html` option) calls `stripHtmlStyles()` which\n * removes all CSS styles except `text-align`. The paste path (via `view.pasteHTML()`)\n * preserves inline styles like color, font-size, font-family, font-weight, etc.\n * \n * Flow:\n * 1. Create SuperDoc with empty HTML document\n * 2. Wait for editor to be ready\n * 3. Select all content and delete it (start fresh)\n * 4. Use editor.view.pasteHTML(html) - this uses the paste path which preserves styles\n * 5. Return the resulting JSON\n * \n * Falls back to the standard import approach if paste fails.\n */\nexport async function parseHtmlToJson(\n html: string,\n SuperDoc: SuperDocConstructor\n): Promise<ProseMirrorJSON> {\n // Create a hidden container for the editor\n const container = document.createElement('div');\n container.style.cssText =\n 'position:absolute;top:-9999px;left:-9999px;width:800px;height:600px;visibility:hidden;';\n document.body.appendChild(container);\n\n return new Promise((resolve, reject) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let superdoc: any = null;\n let resolved = false;\n\n const cleanup = () => {\n setTimeout(() => {\n if (superdoc) {\n try {\n const sd = superdoc;\n superdoc = null;\n sd.destroy?.();\n } catch {\n // Ignore cleanup errors\n }\n }\n if (container.parentNode) {\n container.parentNode.removeChild(container);\n }\n }, TIMEOUTS.CLEANUP_DELAY);\n };\n\n /**\n * Create a mock ClipboardEvent with proper getData() support.\n * This is needed because pasteHTML internally calls event.clipboardData.getData().\n */\n const createMockPasteEvent = (htmlContent: string): ClipboardEvent => {\n // Create a DataTransfer object to hold the clipboard data\n const dataTransfer = new DataTransfer();\n dataTransfer.setData('text/html', htmlContent);\n dataTransfer.setData('text/plain', ''); // Some handlers check for plain text too\n\n // Create the ClipboardEvent with our DataTransfer\n const event = new ClipboardEvent('paste', {\n bubbles: true,\n cancelable: true,\n clipboardData: dataTransfer,\n });\n\n return event;\n };\n\n /**\n * Attempt the paste approach (preserves styles)\n */\n const tryPasteApproach = (\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n sd: any,\n onSuccess: (json: ProseMirrorJSON) => void,\n onFail: () => void\n ) => {\n try {\n const editor = sd?.activeEditor;\n if (!editor?.view?.pasteHTML) {\n // pasteHTML not available, fall back\n onFail();\n return;\n }\n\n // Focus the editor (required for some operations)\n editor.commands.focus?.();\n\n // Select all content and delete it to start fresh\n if (editor.commands.selectAll && editor.commands.deleteSelection) {\n editor.commands.selectAll();\n editor.commands.deleteSelection();\n }\n\n // Create a mock paste event with proper clipboardData\n const mockEvent = createMockPasteEvent(html);\n\n // Use pasteHTML which goes through the paste path\n // This path does NOT call stripHtmlStyles(), preserving inline styles\n // Pass the mock event so getData() works\n editor.view.pasteHTML(html, mockEvent);\n\n // Small delay to let the paste operation complete\n setTimeout(() => {\n try {\n const json = editor.getJSON();\n // Verify we got content (paste succeeded)\n if (json?.content?.length > 0) {\n // Normalize runProperties to ensure styles render correctly\n const normalizedJson = normalizeRunProperties(json);\n onSuccess(normalizedJson);\n } else {\n // Paste produced empty doc, fall back\n onFail();\n }\n } catch {\n onFail();\n }\n }, 100);\n } catch (err) {\n console.warn('[parseHtmlToJson] Paste approach error:', err);\n onFail();\n }\n };\n\n /**\n * Fallback to standard import approach (strips some styles but works reliably)\n */\n const fallbackToImport = () => {\n // Clean up the paste attempt\n if (superdoc) {\n try {\n superdoc.destroy?.();\n } catch {\n // Ignore\n }\n superdoc = null;\n }\n\n // Create new SuperDoc with standard import\n superdoc = new SuperDoc({\n selector: container,\n html: html, // Use the actual HTML content\n documentMode: 'viewing',\n rulers: false,\n user: { name: 'Parser', email: 'parser@local' },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onReady: ({ superdoc: sd }: { superdoc: any }) => {\n if (resolved) return;\n try {\n const editor = sd?.activeEditor;\n if (!editor) {\n throw new Error('No active editor found');\n }\n const json = editor.getJSON();\n // Normalize runProperties to ensure styles render correctly\n const normalizedJson = normalizeRunProperties(json);\n resolved = true;\n cleanup();\n resolve(normalizedJson);\n } catch (err) {\n resolved = true;\n cleanup();\n reject(err);\n }\n },\n onException: ({ error: err }: { error: Error }) => {\n if (resolved) return;\n resolved = true;\n cleanup();\n reject(err);\n },\n });\n };\n\n setTimeout(async () => {\n if (resolved) return;\n\n try {\n // First, try the paste approach (preserves styles)\n superdoc = new SuperDoc({\n selector: container,\n html: '<p></p>', // Minimal empty document\n documentMode: 'editing', // Need editing mode to use paste\n rulers: false,\n user: { name: 'Parser', email: 'parser@local' },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onReady: ({ superdoc: sd }: { superdoc: any }) => {\n if (resolved) return;\n \n tryPasteApproach(\n sd,\n // Success callback\n (json) => {\n if (resolved) return;\n resolved = true;\n cleanup();\n resolve(json);\n },\n // Fail callback - try fallback\n () => {\n if (resolved) return;\n console.warn('[parseHtmlToJson] Paste approach failed, falling back to import');\n fallbackToImport();\n }\n );\n },\n onException: ({ error: err }: { error: Error }) => {\n if (resolved) return;\n // Try fallback on exception\n console.warn('[parseHtmlToJson] Paste approach exception, falling back:', err);\n fallbackToImport();\n },\n });\n\n // Timeout\n setTimeout(() => {\n if (!resolved) {\n resolved = true;\n cleanup();\n reject(new Error('HTML parsing timed out'));\n }\n }, TIMEOUTS.PARSE_TIMEOUT);\n } catch (err) {\n // Try fallback on error\n try {\n fallbackToImport();\n } catch (fallbackErr) {\n cleanup();\n reject(fallbackErr);\n }\n }\n }, 50);\n });\n}\n\n/**\n * Parse a DOCX File into ProseMirror JSON using a hidden SuperDoc instance.\n */\nexport async function parseDocxFile(\n file: File,\n SuperDoc: SuperDocConstructor\n): Promise<ProseMirrorJSON> {\n // Create a hidden container for the editor\n const container = document.createElement('div');\n container.style.cssText =\n 'position:absolute;top:-9999px;left:-9999px;width:800px;height:600px;visibility:hidden;';\n document.body.appendChild(container);\n\n return new Promise((resolve, reject) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let superdoc: any = null;\n let resolved = false;\n\n const cleanup = () => {\n setTimeout(() => {\n if (superdoc) {\n try {\n const sd = superdoc;\n superdoc = null;\n sd.destroy?.();\n } catch {\n // Ignore cleanup errors\n }\n }\n if (container.parentNode) {\n container.parentNode.removeChild(container);\n }\n }, TIMEOUTS.CLEANUP_DELAY);\n };\n\n setTimeout(async () => {\n if (resolved) return;\n\n try {\n superdoc = new SuperDoc({\n selector: container,\n document: file,\n documentMode: 'viewing',\n rulers: false,\n user: { name: 'Parser', email: 'parser@local' },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onReady: ({ superdoc: sd }: { superdoc: any }) => {\n if (resolved) return;\n try {\n const editor = sd?.activeEditor;\n if (!editor) {\n throw new Error('No active editor found');\n }\n\n const json = editor.getJSON();\n resolved = true;\n cleanup();\n resolve(json);\n } catch (err) {\n resolved = true;\n cleanup();\n reject(err);\n }\n },\n onException: ({ error: err }: { error: Error }) => {\n if (resolved) return;\n resolved = true;\n cleanup();\n reject(err);\n },\n });\n\n // Timeout\n setTimeout(() => {\n if (!resolved) {\n resolved = true;\n cleanup();\n reject(new Error('Document parsing timed out'));\n }\n }, TIMEOUTS.PARSE_TIMEOUT);\n } catch (err) {\n cleanup();\n reject(err);\n }\n }, 50);\n });\n}\n","/**\n * Document Differ Service\n * Diffs two ProseMirror JSON documents at the character level,\n * including text changes and formatting changes.\n */\n\nimport DiffMatchPatch from 'diff-match-patch';\nimport type {\n ProseMirrorJSON,\n ProseMirrorMark,\n DiffSegment,\n DiffResult,\n FormatChange,\n TextSpan,\n} from '../types';\n\nconst dmp = new DiffMatchPatch();\n\n// Diff operation types\nconst DIFF_DELETE = -1;\nconst DIFF_INSERT = 1;\nconst DIFF_EQUAL = 0;\n\n/**\n * Extract text spans with their marks from a ProseMirror node.\n */\nfunction extractTextSpans(node: ProseMirrorJSON, offset: number = 0): TextSpan[] {\n const spans: TextSpan[] = [];\n\n if (!node) return spans;\n\n if (node.type === 'text' && node.text) {\n spans.push({\n text: node.text,\n from: offset,\n to: offset + node.text.length,\n marks: node.marks || [],\n });\n return spans;\n }\n\n if (node.content && Array.isArray(node.content)) {\n let currentOffset = offset;\n for (const child of node.content) {\n const childSpans = extractTextSpans(child, currentOffset);\n spans.push(...childSpans);\n // Calculate consumed length\n for (const span of childSpans) {\n currentOffset = Math.max(currentOffset, span.to);\n }\n // If no spans, check if it's a text node for offset\n if (childSpans.length === 0 && child.type === 'text' && child.text) {\n currentOffset += child.text.length;\n }\n }\n }\n\n return spans;\n}\n\n/**\n * Extract text content from a ProseMirror node recursively.\n */\nfunction extractTextContent(node: ProseMirrorJSON): string {\n if (!node) return '';\n\n if (node.type === 'text' && node.text) {\n return node.text;\n }\n\n if (node.content && Array.isArray(node.content)) {\n return node.content.map(extractTextContent).join('');\n }\n\n return '';\n}\n\n/**\n * Deep compare two values.\n */\nfunction deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (typeof a !== typeof b) return false;\n if (typeof a !== 'object' || a === null || b === null) return false;\n\n const objA = a as Record<string, unknown>;\n const objB = b as Record<string, unknown>;\n const keysA = Object.keys(objA);\n const keysB = Object.keys(objB);\n\n if (keysA.length !== keysB.length) return false;\n\n for (const key of keysA) {\n if (!keysB.includes(key)) return false;\n if (!deepEqual(objA[key], objB[key])) return false;\n }\n\n return true;\n}\n\n/**\n * Compare marks arrays to check if they're equivalent.\n */\nfunction marksEqual(marksA: ProseMirrorMark[], marksB: ProseMirrorMark[]): boolean {\n if (marksA.length !== marksB.length) return false;\n\n // Sort by type for consistent comparison\n const sortedA = [...marksA].sort((a, b) => (a.type || '').localeCompare(b.type || ''));\n const sortedB = [...marksB].sort((a, b) => (a.type || '').localeCompare(b.type || ''));\n\n return deepEqual(sortedA, sortedB);\n}\n\n/**\n * Get marks at a specific character position from spans.\n */\nfunction getMarksAtPosition(spans: TextSpan[], pos: number): ProseMirrorMark[] {\n for (const span of spans) {\n if (pos >= span.from && pos < span.to) {\n return span.marks;\n }\n }\n return [];\n}\n\n/**\n * Check if marks have any defined (non-undefined/null) attribute values.\n * Returns false if marks array is empty or all marks have only undefined attrs.\n */\nfunction hasDefinedAttributes(marks: ProseMirrorMark[]): boolean {\n if (!marks || marks.length === 0) return false;\n\n for (const mark of marks) {\n // Marks without attrs (like simple bold/italic) are considered defined\n if (!mark.attrs) continue;\n\n for (const value of Object.values(mark.attrs)) {\n if (value !== undefined && value !== null) {\n return true;\n }\n }\n }\n\n // If we only have marks without attrs, they count as defined\n return marks.some((m) => !m.attrs);\n}\n\n/**\n * Detect format changes on equal text segments.\n */\nfunction detectFormatChanges(\n spansA: TextSpan[],\n spansB: TextSpan[],\n segments: DiffSegment[]\n): FormatChange[] {\n const formatChanges: FormatChange[] = [];\n\n let posA = 0;\n let posB = 0;\n\n for (const segment of segments) {\n if (segment.type === 'equal') {\n // For equal text, compare marks character by character\n // Group consecutive chars with same mark difference\n let i = 0;\n while (i < segment.text.length) {\n const marksA = getMarksAtPosition(spansA, posA + i);\n const marksB = getMarksAtPosition(spansB, posB + i);\n\n if (!marksEqual(marksA, marksB)) {\n // Found a format difference - find the extent\n const startI = i;\n const startMarksA = marksA;\n const startMarksB = marksB;\n\n // Extend while marks remain the same different pattern\n while (i < segment.text.length) {\n const currentMarksA = getMarksAtPosition(spansA, posA + i);\n const currentMarksB = getMarksAtPosition(spansB, posB + i);\n\n if (marksEqual(currentMarksA, startMarksA) && marksEqual(currentMarksB, startMarksB)) {\n i++;\n } else {\n break;\n }\n }\n\n // Skip format changes where \"after\" marks have no defined values\n // This avoids showing \"changed to undefined\" for missing styles\n if (hasDefinedAttributes(startMarksB) || hasDefinedAttributes(startMarksA)) {\n // Only record if at least one side has meaningful values\n // and the \"after\" side isn't just undefined values\n if (hasDefinedAttributes(startMarksB)) {\n formatChanges.push({\n from: posA + startI,\n to: posA + i,\n text: segment.text.substring(startI, i),\n before: startMarksA,\n after: startMarksB,\n });\n }\n }\n } else {\n i++;\n }\n }\n\n posA += segment.text.length;\n posB += segment.text.length;\n } else if (segment.type === 'delete') {\n // Deleted text exists only in docA, so only advance posA\n posA += segment.text.length;\n } else if (segment.type === 'insert') {\n // Inserted text exists only in docB, so only advance posB\n posB += segment.text.length;\n }\n }\n\n return formatChanges;\n}\n\n/**\n * Diff two ProseMirror JSON documents at the character level.\n * Detects both text changes and formatting changes.\n * \n * Now also tracks positions in both documents for mark preservation:\n * - posA: position in docA (for equal/delete segments)\n * - posB: position in docB (for equal/insert segments)\n */\nexport function diffDocuments(\n docA: ProseMirrorJSON,\n docB: ProseMirrorJSON\n): DiffResult {\n // Extract full text from both documents\n const textA = extractTextContent(docA);\n const textB = extractTextContent(docB);\n\n // Perform character-level diff on the entire document\n const diffs = dmp.diff_main(textA, textB);\n dmp.diff_cleanupSemantic(diffs);\n\n // Convert to our DiffSegment format with position tracking\n const segments: DiffSegment[] = [];\n let insertCount = 0;\n let deleteCount = 0;\n \n // Track positions in both documents\n let posA = 0;\n let posB = 0;\n\n for (const [op, text] of diffs) {\n if (op === DIFF_EQUAL) {\n // Equal segments exist in both documents\n segments.push({ type: 'equal', text, posA, posB });\n posA += text.length;\n posB += text.length;\n } else if (op === DIFF_INSERT) {\n // Inserted text exists only in docB\n segments.push({ type: 'insert', text, posB });\n posB += text.length;\n insertCount++;\n } else if (op === DIFF_DELETE) {\n // Deleted text exists only in docA\n segments.push({ type: 'delete', text, posA });\n posA += text.length;\n deleteCount++;\n }\n }\n\n // Extract text spans with marks for format comparison\n const spansA = extractTextSpans(docA);\n const spansB = extractTextSpans(docB);\n\n // Detect format changes on equal segments\n const formatChanges = detectFormatChanges(spansA, spansB, segments);\n\n // Build summary\n const summary: string[] = [];\n if (insertCount > 0) {\n summary.push(`${insertCount} insertion(s)`);\n }\n if (deleteCount > 0) {\n summary.push(`${deleteCount} deletion(s)`);\n }\n if (formatChanges.length > 0) {\n summary.push(`${formatChanges.length} format change(s)`);\n }\n if (insertCount === 0 && deleteCount === 0 && formatChanges.length === 0) {\n summary.push('No changes detected');\n }\n\n return {\n segments,\n formatChanges,\n textA,\n textB,\n summary,\n spansB, // Include docB spans for mark preservation during merge\n };\n}\n\n","/**\n * Change Context Extractor\n * Extracts enriched changes with semantic context from merged document.\n * Provides surrounding text so the LLM can understand what the change is about.\n * \n * Updated to include structural change information (tables, lists, images).\n */\n\nimport type {\n ProseMirrorJSON,\n ProseMirrorNode,\n EnrichedChange,\n ChangeLocation,\n TraversalContext,\n StructuralChangeInfo,\n StructuralChangeType,\n} from '../types';\n\n/**\n * Extended traversal context with table/list tracking\n */\ninterface ExtendedContext extends TraversalContext {\n tableIndex?: number;\n rowIndex?: number;\n cellIndex?: number;\n listIndex?: number;\n listItemIndex?: number;\n listDepth?: number;\n}\n\n/**\n * Main entry point - extract enriched changes from merged document\n */\nexport function extractEnrichedChanges(mergedJson: ProseMirrorJSON): EnrichedChange[] {\n const changes: EnrichedChange[] = [];\n const context: ExtendedContext = {\n currentSection: null,\n currentParagraphText: '',\n currentNodeType: 'unknown',\n tableIndex: 0,\n listIndex: 0,\n listDepth: 0,\n };\n\n traverseDocument(mergedJson, context, changes);\n return groupReplacements(changes);\n}\n\n/**\n * Extract enriched changes with structural change infos included.\n * This merges inline text changes with structural change metadata.\n */\nexport function extractEnrichedChangesWithStructural(\n mergedJson: ProseMirrorJSON,\n structuralInfos: StructuralChangeInfo[]\n): EnrichedChange[] {\n // Get inline text changes\n const textChanges = extractEnrichedChanges(mergedJson);\n\n // Convert structural infos to enriched changes\n const structuralChanges: EnrichedChange[] = structuralInfos.map((info) => {\n const location = buildLocationFromStructural(info);\n \n return {\n type: info.type.includes('Insert') ? 'insertion' : 'deletion',\n text: info.preview,\n location,\n surroundingText: info.preview,\n structuralType: info.type,\n charCount: info.preview.length,\n };\n });\n\n // Combine and sort (structural changes typically more significant)\n return [...structuralChanges, ...textChanges];\n}\n\n/**\n * Build location from structural change info\n */\nfunction buildLocationFromStructural(info: StructuralChangeInfo): ChangeLocation {\n const nodeType = mapNodeTypeToLocation(info.nodeType);\n \n return {\n nodeType,\n description: info.location,\n sectionTitle: undefined,\n };\n}\n\n/**\n * Map node types to ChangeLocation nodeType\n */\nfunction mapNodeTypeToLocation(nodeType: string): ChangeLocation['nodeType'] {\n switch (nodeType) {\n case 'tableRow':\n case 'tableCell':\n case 'table':\n return 'table';\n case 'listItem':\n return 'listItem';\n case 'paragraph':\n return 'paragraph';\n case 'heading':\n return 'heading';\n case 'image':\n return 'image';\n default:\n return 'unknown';\n }\n}\n\n/**\n * Recursively walk the document tree\n */\nfunction traverseDocument(\n node: ProseMirrorNode,\n context: ExtendedContext,\n changes: EnrichedChange[]\n): void {\n if (!node) return;\n\n // Update context based on node type\n if (node.type === 'heading') {\n context.currentSection = extractAllText(node);\n context.headingLevel = node.attrs?.level || 1;\n context.currentNodeType = 'heading';\n context.currentParagraphText = context.currentSection;\n } else if (node.type === 'paragraph') {\n context.currentNodeType = 'paragraph';\n context.currentParagraphText = extractAllText(node);\n } else if (node.type === 'listItem') {\n context.currentNodeType = 'listItem';\n context.currentParagraphText = extractAllText(node);\n context.listItemIndex = (context.listItemIndex || 0) + 1;\n } else if (node.type === 'tableCell' || node.type === 'tableHeader') {\n context.currentNodeType = 'tableCell';\n context.currentParagraphText = extractAllText(node);\n context.cellIndex = (context.cellIndex || 0) + 1;\n } else if (node.type === 'tableRow') {\n context.rowIndex = (context.rowIndex || 0) + 1;\n context.cellIndex = 0;\n } else if (node.type === 'table') {\n context.tableIndex = (context.tableIndex || 0) + 1;\n context.rowIndex = 0;\n } else if (node.type === 'bulletList' || node.type === 'orderedList') {\n context.listIndex = (context.listIndex || 0) + 1;\n context.listItemIndex = 0;\n context.listDepth = (context.listDepth || 0) + 1;\n }\n\n // Check for track change marks on text nodes\n if (node.type === 'text' && node.marks) {\n const trackMark = findTrackChangeMark(node.marks);\n if (trackMark) {\n const change = createEnrichedChange(node, trackMark, context);\n if (change) changes.push(change);\n }\n }\n\n // Recurse into children\n if (node.content && Array.isArray(node.content)) {\n for (const child of node.content) {\n traverseDocument(child, context, changes);\n }\n }\n\n // Reset depth counters when exiting lists\n if (node.type === 'bulletList' || node.type === 'orderedList') {\n context.listDepth = Math.max(0, (context.listDepth || 1) - 1);\n }\n}\n\n/**\n * Extract ALL text from a node (including deleted text, for context)\n */\nfunction extractAllText(node: ProseMirrorNode): string {\n if (!node) return '';\n if (node.type === 'text') {\n return node.text || '';\n }\n if (node.content && Array.isArray(node.content)) {\n return node.content.map(extractAllText).join('');\n }\n return '';\n}\n\n/**\n * Find trackInsert, trackDelete, or trackFormat mark\n */\nfunction findTrackChangeMark(marks: ProseMirrorNode[]): ProseMirrorNode | null {\n return (\n marks.find(\n (m) =>\n m.type === 'trackInsert' || m.type === 'trackDelete' || m.type === 'trackFormat'\n ) || null\n );\n}\n\n/**\n * Create enriched change from node and track mark\n */\nfunction createEnrichedChange(\n node: ProseMirrorNode,\n trackMark: ProseMirrorNode,\n context: ExtendedContext\n): EnrichedChange | null {\n const text = node.text || '';\n const location = buildLocation(context);\n const surroundingText = extractSurroundingSentence(text, context.currentParagraphText);\n\n // Add table/list position info if applicable\n const tablePosition = context.currentNodeType === 'tableCell' && context.rowIndex !== undefined\n ? { row: context.rowIndex, column: context.cellIndex || 0 }\n : undefined;\n \n const listPosition = context.currentNodeType === 'listItem' && context.listItemIndex !== undefined\n ? { index: context.listItemIndex, depth: context.listDepth || 0 }\n : undefined;\n\n if (trackMark.type === 'trackInsert') {\n return {\n type: 'insertion',\n text,\n location,\n surroundingText,\n charCount: text.length,\n tablePosition,\n listPosition,\n };\n }\n\n if (trackMark.type === 'trackDelete') {\n return {\n type: 'deletion',\n text,\n location,\n surroundingText,\n charCount: text.length,\n tablePosition,\n listPosition,\n };\n }\n\n if (trackMark.type === 'trackFormat') {\n const before = trackMark.attrs?.before || [];\n const after = trackMark.attrs?.after || [];\n return {\n type: 'format',\n text,\n location,\n surroundingText,\n formatDetails: {\n added: after\n .map((m: ProseMirrorNode) => m.type)\n .filter((t: string) => !before.some((b: ProseMirrorNode) => b.type === t)),\n removed: before\n .map((m: ProseMirrorNode) => m.type)\n .filter((t: string) => !after.some((a: ProseMirrorNode) => a.type === t)),\n },\n charCount: text.length,\n tablePosition,\n listPosition,\n };\n }\n\n return null;\n}\n\n/**\n * Extract the sentence or clause containing the changed text\n */\nfunction extractSurroundingSentence(changedText: string, paragraphText: string): string {\n if (!paragraphText || !changedText) return '';\n\n // Find where the change is in the paragraph\n const changeIndex = paragraphText.indexOf(changedText);\n if (changeIndex === -1) {\n // If exact match not found, return truncated paragraph\n return truncate(paragraphText, 150);\n }\n\n // Split into sentences (by period, semicolon, or significant punctuation)\n // But keep the delimiters for context\n const sentenceBreaks = /([.;!?]\\s+)/g;\n const sentences: { text: string; start: number; end: number }[] = [];\n\n let lastEnd = 0;\n let match;\n\n while ((match = sentenceBreaks.exec(paragraphText)) !== null) {\n sentences.push({\n text: paragraphText.slice(lastEnd, match.index + match[0].length).trim(),\n start: lastEnd,\n end: match.index + match[0].length,\n });\n lastEnd = match.index + match[0].length;\n }\n\n // Add remaining text as final sentence\n if (lastEnd < paragraphText.length) {\n sentences.push({\n text: paragraphText.slice(lastEnd).trim(),\n start: lastEnd,\n end: paragraphText.length,\n });\n }\n\n // Find which sentence contains the change\n const changeEnd = changeIndex + changedText.length;\n for (const sentence of sentences) {\n if (changeIndex >= sentence.start && changeIndex < sentence.end) {\n // Found it - return this sentence (truncated if too long)\n return truncate(sentence.text, 200);\n }\n }\n\n // Fallback: return a window around the change\n const windowSize = 100;\n const start = Math.max(0, changeIndex - windowSize);\n const end = Math.min(paragraphText.length, changeEnd + windowSize);\n\n let result = paragraphText.slice(start, end);\n if (start > 0) result = '...' + result;\n if (end < paragraphText.length) result = result + '...';\n\n return result;\n}\n\n/**\n * Truncate text with ellipsis\n */\nfunction truncate(text: string, maxLen: number): string {\n if (!text) return '';\n const cleaned = text.replace(/\\s+/g, ' ').trim();\n if (cleaned.length <= maxLen) return cleaned;\n return cleaned.slice(0, maxLen - 3).trim() + '...';\n}\n\n/**\n * Build location info\n */\nfunction buildLocation(context: ExtendedContext): ChangeLocation {\n const nodeType = context.currentNodeType as ChangeLocation['nodeType'];\n\n let description: string;\n if (nodeType === 'heading') {\n description = context.headingLevel === 1 ? 'document title' : 'section heading';\n } else if (nodeType === 'tableCell' && context.tableIndex !== undefined) {\n const colLetter = String.fromCharCode(65 + (context.cellIndex || 0));\n description = `Table ${context.tableIndex}, Cell ${colLetter}${context.rowIndex || 1}`;\n } else if (nodeType === 'listItem' && context.listIndex !== undefined) {\n const depthStr = (context.listDepth || 0) > 1 ? ` (nested, level ${context.listDepth})` : '';\n description = `List ${context.listIndex}, Item ${context.listItemIndex || 1}${depthStr}`;\n } else if (context.currentSection) {\n description = `\"${truncate(context.currentSection, 50)}\" section`;\n } else {\n description = 'document body';\n }\n\n // Add table/list coordinates to location\n const tableCoords = context.currentNodeType === 'tableCell' && context.rowIndex !== undefined\n ? { row: context.rowIndex, column: context.cellIndex || 0 }\n : undefined;\n\n return {\n nodeType,\n headingLevel: context.headingLevel,\n sectionTitle: context.currentSection || undefined,\n description,\n tableCoords,\n listIndex: context.currentNodeType === 'listItem' ? context.listItemIndex : undefined,\n listDepth: context.currentNodeType === 'listItem' ? context.listDepth : undefined,\n };\n}\n\n/**\n * Combine adjacent delete+insert into replacements\n */\nfunction groupReplacements(changes: EnrichedChange[]): EnrichedChange[] {\n const result: EnrichedChange[] = [];\n let i = 0;\n\n while (i < changes.length) {\n const current = changes[i];\n const next = changes[i + 1];\n\n // Check if delete followed by insert (same section = likely replacement)\n if (\n current.type === 'deletion' &&\n next?.type === 'insertion' &&\n current.location.sectionTitle === next.location.sectionTitle\n ) {\n result.push({\n type: 'replacement',\n oldText: current.text,\n newText: next.text,\n location: current.location,\n surroundingText: current.surroundingText || next.surroundingText,\n charCount: (current.charCount || 0) + (next.charCount || 0),\n });\n i += 2;\n } else {\n result.push(current);\n i++;\n }\n }\n\n return result;\n}\n\n","/**\n * Node Aligner Service\n * \n * Aligns nodes between two documents using fingerprints and LCS algorithm.\n * Produces matched pairs, insertions, and deletions.\n */\n\nimport type { ProseMirrorJSON, FingerprintedNode, NodeMatch } from '../types';\nimport {\n extractBlockFingerprints,\n calculateSimilarity,\n getNodeTextSimilarity,\n} from './nodeFingerprint';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Result of aligning two node sequences\n */\nexport interface AlignmentResult {\n /** Nodes that match between documents */\n matched: NodeMatch[];\n /** Nodes only in document A (deleted) */\n deletions: FingerprintedNode[];\n /** Nodes only in document B (inserted) */\n insertions: FingerprintedNode[];\n}\n\n// ============================================================================\n// Configuration\n// ============================================================================\n\n/** Minimum similarity threshold for fuzzy matching */\nconst SIMILARITY_THRESHOLD = 0.7;\n\n// ============================================================================\n// LCS-Based Alignment\n// ============================================================================\n\n/**\n * Find the Longest Common Subsequence of two fingerprint arrays.\n * Returns indices of matched elements.\n */\nfunction findLCS(seqA: string[], seqB: string[]): [number, number][] {\n const m = seqA.length;\n const n = seqB.length;\n\n // Build LCS length table\n const dp: number[][] = Array.from({ length: m + 1 }, () =>\n Array(n + 1).fill(0)\n );\n\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n if (seqA[i - 1] === seqB[j - 1]) {\n dp[i][j] = dp[i - 1][j - 1] + 1;\n } else {\n dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);\n }\n }\n }\n\n // Backtrack to find the actual LCS\n const result: [number, number][] = [];\n let i = m;\n let j = n;\n\n while (i > 0 && j > 0) {\n if (seqA[i - 1] === seqB[j - 1]) {\n result.unshift([i - 1, j - 1]);\n i--;\n j--;\n } else if (dp[i - 1][j] > dp[i][j - 1]) {\n i--;\n } else {\n j--;\n }\n }\n\n return result;\n}\n\n/**\n * Find fuzzy matches for unmatched nodes.\n * Uses text similarity to find partial matches.\n */\nfunction findFuzzyMatches(\n unmatchedA: FingerprintedNode[],\n unmatchedB: FingerprintedNode[],\n threshold: number = SIMILARITY_THRESHOLD\n): { matches: [FingerprintedNode, FingerprintedNode, number][]; remainingA: FingerprintedNode[]; remainingB: FingerprintedNode[] } {\n const matches: [FingerprintedNode, FingerprintedNode, number][] = [];\n const usedA = new Set<number>();\n const usedB = new Set<number>();\n\n // Build similarity matrix\n const similarities: { i: number; j: number; sim: number }[] = [];\n \n for (let i = 0; i < unmatchedA.length; i++) {\n for (let j = 0; j < unmatchedB.length; j++) {\n // Quick check: same type prefix?\n const fpSim = calculateSimilarity(unmatchedA[i].fingerprint, unmatchedB[j].fingerprint);\n if (fpSim === 0) continue;\n\n // Calculate text similarity\n const textSim = getNodeTextSimilarity(unmatchedA[i].node, unmatchedB[j].node);\n if (textSim >= threshold) {\n similarities.push({ i, j, sim: textSim });\n }\n }\n }\n\n // Sort by similarity (highest first) and greedily match\n similarities.sort((a, b) => b.sim - a.sim);\n\n for (const { i, j, sim } of similarities) {\n if (!usedA.has(i) && !usedB.has(j)) {\n matches.push([unmatchedA[i], unmatchedB[j], sim]);\n usedA.add(i);\n usedB.add(j);\n }\n }\n\n // Collect remaining unmatched\n const remainingA = unmatchedA.filter((_, i) => !usedA.has(i));\n const remainingB = unmatchedB.filter((_, j) => !usedB.has(j));\n\n return { matches, remainingA, remainingB };\n}\n\n/**\n * Align two sequences of fingerprinted nodes.\n * Uses LCS for exact matches, then fuzzy matching for similar nodes.\n */\nexport function alignNodes(\n nodesA: FingerprintedNode[],\n nodesB: FingerprintedNode[]\n): AlignmentResult {\n // Extract fingerprints\n const fpsA = nodesA.map((n) => n.fingerprint);\n const fpsB = nodesB.map((n) => n.fingerprint);\n\n // Find exact matches using LCS\n const lcsMatches = findLCS(fpsA, fpsB);\n const matchedIndicesA = new Set(lcsMatches.map(([i]) => i));\n const matchedIndicesB = new Set(lcsMatches.map(([, j]) => j));\n\n // Build matched pairs from LCS\n const matched: NodeMatch[] = lcsMatches.map(([i, j]) => ({\n pathA: nodesA[i].path,\n pathB: nodesB[j].path,\n fingerprint: nodesA[i].fingerprint,\n similarity: 1.0, // Exact match\n }));\n\n // Collect unmatched nodes\n const unmatchedA = nodesA.filter((_, i) => !matchedIndicesA.has(i));\n const unmatchedB = nodesB.filter((_, j) => !matchedIndicesB.has(j));\n\n // Try fuzzy matching on unmatched nodes\n const { matches: fuzzyMatches, remainingA, remainingB } = findFuzzyMatches(\n unmatchedA,\n unmatchedB\n );\n\n // Add fuzzy matches\n for (const [nodeA, nodeB, similarity] of fuzzyMatches) {\n matched.push({\n pathA: nodeA.path,\n pathB: nodeB.path,\n fingerprint: nodeA.fingerprint,\n similarity,\n });\n }\n\n return {\n matched,\n deletions: remainingA,\n insertions: remainingB,\n };\n}\n\n/**\n * Align top-level blocks between two documents.\n */\nexport function alignDocuments(\n docA: ProseMirrorJSON,\n docB: ProseMirrorJSON\n): AlignmentResult {\n const blocksA = extractBlockFingerprints(docA);\n const blocksB = extractBlockFingerprints(docB);\n\n return alignNodes(blocksA, blocksB);\n}\n\n/**\n * Align children of two matched nodes.\n * Used for recursive alignment (e.g., table rows, list items).\n */\nexport function alignChildren(\n nodeA: ProseMirrorJSON,\n nodeB: ProseMirrorJSON,\n basePath: number[] = []\n): AlignmentResult {\n const childrenA = (nodeA.content || []).map((child: ProseMirrorJSON, i: number) => ({\n node: child,\n fingerprint: '', // Will be computed\n path: [...basePath, i],\n }));\n\n const childrenB = (nodeB.content || []).map((child: ProseMirrorJSON, i: number) => ({\n node: child,\n fingerprint: '', // Will be computed\n path: [...basePath, i],\n }));\n\n // Compute fingerprints\n const { generateFingerprint } = require('./nodeFingerprint');\n for (const child of childrenA) {\n child.fingerprint = generateFingerprint(child.node);\n }\n for (const child of childrenB) {\n child.fingerprint = generateFingerprint(child.node);\n }\n\n return alignNodes(childrenA, childrenB);\n}\n\n// ============================================================================\n// Table-Specific Alignment\n// ============================================================================\n\n/**\n * Align table rows between two tables.\n */\nexport function alignTableRows(\n tableA: ProseMirrorJSON,\n tableB: ProseMirrorJSON,\n tablePathA: number[],\n tablePathB: number[]\n): AlignmentResult {\n const rowsA = (tableA.content || []).map((row: ProseMirrorJSON, i: number) => ({\n node: row,\n fingerprint: '', // Will be computed\n path: [...tablePathA, i],\n }));\n\n const rowsB = (tableB.content || []).map((row: ProseMirrorJSON, i: number) => ({\n node: row,\n fingerprint: '', // Will be computed\n path: [...tablePathB, i],\n }));\n\n // Compute fingerprints\n const { generateFingerprint } = require('./nodeFingerprint');\n for (const row of rowsA) {\n row.fingerprint = generateFingerprint(row.node);\n }\n for (const row of rowsB) {\n row.fingerprint = generateFingerprint(row.node);\n }\n\n return alignNodes(rowsA, rowsB);\n}\n\n/**\n * Align table cells between two rows.\n * Cells are typically position-based, but we still check for content matches.\n */\nexport function alignTableCells(\n rowA: ProseMirrorJSON,\n rowB: ProseMirrorJSON,\n rowPathA: number[],\n rowPathB: number[]\n): AlignmentResult {\n const cellsA = (rowA.content || []).map((cell: ProseMirrorJSON, i: number) => ({\n node: cell,\n fingerprint: '', // Will be computed\n path: [...rowPathA, i],\n }));\n\n const cellsB = (rowB.content || []).map((cell: ProseMirrorJSON, i: number) => ({\n node: cell,\n fingerprint: '', // Will be computed\n path: [...rowPathB, i],\n }));\n\n // Compute fingerprints\n const { generateFingerprint } = require('./nodeFingerprint');\n for (const cell of cellsA) {\n cell.fingerprint = generateFingerprint(cell.node);\n }\n for (const cell of cellsB) {\n cell.fingerprint = generateFingerprint(cell.node);\n }\n\n // For cells, prefer position-based matching when counts are equal\n if (cellsA.length === cellsB.length) {\n const matched: NodeMatch[] = [];\n for (let i = 0; i < cellsA.length; i++) {\n const similarity = getNodeTextSimilarity(cellsA[i].node, cellsB[i].node);\n matched.push({\n pathA: cellsA[i].path,\n pathB: cellsB[i].path,\n fingerprint: cellsA[i].fingerprint,\n similarity,\n });\n }\n return { matched, deletions: [], insertions: [] };\n }\n\n // Different cell counts = use LCS-based alignment\n return alignNodes(cellsA, cellsB);\n}\n\n// ============================================================================\n// List-Specific Alignment\n// ============================================================================\n\n/**\n * Align list items between two lists.\n */\nexport function alignListItems(\n listA: ProseMirrorJSON,\n listB: ProseMirrorJSON,\n listPathA: number[],\n listPathB: number[]\n): AlignmentResult {\n const itemsA = (listA.content || []).map((item: ProseMirrorJSON, i: number) => ({\n node: item,\n fingerprint: '', // Will be computed\n path: [...listPathA, i],\n }));\n\n const itemsB = (listB.content || []).map((item: ProseMirrorJSON, i: number) => ({\n node: item,\n fingerprint: '', // Will be computed\n path: [...listPathB, i],\n }));\n\n // Compute fingerprints\n const { generateFingerprint } = require('./nodeFingerprint');\n for (const item of itemsA) {\n item.fingerprint = generateFingerprint(item.node);\n }\n for (const item of itemsB) {\n item.fingerprint = generateFingerprint(item.node);\n }\n\n return alignNodes(itemsA, itemsB);\n}\n","/**\n * Merge Documents Service\n * Applies track change marks to the original document structure\n * based on character-level diff segments.\n */\n\nimport { v4 as uuidv4 } from 'uuid';\nimport type {\n ProseMirrorJSON,\n ProseMirrorNode,\n ProseMirrorMark,\n DiffResult,\n FormatChange,\n TrackChangeAuthor,\n TextSpan,\n} from '../types';\nimport {\n createTrackInsertMark,\n createTrackDeleteMark,\n createTrackFormatMark,\n normalizeMarksForRendering,\n} from './trackChangeInjector';\nimport { DEFAULT_AUTHOR } from '../constants';\n\n/**\n * Deep clone a node\n */\nfunction cloneNode(node: ProseMirrorNode): ProseMirrorNode {\n return JSON.parse(JSON.stringify(node));\n}\n\n/**\n * Get marks from docB spans at a specific character position.\n * Used to preserve styling from the source document for inserted text.\n */\nfunction getMarksFromSpansB(spansB: TextSpan[], position: number): ProseMirrorMark[] {\n for (const span of spansB) {\n if (position >= span.from && position < span.to) {\n return span.marks || [];\n }\n }\n return [];\n}\n\n/**\n * Get mark spans that cover a range of text in docB.\n * Used when inserted text spans multiple differently-styled regions.\n */\nfunction getMarkSpansForRange(\n spansB: TextSpan[],\n start: number,\n end: number\n): { relStart: number; relEnd: number; marks: ProseMirrorMark[] }[] {\n const result: { relStart: number; relEnd: number; marks: ProseMirrorMark[] }[] = [];\n \n for (const span of spansB) {\n // Check if span overlaps with our range\n if (span.to > start && span.from < end) {\n // Calculate relative positions within the insertion range\n const overlapStart = Math.max(span.from, start);\n const overlapEnd = Math.min(span.to, end);\n \n result.push({\n relStart: overlapStart - start,\n relEnd: overlapEnd - start,\n marks: span.marks || [],\n });\n }\n }\n \n return result;\n}\n\n/**\n * Create text nodes for inserted text, preserving marks from docB.\n * \n * If the inserted text spans multiple mark regions in docB, this will\n * create multiple text nodes, each with the appropriate marks from docB\n * plus the trackInsert mark.\n * \n * @param text - The inserted text content\n * @param posB - Position in docB where this text originated (undefined if unknown)\n * @param spansB - Text spans from docB with mark information\n * @param author - Author for track change marks\n * @param replacementId - Optional shared ID for replacement operations\n * @returns Array of text nodes with preserved marks\n */\nfunction createInsertedTextNodes(\n text: string,\n posB: number | undefined,\n spansB: TextSpan[],\n author: TrackChangeAuthor,\n replacementId?: string\n): ProseMirrorNode[] {\n const result: ProseMirrorNode[] = [];\n const trackMark = createTrackInsertMark(author, replacementId);\n \n // If we don't have position info or spans, create a simple node with just trackInsert\n if (posB === undefined || spansB.length === 0) {\n return [{\n type: 'text',\n text,\n marks: [trackMark],\n }];\n }\n \n // Get all mark spans that cover this inserted text range\n const markSpans = getMarkSpansForRange(spansB, posB, posB + text.length);\n \n // If no spans found, create simple node\n if (markSpans.length === 0) {\n return [{\n type: 'text',\n text,\n marks: [trackMark],\n }];\n }\n \n // Sort spans by start position\n markSpans.sort((a, b) => a.relStart - b.relStart);\n \n // Track how much text we've processed\n let processedUpTo = 0;\n \n for (const span of markSpans) {\n // If there's a gap before this span, create a node without marks\n if (span.relStart > processedUpTo) {\n result.push({\n type: 'text',\n text: text.substring(processedUpTo, span.relStart),\n marks: [trackMark],\n });\n }\n \n // Create node with marks from docB plus trackInsert\n // Normalize marks to ensure valid CSS color format (# prefix for hex colors)\n if (span.relEnd > span.relStart) {\n const spanText = text.substring(span.relStart, span.relEnd);\n const normalizedSpanMarks = normalizeMarksForRendering(span.marks);\n const marks = [...normalizedSpanMarks, trackMark];\n \n result.push({\n type: 'text',\n text: spanText,\n marks,\n });\n processedUpTo = span.relEnd;\n }\n }\n \n // Handle any remaining text after the last span\n if (processedUpTo < text.length) {\n result.push({\n type: 'text',\n text: text.substring(processedUpTo),\n marks: [trackMark],\n });\n }\n \n return result;\n}\n\n/**\n * Character state during merge\n */\ninterface CharState {\n type: 'equal' | 'delete' | 'insert';\n insertText?: string;\n /** Shared ID for replacement operations (delete + insert at same position) */\n replacementId?: string;\n}\n\n/**\n * Insertion point during merge\n */\ninterface Insertion {\n afterOffset: number;\n text: string;\n /** Shared ID for replacement operations (delete + insert at same position) */\n replacementId?: string;\n /** Position in docB where this inserted text originated (for mark lookup) */\n posB?: number;\n}\n\n/**\n * Build a merged document by applying diff segments to the original structure.\n *\n * Strategy:\n * 1. Clone docA (original)\n * 2. Walk through diff segments\n * 3. For 'equal' segments: keep original content as-is\n * 4. For 'delete' segments: add trackDelete mark to the corresponding text\n * 5. For 'insert' segments: insert new text nodes with trackInsert mark\n */\nexport function mergeDocuments(\n docA: ProseMirrorNode,\n docB: ProseMirrorNode,\n diffResult: DiffResult,\n author: TrackChangeAuthor = DEFAULT_AUTHOR\n): ProseMirrorNode {\n // Clone the original document\n const merged = cloneNode(docA);\n\n // Build a map of character offset -> segment type\n // This tells us for each character what its state is\n const charStates: CharState[] = [];\n let insertions: Insertion[] = [];\n\n // Store format changes as array for range lookups\n const formatChanges: FormatChange[] = diffResult.formatChanges || [];\n\n // Helper to find format change at a position\n function getFormatChangeAt(pos: number): FormatChange | null {\n for (const fc of formatChanges) {\n if (pos >= fc.from && pos < fc.to) {\n return fc;\n }\n }\n return null;\n }\n\n let docAOffset = 0;\n const segments = diffResult.segments;\n \n for (let segIdx = 0; segIdx < segments.length; segIdx++) {\n const segment = segments[segIdx];\n \n if (segment.type === 'equal') {\n // Mark these characters as equal\n for (let i = 0; i < segment.text.length; i++) {\n charStates[docAOffset + i] = { type: 'equal' };\n }\n docAOffset += segment.text.length;\n } else if (segment.type === 'delete') {\n // Check if next segment is an insert (replacement pattern)\n const nextSegment = segments[segIdx + 1];\n const isReplacement = nextSegment && nextSegment.type === 'insert';\n const replacementId = isReplacement ? uuidv4() : undefined;\n \n // Mark these characters as deleted\n for (let i = 0; i < segment.text.length; i++) {\n charStates[docAOffset + i] = { type: 'delete', replacementId };\n }\n docAOffset += segment.text.length;\n \n // If this is a replacement, process the insert segment now with the same ID\n if (isReplacement && nextSegment) {\n insertions.push({\n afterOffset: docAOffset,\n text: nextSegment.text,\n replacementId,\n posB: nextSegment.posB, // Capture docB position for mark lookup\n });\n segIdx++; // Skip the next segment since we processed it here\n }\n } else if (segment.type === 'insert') {\n // Standalone insert (not part of a replacement)\n insertions.push({\n afterOffset: docAOffset,\n text: segment.text,\n posB: segment.posB, // Capture docB position for mark lookup\n });\n }\n }\n\n // Get docB spans for mark preservation (if available)\n const spansB = diffResult.spansB || [];\n\n // Now we need to transform the document\n // For each text span in the original:\n // 1. Split it based on character states (equal vs delete)\n // 2. Apply trackDelete marks to deleted parts\n // 3. Insert new content where insertions occur\n\n function transformNode(\n node: ProseMirrorNode,\n nodeOffset: number,\n path: number[]\n ): { nodes: ProseMirrorNode[]; consumedLength: number } {\n if (node.type === 'text' && node.text) {\n const text = node.text;\n const result: ProseMirrorNode[] = [];\n let i = 0;\n\n while (i < text.length) {\n const charOffset = nodeOffset + i;\n const charState = charStates[charOffset] || { type: 'equal' };\n\n // Check for insertions at this position\n const insertionsHere = insertions.filter((ins) => ins.afterOffset === charOffset);\n for (const ins of insertionsHere) {\n // Create inserted text nodes, preserving marks from docB\n const insertedNodes = createInsertedTextNodes(\n ins.text,\n ins.posB,\n spansB,\n author,\n ins.replacementId\n );\n result.push(...insertedNodes);\n }\n\n // Find run of same state AND same format change status\n const currentFormatChange = getFormatChangeAt(nodeOffset + i);\n let j = i + 1;\n while (j < text.length) {\n const nextState = charStates[nodeOffset + j] || { type: 'equal' };\n if (nextState.type !== charState.type) break;\n // Also break if there's an insertion point here\n if (insertions.some((ins) => ins.afterOffset === nodeOffset + j)) break;\n // Break if format change status changes\n const nextFormatChange = getFormatChangeAt(nodeOffset + j);\n if (currentFormatChange !== nextFormatChange) break;\n j++;\n }\n\n const chunk = text.substring(i, j);\n let marks = [...(node.marks || [])];\n\n if (charState.type === 'delete') {\n marks.push(createTrackDeleteMark(author, charState.replacementId));\n } else if (charState.type === 'equal') {\n // Check if there's a format change at this position\n if (currentFormatChange) {\n // For format changes, use the NEW marks (after) plus trackFormat\n // Note: createTrackFormatMark already normalizes before/after marks\n const trackFormatMark = createTrackFormatMark(\n currentFormatChange.before,\n currentFormatChange.after,\n author\n );\n // Normalize the after marks to ensure valid CSS color format\n const normalizedAfterMarks = normalizeMarksForRendering(currentFormatChange.after);\n marks = [...normalizedAfterMarks, trackFormatMark];\n }\n }\n\n result.push({\n type: 'text',\n text: chunk,\n marks: marks.length > 0 ? marks : undefined,\n });\n\n i = j;\n }\n\n // Check for insertions at the end of this text node\n const endOffset = nodeOffset + text.length;\n const endInsertions = insertions.filter((ins) => ins.afterOffset === endOffset);\n for (const ins of endInsertions) {\n // Create inserted text nodes, preserving marks from docB\n const insertedNodes = createInsertedTextNodes(\n ins.text,\n ins.posB,\n spansB,\n author,\n ins.replacementId\n );\n result.push(...insertedNodes);\n }\n\n // Remove processed insertions\n insertions = insertions.filter(\n (ins) => ins.afterOffset < nodeOffset || ins.afterOffset > endOffset\n );\n\n return { nodes: result, consumedLength: text.length };\n }\n\n // Non-text node: recursively transform children\n if (node.content && Array.isArray(node.content)) {\n const newContent: ProseMirrorNode[] = [];\n let offset = nodeOffset;\n\n for (const child of node.content) {\n const { nodes, consumedLength } = transformNode(child, offset, path);\n newContent.push(...nodes);\n offset += consumedLength;\n }\n\n return {\n nodes: [{ ...node, content: newContent }],\n consumedLength: offset - nodeOffset,\n };\n }\n\n // Node without content (like hard break)\n return { nodes: [node], consumedLength: 0 };\n }\n\n // Transform the document content\n if (merged.content && Array.isArray(merged.content)) {\n const newContent: ProseMirrorNode[] = [];\n let offset = 0;\n\n for (let i = 0; i < merged.content.length; i++) {\n const child = merged.content[i];\n const { nodes, consumedLength } = transformNode(child, offset, [i]);\n newContent.push(...nodes);\n offset += consumedLength;\n }\n\n merged.content = newContent;\n }\n\n // Handle any remaining insertions (at the very end)\n if (insertions.length > 0) {\n for (const ins of insertions) {\n // Create text nodes with preserved marks from docB\n const insertedNodes = createInsertedTextNodes(\n ins.text,\n ins.posB,\n spansB,\n author,\n ins.replacementId\n );\n \n const insertNode = {\n type: 'paragraph',\n content: [\n {\n type: 'run',\n content: insertedNodes,\n },\n ],\n };\n if (!merged.content) merged.content = [];\n merged.content.push(insertNode);\n }\n }\n\n return merged;\n}\n\n/**\n * Export for compatibility\n */\nexport function createSimpleMergedDocument(\n docA: ProseMirrorNode,\n docB: ProseMirrorNode,\n diffResult: DiffResult,\n author: TrackChangeAuthor = DEFAULT_AUTHOR\n): ProseMirrorNode {\n return mergeDocuments(docA, docB, diffResult, author);\n}\n\n","/**\n * Attribute Comparer Service\n * \n * Deep comparison of node attributes to detect style/formatting changes.\n * Handles nested objects and default value normalization.\n */\n\nimport type { AttrDiff } from '../types';\n\n// ============================================================================\n// Types\n// ============================================================================\n\ntype AttrValue = unknown;\ntype AttrObject = Record<string, AttrValue>;\n\n// ============================================================================\n// Default Values\n// ============================================================================\n\n/**\n * Known default values for common ProseMirror node attributes.\n * Used to normalize comparisons (e.g., missing attr vs explicit default).\n */\nconst KNOWN_DEFAULTS: Record<string, Record<string, AttrValue>> = {\n paragraph: {\n textAlign: 'left',\n indent: 0,\n lineSpacing: 1,\n },\n heading: {\n level: 1,\n textAlign: 'left',\n },\n table: {\n alignment: 'left',\n borderStyle: 'single',\n },\n tableCell: {\n verticalAlign: 'top',\n colspan: 1,\n rowspan: 1,\n },\n listItem: {\n indent: 0,\n },\n image: {\n width: 'auto',\n height: 'auto',\n },\n};\n\n/**\n * Attributes to ignore during comparison.\n * These are internal/computed values that don't represent user changes.\n */\nconst IGNORED_ATTRS = new Set([\n 'id',\n 'class',\n 'data-id',\n 'data-pm-slice',\n '__trackAttrChanges',\n]);\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * Check if a value is a plain object (not array, null, etc.).\n */\nfunction isPlainObject(value: unknown): value is AttrObject {\n return (\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n Object.prototype.toString.call(value) === '[object Object]'\n );\n}\n\n/**\n * Check if two values are deeply equal.\n */\nfunction deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (typeof a !== typeof b) return false;\n if (a === null || b === null) return a === b;\n\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false;\n return a.every((val, i) => deepEqual(val, b[i]));\n }\n\n if (isPlainObject(a) && isPlainObject(b)) {\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n if (keysA.length !== keysB.length) return false;\n return keysA.every((key) => deepEqual(a[key], b[key]));\n }\n\n return false;\n}\n\n/**\n * Normalize an attribute value using known defaults.\n * Returns the default value if the input is undefined/null.\n */\nfunction normalizeValue(\n value: AttrValue,\n key: string,\n nodeType: string\n): AttrValue {\n if (value !== undefined && value !== null) {\n return value;\n }\n\n // Look up default\n const defaults = KNOWN_DEFAULTS[nodeType];\n if (defaults && key in defaults) {\n return defaults[key];\n }\n\n return value;\n}\n\n/**\n * Format a value for display in diff output.\n */\nfunction formatValue(value: unknown): string {\n if (value === undefined) return 'undefined';\n if (value === null) return 'null';\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean') {\n return String(value);\n }\n return JSON.stringify(value);\n}\n\n// ============================================================================\n// Comparison Functions\n// ============================================================================\n\n/**\n * Compare two attribute objects and return differences.\n * \n * @param attrsA - Attributes from original node\n * @param attrsB - Attributes from new node\n * @param nodeType - Type of node (for default normalization)\n * @param prefix - Key prefix for nested comparisons\n * @returns Array of attribute differences\n */\nexport function compareAttrs(\n attrsA: AttrObject | undefined,\n attrsB: AttrObject | undefined,\n nodeType: string = '',\n prefix: string = ''\n): AttrDiff[] {\n const diffs: AttrDiff[] = [];\n \n const a = attrsA || {};\n const b = attrsB || {};\n\n // Collect all keys from both objects\n const allKeys = new Set([...Object.keys(a), ...Object.keys(b)]);\n\n for (const key of allKeys) {\n // Skip ignored attributes\n if (IGNORED_ATTRS.has(key)) continue;\n\n const fullKey = prefix ? `${prefix}.${key}` : key;\n const valueA = normalizeValue(a[key], key, nodeType);\n const valueB = normalizeValue(b[key], key, nodeType);\n\n // If both are objects, recurse\n if (isPlainObject(valueA) && isPlainObject(valueB)) {\n const nestedDiffs = compareAttrs(\n valueA as AttrObject,\n valueB as AttrObject,\n nodeType,\n fullKey\n );\n diffs.push(...nestedDiffs);\n continue;\n }\n\n // Compare values\n if (!deepEqual(valueA, valueB)) {\n diffs.push({\n key: fullKey,\n before: valueA,\n after: valueB,\n });\n }\n }\n\n return diffs;\n}\n\n/**\n * Compare attributes of two nodes and return differences.\n * Convenience wrapper that extracts attrs from nodes.\n */\nexport function compareNodeAttrs(\n nodeA: { type?: string; attrs?: AttrObject },\n nodeB: { type?: string; attrs?: AttrObject }\n): AttrDiff[] {\n const nodeType = nodeA.type || nodeB.type || '';\n return compareAttrs(nodeA.attrs, nodeB.attrs, nodeType);\n}\n\n/**\n * Check if two nodes have different attributes.\n */\nexport function hasAttrChanges(\n nodeA: { type?: string; attrs?: AttrObject },\n nodeB: { type?: string; attrs?: AttrObject }\n): boolean {\n const diffs = compareNodeAttrs(nodeA, nodeB);\n return diffs.length > 0;\n}\n\n// ============================================================================\n// Formatting Functions\n// ============================================================================\n\n/**\n * Format attribute differences for display.\n * Returns human-readable strings like \"Border: black → blue\".\n */\nexport function formatAttrDiffs(diffs: AttrDiff[]): string[] {\n return diffs.map((diff) => {\n const before = formatValue(diff.before);\n const after = formatValue(diff.after);\n \n // Prettify the key name\n const keyParts = diff.key.split('.');\n const prettyKey = keyParts\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(' ');\n\n return `${prettyKey}: ${before} → ${after}`;\n });\n}\n\n/**\n * Get a short summary of attribute changes.\n */\nexport function summarizeAttrChanges(diffs: AttrDiff[]): string {\n if (diffs.length === 0) return '';\n if (diffs.length === 1) {\n const diff = diffs[0];\n return `${diff.key}: ${formatValue(diff.before)} → ${formatValue(diff.after)}`;\n }\n return `${diffs.length} formatting changes`;\n}\n","/**\n * Table Block Differ Service\n * \n * Specialized diffing logic for tables:\n * - Row insertions/deletions\n * - Column insertions/deletions\n * - Cell-level content changes\n * - Table/cell attribute changes\n */\n\nimport type {\n ProseMirrorJSON,\n StructuralChange,\n AttributeChange,\n NodeMatch,\n StructuralChangeType,\n} from '../types';\nimport { v4 as uuidv4 } from 'uuid';\nimport { alignTableRows, alignTableCells } from './nodeAligner';\nimport { compareNodeAttrs } from './attrComparer';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Result of diffing two tables\n */\nexport interface TableDiffResult {\n /** Row-level structural changes */\n rowChanges: StructuralChange[];\n /** Column-level structural changes (detected from cell patterns) */\n columnChanges: StructuralChange[];\n /** Cell-level matches for content diffing */\n cellMatches: NodeMatch[];\n /** Attribute changes on the table itself */\n tableAttrChanges: AttributeChange | null;\n /** Attribute changes on cells */\n cellAttrChanges: AttributeChange[];\n}\n\n// ============================================================================\n// Table Analysis\n// ============================================================================\n\n/**\n * Get the number of columns in a table (based on first row).\n */\nfunction getColumnCount(table: ProseMirrorJSON): number {\n if (!table.content || table.content.length === 0) return 0;\n const firstRow = table.content[0];\n return firstRow.content?.length || 0;\n}\n\n/**\n * Check if a column was inserted or deleted.\n * Compares cell counts across matched rows to detect consistent column changes.\n */\nfunction detectColumnChanges(\n matchedRows: NodeMatch[],\n tableA: ProseMirrorJSON,\n tableB: ProseMirrorJSON,\n tablePathA: number[],\n tablePathB: number[]\n): StructuralChange[] {\n const changes: StructuralChange[] = [];\n \n if (matchedRows.length === 0) return changes;\n\n // Get cell counts from first matched row pair\n const firstMatch = matchedRows[0];\n const rowIdxA = firstMatch.pathA[firstMatch.pathA.length - 1];\n const rowIdxB = firstMatch.pathB[firstMatch.pathB.length - 1];\n \n const rowA = tableA.content?.[rowIdxA];\n const rowB = tableB.content?.[rowIdxB];\n \n if (!rowA || !rowB) return changes;\n \n const cellCountA = rowA.content?.length || 0;\n const cellCountB = rowB.content?.length || 0;\n \n const diff = cellCountB - cellCountA;\n \n if (diff === 0) return changes;\n\n // Verify the pattern is consistent across all matched rows\n let consistent = true;\n for (const match of matchedRows) {\n const idxA = match.pathA[match.pathA.length - 1];\n const idxB = match.pathB[match.pathB.length - 1];\n const rA = tableA.content?.[idxA];\n const rB = tableB.content?.[idxB];\n \n if (!rA || !rB) continue;\n \n const countA = rA.content?.length || 0;\n const countB = rB.content?.length || 0;\n \n if (countB - countA !== diff) {\n consistent = false;\n break;\n }\n }\n\n if (!consistent) return changes;\n\n // Detected consistent column change\n if (diff > 0) {\n // Column(s) inserted\n for (let i = 0; i < diff; i++) {\n changes.push({\n id: uuidv4(),\n type: 'columnInsert',\n nodeType: 'tableColumn',\n path: [...tablePathB],\n node: { type: 'column', position: cellCountA + i },\n });\n }\n } else {\n // Column(s) deleted\n for (let i = 0; i < Math.abs(diff); i++) {\n changes.push({\n id: uuidv4(),\n type: 'columnDelete',\n nodeType: 'tableColumn',\n path: [...tablePathA],\n node: { type: 'column', position: cellCountB + i },\n });\n }\n }\n\n return changes;\n}\n\n// ============================================================================\n// Main Table Diff Function\n// ============================================================================\n\n/**\n * Diff two tables and return all detected changes.\n */\nexport function diffTables(\n tableA: ProseMirrorJSON,\n tableB: ProseMirrorJSON,\n tablePathA: number[],\n tablePathB: number[]\n): TableDiffResult {\n const result: TableDiffResult = {\n rowChanges: [],\n columnChanges: [],\n cellMatches: [],\n tableAttrChanges: null,\n cellAttrChanges: [],\n };\n\n // 1. Compare table-level attributes\n const tableAttrDiffs = compareNodeAttrs(tableA, tableB);\n if (tableAttrDiffs.length > 0) {\n result.tableAttrChanges = {\n id: uuidv4(),\n nodeType: 'table',\n pathA: tablePathA,\n pathB: tablePathB,\n changes: tableAttrDiffs,\n };\n }\n\n // 2. Align rows between tables\n const rowAlignment = alignTableRows(tableA, tableB, tablePathA, tablePathB);\n\n // 3. Process row insertions\n for (const inserted of rowAlignment.insertions) {\n result.rowChanges.push({\n id: uuidv4(),\n type: 'rowInsert',\n nodeType: 'tableRow',\n path: inserted.path,\n node: inserted.node,\n });\n }\n\n // 4. Process row deletions\n for (const deleted of rowAlignment.deletions) {\n result.rowChanges.push({\n id: uuidv4(),\n type: 'rowDelete',\n nodeType: 'tableRow',\n path: deleted.path,\n node: deleted.node,\n });\n }\n\n // 5. Detect column changes from matched rows\n result.columnChanges = detectColumnChanges(\n rowAlignment.matched,\n tableA,\n tableB,\n tablePathA,\n tablePathB\n );\n\n // 6. Process matched rows - align cells within each\n for (const rowMatch of rowAlignment.matched) {\n const rowIdxA = rowMatch.pathA[rowMatch.pathA.length - 1];\n const rowIdxB = rowMatch.pathB[rowMatch.pathB.length - 1];\n \n const rowA = tableA.content?.[rowIdxA];\n const rowB = tableB.content?.[rowIdxB];\n \n if (!rowA || !rowB) continue;\n\n // Align cells within this row pair\n const cellAlignment = alignTableCells(\n rowA,\n rowB,\n rowMatch.pathA,\n rowMatch.pathB\n );\n\n // Add cell matches for content diffing\n result.cellMatches.push(...cellAlignment.matched);\n\n // Check for cell attribute changes on matched cells\n for (const cellMatch of cellAlignment.matched) {\n const cellIdxA = cellMatch.pathA[cellMatch.pathA.length - 1];\n const cellIdxB = cellMatch.pathB[cellMatch.pathB.length - 1];\n \n const cellA = rowA.content?.[cellIdxA];\n const cellB = rowB.content?.[cellIdxB];\n \n if (!cellA || !cellB) continue;\n\n const cellAttrDiffs = compareNodeAttrs(cellA, cellB);\n if (cellAttrDiffs.length > 0) {\n result.cellAttrChanges.push({\n id: uuidv4(),\n nodeType: 'tableCell',\n pathA: cellMatch.pathA,\n pathB: cellMatch.pathB,\n changes: cellAttrDiffs,\n });\n }\n }\n }\n\n return result;\n}\n\n/**\n * Check if a node is a table.\n */\nexport function isTable(node: ProseMirrorJSON): boolean {\n return node?.type === 'table';\n}\n\n/**\n * Check if a node is a table row.\n */\nexport function isTableRow(node: ProseMirrorJSON): boolean {\n return node?.type === 'tableRow';\n}\n\n/**\n * Check if a node is a table cell.\n */\nexport function isTableCell(node: ProseMirrorJSON): boolean {\n return node?.type === 'tableCell' || node?.type === 'tableHeader';\n}\n\n/**\n * Get a human-readable location string for a table.\n */\nexport function getTableLocation(tablePath: number[], tableIndex: number): string {\n return `Table ${tableIndex + 1}`;\n}\n\n/**\n * Get a human-readable location string for a row.\n */\nexport function getRowLocation(\n tablePath: number[],\n rowIndex: number,\n tableIndex: number\n): string {\n return `Table ${tableIndex + 1}, Row ${rowIndex + 1}`;\n}\n\n/**\n * Get a human-readable location string for a cell.\n */\nexport function getCellLocation(\n rowIndex: number,\n cellIndex: number,\n tableIndex: number\n): string {\n // Convert to A1 notation for column\n const colLetter = String.fromCharCode(65 + cellIndex);\n return `Table ${tableIndex + 1}, Cell ${colLetter}${rowIndex + 1}`;\n}\n\n/**\n * Extract text preview from a table row.\n */\nexport function getRowPreview(row: ProseMirrorJSON, maxLength: number = 50): string {\n const cells: string[] = [];\n \n for (const cell of row.content || []) {\n const cellText = extractCellText(cell);\n if (cellText) {\n cells.push(cellText);\n }\n }\n \n const preview = cells.join(' | ');\n if (preview.length > maxLength) {\n return preview.substring(0, maxLength - 3) + '...';\n }\n return preview;\n}\n\n/**\n * Extract text from a table cell.\n */\nfunction extractCellText(cell: ProseMirrorJSON): string {\n if (!cell.content) return '';\n \n const texts: string[] = [];\n \n for (const child of cell.content) {\n if (child.type === 'text') {\n texts.push(child.text || '');\n } else if (child.type === 'paragraph' && child.content) {\n for (const pChild of child.content) {\n if (pChild.type === 'text') {\n texts.push(pChild.text || '');\n }\n }\n }\n }\n \n return texts.join('').trim();\n}\n","/**\n * List Block Differ Service\n * \n * Specialized diffing logic for lists:\n * - List item insertions/deletions\n * - List item reordering detection\n * - Nested list handling\n */\n\nimport type {\n ProseMirrorJSON,\n StructuralChange,\n NodeMatch,\n} from '../types';\nimport { v4 as uuidv4 } from 'uuid';\nimport { alignListItems } from './nodeAligner';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Result of diffing two lists\n */\nexport interface ListDiffResult {\n /** Item-level structural changes */\n itemChanges: StructuralChange[];\n /** Item matches for content diffing */\n itemMatches: NodeMatch[];\n /** Nested list changes (recursive) */\n nestedChanges: ListDiffResult[];\n}\n\n// ============================================================================\n// List Analysis\n// ============================================================================\n\n/**\n * Check if a node is a list (ordered or unordered).\n */\nexport function isList(node: ProseMirrorJSON): boolean {\n return node?.type === 'bulletList' || node?.type === 'orderedList';\n}\n\n/**\n * Check if a node is a list item.\n */\nexport function isListItem(node: ProseMirrorJSON): boolean {\n return node?.type === 'listItem';\n}\n\n/**\n * Get the list type string.\n */\nexport function getListType(node: ProseMirrorJSON): 'ordered' | 'unordered' | null {\n if (node?.type === 'orderedList') return 'ordered';\n if (node?.type === 'bulletList') return 'unordered';\n return null;\n}\n\n/**\n * Extract text content from a list item.\n */\nfunction extractListItemText(item: ProseMirrorJSON): string {\n const texts: string[] = [];\n \n function extract(node: ProseMirrorJSON): void {\n if (!node) return;\n \n if (node.type === 'text') {\n texts.push(node.text || '');\n }\n \n if (node.content && Array.isArray(node.content)) {\n for (const child of node.content) {\n // Skip nested lists when extracting text\n if (!isList(child)) {\n extract(child);\n }\n }\n }\n }\n \n extract(item);\n return texts.join('').trim();\n}\n\n/**\n * Find nested lists within a list item.\n */\nfunction findNestedLists(item: ProseMirrorJSON): ProseMirrorJSON[] {\n const lists: ProseMirrorJSON[] = [];\n \n if (!item.content) return lists;\n \n for (const child of item.content) {\n if (isList(child)) {\n lists.push(child);\n }\n }\n \n return lists;\n}\n\n// ============================================================================\n// Main List Diff Function\n// ============================================================================\n\n/**\n * Diff two lists and return all detected changes.\n */\nexport function diffLists(\n listA: ProseMirrorJSON,\n listB: ProseMirrorJSON,\n listPathA: number[],\n listPathB: number[],\n depth: number = 0\n): ListDiffResult {\n const result: ListDiffResult = {\n itemChanges: [],\n itemMatches: [],\n nestedChanges: [],\n };\n\n // Align list items\n const alignment = alignListItems(listA, listB, listPathA, listPathB);\n\n // Process insertions\n for (const inserted of alignment.insertions) {\n result.itemChanges.push({\n id: uuidv4(),\n type: 'listItemInsert',\n nodeType: 'listItem',\n path: inserted.path,\n node: inserted.node,\n });\n }\n\n // Process deletions\n for (const deleted of alignment.deletions) {\n result.itemChanges.push({\n id: uuidv4(),\n type: 'listItemDelete',\n nodeType: 'listItem',\n path: deleted.path,\n node: deleted.node,\n });\n }\n\n // Store matches for content diffing\n result.itemMatches = alignment.matched;\n\n // Process nested lists in matched items\n for (const match of alignment.matched) {\n const itemIdxA = match.pathA[match.pathA.length - 1];\n const itemIdxB = match.pathB[match.pathB.length - 1];\n \n const itemA = listA.content?.[itemIdxA];\n const itemB = listB.content?.[itemIdxB];\n \n if (!itemA || !itemB) continue;\n\n // Find nested lists\n const nestedA = findNestedLists(itemA);\n const nestedB = findNestedLists(itemB);\n\n // Diff nested lists (simple 1:1 matching by position for now)\n const maxNested = Math.max(nestedA.length, nestedB.length);\n \n for (let i = 0; i < maxNested; i++) {\n const nA = nestedA[i];\n const nB = nestedB[i];\n \n if (nA && nB) {\n // Both exist - recurse\n const nestedResult = diffLists(\n nA,\n nB,\n [...match.pathA, i],\n [...match.pathB, i],\n depth + 1\n );\n result.nestedChanges.push(nestedResult);\n } else if (!nA && nB) {\n // Nested list inserted\n result.itemChanges.push({\n id: uuidv4(),\n type: 'listItemInsert',\n nodeType: 'nestedList',\n path: [...match.pathB, i],\n node: nB,\n });\n } else if (nA && !nB) {\n // Nested list deleted\n result.itemChanges.push({\n id: uuidv4(),\n type: 'listItemDelete',\n nodeType: 'nestedList',\n path: [...match.pathA, i],\n node: nA,\n });\n }\n }\n }\n\n return result;\n}\n\n// ============================================================================\n// Location & Preview Functions\n// ============================================================================\n\n/**\n * Get a human-readable location string for a list.\n */\nexport function getListLocation(listPath: number[], listIndex: number): string {\n return `List ${listIndex + 1}`;\n}\n\n/**\n * Get a human-readable location string for a list item.\n */\nexport function getListItemLocation(\n listPath: number[],\n itemIndex: number,\n listIndex: number,\n depth: number = 0\n): string {\n const depthStr = depth > 0 ? ` (nested, level ${depth + 1})` : '';\n return `List ${listIndex + 1}, Item ${itemIndex + 1}${depthStr}`;\n}\n\n/**\n * Get a text preview from a list item.\n */\nexport function getListItemPreview(item: ProseMirrorJSON, maxLength: number = 50): string {\n const text = extractListItemText(item);\n if (text.length > maxLength) {\n return text.substring(0, maxLength - 3) + '...';\n }\n return text || '(empty item)';\n}\n\n/**\n * Count total items in a list (including nested).\n */\nexport function countListItems(list: ProseMirrorJSON): number {\n let count = 0;\n \n function countRecursive(node: ProseMirrorJSON): void {\n if (isListItem(node)) {\n count++;\n }\n if (node.content) {\n for (const child of node.content) {\n countRecursive(child);\n }\n }\n }\n \n countRecursive(list);\n return count;\n}\n","/**\n * Non-Text Node Differ Service\n * \n * Handles diffing of atomic non-text nodes:\n * - Images\n * - Horizontal rules\n * - Page breaks\n * - Embedded objects (equations, etc.)\n */\n\nimport type {\n ProseMirrorJSON,\n StructuralChange,\n} from '../types';\nimport { v4 as uuidv4 } from 'uuid';\n\n// ============================================================================\n// Node Type Detection\n// ============================================================================\n\n/**\n * Check if a node is an image.\n */\nexport function isImage(node: ProseMirrorJSON): boolean {\n return node?.type === 'image';\n}\n\n/**\n * Check if a node is a horizontal rule.\n */\nexport function isHorizontalRule(node: ProseMirrorJSON): boolean {\n return node?.type === 'horizontalRule' || node?.type === 'hr';\n}\n\n/**\n * Check if a node is a hard break.\n */\nexport function isHardBreak(node: ProseMirrorJSON): boolean {\n return node?.type === 'hardBreak';\n}\n\n/**\n * Check if a node is a page break.\n */\nexport function isPageBreak(node: ProseMirrorJSON): boolean {\n return node?.type === 'pageBreak';\n}\n\n/**\n * Check if a node is an embedded object (equation, chart, etc.).\n */\nexport function isEmbedded(node: ProseMirrorJSON): boolean {\n const embeddedTypes = [\n 'equation',\n 'math',\n 'embed',\n 'chart',\n 'drawing',\n 'shape',\n ];\n return embeddedTypes.includes(node?.type);\n}\n\n/**\n * Check if a node is an atomic (non-text, leaf) node.\n */\nexport function isAtomicNode(node: ProseMirrorJSON): boolean {\n return (\n isImage(node) ||\n isHorizontalRule(node) ||\n isHardBreak(node) ||\n isPageBreak(node) ||\n isEmbedded(node)\n );\n}\n\n// ============================================================================\n// Image Comparison\n// ============================================================================\n\n/**\n * Get image identifier for comparison.\n * Uses src URL or data hash.\n */\nexport function getImageIdentifier(node: ProseMirrorJSON): string {\n if (!isImage(node)) return '';\n \n const attrs = node.attrs || {};\n \n // Prefer src URL\n if (attrs.src) {\n return `src:${attrs.src}`;\n }\n \n // Fall back to data if available\n if (attrs.data) {\n // Hash the data for comparison\n return `data:${simpleHash(attrs.data)}`;\n }\n \n // Use alt text as last resort\n if (attrs.alt) {\n return `alt:${attrs.alt}`;\n }\n \n return 'unknown';\n}\n\n/**\n * Simple hash function for image data.\n */\nfunction simpleHash(str: string): string {\n let hash = 5381;\n const sample = str.substring(0, 1000); // Sample first 1000 chars for speed\n for (let i = 0; i < sample.length; i++) {\n hash = ((hash << 5) + hash) ^ sample.charCodeAt(i);\n }\n return (hash >>> 0).toString(16);\n}\n\n/**\n * Compare two images and determine if they're the same.\n */\nexport function imagesMatch(imgA: ProseMirrorJSON, imgB: ProseMirrorJSON): boolean {\n if (!isImage(imgA) || !isImage(imgB)) return false;\n return getImageIdentifier(imgA) === getImageIdentifier(imgB);\n}\n\n// ============================================================================\n// Image Diff Detection\n// ============================================================================\n\n/**\n * Find images in a document (at any depth).\n */\nexport function findImages(doc: ProseMirrorJSON, basePath: number[] = []): { node: ProseMirrorJSON; path: number[] }[] {\n const images: { node: ProseMirrorJSON; path: number[] }[] = [];\n \n function traverse(node: ProseMirrorJSON, path: number[]): void {\n if (!node) return;\n \n if (isImage(node)) {\n images.push({ node, path: [...path] });\n }\n \n if (node.content && Array.isArray(node.content)) {\n node.content.forEach((child: ProseMirrorJSON, i: number) => {\n traverse(child, [...path, i]);\n });\n }\n }\n \n traverse(doc, basePath);\n return images;\n}\n\n/**\n * Diff images between two documents.\n */\nexport function diffImages(\n docA: ProseMirrorJSON,\n docB: ProseMirrorJSON\n): { inserted: StructuralChange[]; deleted: StructuralChange[] } {\n const imagesA = findImages(docA);\n const imagesB = findImages(docB);\n \n const inserted: StructuralChange[] = [];\n const deleted: StructuralChange[] = [];\n \n // Build identifier sets\n const idsA = new Map<string, { node: ProseMirrorJSON; path: number[] }>();\n const idsB = new Map<string, { node: ProseMirrorJSON; path: number[] }>();\n \n for (const img of imagesA) {\n const id = getImageIdentifier(img.node);\n idsA.set(id, img);\n }\n \n for (const img of imagesB) {\n const id = getImageIdentifier(img.node);\n idsB.set(id, img);\n }\n \n // Find deleted images (in A but not in B)\n for (const [id, img] of idsA) {\n if (!idsB.has(id)) {\n deleted.push({\n id: uuidv4(),\n type: 'imageDelete',\n nodeType: 'image',\n path: img.path,\n node: img.node,\n });\n }\n }\n \n // Find inserted images (in B but not in A)\n for (const [id, img] of idsB) {\n if (!idsA.has(id)) {\n inserted.push({\n id: uuidv4(),\n type: 'imageInsert',\n nodeType: 'image',\n path: img.path,\n node: img.node,\n });\n }\n }\n \n return { inserted, deleted };\n}\n\n// ============================================================================\n// Location & Preview Functions\n// ============================================================================\n\n/**\n * Get a human-readable location for an image.\n */\nexport function getImageLocation(path: number[]): string {\n // Simple location based on path depth\n if (path.length <= 1) {\n return `Image at position ${path[0] + 1}`;\n }\n return `Image (nested at depth ${path.length})`;\n}\n\n/**\n * Get a preview/description for an image.\n */\nexport function getImagePreview(node: ProseMirrorJSON): string {\n if (!isImage(node)) return '';\n \n const attrs = node.attrs || {};\n \n // Use alt text if available\n if (attrs.alt) {\n return `\"${attrs.alt}\"`;\n }\n \n // Use filename from src if available\n if (attrs.src) {\n const src = attrs.src as string;\n const filename = src.split('/').pop()?.split('?')[0];\n if (filename) {\n return filename;\n }\n }\n \n return '(image)';\n}\n\n/**\n * Get a preview for an atomic node.\n */\nexport function getAtomicNodePreview(node: ProseMirrorJSON): string {\n if (isImage(node)) return getImagePreview(node);\n if (isHorizontalRule(node)) return '—— (horizontal rule)';\n if (isPageBreak(node)) return '⏎ (page break)';\n if (isHardBreak(node)) return '↵ (line break)';\n if (isEmbedded(node)) return `[${node.type}]`;\n return `[${node.type || 'unknown'}]`;\n}\n","/**\n * Structural Merger Service\n * \n * Implements structure-aware document merging. Unlike character-level merging,\n * this service aligns blocks first, then applies the appropriate merge strategy\n * for each alignment type:\n * \n * - Matched blocks: Apply character-level diff internally\n * - Inserted blocks: Insert entire node with trackInsert marks\n * - Deleted blocks: Keep node with trackDelete marks\n * \n * This is the CRITICAL piece that makes structural changes visible and actionable.\n */\n\nimport { v4 as uuidv4 } from 'uuid';\nimport type {\n ProseMirrorJSON,\n ProseMirrorNode,\n StructuralChange,\n StructuralChangeInfo,\n TrackChangeAuthor,\n DiffResult,\n} from '../types';\nimport {\n createTrackInsertMark,\n createTrackDeleteMark,\n normalizeMarksForRendering,\n} from './trackChangeInjector';\nimport { alignDocuments, alignTableRows, alignListItems } from './nodeAligner';\nimport { diffDocuments } from './documentDiffer';\nimport { mergeDocuments } from './mergeDocuments';\nimport { isTable, isTableRow } from './tableBlockDiffer';\nimport { isList, isListItem } from './listBlockDiffer';\nimport { isImage } from './nonTextNodeDiffer';\nimport { DEFAULT_AUTHOR } from '../constants';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Result of structural merge\n */\nexport interface StructuralMergeResult {\n /** The merged document with all changes applied */\n mergedDoc: ProseMirrorNode;\n /** Metadata for the structural changes pane */\n structuralInfos: StructuralChangeInfo[];\n /** Summary strings for reporting */\n summary: string[];\n /** Count of text-level changes within matched blocks */\n textChangeCount: number;\n}\n\n/**\n * Operation to perform during merge\n */\ninterface MergeOperation {\n type: 'matched' | 'inserted' | 'deleted';\n nodeA?: ProseMirrorNode;\n nodeB?: ProseMirrorNode;\n pathA?: number[];\n pathB?: number[];\n}\n\n// ============================================================================\n// Node Marking Functions\n// ============================================================================\n\n/**\n * Deep clone a node\n */\nfunction cloneNode(node: ProseMirrorNode): ProseMirrorNode {\n return JSON.parse(JSON.stringify(node));\n}\n\n/**\n * Mark all text in a node as inserted (with shared ID).\n * Normalizes existing marks to ensure valid CSS color format.\n */\nfunction markAllTextAsInserted(\n node: ProseMirrorNode,\n sharedId: string,\n author: TrackChangeAuthor\n): ProseMirrorNode {\n if (node.type === 'text') {\n // Normalize existing marks to ensure valid CSS colors (# prefix for hex)\n const existingMarks = normalizeMarksForRendering(node.marks || []);\n return {\n ...node,\n marks: [...existingMarks, createTrackInsertMark(author, sharedId)],\n };\n }\n\n if (node.content && Array.isArray(node.content)) {\n return {\n ...node,\n content: node.content.map((child: ProseMirrorNode) =>\n markAllTextAsInserted(child, sharedId, author)\n ),\n };\n }\n\n return { ...node };\n}\n\n/**\n * Mark all text in a node as deleted (with shared ID).\n * Normalizes existing marks to ensure valid CSS color format.\n */\nfunction markAllTextAsDeleted(\n node: ProseMirrorNode,\n sharedId: string,\n author: TrackChangeAuthor\n): ProseMirrorNode {\n if (node.type === 'text') {\n // Normalize existing marks to ensure valid CSS colors (# prefix for hex)\n const existingMarks = normalizeMarksForRendering(node.marks || []);\n return {\n ...node,\n marks: [...existingMarks, createTrackDeleteMark(author, sharedId)],\n };\n }\n\n if (node.content && Array.isArray(node.content)) {\n return {\n ...node,\n content: node.content.map((child: ProseMirrorNode) =>\n markAllTextAsDeleted(child, sharedId, author)\n ),\n };\n }\n\n return { ...node };\n}\n\n/**\n * Extract text preview from a node.\n */\nfunction extractTextPreview(node: ProseMirrorNode, maxLength: number = 50): string {\n const texts: string[] = [];\n \n function extract(n: ProseMirrorNode): void {\n if (n.type === 'text') {\n texts.push(n.text || '');\n }\n if (n.content) {\n for (const child of n.content) {\n extract(child);\n }\n }\n }\n \n extract(node);\n const text = texts.join('').trim();\n \n if (text.length > maxLength) {\n return text.substring(0, maxLength - 3) + '...';\n }\n return text || '(empty)';\n}\n\n/**\n * Get human-readable node type description.\n */\nfunction getNodeTypeDescription(node: ProseMirrorNode): string {\n if (isTable(node)) return 'Table';\n if (isList(node)) return 'List';\n if (isListItem(node)) return 'List item';\n if (isTableRow(node)) return 'Table row';\n if (isImage(node)) return 'Image';\n if (node.type === 'heading') return `Heading ${node.attrs?.level || 1}`;\n if (node.type === 'paragraph') return 'Paragraph';\n if (node.type === 'blockquote') return 'Blockquote';\n if (node.type === 'codeBlock') return 'Code block';\n return node.type || 'Block';\n}\n\n// ============================================================================\n// Main Structural Merge Function\n// ============================================================================\n\n/**\n * Merge two documents with structural awareness.\n * \n * This is the main entry point that replaces the character-level-only merge.\n * It aligns blocks first, then processes each alignment appropriately.\n */\nexport function mergeWithStructuralAwareness(\n docA: ProseMirrorJSON,\n docB: ProseMirrorJSON,\n author: TrackChangeAuthor = DEFAULT_AUTHOR\n): StructuralMergeResult {\n const structuralInfos: StructuralChangeInfo[] = [];\n const summary: string[] = [];\n let textChangeCount = 0;\n\n // Align top-level blocks\n const alignment = alignDocuments(docA, docB);\n\n // Build merge operations in document order\n const operations = buildMergeOperations(alignment, docA, docB);\n\n // Process each operation to build merged content\n const mergedContent: ProseMirrorNode[] = [];\n let blockIndex = 0;\n\n for (const op of operations) {\n blockIndex++;\n\n switch (op.type) {\n case 'matched': {\n // Matched blocks: merge content (character-level or recursive structural)\n const { mergedNode, infos, changes } = mergeMatchedBlock(\n op.nodeA!,\n op.nodeB!,\n blockIndex,\n author\n );\n mergedContent.push(mergedNode);\n structuralInfos.push(...infos);\n textChangeCount += changes;\n break;\n }\n\n case 'inserted': {\n // Inserted blocks: add with trackInsert marks\n const { markedNode, info } = createInsertedBlock(\n op.nodeB!,\n blockIndex,\n author\n );\n mergedContent.push(markedNode);\n if (info) {\n structuralInfos.push(info);\n }\n break;\n }\n\n case 'deleted': {\n // Deleted blocks: keep with trackDelete marks\n const { markedNode, info } = createDeletedBlock(\n op.nodeA!,\n blockIndex,\n author\n );\n mergedContent.push(markedNode);\n if (info) {\n structuralInfos.push(info);\n }\n break;\n }\n }\n }\n\n // Build merged document\n const mergedDoc: ProseMirrorNode = {\n type: 'doc',\n content: mergedContent,\n };\n\n // Generate summary\n const insertCount = structuralInfos.filter(i => i.type.includes('Insert')).length;\n const deleteCount = structuralInfos.filter(i => i.type.includes('Delete')).length;\n \n if (insertCount > 0) summary.push(`${insertCount} block(s) inserted`);\n if (deleteCount > 0) summary.push(`${deleteCount} block(s) deleted`);\n if (textChangeCount > 0) summary.push(`${textChangeCount} text change(s)`);\n\n return {\n mergedDoc,\n structuralInfos,\n summary,\n textChangeCount,\n };\n}\n\n// ============================================================================\n// Build Merge Operations\n// ============================================================================\n\n/**\n * Build ordered list of merge operations from alignment result.\n * \n * This determines the order of blocks in the merged document:\n * - Walk through docB to get the \"new\" order\n * - Insert deletions from docA at their relative positions\n */\nfunction buildMergeOperations(\n alignment: ReturnType<typeof alignDocuments>,\n docA: ProseMirrorJSON,\n docB: ProseMirrorJSON\n): MergeOperation[] {\n const operations: MergeOperation[] = [];\n \n // Create maps for quick lookup\n const matchedFromA = new Map<number, { pathB: number[]; similarity: number }>();\n const matchedFromB = new Map<number, { pathA: number[]; similarity: number }>();\n \n for (const match of alignment.matched) {\n const idxA = match.pathA[0];\n const idxB = match.pathB[0];\n matchedFromA.set(idxA, { pathB: match.pathB, similarity: match.similarity });\n matchedFromB.set(idxB, { pathA: match.pathA, similarity: match.similarity });\n }\n\n // Track which deletions we've processed\n const deletedIndices = new Set(alignment.deletions.map(d => d.path[0]));\n const processedDeletions = new Set<number>();\n\n // Walk through docB in order\n const contentB = docB.content || [];\n const contentA = docA.content || [];\n\n for (let idxB = 0; idxB < contentB.length; idxB++) {\n const nodeB = contentB[idxB];\n \n // Check if this B position is matched to an A position\n const match = matchedFromB.get(idxB);\n \n if (match) {\n const idxA = match.pathA[0];\n const nodeA = contentA[idxA];\n \n // Before adding the matched block, check for deletions that came before it in A\n // This handles the case where deleted content should appear before matched content\n for (let checkIdx = 0; checkIdx < idxA; checkIdx++) {\n if (deletedIndices.has(checkIdx) && !processedDeletions.has(checkIdx)) {\n operations.push({\n type: 'deleted',\n nodeA: contentA[checkIdx],\n pathA: [checkIdx],\n });\n processedDeletions.add(checkIdx);\n }\n }\n \n // Add matched block\n operations.push({\n type: 'matched',\n nodeA,\n nodeB,\n pathA: match.pathA,\n pathB: [idxB],\n });\n } else {\n // This is an insertion (only in B)\n operations.push({\n type: 'inserted',\n nodeB,\n pathB: [idxB],\n });\n }\n }\n\n // Add any remaining deletions that weren't processed\n for (const deletion of alignment.deletions) {\n const idxA = deletion.path[0];\n if (!processedDeletions.has(idxA)) {\n operations.push({\n type: 'deleted',\n nodeA: deletion.node,\n pathA: deletion.path,\n });\n }\n }\n\n return operations;\n}\n\n// ============================================================================\n// Process Matched Blocks\n// ============================================================================\n\n/**\n * Merge a matched block pair.\n * For simple blocks (paragraphs), uses character-level diff.\n * For complex blocks (tables, lists), recurses into children.\n */\nfunction mergeMatchedBlock(\n nodeA: ProseMirrorNode,\n nodeB: ProseMirrorNode,\n blockIndex: number,\n author: TrackChangeAuthor\n): { mergedNode: ProseMirrorNode; infos: StructuralChangeInfo[]; changes: number } {\n const infos: StructuralChangeInfo[] = [];\n let changes = 0;\n\n // Handle tables: recurse into rows\n if (isTable(nodeA) && isTable(nodeB)) {\n const { mergedTable, tableInfos, changeCount } = mergeMatchedTable(\n nodeA,\n nodeB,\n blockIndex,\n author\n );\n return { mergedNode: mergedTable, infos: tableInfos, changes: changeCount };\n }\n\n // Handle lists: recurse into items\n if (isList(nodeA) && isList(nodeB)) {\n const { mergedList, listInfos, changeCount } = mergeMatchedList(\n nodeA,\n nodeB,\n blockIndex,\n author\n );\n return { mergedNode: mergedList, infos: listInfos, changes: changeCount };\n }\n\n // For other blocks (paragraphs, headings, etc.): use character-level diff\n const diff = diffDocuments(\n { type: 'doc', content: [nodeA] },\n { type: 'doc', content: [nodeB] }\n );\n\n // Count changes\n changes = diff.segments.filter(s => s.type !== 'equal').length;\n changes += diff.formatChanges?.length || 0;\n\n // Merge using existing character-level merger\n const merged = mergeDocuments(\n { type: 'doc', content: [nodeA] },\n { type: 'doc', content: [nodeB] },\n diff,\n author\n );\n\n // Extract the merged node (first content item)\n const mergedNode = merged.content?.[0] || cloneNode(nodeB);\n\n return { mergedNode, infos, changes };\n}\n\n// ============================================================================\n// Table Merging\n// ============================================================================\n\n/**\n * Merge matched tables by aligning and processing rows.\n */\nfunction mergeMatchedTable(\n tableA: ProseMirrorNode,\n tableB: ProseMirrorNode,\n tableIndex: number,\n author: TrackChangeAuthor\n): { mergedTable: ProseMirrorNode; tableInfos: StructuralChangeInfo[]; changeCount: number } {\n const tableInfos: StructuralChangeInfo[] = [];\n let changeCount = 0;\n\n // Align rows\n const rowAlignment = alignTableRows(tableA, tableB, [tableIndex - 1], [tableIndex - 1]);\n\n // Build merge operations for rows\n const mergedRows: ProseMirrorNode[] = [];\n \n // Create index maps\n const matchedFromA = new Map<number, number>();\n const matchedFromB = new Map<number, number>();\n \n for (const match of rowAlignment.matched) {\n const idxA = match.pathA[match.pathA.length - 1];\n const idxB = match.pathB[match.pathB.length - 1];\n matchedFromA.set(idxA, idxB);\n matchedFromB.set(idxB, idxA);\n }\n\n const deletedIndices = new Set(rowAlignment.deletions.map(d => d.path[d.path.length - 1]));\n const processedDeletions = new Set<number>();\n \n const rowsA = tableA.content || [];\n const rowsB = tableB.content || [];\n\n // Process rows in B's order\n for (let idxB = 0; idxB < rowsB.length; idxB++) {\n const rowB = rowsB[idxB];\n const matchedIdxA = matchedFromB.get(idxB);\n\n if (matchedIdxA !== undefined) {\n const rowA = rowsA[matchedIdxA];\n \n // Insert any deletions that should appear before this row\n for (let checkIdx = 0; checkIdx < matchedIdxA; checkIdx++) {\n if (deletedIndices.has(checkIdx) && !processedDeletions.has(checkIdx)) {\n const deletedRow = rowsA[checkIdx];\n const changeId = uuidv4();\n \n mergedRows.push(markAllTextAsDeleted(cloneNode(deletedRow), changeId, author));\n \n tableInfos.push({\n id: changeId,\n type: 'rowDelete',\n nodeType: 'tableRow',\n location: `Table ${tableIndex}, Row ${checkIdx + 1}`,\n preview: extractTextPreview(deletedRow),\n author,\n date: new Date().toISOString(),\n });\n \n processedDeletions.add(checkIdx);\n }\n }\n \n // Merge matched row (character-level diff on cells)\n const { mergedNode, changes } = mergeMatchedBlock(rowA, rowB, idxB, author);\n mergedRows.push(mergedNode);\n changeCount += changes;\n } else {\n // Inserted row\n const changeId = uuidv4();\n mergedRows.push(markAllTextAsInserted(cloneNode(rowB), changeId, author));\n \n tableInfos.push({\n id: changeId,\n type: 'rowInsert',\n nodeType: 'tableRow',\n location: `Table ${tableIndex}, Row ${idxB + 1}`,\n preview: extractTextPreview(rowB),\n author,\n date: new Date().toISOString(),\n });\n }\n }\n\n // Add remaining deletions\n for (const deletion of rowAlignment.deletions) {\n const idxA = deletion.path[deletion.path.length - 1];\n if (!processedDeletions.has(idxA)) {\n const changeId = uuidv4();\n \n mergedRows.push(markAllTextAsDeleted(cloneNode(deletion.node), changeId, author));\n \n tableInfos.push({\n id: changeId,\n type: 'rowDelete',\n nodeType: 'tableRow',\n location: `Table ${tableIndex}, Row ${idxA + 1}`,\n preview: extractTextPreview(deletion.node),\n author,\n date: new Date().toISOString(),\n });\n }\n }\n\n const mergedTable: ProseMirrorNode = {\n ...tableB,\n content: mergedRows,\n };\n\n return { mergedTable, tableInfos, changeCount };\n}\n\n// ============================================================================\n// List Merging\n// ============================================================================\n\n/**\n * Merge matched lists by aligning and processing items.\n */\nfunction mergeMatchedList(\n listA: ProseMirrorNode,\n listB: ProseMirrorNode,\n listIndex: number,\n author: TrackChangeAuthor\n): { mergedList: ProseMirrorNode; listInfos: StructuralChangeInfo[]; changeCount: number } {\n const listInfos: StructuralChangeInfo[] = [];\n let changeCount = 0;\n\n // Align list items\n const itemAlignment = alignListItems(listA, listB, [listIndex - 1], [listIndex - 1]);\n\n // Build merge operations for items\n const mergedItems: ProseMirrorNode[] = [];\n \n // Create index maps\n const matchedFromA = new Map<number, number>();\n const matchedFromB = new Map<number, number>();\n \n for (const match of itemAlignment.matched) {\n const idxA = match.pathA[match.pathA.length - 1];\n const idxB = match.pathB[match.pathB.length - 1];\n matchedFromA.set(idxA, idxB);\n matchedFromB.set(idxB, idxA);\n }\n\n const deletedIndices = new Set(itemAlignment.deletions.map(d => d.path[d.path.length - 1]));\n const processedDeletions = new Set<number>();\n \n const itemsA = listA.content || [];\n const itemsB = listB.content || [];\n\n // Process items in B's order\n for (let idxB = 0; idxB < itemsB.length; idxB++) {\n const itemB = itemsB[idxB];\n const matchedIdxA = matchedFromB.get(idxB);\n\n if (matchedIdxA !== undefined) {\n const itemA = itemsA[matchedIdxA];\n \n // Insert any deletions that should appear before this item\n for (let checkIdx = 0; checkIdx < matchedIdxA; checkIdx++) {\n if (deletedIndices.has(checkIdx) && !processedDeletions.has(checkIdx)) {\n const deletedItem = itemsA[checkIdx];\n const changeId = uuidv4();\n \n mergedItems.push(markAllTextAsDeleted(cloneNode(deletedItem), changeId, author));\n \n listInfos.push({\n id: changeId,\n type: 'listItemDelete',\n nodeType: 'listItem',\n location: `List ${listIndex}, Item ${checkIdx + 1}`,\n preview: extractTextPreview(deletedItem),\n author,\n date: new Date().toISOString(),\n });\n \n processedDeletions.add(checkIdx);\n }\n }\n \n // Merge matched item (character-level diff on content)\n const { mergedNode, changes } = mergeMatchedBlock(itemA, itemB, idxB, author);\n mergedItems.push(mergedNode);\n changeCount += changes;\n } else {\n // Inserted item\n const changeId = uuidv4();\n mergedItems.push(markAllTextAsInserted(cloneNode(itemB), changeId, author));\n \n listInfos.push({\n id: changeId,\n type: 'listItemInsert',\n nodeType: 'listItem',\n location: `List ${listIndex}, Item ${idxB + 1}`,\n preview: extractTextPreview(itemB),\n author,\n date: new Date().toISOString(),\n });\n }\n }\n\n // Add remaining deletions\n for (const deletion of itemAlignment.deletions) {\n const idxA = deletion.path[deletion.path.length - 1];\n if (!processedDeletions.has(idxA)) {\n const changeId = uuidv4();\n \n mergedItems.push(markAllTextAsDeleted(cloneNode(deletion.node), changeId, author));\n \n listInfos.push({\n id: changeId,\n type: 'listItemDelete',\n nodeType: 'listItem',\n location: `List ${listIndex}, Item ${idxA + 1}`,\n preview: extractTextPreview(deletion.node),\n author,\n date: new Date().toISOString(),\n });\n }\n }\n\n const mergedList: ProseMirrorNode = {\n ...listB,\n content: mergedItems,\n };\n\n return { mergedList, listInfos, changeCount };\n}\n\n// ============================================================================\n// Create Inserted/Deleted Blocks\n// ============================================================================\n\n/**\n * Create an inserted block with trackInsert marks on all text.\n */\nfunction createInsertedBlock(\n node: ProseMirrorNode,\n blockIndex: number,\n author: TrackChangeAuthor\n): { markedNode: ProseMirrorNode; info: StructuralChangeInfo | null } {\n const changeId = uuidv4();\n const markedNode = markAllTextAsInserted(cloneNode(node), changeId, author);\n \n const nodeDesc = getNodeTypeDescription(node);\n \n const info: StructuralChangeInfo = {\n id: changeId,\n type: isTable(node) ? 'rowInsert' : \n isList(node) ? 'listItemInsert' : \n isImage(node) ? 'imageInsert' : 'paragraphInsert',\n nodeType: node.type || 'unknown',\n location: `${nodeDesc} inserted at position ${blockIndex}`,\n preview: extractTextPreview(node),\n author,\n date: new Date().toISOString(),\n };\n\n return { markedNode, info };\n}\n\n/**\n * Create a deleted block with trackDelete marks on all text.\n */\nfunction createDeletedBlock(\n node: ProseMirrorNode,\n blockIndex: number,\n author: TrackChangeAuthor\n): { markedNode: ProseMirrorNode; info: StructuralChangeInfo | null } {\n const changeId = uuidv4();\n const markedNode = markAllTextAsDeleted(cloneNode(node), changeId, author);\n \n const nodeDesc = getNodeTypeDescription(node);\n \n const info: StructuralChangeInfo = {\n id: changeId,\n type: isTable(node) ? 'rowDelete' : \n isList(node) ? 'listItemDelete' : \n isImage(node) ? 'imageDelete' : 'paragraphDelete',\n nodeType: node.type || 'unknown',\n location: `${nodeDesc} deleted from position ${blockIndex}`,\n preview: extractTextPreview(node),\n author,\n date: new Date().toISOString(),\n };\n\n return { markedNode, info };\n}\n","/**\n * DocxDiffEditor Component\n *\n * A React component for DOCX document comparison with track changes visualization.\n * Wraps SuperDoc editor and provides methods for setting source, comparing documents,\n * and extracting change context for LLM processing.\n */\n\nimport {\n useCallback,\n useRef,\n useState,\n useEffect,\n useImperativeHandle,\n forwardRef,\n} from 'react';\n\nimport type {\n DocxDiffEditorProps,\n DocxDiffEditorRef,\n DocxContent,\n ProseMirrorJSON,\n SuperDocInstance,\n DiffSegment,\n DiffResult,\n ComparisonResult,\n EnrichedChange,\n DocumentInfo,\n DocumentProperties,\n StructuralChangeInfo,\n} from './types';\n\nimport { StructuralChangesPane } from './components/StructuralChangesPane';\n\nimport { parseDocxFile, parseHtmlToJson, detectContentType, isProseMirrorJSON } from './services/contentResolver';\nimport { diffDocuments } from './services/documentDiffer';\nimport { mergeDocuments } from './services/mergeDocuments';\nimport { extractEnrichedChanges } from './services/changeContextExtractor';\nimport { processStructuralChanges, generateStructuralChangeSummary } from './services/blockLevelMerger';\nimport { mergeWithStructuralAwareness } from './services/structuralMerger';\nimport { normalizeRunProperties } from './services/runPropertiesSync';\nimport { DEFAULT_AUTHOR, DEFAULT_SUPERDOC_USER, TRACK_CHANGE_PERMISSIONS, TIMEOUTS } from './constants';\n\n/**\n * Permission resolver that allows accepting/rejecting all track changes\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst permissionResolver = ({ permission }: any) => {\n return TRACK_CHANGE_PERMISSIONS.includes(permission) ? true : undefined;\n};\n\n/**\n * Accept all track changes in a ProseMirror JSON document.\n * - Removes text with trackDelete marks\n * - Keeps text with trackInsert marks (removes the mark)\n * - Keeps text with trackFormat marks with new formatting (removes the mark)\n */\nfunction acceptAllChangesInJson(node: ProseMirrorJSON): ProseMirrorJSON | null {\n if (!node) return null;\n\n // Handle text nodes\n if (node.type === 'text') {\n const marks = node.marks || [];\n \n // Check if this text has a trackDelete mark - if so, remove entirely\n if (marks.some((m: { type: string }) => m.type === 'trackDelete')) {\n return null;\n }\n\n // Filter out track marks, keep other marks\n const cleanMarks = marks.filter(\n (m: { type: string }) => !['trackInsert', 'trackDelete', 'trackFormat'].includes(m.type)\n );\n\n return {\n ...node,\n marks: cleanMarks.length > 0 ? cleanMarks : undefined,\n };\n }\n\n // Handle nodes with content\n if (node.content && Array.isArray(node.content)) {\n const cleanContent = node.content\n .map((child: ProseMirrorJSON) => acceptAllChangesInJson(child))\n .filter((child: ProseMirrorJSON | null): child is ProseMirrorJSON => child !== null);\n\n return {\n ...node,\n content: cleanContent.length > 0 ? cleanContent : undefined,\n };\n }\n\n return node;\n}\n\n/**\n * DocxDiffEditor Component\n */\nexport const DocxDiffEditor = forwardRef<DocxDiffEditorRef, DocxDiffEditorProps>(\n function DocxDiffEditor(\n {\n initialSource,\n templateDocx,\n showRulers = false,\n showToolbar = true,\n author = DEFAULT_AUTHOR,\n onReady,\n onSourceLoaded,\n onComparisonComplete,\n onError,\n className = '',\n toolbarClassName = '',\n editorClassName = '',\n // Structural Changes Pane options\n structuralPanePosition = 'bottom-right',\n structuralPaneCollapsed = false,\n hideStructuralPane = false,\n },\n ref\n ) {\n // Refs\n const containerRef = useRef<HTMLDivElement>(null);\n const toolbarRef = useRef<HTMLDivElement>(null);\n const superdocRef = useRef<SuperDocInstance | null>(null);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const SuperDocRef = useRef<any>(null);\n const mountedRef = useRef(true);\n const initRef = useRef(false);\n const readyRef = useRef(false);\n\n // State\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [sourceJson, setSourceJson] = useState<ProseMirrorJSON | null>(null);\n const [mergedJson, setMergedJson] = useState<ProseMirrorJSON | null>(null);\n const [diffResult, setDiffResult] = useState<DiffResult | null>(null);\n \n // Structural changes pane state\n const [structuralChanges, setStructuralChanges] = useState<StructuralChangeInfo[]>([]);\n const [isPaneDismissed, setIsPaneDismissed] = useState(false);\n \n // Ref to track structural change IDs for bubble sync\n // (needed because onCommentsUpdate callback captures stale state)\n const structuralChangeIdsRef = useRef<Set<string>>(new Set());\n\n // Keep the ref in sync with state\n useEffect(() => {\n structuralChangeIdsRef.current = new Set(structuralChanges.map((c) => c.id));\n }, [structuralChanges]);\n\n // Generate unique IDs for this instance\n const instanceId = useRef(`dde-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`);\n const editorId = `dde-editor-${instanceId.current}`;\n const toolbarId = `dde-toolbar-${instanceId.current}`;\n\n /**\n * Set content in the editor using ProseMirror transaction\n */\n const setEditorContent = useCallback((editor: SuperDocInstance, json: ProseMirrorJSON) => {\n const { state, view } = editor;\n if (state?.doc && view && json.content) {\n const newDoc = state.schema.nodeFromJSON(json);\n const tr = state.tr.replaceWith(0, state.doc.content.size, newDoc.content);\n view.dispatch(tr);\n }\n }, []);\n\n /**\n * Enable track changes review mode\n */\n const enableReviewMode = useCallback((sd: SuperDocInstance) => {\n if (sd.setTrackedChangesPreferences) {\n sd.setTrackedChangesPreferences({ mode: 'review', enabled: true });\n } else if (sd.activeEditor?.commands?.enableTrackChanges) {\n sd.activeEditor.commands.enableTrackChanges();\n }\n }, []);\n\n /**\n * Set editing mode (normal mode - shows original without track changes)\n */\n const setEditingMode = useCallback((sd: SuperDocInstance) => {\n if (sd.setTrackedChangesPreferences) {\n // Use 'off' mode with track changes disabled for clean editing view\n // Valid modes (superdoc 1.3+): 'review', 'original', 'final', 'off'\n sd.setTrackedChangesPreferences({ mode: 'off', enabled: false });\n }\n }, []);\n\n /**\n * Handle errors\n */\n const handleError = useCallback(\n (err: Error | string) => {\n const error = err instanceof Error ? err : new Error(err);\n setError(error.message);\n onError?.(error);\n },\n [onError]\n );\n\n // =========================================================================\n // Structural Changes Pane Handlers\n // =========================================================================\n\n /**\n * Accept a structural change by ID\n */\n const handleAcceptStructuralChange = useCallback((changeId: string) => {\n const editor = superdocRef.current?.activeEditor;\n if (editor?.commands?.acceptTrackedChangeById) {\n editor.commands.acceptTrackedChangeById(changeId);\n // Remove from state\n setStructuralChanges((prev) => prev.filter((c) => c.id !== changeId));\n }\n }, []);\n\n /**\n * Reject a structural change by ID\n */\n const handleRejectStructuralChange = useCallback((changeId: string) => {\n const editor = superdocRef.current?.activeEditor;\n if (editor?.commands?.rejectTrackedChangeById) {\n editor.commands.rejectTrackedChangeById(changeId);\n // Remove from state\n setStructuralChanges((prev) => prev.filter((c) => c.id !== changeId));\n }\n }, []);\n\n /**\n * Accept all structural changes\n */\n const handleAcceptAllStructural = useCallback(() => {\n const editor = superdocRef.current?.activeEditor;\n if (editor?.commands?.acceptTrackedChangeById) {\n for (const change of structuralChanges) {\n editor.commands.acceptTrackedChangeById(change.id);\n }\n setStructuralChanges([]);\n }\n }, [structuralChanges]);\n\n /**\n * Reject all structural changes\n */\n const handleRejectAllStructural = useCallback(() => {\n const editor = superdocRef.current?.activeEditor;\n if (editor?.commands?.rejectTrackedChangeById) {\n for (const change of structuralChanges) {\n editor.commands.rejectTrackedChangeById(change.id);\n }\n setStructuralChanges([]);\n }\n }, [structuralChanges]);\n\n /**\n * Navigate to a structural change in the document\n */\n const handleNavigateToChange = useCallback((changeId: string) => {\n // Find the change\n const change = structuralChanges.find((c) => c.id === changeId);\n if (!change) return;\n\n // Try to scroll to the change using SuperDoc's API\n const editor = superdocRef.current?.activeEditor;\n if (editor?.commands?.focus) {\n // Focus the editor first\n editor.commands.focus();\n }\n \n // Note: Actual scroll-to-change would require knowing the position\n // in the document. This is a placeholder for future enhancement.\n // For now, the visual highlight from the track change marks\n // should help users locate the change.\n }, [structuralChanges]);\n\n /**\n * Handle pane dismiss\n */\n const handlePaneDismiss = useCallback(() => {\n setIsPaneDismissed(true);\n }, []);\n\n /**\n * Handle SuperDoc comments update (for bubble sync)\n * When user accepts/rejects via SuperDoc bubbles, we sync our state\n */\n const handleCommentsUpdate = useCallback(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (event: any) => {\n // Check if this is a resolved track change event\n if (event?.type === 'resolved' && event?.comment?.trackedChange) {\n const commentId = event.comment.commentId;\n \n // Check if this is one of our structural changes\n if (structuralChangeIdsRef.current.has(commentId)) {\n // Remove from our state - the change was handled via SuperDoc bubble\n setStructuralChanges((prev) => prev.filter((c) => c.id !== commentId));\n }\n }\n },\n []\n );\n\n /**\n * Destroy current SuperDoc instance\n */\n const destroySuperdoc = useCallback(() => {\n if (superdocRef.current) {\n try {\n superdocRef.current.destroy?.();\n } catch {\n // Ignore cleanup errors\n }\n superdocRef.current = null;\n }\n readyRef.current = false;\n }, []);\n\n /**\n * Create a new SuperDoc instance with the given options.\n * Accepts either a DOCX File/Blob or HTML string.\n * \n * Track bubbles are enabled by calling processLoadedDocxComments after\n * setting merged content (see compareWith method).\n */\n const createSuperdoc = useCallback(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async (options: { document?: File | Blob; html?: string }): Promise<{ superdoc: SuperDocInstance; json: ProseMirrorJSON }> => {\n if (!SuperDocRef.current) {\n throw new Error('SuperDoc not loaded');\n }\n if (!containerRef.current) {\n throw new Error('Container not available');\n }\n\n // Clear containers to avoid Vue \"already mounted\" warning\n containerRef.current.innerHTML = '';\n if (toolbarRef.current) {\n toolbarRef.current.innerHTML = '';\n }\n\n // Set IDs on DOM elements\n containerRef.current.id = editorId;\n if (toolbarRef.current) {\n toolbarRef.current.id = toolbarId;\n }\n\n return new Promise((resolve, reject) => {\n let resolved = false;\n \n try {\n // Build SuperDoc config - use document OR html, not both\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const superdocConfig: any = {\n selector: `#${editorId}`,\n toolbar: showToolbar ? `#${toolbarId}` : undefined,\n documentMode: 'editing',\n role: 'editor',\n rulers: showRulers,\n user: DEFAULT_SUPERDOC_USER,\n permissionResolver,\n // Bubble sync: listen for track changes resolved via SuperDoc bubbles\n onCommentsUpdate: handleCommentsUpdate,\n };\n\n if (options.document) {\n superdocConfig.document = options.document;\n } else if (options.html) {\n superdocConfig.html = options.html;\n }\n // If neither document nor html provided, SuperDoc creates blank document\n\n const superdoc = new SuperDocRef.current({\n ...superdocConfig,\n onReady: ({ superdoc: sd }: { superdoc: SuperDocInstance }) => {\n if (resolved) return;\n resolved = true;\n \n superdocRef.current = sd;\n readyRef.current = true;\n\n // Extract JSON from the loaded document\n let json: ProseMirrorJSON = { type: 'doc', content: [] };\n if (sd?.activeEditor) {\n try {\n json = sd.activeEditor.getJSON();\n } catch (err) {\n console.error('Failed to extract JSON:', err);\n }\n }\n\n resolve({ superdoc: sd, json });\n },\n onException: ({ error: err }: { error: Error }) => {\n if (resolved) return;\n resolved = true;\n console.error('SuperDoc error:', err);\n reject(err);\n },\n });\n\n superdocRef.current = superdoc;\n\n // Timeout\n setTimeout(() => {\n if (!resolved) {\n resolved = true;\n reject(new Error('SuperDoc initialization timed out'));\n }\n }, TIMEOUTS.PARSE_TIMEOUT);\n } catch (err) {\n if (!resolved) {\n resolved = true;\n reject(err);\n }\n }\n });\n },\n [editorId, toolbarId, showToolbar, showRulers]\n );\n\n /**\n * Initialize SuperDoc instance\n */\n const initialize = useCallback(async () => {\n if (initRef.current || !containerRef.current || !mountedRef.current) return;\n if (!showToolbar && !toolbarRef.current) {\n // Continue without toolbar\n } else if (showToolbar && !toolbarRef.current) {\n return;\n }\n\n initRef.current = true;\n\n // Small delay for React to settle\n await new Promise((resolve) => setTimeout(resolve, TIMEOUTS.INIT_DELAY));\n\n if (!mountedRef.current || !containerRef.current) {\n initRef.current = false;\n return;\n }\n\n setIsLoading(true);\n setError(null);\n destroySuperdoc();\n\n try {\n // Note: superdoc CSS is bundled in dist/styles.css - user must import 'docx-diff-editor/styles.css'\n const { SuperDoc } = await import('superdoc');\n SuperDocRef.current = SuperDoc;\n\n // Determine initialization options based on initialSource\n let initOptions: { document?: File | Blob; html?: string } = {};\n\n if (initialSource) {\n const contentType = detectContentType(initialSource);\n if (contentType === 'file') {\n initOptions = { document: initialSource as File };\n } else if (contentType === 'html') {\n // Use SuperDoc's native HTML support\n initOptions = { html: initialSource as string };\n } else if (contentType === 'json') {\n // For JSON, we need a document first, then set content\n // Use template if provided, otherwise SuperDoc will create blank\n initOptions = templateDocx ? { document: templateDocx } : {};\n }\n } else if (templateDocx) {\n initOptions = { document: templateDocx };\n }\n // If no initialSource and no template, SuperDoc creates a blank document\n\n const { superdoc: sd, json } = await createSuperdoc(initOptions);\n\n // For JSON content, set it after initialization\n if (initialSource && detectContentType(initialSource) === 'json') {\n if (sd?.activeEditor && isProseMirrorJSON(initialSource)) {\n setEditorContent(sd.activeEditor, initialSource as ProseMirrorJSON);\n setSourceJson(initialSource as ProseMirrorJSON);\n onSourceLoaded?.(initialSource as ProseMirrorJSON);\n }\n } else {\n // Use JSON extracted from the loaded document\n setSourceJson(json);\n onSourceLoaded?.(json);\n }\n\n setIsLoading(false);\n onReady?.();\n } catch (err) {\n console.error('Failed to initialize SuperDoc:', err);\n handleError(err instanceof Error ? err : new Error('Failed to load editor'));\n setIsLoading(false);\n // Allow retry on error\n initRef.current = false;\n }\n // Note: initRef stays true on success to prevent re-initialization\n }, [\n initialSource,\n showRulers,\n showToolbar,\n templateDocx,\n onReady,\n onSourceLoaded,\n destroySuperdoc,\n createSuperdoc,\n setEditorContent,\n handleError,\n ]);\n\n // Initialize on mount - only once\n useEffect(() => {\n mountedRef.current = true;\n \n // Only initialize once\n if (!initRef.current) {\n initialize();\n }\n\n return () => {\n mountedRef.current = false;\n destroySuperdoc();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []); // Empty deps - only run on mount\n\n // =========================================================================\n // Imperative API\n // =========================================================================\n\n useImperativeHandle(\n ref,\n () => ({\n /**\n * Update content in the existing editor without recreating SuperDoc instance.\n * Preserves the DOCX template/styling. Ideal for replacing content with translated JSON.\n */\n updateContent(json: ProseMirrorJSON): void {\n const editor = superdocRef.current?.activeEditor;\n if (!editor) {\n throw new Error('Editor not ready');\n }\n\n setEditorContent(editor, json);\n setSourceJson(json);\n setMergedJson(null);\n setDiffResult(null);\n onSourceLoaded?.(json);\n },\n\n /**\n * Set the source/base document.\n * Accepts File (DOCX), HTML string, or ProseMirror JSON.\n * Note: This destroys and recreates the SuperDoc instance.\n * For JSON content updates, prefer updateContent() to preserve the existing template.\n */\n async setSource(content: DocxContent): Promise<void> {\n if (!SuperDocRef.current) {\n throw new Error('Editor not initialized');\n }\n\n setIsLoading(true);\n setError(null);\n\n try {\n const contentType = detectContentType(content);\n let json: ProseMirrorJSON;\n\n // Destroy current instance and create new one\n destroySuperdoc();\n\n if (contentType === 'file') {\n // Initialize with DOCX file\n const result = await createSuperdoc({ document: content as File });\n json = result.json;\n } else if (contentType === 'html') {\n // Use SuperDoc's native HTML support\n const result = await createSuperdoc({ html: content as string });\n json = result.json;\n } else {\n // JSON content - initialize with template or blank, then set content\n const result = await createSuperdoc(templateDocx ? { document: templateDocx } : {});\n if (result.superdoc?.activeEditor && isProseMirrorJSON(content)) {\n setEditorContent(result.superdoc.activeEditor, content as ProseMirrorJSON);\n json = content as ProseMirrorJSON;\n } else {\n json = result.json;\n }\n }\n\n setSourceJson(json);\n setMergedJson(null);\n setDiffResult(null);\n setEditingMode(superdocRef.current!);\n onSourceLoaded?.(json);\n } catch (err) {\n handleError(err instanceof Error ? err : new Error('Failed to set source'));\n throw err;\n } finally {\n setIsLoading(false);\n }\n },\n\n /**\n * Compare source with new content, show track changes\n */\n async compareWith(content: DocxContent): Promise<ComparisonResult> {\n if (!SuperDocRef.current) {\n throw new Error('Editor not initialized');\n }\n if (!sourceJson) {\n throw new Error('No source document set. Call setSource() first.');\n }\n\n setIsLoading(true);\n try {\n const contentType = detectContentType(content);\n let newJson: ProseMirrorJSON;\n\n if (contentType === 'file') {\n // Parse DOCX file using hidden SuperDoc instance\n newJson = await parseDocxFile(content as File, SuperDocRef.current);\n } else if (contentType === 'html') {\n // Parse HTML using a temporary SuperDoc instance\n const tempContainer = document.createElement('div');\n tempContainer.style.cssText = 'position:absolute;top:-9999px;left:-9999px;width:800px;height:600px;visibility:hidden;';\n document.body.appendChild(tempContainer);\n\n try {\n newJson = await new Promise((resolve, reject) => {\n const tempSuperdoc = new SuperDocRef.current({\n selector: tempContainer,\n html: content as string,\n documentMode: 'viewing',\n rulers: false,\n user: { name: 'Parser', email: 'parser@local' },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onReady: ({ superdoc: sd }: { superdoc: any }) => {\n try {\n const json = sd?.activeEditor?.getJSON() || { type: 'doc', content: [] };\n setTimeout(() => {\n try { sd?.destroy?.(); } catch { /* ignore */ }\n tempContainer.parentNode?.removeChild(tempContainer);\n }, 100);\n resolve(json);\n } catch (err) {\n reject(err);\n }\n },\n onException: ({ error: err }: { error: Error }) => {\n tempContainer.parentNode?.removeChild(tempContainer);\n reject(err);\n },\n });\n\n setTimeout(() => {\n try { tempSuperdoc?.destroy?.(); } catch { /* ignore */ }\n tempContainer.parentNode?.removeChild(tempContainer);\n reject(new Error('HTML parsing timed out'));\n }, TIMEOUTS.PARSE_TIMEOUT);\n });\n } catch (err) {\n tempContainer.parentNode?.removeChild(tempContainer);\n throw err;\n }\n } else {\n // JSON content - use directly\n if (!isProseMirrorJSON(content)) {\n throw new Error('Invalid ProseMirror JSON structure');\n }\n newJson = content as ProseMirrorJSON;\n }\n\n // =========================================================\n // STRUCTURAL MERGE (Phase 6b)\n // Instead of character-level-only merge, we now use the\n // structure-aware merger which:\n // 1. Aligns blocks first (tables, lists, paragraphs)\n // 2. Inserts/deletes entire blocks with track marks\n // 3. Applies character-level diff within matched blocks\n // =========================================================\n \n // Normalize runProperties on the new document to ensure\n // styles from marks are synced to runProperties for rendering.\n // This is a safety net for content that didn't come through parseHtml.\n const normalizedNewJson = normalizeRunProperties(newJson);\n \n // Use structural merger for the main merge\n const structuralResult = mergeWithStructuralAwareness(\n sourceJson,\n normalizedNewJson,\n author\n );\n \n const merged = structuralResult.mergedDoc;\n const structInfos = structuralResult.structuralInfos;\n \n setMergedJson(merged);\n \n // Also keep the text-level diff for getDiffSegments() backward compat\n const diff = diffDocuments(sourceJson, newJson);\n setDiffResult(diff);\n\n // Update editor with merged content and enable review mode\n if (superdocRef.current?.activeEditor) {\n setEditorContent(superdocRef.current.activeEditor, merged);\n enableReviewMode(superdocRef.current);\n \n // CRITICAL FIX: Trigger comment creation for track marks\n // SuperDoc's track bubbles require comment entries in commentsStore.\n // When we inject JSON with track marks via setEditorContent, no comments\n // are created automatically. We need to call processLoadedDocxComments\n // which internally calls createCommentForTrackChanges to:\n // 1. Scan the document for track marks using getTrackChanges\n // 2. Create comment entries for each track mark\n // 3. This populates getFloatingComments which renders the bubbles\n //\n // Source reference: superdoc/dist/chunks/index-1n6qegaQ.es.js\n // - Line 4212: processLoadedDocxComments function\n // - Line 4247: setTimeout(() => createCommentForTrackChanges(editor))\n // - Line 4250: createCommentForTrackChanges scans for track marks\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const sd = superdocRef.current as any;\n if (sd.commentsStore?.processLoadedDocxComments) {\n // Small delay to ensure editor state is fully updated\n setTimeout(() => {\n try {\n sd.commentsStore.processLoadedDocxComments({\n superdoc: sd,\n editor: sd.activeEditor,\n comments: [], // Empty array - we just want to trigger createCommentForTrackChanges\n documentId: sd.activeEditor?.options?.documentId || 'primary',\n });\n } catch (err) {\n console.warn('[DocxDiffEditor] Failed to process track changes for bubbles:', err);\n }\n }, 50);\n }\n }\n\n // Store structural changes for the pane\n setStructuralChanges(structInfos);\n setIsPaneDismissed(false); // Reset dismissed state on new comparison\n\n // Build result\n // Note: insertions/deletions from text diff for backward compat,\n // but structuralChanges now contains the actual block changes\n const insertions = diff.segments.filter((s) => s.type === 'insert').length;\n const deletions = diff.segments.filter((s) => s.type === 'delete').length;\n const formatChanges = diff.formatChanges?.length || 0;\n const structuralChangeCount = structInfos.length;\n\n // Combine summaries\n const combinedSummary = [...structuralResult.summary];\n if (diff.summary.length > 0 && structuralResult.summary.length === 0) {\n // Only add text-level summary if no structural changes\n combinedSummary.push(...diff.summary);\n }\n\n const result: ComparisonResult = {\n totalChanges: insertions + deletions + formatChanges + structuralChangeCount,\n insertions,\n deletions,\n formatChanges,\n structuralChanges: structuralChangeCount,\n summary: combinedSummary,\n mergedJson: merged,\n structuralChangeInfos: structInfos,\n };\n\n onComparisonComplete?.(result);\n return result;\n } catch (err) {\n handleError(err instanceof Error ? err : new Error('Comparison failed'));\n throw err;\n } finally {\n setIsLoading(false);\n }\n },\n\n /**\n * Get raw diff segments\n */\n getDiffSegments(): DiffSegment[] {\n return diffResult?.segments || [];\n },\n\n /**\n * Get enriched changes with context for LLM processing\n */\n getEnrichedChangesContext(): EnrichedChange[] {\n if (!mergedJson) return [];\n return extractEnrichedChanges(mergedJson);\n },\n\n /**\n * Get current document content as JSON\n */\n getContent(): ProseMirrorJSON {\n if (superdocRef.current?.activeEditor) {\n return superdocRef.current.activeEditor.getJSON();\n }\n return mergedJson || sourceJson || { type: 'doc', content: [] };\n },\n\n /**\n * Get source document JSON (before comparison)\n */\n getSourceContent(): ProseMirrorJSON | null {\n return sourceJson;\n },\n\n /**\n * Export current document to DOCX blob\n */\n async exportDocx(): Promise<Blob> {\n if (!superdocRef.current?.activeEditor) {\n throw new Error('Editor not ready');\n }\n\n const blob = await superdocRef.current.activeEditor.exportDocx({\n isFinalDoc: false,\n });\n\n if (!blob) {\n throw new Error('Export returned no data');\n }\n\n return blob;\n },\n\n /**\n * Reset to source state (clear comparison)\n */\n resetComparison(): void {\n if (sourceJson && superdocRef.current?.activeEditor) {\n setEditorContent(superdocRef.current.activeEditor, sourceJson);\n setEditingMode(superdocRef.current);\n setMergedJson(null);\n setDiffResult(null);\n }\n },\n\n /**\n * Accept all track changes and return the clean document\n */\n async acceptAllChanges(): Promise<ProseMirrorJSON> {\n const editor = superdocRef.current?.activeEditor;\n const sd = superdocRef.current;\n if (!editor || !sd) {\n throw new Error('Editor not ready');\n }\n\n // Try different API paths with fallback\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const editorAny = editor as any;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const sdAny = sd as any;\n\n let cleanJson: ProseMirrorJSON;\n\n if (typeof editorAny.commands?.acceptAllChanges === 'function') {\n editorAny.commands.acceptAllChanges();\n cleanJson = editor.getJSON();\n } else if (typeof sdAny.commands?.acceptAllChanges === 'function') {\n sdAny.commands.acceptAllChanges();\n cleanJson = editor.getJSON();\n } else if (typeof sdAny.acceptAllChanges === 'function') {\n sdAny.acceptAllChanges();\n cleanJson = editor.getJSON();\n } else {\n // Fallback: process JSON manually to accept all changes\n const currentJson = editor.getJSON();\n cleanJson = acceptAllChangesInJson(currentJson) || { type: 'doc', content: [] };\n }\n\n // Clear comparison state since changes are now accepted\n setMergedJson(null);\n setDiffResult(null);\n\n return cleanJson;\n },\n\n /**\n * Check if editor is ready\n */\n isReady(): boolean {\n return readyRef.current;\n },\n\n /**\n * Get the current page count from the presentation editor.\n * Returns 0 if editor is not ready or pages are unavailable.\n */\n getPages(): number {\n if (!readyRef.current || !superdocRef.current) {\n return 0;\n }\n\n try {\n // Access the document from the superdoc store\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const sd = superdocRef.current as any;\n const doc = sd.superdocStore?.documents?.[0];\n \n if (!doc) {\n return 0;\n }\n\n // Get the PresentationEditor and retrieve page count\n const presentationEditor = doc.getPresentationEditor?.();\n const pages = presentationEditor?.getPages?.();\n \n return pages?.length ?? 0;\n } catch (err) {\n console.warn('[DocxDiffEditor] Failed to get page count:', err);\n return 0;\n }\n },\n\n /**\n * Get combined document metadata and statistics.\n * Returns null if editor is not ready.\n */\n getDocumentInfo(): DocumentInfo | null {\n if (!readyRef.current || !superdocRef.current) {\n return null;\n }\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const sd = superdocRef.current as any;\n const doc = sd.superdocStore?.documents?.[0];\n \n if (!doc) {\n return null;\n }\n\n // Get the editor instance\n const editor = doc.getEditor?.();\n \n // Get metadata\n const metadata = editor?.getMetadata?.() ?? {};\n \n // Get stats\n const stats = editor?.commands?.getDocumentStats?.() ?? {};\n \n // Get page count\n const presentationEditor = doc.getPresentationEditor?.();\n const pages = presentationEditor?.getPages?.();\n const pageCount = pages?.length ?? 0;\n\n return {\n // Metadata\n documentGuid: metadata.documentGuid ?? null,\n isModified: metadata.isModified ?? false,\n version: metadata.version ?? null,\n // Stats\n words: stats.words ?? 0,\n characters: stats.characters ?? 0,\n paragraphs: stats.paragraphs ?? 0,\n // Pages\n pages: pageCount,\n };\n } catch (err) {\n console.warn('[DocxDiffEditor] Failed to get document info:', err);\n return null;\n }\n },\n\n /**\n * Get document core properties from docProps/core.xml.\n * Returns null if editor is not ready or properties unavailable.\n */\n async getProperties(): Promise<DocumentProperties | null> {\n if (!readyRef.current || !superdocRef.current) {\n return null;\n }\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const sd = superdocRef.current as any;\n const doc = sd.superdocStore?.documents?.[0];\n \n if (!doc) {\n return null;\n }\n\n const editor = doc.getEditor?.();\n if (!editor) {\n return null;\n }\n\n // Access core.xml via converter.convertedXml\n const coreXml = editor.converter?.convertedXml?.['docProps/core.xml'];\n if (!coreXml?.elements?.[0]?.elements) {\n return null;\n }\n\n // The root element is cp:coreProperties, get its children\n const elements = coreXml.elements[0].elements;\n\n // Property mapping from XML element names to our interface\n const xmlToKey: Record<string, keyof DocumentProperties> = {\n 'dc:title': 'title',\n 'dc:creator': 'author',\n 'dc:subject': 'subject',\n 'dc:description': 'description',\n 'cp:keywords': 'keywords',\n 'cp:category': 'category',\n 'cp:lastModifiedBy': 'lastModifiedBy',\n 'cp:revision': 'revision',\n 'dcterms:created': 'created',\n 'dcterms:modified': 'modified',\n };\n\n const props: DocumentProperties = {};\n\n // Parse elements from the core properties\n for (const el of elements) {\n const key = xmlToKey[el.name];\n if (key) {\n const textValue = el.elements?.[0]?.text;\n if (textValue !== undefined && textValue !== null) {\n if (key === 'created' || key === 'modified') {\n // Convert ISO string to Date object\n props[key] = new Date(textValue);\n } else {\n props[key] = textValue;\n }\n }\n }\n }\n\n return props;\n } catch (err) {\n console.warn('[DocxDiffEditor] Failed to get properties:', err);\n return null;\n }\n },\n\n /**\n * Set document core properties (partial update).\n * Only provided properties will be updated; others are preserved.\n * Preserves XML namespaces and structure for valid DOCX output.\n * Returns true on success, false on failure.\n */\n async setProperties(properties: Partial<DocumentProperties>): Promise<boolean> {\n if (!readyRef.current || !superdocRef.current) {\n return false;\n }\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const sd = superdocRef.current as any;\n const doc = sd.superdocStore?.documents?.[0];\n \n if (!doc) {\n return false;\n }\n\n const editor = doc.getEditor?.();\n if (!editor) {\n return false;\n }\n\n // Access core.xml via converter.convertedXml\n const coreXml = editor.converter?.convertedXml?.['docProps/core.xml'];\n if (!coreXml?.elements?.[0]?.elements) {\n console.warn('[DocxDiffEditor] docProps/core.xml not found or invalid structure');\n return false;\n }\n\n // The root element is cp:coreProperties, get its children\n const coreProperties = coreXml.elements[0];\n const elements = coreProperties.elements;\n\n // Property mapping from our interface to XML element names\n const keyToXml: Record<string, string> = {\n title: 'dc:title',\n author: 'dc:creator',\n subject: 'dc:subject',\n description: 'dc:description',\n keywords: 'cp:keywords',\n category: 'cp:category',\n lastModifiedBy: 'cp:lastModifiedBy',\n revision: 'cp:revision',\n created: 'dcterms:created',\n modified: 'dcterms:modified',\n };\n\n // Update or add properties\n for (const [key, value] of Object.entries(properties)) {\n if (value === undefined) continue;\n\n const xmlName = keyToXml[key];\n if (!xmlName) continue;\n\n // Convert Date objects to ISO strings\n const textValue = value instanceof Date ? value.toISOString() : String(value);\n\n // Find existing element\n const existingProp = elements.find((el: { name: string }) => el.name === xmlName);\n\n if (existingProp) {\n // Update existing - preserve structure, only change text\n if (!existingProp.elements) {\n existingProp.elements = [];\n }\n if (existingProp.elements[0]) {\n existingProp.elements[0].text = textValue;\n } else {\n existingProp.elements.push({ type: 'text', text: textValue });\n }\n } else {\n // Add new property element\n elements.push({\n type: 'element',\n name: xmlName,\n elements: [{ type: 'text', text: textValue }],\n });\n }\n }\n\n // Mark document as modified\n if (editor.converter) {\n editor.converter.documentModified = true;\n }\n\n // Serialize and register for export\n // This ensures changes are included when downloading the DOCX\n if (editor.converter?.schemaToXml) {\n const serialized = editor.converter.schemaToXml(coreXml.elements[0]);\n \n if (!editor.options) {\n editor.options = {};\n }\n if (!editor.options.customUpdatedFiles) {\n editor.options.customUpdatedFiles = {};\n }\n \n editor.options.customUpdatedFiles['docProps/core.xml'] = String(serialized);\n editor.options.isCustomXmlChanged = true;\n }\n\n return true;\n } catch (err) {\n console.warn('[DocxDiffEditor] Failed to set properties:', err);\n return false;\n }\n },\n\n /**\n * Parse HTML string to ProseMirror JSON using a hidden SuperDoc instance.\n * Useful for converting HTML content before using with other methods.\n */\n async parseHtml(html: string): Promise<ProseMirrorJSON> {\n if (!SuperDocRef.current) {\n throw new Error('Editor not initialized');\n }\n\n return parseHtmlToJson(html, SuperDocRef.current);\n },\n }),\n [\n sourceJson,\n mergedJson,\n diffResult,\n templateDocx,\n author,\n destroySuperdoc,\n createSuperdoc,\n setEditorContent,\n enableReviewMode,\n setEditingMode,\n onSourceLoaded,\n onComparisonComplete,\n handleError,\n ]\n );\n\n // =========================================================================\n // Render\n // =========================================================================\n\n return (\n <div className={`dde-container ${className}`.trim()}>\n {/* Loading overlay */}\n {isLoading && (\n <div className=\"dde-loading\">\n <div className=\"dde-loading__spinner\" />\n <p className=\"dde-loading__text\">Loading document...</p>\n </div>\n )}\n\n {/* Error overlay */}\n {error && (\n <div className=\"dde-error\">\n <div className=\"dde-error__icon\">\n <svg\n className=\"dde-error__svg\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"2\"\n d=\"M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"\n />\n </svg>\n </div>\n <p className=\"dde-error__title\">Failed to load document</p>\n <p className=\"dde-error__message\">{error}</p>\n </div>\n )}\n\n {/* Toolbar */}\n {showToolbar && (\n <div\n ref={toolbarRef}\n className={`dde-toolbar ${toolbarClassName}`.trim()}\n />\n )}\n\n {/* Editor container */}\n <div\n ref={containerRef}\n className={`dde-editor ${editorClassName}`.trim()}\n />\n\n {/* Structural Changes Pane */}\n {!hideStructuralPane && !isPaneDismissed && structuralChanges.length > 0 && (\n <StructuralChangesPane\n changes={structuralChanges}\n position={structuralPanePosition}\n initiallyCollapsed={structuralPaneCollapsed}\n onAccept={handleAcceptStructuralChange}\n onReject={handleRejectStructuralChange}\n onAcceptAll={handleAcceptAllStructural}\n onRejectAll={handleRejectAllStructural}\n onNavigate={handleNavigateToChange}\n onDismiss={handlePaneDismiss}\n />\n )}\n </div>\n );\n }\n);\n\nexport default DocxDiffEditor;\n","/**\n * Services barrel export\n */\n\nexport {\n detectContentType,\n parseDocxFile,\n parseHtmlToJson,\n isProseMirrorJSON,\n} from './contentResolver';\n\nexport { diffDocuments } from './documentDiffer';\n\nexport { mergeDocuments, createSimpleMergedDocument } from './mergeDocuments';\n\nexport {\n createTrackInsertMark,\n createTrackDeleteMark,\n createTrackFormatMark,\n addMarkToTextNode,\n createTextNode,\n markAllAsDeleted,\n markAllAsInserted,\n cloneNode,\n normalizeMarksForRendering,\n} from './trackChangeInjector';\n\nexport {\n extractEnrichedChanges,\n extractEnrichedChangesWithStructural,\n} from './changeContextExtractor';\n\n// Block-level diffing services\nexport {\n generateFingerprint,\n buildFingerprintTree,\n extractBlockFingerprints,\n calculateSimilarity,\n calculateTextSimilarity,\n getNodeTextSimilarity,\n} from './nodeFingerprint';\n\nexport {\n alignNodes,\n alignDocuments,\n alignChildren,\n alignTableRows,\n alignTableCells,\n alignListItems,\n} from './nodeAligner';\n\nexport type { AlignmentResult } from './nodeAligner';\n\nexport {\n compareAttrs,\n compareNodeAttrs,\n hasAttrChanges,\n formatAttrDiffs,\n summarizeAttrChanges,\n} from './attrComparer';\n\nexport {\n diffTables,\n isTable,\n isTableRow,\n isTableCell,\n getTableLocation,\n getRowLocation,\n getCellLocation,\n getRowPreview,\n} from './tableBlockDiffer';\n\nexport type { TableDiffResult } from './tableBlockDiffer';\n\nexport {\n diffLists,\n isList,\n isListItem,\n getListType,\n getListLocation,\n getListItemLocation,\n getListItemPreview,\n countListItems,\n} from './listBlockDiffer';\n\nexport type { ListDiffResult } from './listBlockDiffer';\n\nexport {\n isImage,\n isHorizontalRule,\n isHardBreak,\n isPageBreak,\n isEmbedded,\n isAtomicNode,\n getImageIdentifier,\n imagesMatch,\n findImages,\n diffImages,\n getImageLocation,\n getImagePreview,\n getAtomicNodePreview,\n} from './nonTextNodeDiffer';\n\nexport {\n processStructuralChanges,\n buildMergedDocumentWithStructuralChanges,\n generateStructuralChangeSummary,\n} from './blockLevelMerger';\n\nexport type { BlockMergeResult } from './blockLevelMerger';\n\n// Structural merger (Phase 6b - structure-aware merge)\nexport { mergeWithStructuralAwareness } from './structuralMerger';\n\nexport type { StructuralMergeResult } from './structuralMerger';\n\n// Run properties sync (ensures marks are synced to runProperties for rendering)\nexport { marksToRunProperties, normalizeRunProperties } from './runPropertiesSync';\n\n// Color utilities (shared color conversion functions)\nexport {\n CSS_NAMED_COLORS,\n colorToHexWithoutHash,\n ensureValidCssColor,\n isNamedColor,\n} from './colorUtils';\n","/**\n * Block Level Merger Service\n * \n * Handles merging of structural changes (tables, lists, images)\n * with shared IDs for all marks within a structural change.\n * \n * This allows the Structural Changes Pane to accept/reject\n * entire structural units (e.g., a whole table row) with a single action.\n */\n\nimport { v4 as uuidv4 } from 'uuid';\nimport type {\n ProseMirrorJSON,\n ProseMirrorNode,\n StructuralChange,\n StructuralChangeInfo,\n TrackChangeAuthor,\n HybridDiffResult,\n} from '../types';\nimport {\n createTrackInsertMark,\n createTrackDeleteMark,\n normalizeMarksForRendering,\n} from './trackChangeInjector';\nimport { alignDocuments } from './nodeAligner';\nimport { diffTables, isTable, getRowLocation, getRowPreview } from './tableBlockDiffer';\nimport { diffLists, isList, getListItemLocation, getListItemPreview } from './listBlockDiffer';\nimport { diffImages, getImageLocation, getImagePreview } from './nonTextNodeDiffer';\nimport { DEFAULT_AUTHOR } from '../constants';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Result of block-level merging\n */\nexport interface BlockMergeResult {\n /** The merged document */\n mergedDoc: ProseMirrorNode;\n /** Structural change metadata for the pane */\n structuralChangeInfos: StructuralChangeInfo[];\n /** Summary of structural changes */\n structuralChangeSummary: string[];\n}\n\n// ============================================================================\n// Node Marking Functions\n// ============================================================================\n\n/**\n * Mark all text in a node as inserted (with shared ID).\n * Used for inserted blocks (rows, paragraphs, list items).\n * Normalizes existing marks to ensure valid CSS color format.\n */\nfunction markAllTextAsInserted(\n node: ProseMirrorNode,\n sharedId: string,\n author: TrackChangeAuthor\n): ProseMirrorNode {\n if (node.type === 'text') {\n // Normalize existing marks to ensure valid CSS colors (# prefix for hex)\n const existingMarks = normalizeMarksForRendering(node.marks || []);\n return {\n ...node,\n marks: [...existingMarks, createTrackInsertMark(author, sharedId)],\n };\n }\n\n if (node.content && Array.isArray(node.content)) {\n return {\n ...node,\n content: node.content.map((child: ProseMirrorNode) =>\n markAllTextAsInserted(child, sharedId, author)\n ),\n };\n }\n\n return node;\n}\n\n/**\n * Mark all text in a node as deleted (with shared ID).\n * Used for deleted blocks (rows, paragraphs, list items).\n * Normalizes existing marks to ensure valid CSS color format.\n */\nfunction markAllTextAsDeleted(\n node: ProseMirrorNode,\n sharedId: string,\n author: TrackChangeAuthor\n): ProseMirrorNode {\n if (node.type === 'text') {\n // Normalize existing marks to ensure valid CSS colors (# prefix for hex)\n const existingMarks = normalizeMarksForRendering(node.marks || []);\n return {\n ...node,\n marks: [...existingMarks, createTrackDeleteMark(author, sharedId)],\n };\n }\n\n if (node.content && Array.isArray(node.content)) {\n return {\n ...node,\n content: node.content.map((child: ProseMirrorNode) =>\n markAllTextAsDeleted(child, sharedId, author)\n ),\n };\n }\n\n return node;\n}\n\n/**\n * Deep clone a node.\n */\nfunction cloneNode(node: ProseMirrorNode): ProseMirrorNode {\n return JSON.parse(JSON.stringify(node));\n}\n\n/**\n * Extract text content from a node for preview.\n */\nfunction extractTextPreview(node: ProseMirrorNode, maxLength: number = 50): string {\n const texts: string[] = [];\n \n function extract(n: ProseMirrorNode): void {\n if (n.type === 'text') {\n texts.push(n.text || '');\n }\n if (n.content) {\n for (const child of n.content) {\n extract(child);\n }\n }\n }\n \n extract(node);\n const text = texts.join('').trim();\n \n if (text.length > maxLength) {\n return text.substring(0, maxLength - 3) + '...';\n }\n return text || '(empty)';\n}\n\n// ============================================================================\n// Block-Level Merge Functions\n// ============================================================================\n\n/**\n * Process structural changes and generate marked blocks with shared IDs.\n */\nexport function processStructuralChanges(\n docA: ProseMirrorNode,\n docB: ProseMirrorNode,\n author: TrackChangeAuthor = DEFAULT_AUTHOR\n): { changes: StructuralChange[]; infos: StructuralChangeInfo[] } {\n const changes: StructuralChange[] = [];\n const infos: StructuralChangeInfo[] = [];\n\n // Align top-level blocks\n const alignment = alignDocuments(docA, docB);\n\n // Track table and list indices for location strings\n let tableIndex = 0;\n let listIndex = 0;\n let paragraphIndex = 0;\n\n // Process top-level insertions\n for (const inserted of alignment.insertions) {\n const node = inserted.node;\n const sharedId = uuidv4();\n const date = new Date().toISOString();\n\n let type: StructuralChangeInfo['type'] = 'paragraphInsert';\n let location = '';\n let preview = '';\n\n if (isTable(node)) {\n type = 'rowInsert'; // Treat as table insertion (could add 'tableInsert' type)\n location = `New table at position ${inserted.path[0] + 1}`;\n preview = `Table with ${node.content?.length || 0} rows`;\n tableIndex++;\n } else if (isList(node)) {\n type = 'listItemInsert';\n location = `New list at position ${inserted.path[0] + 1}`;\n preview = `List with ${node.content?.length || 0} items`;\n listIndex++;\n } else {\n type = 'paragraphInsert';\n paragraphIndex++;\n location = `Paragraph ${paragraphIndex}`;\n preview = extractTextPreview(node);\n }\n\n changes.push({\n id: sharedId,\n type,\n nodeType: node.type,\n path: inserted.path,\n node: markAllTextAsInserted(cloneNode(node), sharedId, author),\n });\n\n infos.push({\n id: sharedId,\n type,\n nodeType: node.type,\n location,\n preview,\n author,\n date,\n });\n }\n\n // Process top-level deletions\n for (const deleted of alignment.deletions) {\n const node = deleted.node;\n const sharedId = uuidv4();\n const date = new Date().toISOString();\n\n let type: StructuralChangeInfo['type'] = 'paragraphDelete';\n let location = '';\n let preview = '';\n\n if (isTable(node)) {\n type = 'rowDelete';\n location = `Deleted table at position ${deleted.path[0] + 1}`;\n preview = `Table with ${node.content?.length || 0} rows`;\n } else if (isList(node)) {\n type = 'listItemDelete';\n location = `Deleted list at position ${deleted.path[0] + 1}`;\n preview = `List with ${node.content?.length || 0} items`;\n } else {\n type = 'paragraphDelete';\n location = `Deleted paragraph`;\n preview = extractTextPreview(node);\n }\n\n changes.push({\n id: sharedId,\n type,\n nodeType: node.type,\n path: deleted.path,\n node: markAllTextAsDeleted(cloneNode(node), sharedId, author),\n });\n\n infos.push({\n id: sharedId,\n type,\n nodeType: node.type,\n location,\n preview,\n author,\n date,\n });\n }\n\n // Process matched blocks for internal changes (tables, lists)\n for (const match of alignment.matched) {\n const nodeA = docA.content?.[match.pathA[0]];\n const nodeB = docB.content?.[match.pathB[0]];\n\n if (!nodeA || !nodeB) continue;\n\n // Check for table-specific changes\n if (isTable(nodeA) && isTable(nodeB)) {\n tableIndex++;\n const tableResult = diffTables(nodeA, nodeB, match.pathA, match.pathB);\n\n // Process row changes\n for (const rowChange of tableResult.rowChanges) {\n const sharedId = rowChange.id;\n const date = new Date().toISOString();\n const rowIndex = rowChange.path[rowChange.path.length - 1];\n\n const isInsert = rowChange.type === 'rowInsert';\n const location = getRowLocation(rowChange.path, rowIndex, tableIndex - 1);\n const preview = getRowPreview(rowChange.node);\n\n // Update the node with marks\n const markedNode = isInsert\n ? markAllTextAsInserted(cloneNode(rowChange.node), sharedId, author)\n : markAllTextAsDeleted(cloneNode(rowChange.node), sharedId, author);\n\n changes.push({\n ...rowChange,\n node: markedNode,\n });\n\n infos.push({\n id: sharedId,\n type: rowChange.type,\n nodeType: 'tableRow',\n location,\n preview,\n author,\n date,\n });\n }\n }\n\n // Check for list-specific changes\n if (isList(nodeA) && isList(nodeB)) {\n listIndex++;\n const listResult = diffLists(nodeA, nodeB, match.pathA, match.pathB);\n\n // Process item changes\n for (const itemChange of listResult.itemChanges) {\n const sharedId = itemChange.id;\n const date = new Date().toISOString();\n const itemIndex = itemChange.path[itemChange.path.length - 1];\n\n const isInsert = itemChange.type === 'listItemInsert';\n const location = getListItemLocation(itemChange.path, itemIndex, listIndex - 1);\n const preview = getListItemPreview(itemChange.node);\n\n // Update the node with marks\n const markedNode = isInsert\n ? markAllTextAsInserted(cloneNode(itemChange.node), sharedId, author)\n : markAllTextAsDeleted(cloneNode(itemChange.node), sharedId, author);\n\n changes.push({\n ...itemChange,\n node: markedNode,\n });\n\n infos.push({\n id: sharedId,\n type: itemChange.type,\n nodeType: 'listItem',\n location,\n preview,\n author,\n date,\n });\n }\n }\n }\n\n // Process image changes\n const imageChanges = diffImages(docA, docB);\n\n for (const imgInsert of imageChanges.inserted) {\n const sharedId = imgInsert.id;\n const date = new Date().toISOString();\n\n infos.push({\n id: sharedId,\n type: 'imageInsert',\n nodeType: 'image',\n location: getImageLocation(imgInsert.path),\n preview: getImagePreview(imgInsert.node),\n author,\n date,\n });\n\n changes.push(imgInsert);\n }\n\n for (const imgDelete of imageChanges.deleted) {\n const sharedId = imgDelete.id;\n const date = new Date().toISOString();\n\n infos.push({\n id: sharedId,\n type: 'imageDelete',\n nodeType: 'image',\n location: getImageLocation(imgDelete.path),\n preview: getImagePreview(imgDelete.node),\n author,\n date,\n });\n\n changes.push(imgDelete);\n }\n\n return { changes, infos };\n}\n\n/**\n * Build the merged document with structural changes applied.\n * Combines the original character-level merge with block-level changes.\n */\nexport function buildMergedDocumentWithStructuralChanges(\n baseMergedDoc: ProseMirrorNode,\n structuralChanges: StructuralChange[],\n docA: ProseMirrorNode,\n docB: ProseMirrorNode\n): ProseMirrorNode {\n // For now, the structural changes are already marked in processStructuralChanges\n // The merged document from the base merge already contains most changes\n // We need to integrate the structural changes into the document\n \n // Clone the base merged document\n const result = cloneNode(baseMergedDoc);\n\n // Insert structural insertions at appropriate positions\n // Delete structural deletions by including them with delete marks\n \n // This is a simplified approach - full implementation would need\n // careful position tracking. For now, structural changes are\n // handled through the existing merge process, and this function\n // serves as an integration point for future enhancements.\n\n return result;\n}\n\n/**\n * Generate a summary of structural changes.\n */\nexport function generateStructuralChangeSummary(\n infos: StructuralChangeInfo[]\n): string[] {\n const summary: string[] = [];\n\n const rowInserts = infos.filter((i) => i.type === 'rowInsert').length;\n const rowDeletes = infos.filter((i) => i.type === 'rowDelete').length;\n const paragraphInserts = infos.filter((i) => i.type === 'paragraphInsert').length;\n const paragraphDeletes = infos.filter((i) => i.type === 'paragraphDelete').length;\n const listItemInserts = infos.filter((i) => i.type === 'listItemInsert').length;\n const listItemDeletes = infos.filter((i) => i.type === 'listItemDelete').length;\n const imageInserts = infos.filter((i) => i.type === 'imageInsert').length;\n const imageDeletes = infos.filter((i) => i.type === 'imageDelete').length;\n\n if (rowInserts > 0) summary.push(`${rowInserts} row(s) inserted`);\n if (rowDeletes > 0) summary.push(`${rowDeletes} row(s) deleted`);\n if (paragraphInserts > 0) summary.push(`${paragraphInserts} paragraph(s) inserted`);\n if (paragraphDeletes > 0) summary.push(`${paragraphDeletes} paragraph(s) deleted`);\n if (listItemInserts > 0) summary.push(`${listItemInserts} list item(s) inserted`);\n if (listItemDeletes > 0) summary.push(`${listItemDeletes} list item(s) deleted`);\n if (imageInserts > 0) summary.push(`${imageInserts} image(s) inserted`);\n if (imageDeletes > 0) summary.push(`${imageDeletes} image(s) deleted`);\n\n return summary;\n}\n","/**\n * Embedded DOCX template\n *\n * This is a base64-encoded blank DOCX file created with Microsoft Word.\n * It provides the complete schema, styles, themes, and fonts needed to\n * initialize SuperDoc when working with HTML or JSON content.\n *\n * The DOCX contains all standard Word document components:\n * - [Content_Types].xml\n * - _rels/.rels\n * - word/document.xml\n * - word/_rels/document.xml.rels\n * - word/styles.xml (full Word styles)\n * - word/settings.xml\n * - word/fontTable.xml\n * - word/webSettings.xml\n * - word/theme/theme1.xml\n * - docProps/core.xml\n * - docProps/app.xml\n */\n\n/**\n * Base64-encoded blank DOCX file created with Microsoft Word.\n */\nconst BLANK_DOCX_BASE64 = `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`;\n\n/**\n * Convert base64 string to Blob\n */\nfunction base64ToBlob(base64: string, mimeType: string): Blob {\n const byteCharacters = atob(base64.replace(/\\s/g, ''));\n const byteNumbers = new Array(byteCharacters.length);\n\n for (let i = 0; i < byteCharacters.length; i++) {\n byteNumbers[i] = byteCharacters.charCodeAt(i);\n }\n\n const byteArray = new Uint8Array(byteNumbers);\n return new Blob([byteArray], { type: mimeType });\n}\n\n/**\n * Convert base64 string to File\n */\nfunction base64ToFile(base64: string, filename: string, mimeType: string): File {\n const blob = base64ToBlob(base64, mimeType);\n return new File([blob], filename, { type: mimeType });\n}\n\n/**\n * Get the blank DOCX template as a File object\n */\nexport function getBlankTemplateFile(): File {\n return base64ToFile(\n BLANK_DOCX_BASE64,\n 'blank-template.docx',\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'\n );\n}\n\n/**\n * Get the blank DOCX template as a Blob\n */\nexport function getBlankTemplateBlob(): Blob {\n return base64ToBlob(\n BLANK_DOCX_BASE64,\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'\n );\n}\n\n/**\n * Check if a File is a valid DOCX file (basic check)\n */\nexport function isValidDocxFile(file: File): boolean {\n const validTypes = [\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n 'application/msword',\n ];\n return validTypes.includes(file.type) || file.name.endsWith('.docx');\n}\n"]}
1
+ {"version":3,"sources":["../src/services/nodeFingerprint.ts","../src/components/StructuralChangesPane.tsx","../src/constants.ts","../src/services/colorUtils.ts","../src/services/trackChangeInjector.ts","../src/services/runPropertiesSync.ts","../src/services/contentResolver.ts","../src/services/documentDiffer.ts","../src/services/changeContextExtractor.ts","../src/services/nodeAligner.ts","../src/services/mergeDocuments.ts","../src/services/attrComparer.ts","../src/services/tableBlockDiffer.ts","../src/services/listBlockDiffer.ts","../src/services/nonTextNodeDiffer.ts","../src/services/structuralMerger.ts","../src/DocxDiffEditor.tsx","../src/services/index.ts","../src/services/blockLevelMerger.ts","../src/blankTemplate.ts"],"names":["extractTextContent","useState","useEffect","useCallback","jsxs","jsx","Fragment","uuidv4","DiffMatchPatch","i","j","generateFingerprint","deepEqual","simpleHash","cloneNode","forwardRef","DocxDiffEditor","useRef","error","useImperativeHandle","markAllTextAsInserted","markAllTextAsDeleted","extractTextPreview"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Node Fingerprint Service\n * \n * Generates content-based fingerprints for ProseMirror nodes.\n * Fingerprints are used to match nodes between documents during diffing.\n * \n * Key principle: Two nodes with the same content (ignoring styles/attrs)\n * should produce the same or similar fingerprints.\n */\n\nimport type { ProseMirrorJSON, FingerprintedNode } from '../types';\n\n// ============================================================================\n// Fingerprint Generation\n// ============================================================================\n\n/**\n * Extract text content from a node recursively.\n * Used as the basis for fingerprint generation.\n */\nfunction extractTextContent(node: ProseMirrorJSON): string {\n if (!node) return '';\n\n if (node.type === 'text' && node.text) {\n return node.text;\n }\n\n if (node.content && Array.isArray(node.content)) {\n return node.content.map(extractTextContent).join('');\n }\n\n return '';\n}\n\n/**\n * Simple hash function for strings.\n * Uses djb2 algorithm - fast and produces reasonably distributed hashes.\n */\nfunction simpleHash(str: string): string {\n let hash = 5381;\n for (let i = 0; i < str.length; i++) {\n hash = ((hash << 5) + hash) ^ str.charCodeAt(i);\n }\n // Convert to unsigned 32-bit and then to hex\n return (hash >>> 0).toString(16);\n}\n\n/**\n * Normalize text for fingerprinting.\n * Removes extra whitespace, lowercases, trims.\n */\nfunction normalizeText(text: string): string {\n return text\n .toLowerCase()\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\n/**\n * Generate a fingerprint for a single node.\n * \n * Fingerprint format by node type:\n * - text: \"t:{hash}\"\n * - paragraph: \"p:{hash}\"\n * - heading: \"h{level}:{hash}\"\n * - table: \"table:{rowCount}:{hash}\"\n * - tableRow: \"tr:{cellCount}:{hash}\"\n * - tableCell: \"tc:{hash}\"\n * - listItem: \"li:{hash}\"\n * - image: \"img:{srcHash}\"\n * - hardBreak: \"br\"\n * - horizontalRule: \"hr\"\n * - other: \"{type}:{hash}\"\n */\nexport function generateFingerprint(node: ProseMirrorJSON): string {\n if (!node) return '';\n\n const type = node.type || 'unknown';\n\n switch (type) {\n case 'text': {\n const text = normalizeText(node.text || '');\n return `t:${simpleHash(text)}`;\n }\n\n case 'paragraph': {\n const text = normalizeText(extractTextContent(node));\n return `p:${simpleHash(text)}`;\n }\n\n case 'heading': {\n const level = node.attrs?.level || 1;\n const text = normalizeText(extractTextContent(node));\n return `h${level}:${simpleHash(text)}`;\n }\n\n case 'table': {\n const rowCount = node.content?.length || 0;\n // Include child fingerprints for more accurate matching\n const childFps = (node.content || [])\n .map((child: ProseMirrorJSON) => generateFingerprint(child))\n .join('|');\n return `table:${rowCount}:${simpleHash(childFps)}`;\n }\n\n case 'tableRow': {\n const cellCount = node.content?.length || 0;\n const childFps = (node.content || [])\n .map((child: ProseMirrorJSON) => generateFingerprint(child))\n .join('|');\n return `tr:${cellCount}:${simpleHash(childFps)}`;\n }\n\n case 'tableCell':\n case 'tableHeader': {\n const text = normalizeText(extractTextContent(node));\n return `tc:${simpleHash(text)}`;\n }\n\n case 'bulletList':\n case 'orderedList': {\n const itemCount = node.content?.length || 0;\n const childFps = (node.content || [])\n .map((child: ProseMirrorJSON) => generateFingerprint(child))\n .join('|');\n return `list:${itemCount}:${simpleHash(childFps)}`;\n }\n\n case 'listItem': {\n const text = normalizeText(extractTextContent(node));\n return `li:${simpleHash(text)}`;\n }\n\n case 'image': {\n // Use src attribute as the basis for image fingerprint\n const src = node.attrs?.src || '';\n return `img:${simpleHash(src)}`;\n }\n\n case 'hardBreak':\n return 'br';\n\n case 'horizontalRule':\n return 'hr';\n\n case 'codeBlock': {\n const text = normalizeText(extractTextContent(node));\n const lang = node.attrs?.language || '';\n return `code:${lang}:${simpleHash(text)}`;\n }\n\n case 'blockquote': {\n const text = normalizeText(extractTextContent(node));\n return `bq:${simpleHash(text)}`;\n }\n\n // For doc and other container types, fingerprint based on content\n case 'doc': {\n const childFps = (node.content || [])\n .map((child: ProseMirrorJSON) => generateFingerprint(child))\n .join('|');\n return `doc:${simpleHash(childFps)}`;\n }\n\n // Default: use type and text content\n default: {\n const text = normalizeText(extractTextContent(node));\n return `${type}:${simpleHash(text)}`;\n }\n }\n}\n\n// ============================================================================\n// Fingerprinted Node Tree\n// ============================================================================\n\n/**\n * Build a tree of fingerprinted nodes from a document.\n * Each node gets a fingerprint and path for later reference.\n */\nexport function buildFingerprintTree(\n node: ProseMirrorJSON,\n path: number[] = []\n): FingerprintedNode {\n const fingerprint = generateFingerprint(node);\n \n const result: FingerprintedNode = {\n node,\n fingerprint,\n path: [...path],\n };\n\n if (node.content && Array.isArray(node.content)) {\n result.children = node.content.map((child: ProseMirrorJSON, index: number) =>\n buildFingerprintTree(child, [...path, index])\n );\n }\n\n return result;\n}\n\n/**\n * Extract top-level block nodes with their fingerprints.\n * These are the nodes we'll align between documents.\n */\nexport function extractBlockFingerprints(doc: ProseMirrorJSON): FingerprintedNode[] {\n if (!doc || !doc.content || !Array.isArray(doc.content)) {\n return [];\n }\n\n return doc.content.map((child: ProseMirrorJSON, index: number) => ({\n node: child,\n fingerprint: generateFingerprint(child),\n path: [index],\n }));\n}\n\n// ============================================================================\n// Similarity Calculation\n// ============================================================================\n\n/**\n * Calculate similarity between two fingerprints.\n * Returns a value between 0.0 (completely different) and 1.0 (identical).\n * \n * For identical fingerprints, returns 1.0.\n * For fingerprints of the same type, calculates content similarity.\n */\nexport function calculateSimilarity(fpA: string, fpB: string): number {\n // Identical fingerprints = perfect match\n if (fpA === fpB) return 1.0;\n\n // Extract type prefix\n const typeA = fpA.split(':')[0];\n const typeB = fpB.split(':')[0];\n\n // Different types = no match\n if (typeA !== typeB) return 0.0;\n\n // Same type but different content = partial match\n // Use simple heuristic based on prefix length\n // This is a simplified approach - could be enhanced with actual content comparison\n \n // For now, same type gives a base similarity\n // The actual matching will use this along with content comparison\n return 0.3;\n}\n\n/**\n * Calculate text similarity using Levenshtein distance.\n * Returns a value between 0.0 and 1.0.\n */\nexport function calculateTextSimilarity(textA: string, textB: string): number {\n const a = normalizeText(textA);\n const b = normalizeText(textB);\n\n if (a === b) return 1.0;\n if (a.length === 0 || b.length === 0) return 0.0;\n\n // For very different lengths, quick reject\n const lenRatio = Math.min(a.length, b.length) / Math.max(a.length, b.length);\n if (lenRatio < 0.3) return lenRatio;\n\n // Calculate Levenshtein distance\n const distance = levenshteinDistance(a, b);\n const maxLen = Math.max(a.length, b.length);\n \n return 1 - (distance / maxLen);\n}\n\n/**\n * Levenshtein distance implementation.\n * Optimized for memory by only keeping two rows.\n */\nfunction levenshteinDistance(a: string, b: string): number {\n if (a.length === 0) return b.length;\n if (b.length === 0) return a.length;\n\n // Use two rows for memory efficiency\n let prevRow = Array.from({ length: b.length + 1 }, (_, i) => i);\n let currRow = new Array(b.length + 1);\n\n for (let i = 1; i <= a.length; i++) {\n currRow[0] = i;\n for (let j = 1; j <= b.length; j++) {\n const cost = a[i - 1] === b[j - 1] ? 0 : 1;\n currRow[j] = Math.min(\n prevRow[j] + 1, // deletion\n currRow[j - 1] + 1, // insertion\n prevRow[j - 1] + cost // substitution\n );\n }\n [prevRow, currRow] = [currRow, prevRow];\n }\n\n return prevRow[b.length];\n}\n\n/**\n * Get full text similarity between two nodes.\n */\nexport function getNodeTextSimilarity(nodeA: ProseMirrorJSON, nodeB: ProseMirrorJSON): number {\n const textA = extractTextContent(nodeA);\n const textB = extractTextContent(nodeB);\n return calculateTextSimilarity(textA, textB);\n}\n","/**\n * Structural Changes Pane Component\n * \n * A floating, collapsible panel that displays structural changes\n * (table rows, list items, images, etc.) with Accept/Reject controls.\n * \n * Uses SuperDoc's acceptTrackedChangeById/rejectTrackedChangeById commands\n * to handle accept/reject actions.\n */\n\nimport React, { useState, useCallback, useEffect } from 'react';\nimport type { StructuralChangeInfo, StructuralPanePosition } from '../types';\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface StructuralChangesPaneProps {\n /** Array of structural changes to display */\n changes: StructuralChangeInfo[];\n \n /** Position of the pane */\n position?: StructuralPanePosition;\n \n /** Start collapsed? */\n initiallyCollapsed?: boolean;\n \n /** Callback when a change is accepted */\n onAccept: (changeId: string) => void;\n \n /** Callback when a change is rejected */\n onReject: (changeId: string) => void;\n \n /** Callback when Accept All is clicked */\n onAcceptAll: () => void;\n \n /** Callback when Reject All is clicked */\n onRejectAll: () => void;\n \n /** Callback when a change is clicked (for navigation) */\n onNavigate?: (changeId: string) => void;\n \n /** Callback when pane is dismissed */\n onDismiss?: () => void;\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Get icon for change type\n */\nfunction getChangeIcon(type: StructuralChangeInfo['type']): string {\n switch (type) {\n case 'rowInsert':\n case 'columnInsert':\n case 'paragraphInsert':\n case 'listItemInsert':\n case 'imageInsert':\n return '➕';\n case 'rowDelete':\n case 'columnDelete':\n case 'paragraphDelete':\n case 'listItemDelete':\n case 'imageDelete':\n return '➖';\n case 'attrChange':\n return '✏️';\n default:\n return '•';\n }\n}\n\n/**\n * Get human-readable label for change type\n */\nfunction getChangeLabel(type: StructuralChangeInfo['type']): string {\n switch (type) {\n case 'rowInsert':\n return 'Row inserted';\n case 'rowDelete':\n return 'Row deleted';\n case 'columnInsert':\n return 'Column inserted';\n case 'columnDelete':\n return 'Column deleted';\n case 'paragraphInsert':\n return 'Paragraph inserted';\n case 'paragraphDelete':\n return 'Paragraph deleted';\n case 'listItemInsert':\n return 'List item inserted';\n case 'listItemDelete':\n return 'List item deleted';\n case 'imageInsert':\n return 'Image inserted';\n case 'imageDelete':\n return 'Image deleted';\n case 'attrChange':\n return 'Formatting changed';\n default:\n return 'Change';\n }\n}\n\n/**\n * Format date for display\n */\nfunction formatDate(isoDate: string): string {\n try {\n const date = new Date(isoDate);\n return date.toLocaleDateString(undefined, {\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n });\n } catch {\n return '';\n }\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport const StructuralChangesPane: React.FC<StructuralChangesPaneProps> = ({\n changes,\n position = 'bottom-right',\n initiallyCollapsed = false,\n onAccept,\n onReject,\n onAcceptAll,\n onRejectAll,\n onNavigate,\n onDismiss,\n}) => {\n const [isCollapsed, setIsCollapsed] = useState(initiallyCollapsed);\n const [isVisible, setIsVisible] = useState(true);\n const [isAnimatingOut, setIsAnimatingOut] = useState(false);\n\n // Auto-hide when no changes\n useEffect(() => {\n if (changes.length === 0) {\n setIsAnimatingOut(true);\n const timer = setTimeout(() => setIsVisible(false), 300);\n return () => clearTimeout(timer);\n } else {\n setIsVisible(true);\n setIsAnimatingOut(false);\n }\n }, [changes.length]);\n\n // Handle dismiss\n const handleDismiss = useCallback(() => {\n setIsAnimatingOut(true);\n setTimeout(() => {\n setIsVisible(false);\n onDismiss?.();\n }, 300);\n }, [onDismiss]);\n\n // Handle toggle collapse\n const handleToggleCollapse = useCallback(() => {\n setIsCollapsed((prev) => !prev);\n }, []);\n\n // Handle accept single change\n const handleAccept = useCallback((e: React.MouseEvent, changeId: string) => {\n e.stopPropagation();\n onAccept(changeId);\n }, [onAccept]);\n\n // Handle reject single change\n const handleReject = useCallback((e: React.MouseEvent, changeId: string) => {\n e.stopPropagation();\n onReject(changeId);\n }, [onReject]);\n\n // Handle navigate to change\n const handleNavigate = useCallback((changeId: string) => {\n onNavigate?.(changeId);\n }, [onNavigate]);\n\n // Don't render if not visible\n if (!isVisible) return null;\n\n // Position classes\n const positionClasses: Record<StructuralPanePosition, string> = {\n 'top-right': 'dde-pane--top-right',\n 'bottom-right': 'dde-pane--bottom-right',\n 'top-left': 'dde-pane--top-left',\n 'bottom-left': 'dde-pane--bottom-left',\n };\n\n return (\n <div\n className={`dde-structural-pane ${positionClasses[position]} ${\n isAnimatingOut ? 'dde-pane--animating-out' : ''\n } ${isCollapsed ? 'dde-pane--collapsed' : ''}`}\n role=\"region\"\n aria-label=\"Structural Changes\"\n >\n {/* Header */}\n <div className=\"dde-pane__header\" onClick={handleToggleCollapse}>\n <div className=\"dde-pane__title\">\n <span className=\"dde-pane__icon\">📋</span>\n <span className=\"dde-pane__label\">\n Structural Changes\n <span className=\"dde-pane__count\">{changes.length}</span>\n </span>\n </div>\n <div className=\"dde-pane__controls\">\n <button\n className=\"dde-pane__btn dde-pane__btn--collapse\"\n onClick={(e) => {\n e.stopPropagation();\n handleToggleCollapse();\n }}\n aria-label={isCollapsed ? 'Expand' : 'Collapse'}\n title={isCollapsed ? 'Expand' : 'Collapse'}\n >\n {isCollapsed ? '+' : '−'}\n </button>\n <button\n className=\"dde-pane__btn dde-pane__btn--close\"\n onClick={(e) => {\n e.stopPropagation();\n handleDismiss();\n }}\n aria-label=\"Close\"\n title=\"Close\"\n >\n ×\n </button>\n </div>\n </div>\n\n {/* Body - only visible when not collapsed */}\n {!isCollapsed && (\n <>\n <div className=\"dde-pane__body\">\n {changes.length === 0 ? (\n <div className=\"dde-pane__empty\">No structural changes</div>\n ) : (\n <ul className=\"dde-pane__list\">\n {changes.map((change) => (\n <li\n key={change.id}\n className=\"dde-pane__item\"\n onClick={() => handleNavigate(change.id)}\n >\n <div className=\"dde-pane__item-header\">\n <span className=\"dde-pane__item-icon\">\n {getChangeIcon(change.type)}\n </span>\n <span className=\"dde-pane__item-label\">\n {getChangeLabel(change.type)}\n </span>\n </div>\n <div className=\"dde-pane__item-location\">\n {change.location}\n </div>\n <div className=\"dde-pane__item-preview\">\n {change.preview}\n </div>\n <div className=\"dde-pane__item-meta\">\n <span className=\"dde-pane__item-author\">\n {change.author.name}\n </span>\n <span className=\"dde-pane__item-date\">\n {formatDate(change.date)}\n </span>\n </div>\n <div className=\"dde-pane__item-actions\">\n <button\n className=\"dde-pane__action dde-pane__action--accept\"\n onClick={(e) => handleAccept(e, change.id)}\n title=\"Accept change\"\n >\n Accept\n </button>\n <button\n className=\"dde-pane__action dde-pane__action--reject\"\n onClick={(e) => handleReject(e, change.id)}\n title=\"Reject change\"\n >\n Reject\n </button>\n </div>\n </li>\n ))}\n </ul>\n )}\n </div>\n\n {/* Footer with bulk actions */}\n {changes.length > 0 && (\n <div className=\"dde-pane__footer\">\n <button\n className=\"dde-pane__bulk-btn dde-pane__bulk-btn--accept\"\n onClick={onAcceptAll}\n >\n Accept All\n </button>\n <button\n className=\"dde-pane__bulk-btn dde-pane__bulk-btn--reject\"\n onClick={onRejectAll}\n >\n Reject All\n </button>\n </div>\n )}\n </>\n )}\n </div>\n );\n};\n\nexport default StructuralChangesPane;\n","/**\n * Constants for DocxDiffEditor\n */\n\nimport type { TrackChangeAuthor } from './types';\n\n/**\n * Default author for track changes\n */\nexport const DEFAULT_AUTHOR: TrackChangeAuthor = {\n name: 'DocxDiff Editor',\n email: 'editor@docxdiff.local',\n};\n\n/**\n * Default SuperDoc user (used for editor initialization)\n */\nexport const DEFAULT_SUPERDOC_USER = {\n name: 'DocxDiff User',\n email: 'user@docxdiff.local',\n};\n\n/**\n * Permissions allowed for track change resolution\n */\nexport const TRACK_CHANGE_PERMISSIONS = [\n 'RESOLVE_OWN',\n 'RESOLVE_OTHER',\n 'REJECT_OWN',\n 'REJECT_OTHER',\n];\n\n/**\n * CSS class prefix for all component styles\n */\nexport const CSS_PREFIX = 'dde';\n\n/**\n * Timeouts\n */\nexport const TIMEOUTS = {\n /** Timeout for document parsing (ms) */\n PARSE_TIMEOUT: 30000,\n /** Small delay for React settling (ms) */\n INIT_DELAY: 100,\n /** Cleanup delay (ms) */\n CLEANUP_DELAY: 100,\n};\n\n","/**\n * Color Utilities\n * \n * Shared color conversion utilities for consistent handling across the codebase.\n * Single source of truth for CSS named colors and color format conversions.\n */\n\n// ============================================================================\n// CSS Named Colors Map (Single Source of Truth)\n// ============================================================================\n\n/**\n * Map of CSS named colors to hex values WITHOUT the # prefix.\n * This is the canonical format - add # when needed for CSS, strip for DOCX.\n */\nexport const CSS_NAMED_COLORS: Record<string, string> = {\n // Basic colors\n black: '000000',\n white: 'ffffff',\n red: 'ff0000',\n green: '008000',\n blue: '0000ff',\n yellow: 'ffff00',\n cyan: '00ffff',\n magenta: 'ff00ff',\n \n // Extended colors\n orange: 'ffa500',\n pink: 'ffc0cb',\n purple: '800080',\n violet: 'ee82ee',\n brown: 'a52a2a',\n gray: '808080',\n grey: '808080',\n \n // Light variants\n lightblue: 'add8e6',\n lightgreen: '90ee90',\n lightgray: 'd3d3d3',\n lightgrey: 'd3d3d3',\n lightpink: 'ffb6c1',\n lightyellow: 'ffffe0',\n \n // Dark variants\n darkblue: '00008b',\n darkgreen: '006400',\n darkgray: 'a9a9a9',\n darkgrey: 'a9a9a9',\n darkred: '8b0000',\n \n // Other common colors\n navy: '000080',\n teal: '008080',\n maroon: '800000',\n olive: '808000',\n silver: 'c0c0c0',\n aqua: '00ffff',\n fuchsia: 'ff00ff',\n lime: '00ff00',\n coral: 'ff7f50',\n salmon: 'fa8072',\n gold: 'ffd700',\n indigo: '4b0082',\n crimson: 'dc143c',\n tomato: 'ff6347',\n chocolate: 'd2691e',\n tan: 'd2b48c',\n beige: 'f5f5dc',\n ivory: 'fffff0',\n khaki: 'f0e68c',\n lavender: 'e6e6fa',\n plum: 'dda0dd',\n orchid: 'da70d6',\n turquoise: '40e0d0',\n skyblue: '87ceeb',\n steelblue: '4682b4',\n slategray: '708090',\n slategrey: '708090',\n};\n\n// ============================================================================\n// Color Conversion Functions\n// ============================================================================\n\n/**\n * Convert a color value to hex format WITHOUT # prefix.\n * Used for DOCX runProperties.color.val which expects hex without #.\n * \n * Handles:\n * - Named colors: \"red\" → \"ff0000\"\n * - Hex with #: \"#ff0000\" → \"ff0000\"\n * - Hex without #: \"ff0000\" → \"ff0000\"\n * \n * @param color - The color value to convert\n * @returns Hex color without # prefix\n */\nexport function colorToHexWithoutHash(color: string): string {\n const trimmed = color.trim();\n const lowerColor = trimmed.toLowerCase();\n \n // Check if it's a named color\n if (CSS_NAMED_COLORS[lowerColor]) {\n return CSS_NAMED_COLORS[lowerColor];\n }\n \n // Strip # if present\n return trimmed.replace(/^#/, '');\n}\n\n/**\n * Ensure a color value is valid for CSS (with # prefix for hex).\n * Used for ProseMirror marks which need valid CSS colors.\n * \n * Handles:\n * - Named colors: \"red\" → \"#ff0000\"\n * - Hex without #: \"ff0000\" → \"#ff0000\"\n * - 3-char hex without #: \"f00\" → \"#f00\"\n * - Already valid: \"#ff0000\" → \"#ff0000\"\n * - RGB/HSL: \"rgb(255,0,0)\" → \"rgb(255,0,0)\" (unchanged)\n * \n * @param color - The color value to normalize\n * @returns Valid CSS color string, or undefined if invalid input\n */\nexport function ensureValidCssColor(color: unknown): string | undefined {\n if (typeof color !== 'string' || !color) {\n return undefined;\n }\n \n const trimmed = color.trim();\n const lowerColor = trimmed.toLowerCase();\n \n // If it's a named color, convert to hex with #\n if (CSS_NAMED_COLORS[lowerColor]) {\n return `#${CSS_NAMED_COLORS[lowerColor]}`;\n }\n \n // If it's a 6-character hex without #, add the #\n if (/^[0-9a-fA-F]{6}$/.test(trimmed)) {\n return `#${trimmed}`;\n }\n \n // If it's a 3-character hex without #, add the #\n if (/^[0-9a-fA-F]{3}$/.test(trimmed)) {\n return `#${trimmed}`;\n }\n \n // Already has # or is rgb/hsl/etc - return as-is\n return trimmed;\n}\n\n/**\n * Check if a string is a recognized named CSS color.\n * \n * @param color - The color value to check\n * @returns True if the color is a recognized named color\n */\nexport function isNamedColor(color: string): boolean {\n return CSS_NAMED_COLORS[color.toLowerCase().trim()] !== undefined;\n}\n","/**\n * Track Change Injector Service\n * Creates track change marks for insertions, deletions, and format changes.\n */\n\nimport { v4 as uuidv4 } from 'uuid';\nimport type { TrackChangeAuthor, ProseMirrorJSON, ProseMirrorMark } from '../types';\nimport { DEFAULT_AUTHOR } from '../constants';\nimport { ensureValidCssColor } from './colorUtils';\n\n/**\n * Check if a value is meaningful (not null, undefined, or empty string).\n */\nfunction isMeaningfulValue(value: unknown): boolean {\n return value !== null && value !== undefined && value !== '';\n}\n\n/**\n * Clean attrs by removing null, undefined, and empty string values.\n * This prevents SuperDoc's translateFormatChangesToEnglish from showing\n * \"Changed X from Y to undefined\" when properties don't exist in one side.\n */\nfunction cleanAttrs(attrs: Record<string, unknown>): Record<string, unknown> {\n const cleaned: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(attrs)) {\n if (isMeaningfulValue(value)) {\n cleaned[key] = value;\n }\n }\n return cleaned;\n}\n\n/**\n * Normalize a mark to ensure it has an `attrs` property and valid color format.\n * \n * SuperDoc requirements:\n * 1. parseFormatList filters out marks without `attrs`\n * 2. Color extension renderDOM uses attrs.color directly in CSS (needs # for hex)\n */\nfunction normalizeMark(mark: ProseMirrorMark): ProseMirrorMark {\n const attrs = { ...(mark.attrs || {}) };\n \n // Ensure color has valid CSS format (# prefix for hex colors)\n if (attrs.color !== undefined) {\n attrs.color = ensureValidCssColor(attrs.color);\n }\n \n return {\n type: mark.type,\n attrs,\n };\n}\n\n/**\n * Normalize a mark for use in trackFormat before/after arrays.\n * \n * This is stricter than normalizeMark - it also cleans attrs to remove\n * null/undefined/empty values. This prevents SuperDoc's bubble display from\n * showing \"Set font family to undefined\" when comparing marks with different\n * property sets.\n * \n * Example issue without cleaning:\n * - before: {fontFamily: \"Arial\", fontSize: \"12pt\"}\n * - after: {color: \"#ff0000\"} (no fontFamily property)\n * - Object.keys merge: [\"fontFamily\", \"fontSize\", \"color\"]\n * - afterValue for fontFamily = undefined → shows \"Changed font family from Arial to undefined\"\n */\nfunction normalizeMarkForTrackFormat(mark: ProseMirrorMark): ProseMirrorMark {\n let attrs = { ...(mark.attrs || {}) };\n \n // Ensure color has valid CSS format (# prefix for hex colors)\n if (attrs.color !== undefined) {\n attrs.color = ensureValidCssColor(attrs.color);\n }\n \n // Clean attrs to only include meaningful values\n attrs = cleanAttrs(attrs);\n \n return {\n type: mark.type,\n attrs,\n };\n}\n\n/**\n * Normalize an array of marks to ensure all have `attrs` property\n * and valid color formats.\n */\nfunction normalizeMarks(marks: ProseMirrorMark[]): ProseMirrorMark[] {\n return marks.map(normalizeMark);\n}\n\n/**\n * Normalize an array of marks for use in trackFormat before/after arrays.\n * Cleans attrs to remove null/undefined/empty values.\n */\nfunction normalizeMarksForTrackFormat(marks: ProseMirrorMark[]): ProseMirrorMark[] {\n return marks.map(normalizeMarkForTrackFormat);\n}\n\n/**\n * Normalize marks for DOM rendering.\n * Exported for use in other modules that apply marks to text nodes.\n */\nexport function normalizeMarksForRendering(marks: ProseMirrorMark[]): ProseMirrorMark[] {\n return normalizeMarks(marks);\n}\n\n/**\n * Create a trackInsert mark.\n * @param author - The author of the change\n * @param id - Optional ID to use (for linking with corresponding delete in replacements)\n */\nexport function createTrackInsertMark(\n author: TrackChangeAuthor = DEFAULT_AUTHOR,\n id?: string\n): ProseMirrorMark {\n return {\n type: 'trackInsert',\n attrs: {\n id: id ?? uuidv4(),\n author: author.name,\n authorEmail: author.email,\n authorImage: '',\n date: new Date().toISOString(),\n },\n };\n}\n\n/**\n * Create a trackDelete mark.\n * @param author - The author of the change\n * @param id - Optional ID to use (for linking with corresponding insert in replacements)\n */\nexport function createTrackDeleteMark(\n author: TrackChangeAuthor = DEFAULT_AUTHOR,\n id?: string\n): ProseMirrorMark {\n return {\n type: 'trackDelete',\n attrs: {\n id: id ?? uuidv4(),\n author: author.name,\n authorEmail: author.email,\n authorImage: '',\n date: new Date().toISOString(),\n },\n };\n}\n\n/**\n * Create a trackFormat mark.\n * \n * Note: SuperDoc's parseFormatList requires all marks in before/after arrays\n * to have both `type` and `attrs` properties. Marks without `attrs` get filtered out,\n * causing empty values in track change bubbles.\n * \n * We use normalizeMarksForTrackFormat which:\n * 1. Ensures all marks have `attrs` property (required by parseFormatList)\n * 2. Cleans attrs to remove null/undefined/empty values (prevents \"Set X to undefined\" bubbles)\n * 3. Normalizes color values to valid CSS format\n */\nexport function createTrackFormatMark(\n before: ProseMirrorMark[],\n after: ProseMirrorMark[],\n author: TrackChangeAuthor = DEFAULT_AUTHOR\n): ProseMirrorMark {\n // Normalize marks for trackFormat - cleans attrs to only include meaningful values\n // This prevents SuperDoc's translateFormatChangesToEnglish from showing\n // \"Changed X from Y to undefined\" when comparing marks with different property sets\n const normalizedBefore = normalizeMarksForTrackFormat(before);\n const normalizedAfter = normalizeMarksForTrackFormat(after);\n\n return {\n type: 'trackFormat',\n attrs: {\n id: uuidv4(),\n author: author.name,\n authorEmail: author.email,\n authorImage: '',\n date: new Date().toISOString(),\n before: normalizedBefore,\n after: normalizedAfter,\n },\n };\n}\n\n/**\n * Add a mark to a text node, preserving existing marks.\n */\nexport function addMarkToTextNode(\n node: ProseMirrorJSON,\n mark: ProseMirrorMark\n): ProseMirrorJSON {\n if (node.type !== 'text') {\n return node;\n }\n\n return {\n ...node,\n marks: [...(node.marks || []), mark],\n };\n}\n\n/**\n * Create a text node with specific marks.\n */\nexport function createTextNode(\n text: string,\n marks: ProseMirrorMark[] = []\n): ProseMirrorJSON {\n const node: ProseMirrorJSON = {\n type: 'text',\n text,\n };\n\n if (marks.length > 0) {\n node.marks = marks;\n }\n\n return node;\n}\n\n/**\n * Apply trackDelete mark to all text in a node (recursively).\n */\nexport function markAllAsDeleted(\n node: ProseMirrorJSON,\n author: TrackChangeAuthor = DEFAULT_AUTHOR\n): ProseMirrorJSON {\n if (node.type === 'text') {\n return addMarkToTextNode(node, createTrackDeleteMark(author));\n }\n\n if (node.content && Array.isArray(node.content)) {\n return {\n ...node,\n content: node.content.map((child: ProseMirrorJSON) =>\n markAllAsDeleted(child, author)\n ),\n };\n }\n\n return node;\n}\n\n/**\n * Apply trackInsert mark to all text in a node (recursively).\n */\nexport function markAllAsInserted(\n node: ProseMirrorJSON,\n author: TrackChangeAuthor = DEFAULT_AUTHOR\n): ProseMirrorJSON {\n if (node.type === 'text') {\n return addMarkToTextNode(node, createTrackInsertMark(author));\n }\n\n if (node.content && Array.isArray(node.content)) {\n return {\n ...node,\n content: node.content.map((child: ProseMirrorJSON) =>\n markAllAsInserted(child, author)\n ),\n };\n }\n\n return node;\n}\n\n/**\n * Clone a node deeply.\n */\nexport function cloneNode(node: ProseMirrorJSON): ProseMirrorJSON {\n return JSON.parse(JSON.stringify(node));\n}\n\n","/**\n * Run Properties Sync Service\n * \n * Ensures that ProseMirror marks on text nodes are synced to\n * runProperties on parent run nodes. This is required because\n * SuperDoc has a dual-layer architecture:\n * \n * - ProseMirror marks on text nodes → used for editing interactions\n * - runProperties on run nodes → used for actual DOCX rendering\n * \n * Both need to be in sync for styles to render correctly.\n * \n * Based on SuperDoc's decodeRPrFromMarks logic in converter-BavE2jnW.js\n */\n\nimport type { ProseMirrorJSON, ProseMirrorNode } from '../types';\nimport { normalizeMarksForRendering } from './trackChangeInjector';\nimport { colorToHexWithoutHash } from './colorUtils';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * A ProseMirror mark as it appears in JSON\n */\ninterface ProseMirrorMark {\n type: string;\n attrs?: Record<string, unknown>;\n}\n\n/**\n * SuperDoc's runProperties format\n */\ninterface RunProperties {\n bold?: boolean;\n italic?: boolean;\n strike?: boolean;\n underline?: {\n 'w:val'?: string;\n 'w:color'?: string;\n };\n highlight?: {\n 'w:val': string;\n };\n color?: {\n val: string;\n };\n fontSize?: number;\n fontFamily?: {\n ascii: string;\n eastAsia: string;\n hAnsi: string;\n cs: string;\n };\n letterSpacing?: number;\n textTransform?: string;\n [key: string]: unknown;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/**\n * Points to twips conversion (1 point = 20 twips)\n */\nconst PT_TO_TWIPS = 20;\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Convert points string to twips number.\n * Example: \"1pt\" → 20\n */\nfunction ptToTwips(ptValue: number): number {\n return Math.round(ptValue * PT_TO_TWIPS);\n}\n\n/**\n * Parse a font size string to points.\n * Handles: \"12pt\", \"12\", \"16px\" (approximates px to pt)\n */\nfunction parseFontSizeToPoints(fontSize: string | number): number | null {\n if (typeof fontSize === 'number') {\n return fontSize;\n }\n \n const value = parseFloat(fontSize);\n if (isNaN(value)) {\n return null;\n }\n \n // Check for px suffix and convert (approximate: 1px ≈ 0.75pt)\n if (fontSize.toLowerCase().includes('px')) {\n return value * 0.75;\n }\n \n // Assume pt or no suffix\n return value;\n}\n\n/**\n * Clean font family string - take first font from comma-separated list\n * and remove quotes.\n * Example: \"'Arial', sans-serif\" → \"Arial\"\n */\nfunction cleanFontFamily(fontFamily: string): string {\n return fontFamily\n .split(',')[0]\n .trim()\n .replace(/^[\"']|[\"']$/g, '');\n}\n\n// ============================================================================\n// Main Conversion Function\n// ============================================================================\n\n/**\n * Convert an array of ProseMirror marks to SuperDoc runProperties format.\n * \n * Based on SuperDoc's decodeRPrFromMarks logic.\n */\nexport function marksToRunProperties(marks: ProseMirrorMark[]): RunProperties {\n const runProperties: RunProperties = {};\n\n if (!marks || !Array.isArray(marks)) {\n return runProperties;\n }\n\n for (const mark of marks) {\n const type = mark.type;\n const attrs = mark.attrs || {};\n\n switch (type) {\n // Boolean marks: bold, italic, strike\n case 'bold':\n case 'italic':\n case 'strike': {\n // Check if mark is negated (value === \"0\" or false)\n const isNegated = attrs.value === '0' || attrs.value === false;\n runProperties[type] = !isNegated;\n break;\n }\n\n // Underline with optional type and color\n case 'underline': {\n const underlineAttrs: { 'w:val'?: string; 'w:color'?: string } = {};\n \n if (attrs.underlineType) {\n underlineAttrs['w:val'] = String(attrs.underlineType);\n } else {\n // Default underline type\n underlineAttrs['w:val'] = 'single';\n }\n \n if (attrs.underlineColor) {\n underlineAttrs['w:color'] = colorToHexWithoutHash(String(attrs.underlineColor));\n }\n \n if (Object.keys(underlineAttrs).length > 0) {\n runProperties.underline = underlineAttrs;\n }\n break;\n }\n\n // Highlight (background color)\n case 'highlight': {\n if (attrs.color) {\n const color = String(attrs.color).toLowerCase();\n if (color === 'transparent') {\n runProperties.highlight = { 'w:val': 'none' };\n } else {\n runProperties.highlight = { 'w:val': color };\n }\n }\n break;\n }\n\n // textStyle contains multiple style attributes\n case 'textStyle': {\n // Color - convert named colors to hex for SuperDoc compatibility\n if (attrs.color != null) {\n runProperties.color = {\n val: colorToHexWithoutHash(String(attrs.color)),\n };\n }\n\n // Font size (convert to half-points)\n if (attrs.fontSize != null) {\n const points = parseFontSizeToPoints(attrs.fontSize as string | number);\n if (points !== null) {\n runProperties.fontSize = points * 2; // Half-points\n }\n }\n\n // Font family (needs all 4 properties)\n if (attrs.fontFamily != null) {\n const cleanedFont = cleanFontFamily(String(attrs.fontFamily));\n runProperties.fontFamily = {\n ascii: cleanedFont,\n eastAsia: cleanedFont,\n hAnsi: cleanedFont,\n cs: cleanedFont,\n };\n }\n\n // Letter spacing (convert to twips)\n if (attrs.letterSpacing != null) {\n const ptValue = parseFloat(String(attrs.letterSpacing));\n if (!isNaN(ptValue)) {\n runProperties.letterSpacing = ptToTwips(ptValue);\n }\n }\n\n // Text transform (pass through)\n if (attrs.textTransform != null) {\n runProperties.textTransform = String(attrs.textTransform);\n }\n break;\n }\n\n // Unknown mark types are ignored\n default:\n break;\n }\n }\n\n return runProperties;\n}\n\n// ============================================================================\n// Document Normalization\n// ============================================================================\n\n/**\n * Recursively collect all marks from text nodes within a node.\n * This handles cases where text is nested within inline elements inside a run.\n */\nfunction collectMarksRecursively(node: ProseMirrorNode, allMarks: ProseMirrorMark[]): void {\n if (node.type === 'text' && node.marks && Array.isArray(node.marks)) {\n allMarks.push(...node.marks);\n }\n\n if (node.content && Array.isArray(node.content)) {\n for (const child of node.content) {\n collectMarksRecursively(child, allMarks);\n }\n }\n}\n\n/**\n * Collect all marks from text node descendants of a run node.\n * Recursively searches to handle nested inline content.\n */\nfunction collectMarksFromRunChildren(runNode: ProseMirrorNode): ProseMirrorMark[] {\n const allMarks: ProseMirrorMark[] = [];\n\n if (!runNode.content || !Array.isArray(runNode.content)) {\n return allMarks;\n }\n\n // Recursively collect marks from all text nodes\n for (const child of runNode.content) {\n collectMarksRecursively(child, allMarks);\n }\n\n // Deduplicate marks by type (keep last occurrence for each type)\n const marksByType = new Map<string, ProseMirrorMark>();\n for (const mark of allMarks) {\n marksByType.set(mark.type, mark);\n }\n\n return Array.from(marksByType.values());\n}\n\n/**\n * Recursively walk a node and:\n * 1. Normalize runProperties on run nodes from child text marks\n * 2. Normalize marks on text nodes to ensure valid CSS colors\n * \n * This ensures both the ProseMirror marks AND runProperties have valid values.\n */\nfunction normalizeNode(node: ProseMirrorNode): ProseMirrorNode {\n // If this is a text node with marks, normalize the marks\n if (node.type === 'text' && node.marks && Array.isArray(node.marks)) {\n const normalizedMarks = normalizeMarksForRendering(node.marks);\n return {\n ...node,\n marks: normalizedMarks,\n };\n }\n \n // If this is a run node, sync runProperties from child text marks\n if (node.type === 'run') {\n // First, recursively normalize children (including text node marks)\n const normalizedContent = node.content?.map(normalizeNode);\n \n // Then collect marks from the normalized children\n const normalizedNode = { ...node, content: normalizedContent };\n const marks = collectMarksFromRunChildren(normalizedNode);\n \n if (marks.length > 0) {\n const runPropsFromMarks = marksToRunProperties(marks);\n \n // Merge with existing runProperties (marks override)\n const existingRunProps = (node.attrs?.runProperties as RunProperties) || {};\n const mergedRunProps = {\n ...existingRunProps,\n ...runPropsFromMarks,\n };\n\n // Return node with updated runProperties\n return {\n ...normalizedNode,\n attrs: {\n ...normalizedNode.attrs,\n runProperties: mergedRunProps,\n },\n };\n }\n \n return normalizedNode;\n }\n\n // Recursively process children\n if (node.content && Array.isArray(node.content)) {\n return {\n ...node,\n content: node.content.map(normalizeNode),\n };\n }\n\n return node;\n}\n\n/**\n * Normalize a ProseMirror document by:\n * 1. Normalizing marks on text nodes (ensuring valid CSS colors, attrs property)\n * 2. Syncing runProperties on run nodes from child text node marks\n * \n * This ensures that styles set via marks (from HTML parsing, etc.) are:\n * - Properly formatted for SuperDoc's DOM rendering (valid CSS colors with #)\n * - Properly reflected in runProperties for DOCX export\n * \n * This function is idempotent - running it multiple times produces the same result.\n */\nexport function normalizeRunProperties(doc: ProseMirrorJSON): ProseMirrorJSON {\n // Deep clone to avoid mutating original\n const cloned = JSON.parse(JSON.stringify(doc)) as ProseMirrorJSON;\n \n return normalizeNode(cloned) as ProseMirrorJSON;\n}\n","/**\n * Content Resolver Service\n * Detects content type and parses DOCX files to ProseMirror JSON.\n *\n * Supports three input formats:\n * - File: DOCX file parsed by SuperDoc\n * - string: HTML content (handled directly by SuperDoc in the component)\n * - object: Direct ProseMirror JSON (passed through)\n */\n\nimport type { DocxContent, ProseMirrorJSON } from '../types';\nimport { TIMEOUTS } from '../constants';\nimport { normalizeRunProperties } from './runPropertiesSync';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype SuperDocConstructor = any;\n\n/**\n * Detect the type of content provided\n */\nexport function detectContentType(content: DocxContent): 'file' | 'html' | 'json' {\n if (content instanceof File) {\n return 'file';\n }\n if (typeof content === 'string') {\n return 'html';\n }\n // Assume it's JSON if it's an object\n return 'json';\n}\n\n/**\n * Validate that content looks like ProseMirror JSON\n */\nexport function isProseMirrorJSON(content: unknown): boolean {\n if (!content || typeof content !== 'object') return false;\n const obj = content as Record<string, unknown>;\n return typeof obj.type === 'string' && (obj.type === 'doc' || Array.isArray(obj.content));\n}\n\n/**\n * Parse an HTML string into ProseMirror JSON using a hidden SuperDoc instance.\n * \n * IMPORTANT: Uses the \"paste\" approach instead of the \"import\" approach.\n * SuperDoc's import path (via `html` option) calls `stripHtmlStyles()` which\n * removes all CSS styles except `text-align`. The paste path (via `view.pasteHTML()`)\n * preserves inline styles like color, font-size, font-family, font-weight, etc.\n * \n * Flow:\n * 1. Create SuperDoc with empty HTML document\n * 2. Wait for editor to be ready\n * 3. Select all content and delete it (start fresh)\n * 4. Use editor.view.pasteHTML(html) - this uses the paste path which preserves styles\n * 5. Return the resulting JSON\n * \n * Falls back to the standard import approach if paste fails.\n */\nexport async function parseHtmlToJson(\n html: string,\n SuperDoc: SuperDocConstructor\n): Promise<ProseMirrorJSON> {\n // Create a hidden container for the editor\n const container = document.createElement('div');\n container.style.cssText =\n 'position:absolute;top:-9999px;left:-9999px;width:800px;height:600px;visibility:hidden;';\n document.body.appendChild(container);\n\n return new Promise((resolve, reject) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let superdoc: any = null;\n let resolved = false;\n\n const cleanup = () => {\n setTimeout(() => {\n if (superdoc) {\n try {\n const sd = superdoc;\n superdoc = null;\n sd.destroy?.();\n } catch {\n // Ignore cleanup errors\n }\n }\n if (container.parentNode) {\n container.parentNode.removeChild(container);\n }\n }, TIMEOUTS.CLEANUP_DELAY);\n };\n\n /**\n * Create a mock ClipboardEvent with proper getData() support.\n * This is needed because pasteHTML internally calls event.clipboardData.getData().\n */\n const createMockPasteEvent = (htmlContent: string): ClipboardEvent => {\n // Create a DataTransfer object to hold the clipboard data\n const dataTransfer = new DataTransfer();\n dataTransfer.setData('text/html', htmlContent);\n dataTransfer.setData('text/plain', ''); // Some handlers check for plain text too\n\n // Create the ClipboardEvent with our DataTransfer\n const event = new ClipboardEvent('paste', {\n bubbles: true,\n cancelable: true,\n clipboardData: dataTransfer,\n });\n\n return event;\n };\n\n /**\n * Attempt the paste approach (preserves styles)\n */\n const tryPasteApproach = (\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n sd: any,\n onSuccess: (json: ProseMirrorJSON) => void,\n onFail: () => void\n ) => {\n try {\n const editor = sd?.activeEditor;\n if (!editor?.view?.pasteHTML) {\n // pasteHTML not available, fall back\n onFail();\n return;\n }\n\n // Focus the editor (required for some operations)\n editor.commands.focus?.();\n\n // Select all content and delete it to start fresh\n if (editor.commands.selectAll && editor.commands.deleteSelection) {\n editor.commands.selectAll();\n editor.commands.deleteSelection();\n }\n\n // Create a mock paste event with proper clipboardData\n const mockEvent = createMockPasteEvent(html);\n\n // Use pasteHTML which goes through the paste path\n // This path does NOT call stripHtmlStyles(), preserving inline styles\n // Pass the mock event so getData() works\n editor.view.pasteHTML(html, mockEvent);\n\n // Small delay to let the paste operation complete\n setTimeout(() => {\n try {\n const json = editor.getJSON();\n // Verify we got content (paste succeeded)\n if (json?.content?.length > 0) {\n // Normalize runProperties to ensure styles render correctly\n const normalizedJson = normalizeRunProperties(json);\n onSuccess(normalizedJson);\n } else {\n // Paste produced empty doc, fall back\n onFail();\n }\n } catch {\n onFail();\n }\n }, 100);\n } catch (err) {\n console.warn('[parseHtmlToJson] Paste approach error:', err);\n onFail();\n }\n };\n\n /**\n * Fallback to standard import approach (strips some styles but works reliably)\n */\n const fallbackToImport = () => {\n // Clean up the paste attempt\n if (superdoc) {\n try {\n superdoc.destroy?.();\n } catch {\n // Ignore\n }\n superdoc = null;\n }\n\n // Create new SuperDoc with standard import\n superdoc = new SuperDoc({\n selector: container,\n html: html, // Use the actual HTML content\n documentMode: 'viewing',\n rulers: false,\n user: { name: 'Parser', email: 'parser@local' },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onReady: ({ superdoc: sd }: { superdoc: any }) => {\n if (resolved) return;\n try {\n const editor = sd?.activeEditor;\n if (!editor) {\n throw new Error('No active editor found');\n }\n const json = editor.getJSON();\n // Normalize runProperties to ensure styles render correctly\n const normalizedJson = normalizeRunProperties(json);\n resolved = true;\n cleanup();\n resolve(normalizedJson);\n } catch (err) {\n resolved = true;\n cleanup();\n reject(err);\n }\n },\n onException: ({ error: err }: { error: Error }) => {\n if (resolved) return;\n resolved = true;\n cleanup();\n reject(err);\n },\n });\n };\n\n setTimeout(async () => {\n if (resolved) return;\n\n try {\n // First, try the paste approach (preserves styles)\n superdoc = new SuperDoc({\n selector: container,\n html: '<p></p>', // Minimal empty document\n documentMode: 'editing', // Need editing mode to use paste\n rulers: false,\n user: { name: 'Parser', email: 'parser@local' },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onReady: ({ superdoc: sd }: { superdoc: any }) => {\n if (resolved) return;\n \n tryPasteApproach(\n sd,\n // Success callback\n (json) => {\n if (resolved) return;\n resolved = true;\n cleanup();\n resolve(json);\n },\n // Fail callback - try fallback\n () => {\n if (resolved) return;\n console.warn('[parseHtmlToJson] Paste approach failed, falling back to import');\n fallbackToImport();\n }\n );\n },\n onException: ({ error: err }: { error: Error }) => {\n if (resolved) return;\n // Try fallback on exception\n console.warn('[parseHtmlToJson] Paste approach exception, falling back:', err);\n fallbackToImport();\n },\n });\n\n // Timeout\n setTimeout(() => {\n if (!resolved) {\n resolved = true;\n cleanup();\n reject(new Error('HTML parsing timed out'));\n }\n }, TIMEOUTS.PARSE_TIMEOUT);\n } catch (err) {\n // Try fallback on error\n try {\n fallbackToImport();\n } catch (fallbackErr) {\n cleanup();\n reject(fallbackErr);\n }\n }\n }, 50);\n });\n}\n\n/**\n * Parse a DOCX File into ProseMirror JSON using a hidden SuperDoc instance.\n */\nexport async function parseDocxFile(\n file: File,\n SuperDoc: SuperDocConstructor\n): Promise<ProseMirrorJSON> {\n // Create a hidden container for the editor\n const container = document.createElement('div');\n container.style.cssText =\n 'position:absolute;top:-9999px;left:-9999px;width:800px;height:600px;visibility:hidden;';\n document.body.appendChild(container);\n\n return new Promise((resolve, reject) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let superdoc: any = null;\n let resolved = false;\n\n const cleanup = () => {\n setTimeout(() => {\n if (superdoc) {\n try {\n const sd = superdoc;\n superdoc = null;\n sd.destroy?.();\n } catch {\n // Ignore cleanup errors\n }\n }\n if (container.parentNode) {\n container.parentNode.removeChild(container);\n }\n }, TIMEOUTS.CLEANUP_DELAY);\n };\n\n setTimeout(async () => {\n if (resolved) return;\n\n try {\n superdoc = new SuperDoc({\n selector: container,\n document: file,\n documentMode: 'viewing',\n rulers: false,\n user: { name: 'Parser', email: 'parser@local' },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onReady: ({ superdoc: sd }: { superdoc: any }) => {\n if (resolved) return;\n try {\n const editor = sd?.activeEditor;\n if (!editor) {\n throw new Error('No active editor found');\n }\n\n const json = editor.getJSON();\n resolved = true;\n cleanup();\n resolve(json);\n } catch (err) {\n resolved = true;\n cleanup();\n reject(err);\n }\n },\n onException: ({ error: err }: { error: Error }) => {\n if (resolved) return;\n resolved = true;\n cleanup();\n reject(err);\n },\n });\n\n // Timeout\n setTimeout(() => {\n if (!resolved) {\n resolved = true;\n cleanup();\n reject(new Error('Document parsing timed out'));\n }\n }, TIMEOUTS.PARSE_TIMEOUT);\n } catch (err) {\n cleanup();\n reject(err);\n }\n }, 50);\n });\n}\n","/**\n * Document Differ Service\n * Diffs two ProseMirror JSON documents at the character level,\n * including text changes and formatting changes.\n */\n\nimport DiffMatchPatch from 'diff-match-patch';\nimport type {\n ProseMirrorJSON,\n ProseMirrorMark,\n DiffSegment,\n DiffResult,\n FormatChange,\n TextSpan,\n} from '../types';\n\nconst dmp = new DiffMatchPatch();\n\n// Diff operation types\nconst DIFF_DELETE = -1;\nconst DIFF_INSERT = 1;\nconst DIFF_EQUAL = 0;\n\n/**\n * Extract text spans with their marks from a ProseMirror node.\n */\nfunction extractTextSpans(node: ProseMirrorJSON, offset: number = 0): TextSpan[] {\n const spans: TextSpan[] = [];\n\n if (!node) return spans;\n\n if (node.type === 'text' && node.text) {\n spans.push({\n text: node.text,\n from: offset,\n to: offset + node.text.length,\n marks: node.marks || [],\n });\n return spans;\n }\n\n if (node.content && Array.isArray(node.content)) {\n let currentOffset = offset;\n for (const child of node.content) {\n const childSpans = extractTextSpans(child, currentOffset);\n spans.push(...childSpans);\n // Calculate consumed length\n for (const span of childSpans) {\n currentOffset = Math.max(currentOffset, span.to);\n }\n // If no spans, check if it's a text node for offset\n if (childSpans.length === 0 && child.type === 'text' && child.text) {\n currentOffset += child.text.length;\n }\n }\n }\n\n return spans;\n}\n\n/**\n * Extract text content from a ProseMirror node recursively.\n */\nfunction extractTextContent(node: ProseMirrorJSON): string {\n if (!node) return '';\n\n if (node.type === 'text' && node.text) {\n return node.text;\n }\n\n if (node.content && Array.isArray(node.content)) {\n return node.content.map(extractTextContent).join('');\n }\n\n return '';\n}\n\n/**\n * Deep compare two values.\n */\nfunction deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (typeof a !== typeof b) return false;\n if (typeof a !== 'object' || a === null || b === null) return false;\n\n const objA = a as Record<string, unknown>;\n const objB = b as Record<string, unknown>;\n const keysA = Object.keys(objA);\n const keysB = Object.keys(objB);\n\n if (keysA.length !== keysB.length) return false;\n\n for (const key of keysA) {\n if (!keysB.includes(key)) return false;\n if (!deepEqual(objA[key], objB[key])) return false;\n }\n\n return true;\n}\n\n/**\n * Compare marks arrays to check if they're equivalent.\n */\nfunction marksEqual(marksA: ProseMirrorMark[], marksB: ProseMirrorMark[]): boolean {\n if (marksA.length !== marksB.length) return false;\n\n // Sort by type for consistent comparison\n const sortedA = [...marksA].sort((a, b) => (a.type || '').localeCompare(b.type || ''));\n const sortedB = [...marksB].sort((a, b) => (a.type || '').localeCompare(b.type || ''));\n\n return deepEqual(sortedA, sortedB);\n}\n\n/**\n * Get marks at a specific character position from spans.\n */\nfunction getMarksAtPosition(spans: TextSpan[], pos: number): ProseMirrorMark[] {\n for (const span of spans) {\n if (pos >= span.from && pos < span.to) {\n return span.marks;\n }\n }\n return [];\n}\n\n/**\n * Check if marks have any defined (non-undefined/null) attribute values.\n * Returns false if marks array is empty or all marks have only undefined attrs.\n */\nfunction hasDefinedAttributes(marks: ProseMirrorMark[]): boolean {\n if (!marks || marks.length === 0) return false;\n\n for (const mark of marks) {\n // Marks without attrs (like simple bold/italic) are considered defined\n if (!mark.attrs) continue;\n\n for (const value of Object.values(mark.attrs)) {\n if (value !== undefined && value !== null) {\n return true;\n }\n }\n }\n\n // If we only have marks without attrs, they count as defined\n return marks.some((m) => !m.attrs);\n}\n\n/**\n * Detect format changes on equal text segments.\n */\nfunction detectFormatChanges(\n spansA: TextSpan[],\n spansB: TextSpan[],\n segments: DiffSegment[]\n): FormatChange[] {\n const formatChanges: FormatChange[] = [];\n\n let posA = 0;\n let posB = 0;\n\n for (const segment of segments) {\n if (segment.type === 'equal') {\n // For equal text, compare marks character by character\n // Group consecutive chars with same mark difference\n let i = 0;\n while (i < segment.text.length) {\n const marksA = getMarksAtPosition(spansA, posA + i);\n const marksB = getMarksAtPosition(spansB, posB + i);\n\n if (!marksEqual(marksA, marksB)) {\n // Found a format difference - find the extent\n const startI = i;\n const startMarksA = marksA;\n const startMarksB = marksB;\n\n // Extend while marks remain the same different pattern\n while (i < segment.text.length) {\n const currentMarksA = getMarksAtPosition(spansA, posA + i);\n const currentMarksB = getMarksAtPosition(spansB, posB + i);\n\n if (marksEqual(currentMarksA, startMarksA) && marksEqual(currentMarksB, startMarksB)) {\n i++;\n } else {\n break;\n }\n }\n\n // Skip format changes where \"after\" marks have no defined values\n // This avoids showing \"changed to undefined\" for missing styles\n if (hasDefinedAttributes(startMarksB) || hasDefinedAttributes(startMarksA)) {\n // Only record if at least one side has meaningful values\n // and the \"after\" side isn't just undefined values\n if (hasDefinedAttributes(startMarksB)) {\n formatChanges.push({\n from: posA + startI,\n to: posA + i,\n text: segment.text.substring(startI, i),\n before: startMarksA,\n after: startMarksB,\n });\n }\n }\n } else {\n i++;\n }\n }\n\n posA += segment.text.length;\n posB += segment.text.length;\n } else if (segment.type === 'delete') {\n // Deleted text exists only in docA, so only advance posA\n posA += segment.text.length;\n } else if (segment.type === 'insert') {\n // Inserted text exists only in docB, so only advance posB\n posB += segment.text.length;\n }\n }\n\n return formatChanges;\n}\n\n/**\n * Diff two ProseMirror JSON documents at the character level.\n * Detects both text changes and formatting changes.\n * \n * Now also tracks positions in both documents for mark preservation:\n * - posA: position in docA (for equal/delete segments)\n * - posB: position in docB (for equal/insert segments)\n */\nexport function diffDocuments(\n docA: ProseMirrorJSON,\n docB: ProseMirrorJSON\n): DiffResult {\n // Extract full text from both documents\n const textA = extractTextContent(docA);\n const textB = extractTextContent(docB);\n\n // Perform character-level diff on the entire document\n const diffs = dmp.diff_main(textA, textB);\n dmp.diff_cleanupSemantic(diffs);\n\n // Convert to our DiffSegment format with position tracking\n const segments: DiffSegment[] = [];\n let insertCount = 0;\n let deleteCount = 0;\n \n // Track positions in both documents\n let posA = 0;\n let posB = 0;\n\n for (const [op, text] of diffs) {\n if (op === DIFF_EQUAL) {\n // Equal segments exist in both documents\n segments.push({ type: 'equal', text, posA, posB });\n posA += text.length;\n posB += text.length;\n } else if (op === DIFF_INSERT) {\n // Inserted text exists only in docB\n segments.push({ type: 'insert', text, posB });\n posB += text.length;\n insertCount++;\n } else if (op === DIFF_DELETE) {\n // Deleted text exists only in docA\n segments.push({ type: 'delete', text, posA });\n posA += text.length;\n deleteCount++;\n }\n }\n\n // Extract text spans with marks for format comparison\n const spansA = extractTextSpans(docA);\n const spansB = extractTextSpans(docB);\n\n // Detect format changes on equal segments\n const formatChanges = detectFormatChanges(spansA, spansB, segments);\n\n // Build summary\n const summary: string[] = [];\n if (insertCount > 0) {\n summary.push(`${insertCount} insertion(s)`);\n }\n if (deleteCount > 0) {\n summary.push(`${deleteCount} deletion(s)`);\n }\n if (formatChanges.length > 0) {\n summary.push(`${formatChanges.length} format change(s)`);\n }\n if (insertCount === 0 && deleteCount === 0 && formatChanges.length === 0) {\n summary.push('No changes detected');\n }\n\n return {\n segments,\n formatChanges,\n textA,\n textB,\n summary,\n spansB, // Include docB spans for mark preservation during merge\n };\n}\n\n","/**\n * Change Context Extractor\n * Extracts enriched changes with semantic context from merged document.\n * Provides surrounding text so the LLM can understand what the change is about.\n * \n * Updated to include structural change information (tables, lists, images).\n */\n\nimport type {\n ProseMirrorJSON,\n ProseMirrorNode,\n EnrichedChange,\n ChangeLocation,\n TraversalContext,\n StructuralChangeInfo,\n StructuralChangeType,\n} from '../types';\n\n/**\n * Extended traversal context with table/list tracking\n */\ninterface ExtendedContext extends TraversalContext {\n tableIndex?: number;\n rowIndex?: number;\n cellIndex?: number;\n listIndex?: number;\n listItemIndex?: number;\n listDepth?: number;\n}\n\n/**\n * Main entry point - extract enriched changes from merged document\n */\nexport function extractEnrichedChanges(mergedJson: ProseMirrorJSON): EnrichedChange[] {\n const changes: EnrichedChange[] = [];\n const context: ExtendedContext = {\n currentSection: null,\n currentParagraphText: '',\n currentNodeType: 'unknown',\n tableIndex: 0,\n listIndex: 0,\n listDepth: 0,\n };\n\n traverseDocument(mergedJson, context, changes);\n return groupReplacements(changes);\n}\n\n/**\n * Extract enriched changes with structural change infos included.\n * This merges inline text changes with structural change metadata.\n */\nexport function extractEnrichedChangesWithStructural(\n mergedJson: ProseMirrorJSON,\n structuralInfos: StructuralChangeInfo[]\n): EnrichedChange[] {\n // Get inline text changes\n const textChanges = extractEnrichedChanges(mergedJson);\n\n // Convert structural infos to enriched changes\n const structuralChanges: EnrichedChange[] = structuralInfos.map((info) => {\n const location = buildLocationFromStructural(info);\n \n return {\n type: info.type.includes('Insert') ? 'insertion' : 'deletion',\n text: info.preview,\n location,\n surroundingText: info.preview,\n structuralType: info.type,\n charCount: info.preview.length,\n };\n });\n\n // Combine and sort (structural changes typically more significant)\n return [...structuralChanges, ...textChanges];\n}\n\n/**\n * Build location from structural change info\n */\nfunction buildLocationFromStructural(info: StructuralChangeInfo): ChangeLocation {\n const nodeType = mapNodeTypeToLocation(info.nodeType);\n \n return {\n nodeType,\n description: info.location,\n sectionTitle: undefined,\n };\n}\n\n/**\n * Map node types to ChangeLocation nodeType\n */\nfunction mapNodeTypeToLocation(nodeType: string): ChangeLocation['nodeType'] {\n switch (nodeType) {\n case 'tableRow':\n case 'tableCell':\n case 'table':\n return 'table';\n case 'listItem':\n return 'listItem';\n case 'paragraph':\n return 'paragraph';\n case 'heading':\n return 'heading';\n case 'image':\n return 'image';\n default:\n return 'unknown';\n }\n}\n\n/**\n * Recursively walk the document tree\n */\nfunction traverseDocument(\n node: ProseMirrorNode,\n context: ExtendedContext,\n changes: EnrichedChange[]\n): void {\n if (!node) return;\n\n // Update context based on node type\n if (node.type === 'heading') {\n context.currentSection = extractAllText(node);\n context.headingLevel = node.attrs?.level || 1;\n context.currentNodeType = 'heading';\n context.currentParagraphText = context.currentSection;\n } else if (node.type === 'paragraph') {\n context.currentNodeType = 'paragraph';\n context.currentParagraphText = extractAllText(node);\n } else if (node.type === 'listItem') {\n context.currentNodeType = 'listItem';\n context.currentParagraphText = extractAllText(node);\n context.listItemIndex = (context.listItemIndex || 0) + 1;\n } else if (node.type === 'tableCell' || node.type === 'tableHeader') {\n context.currentNodeType = 'tableCell';\n context.currentParagraphText = extractAllText(node);\n context.cellIndex = (context.cellIndex || 0) + 1;\n } else if (node.type === 'tableRow') {\n context.rowIndex = (context.rowIndex || 0) + 1;\n context.cellIndex = 0;\n } else if (node.type === 'table') {\n context.tableIndex = (context.tableIndex || 0) + 1;\n context.rowIndex = 0;\n } else if (node.type === 'bulletList' || node.type === 'orderedList') {\n context.listIndex = (context.listIndex || 0) + 1;\n context.listItemIndex = 0;\n context.listDepth = (context.listDepth || 0) + 1;\n }\n\n // Check for track change marks on text nodes\n if (node.type === 'text' && node.marks) {\n const trackMark = findTrackChangeMark(node.marks);\n if (trackMark) {\n const change = createEnrichedChange(node, trackMark, context);\n if (change) changes.push(change);\n }\n }\n\n // Recurse into children\n if (node.content && Array.isArray(node.content)) {\n for (const child of node.content) {\n traverseDocument(child, context, changes);\n }\n }\n\n // Reset depth counters when exiting lists\n if (node.type === 'bulletList' || node.type === 'orderedList') {\n context.listDepth = Math.max(0, (context.listDepth || 1) - 1);\n }\n}\n\n/**\n * Extract ALL text from a node (including deleted text, for context)\n */\nfunction extractAllText(node: ProseMirrorNode): string {\n if (!node) return '';\n if (node.type === 'text') {\n return node.text || '';\n }\n if (node.content && Array.isArray(node.content)) {\n return node.content.map(extractAllText).join('');\n }\n return '';\n}\n\n/**\n * Find trackInsert, trackDelete, or trackFormat mark\n */\nfunction findTrackChangeMark(marks: ProseMirrorNode[]): ProseMirrorNode | null {\n return (\n marks.find(\n (m) =>\n m.type === 'trackInsert' || m.type === 'trackDelete' || m.type === 'trackFormat'\n ) || null\n );\n}\n\n/**\n * Create enriched change from node and track mark\n */\nfunction createEnrichedChange(\n node: ProseMirrorNode,\n trackMark: ProseMirrorNode,\n context: ExtendedContext\n): EnrichedChange | null {\n const text = node.text || '';\n const location = buildLocation(context);\n const surroundingText = extractSurroundingSentence(text, context.currentParagraphText);\n\n // Add table/list position info if applicable\n const tablePosition = context.currentNodeType === 'tableCell' && context.rowIndex !== undefined\n ? { row: context.rowIndex, column: context.cellIndex || 0 }\n : undefined;\n \n const listPosition = context.currentNodeType === 'listItem' && context.listItemIndex !== undefined\n ? { index: context.listItemIndex, depth: context.listDepth || 0 }\n : undefined;\n\n if (trackMark.type === 'trackInsert') {\n return {\n type: 'insertion',\n text,\n location,\n surroundingText,\n charCount: text.length,\n tablePosition,\n listPosition,\n };\n }\n\n if (trackMark.type === 'trackDelete') {\n return {\n type: 'deletion',\n text,\n location,\n surroundingText,\n charCount: text.length,\n tablePosition,\n listPosition,\n };\n }\n\n if (trackMark.type === 'trackFormat') {\n const before = trackMark.attrs?.before || [];\n const after = trackMark.attrs?.after || [];\n return {\n type: 'format',\n text,\n location,\n surroundingText,\n formatDetails: {\n added: after\n .map((m: ProseMirrorNode) => m.type)\n .filter((t: string) => !before.some((b: ProseMirrorNode) => b.type === t)),\n removed: before\n .map((m: ProseMirrorNode) => m.type)\n .filter((t: string) => !after.some((a: ProseMirrorNode) => a.type === t)),\n },\n charCount: text.length,\n tablePosition,\n listPosition,\n };\n }\n\n return null;\n}\n\n/**\n * Extract the sentence or clause containing the changed text\n */\nfunction extractSurroundingSentence(changedText: string, paragraphText: string): string {\n if (!paragraphText || !changedText) return '';\n\n // Find where the change is in the paragraph\n const changeIndex = paragraphText.indexOf(changedText);\n if (changeIndex === -1) {\n // If exact match not found, return truncated paragraph\n return truncate(paragraphText, 150);\n }\n\n // Split into sentences (by period, semicolon, or significant punctuation)\n // But keep the delimiters for context\n const sentenceBreaks = /([.;!?]\\s+)/g;\n const sentences: { text: string; start: number; end: number }[] = [];\n\n let lastEnd = 0;\n let match;\n\n while ((match = sentenceBreaks.exec(paragraphText)) !== null) {\n sentences.push({\n text: paragraphText.slice(lastEnd, match.index + match[0].length).trim(),\n start: lastEnd,\n end: match.index + match[0].length,\n });\n lastEnd = match.index + match[0].length;\n }\n\n // Add remaining text as final sentence\n if (lastEnd < paragraphText.length) {\n sentences.push({\n text: paragraphText.slice(lastEnd).trim(),\n start: lastEnd,\n end: paragraphText.length,\n });\n }\n\n // Find which sentence contains the change\n const changeEnd = changeIndex + changedText.length;\n for (const sentence of sentences) {\n if (changeIndex >= sentence.start && changeIndex < sentence.end) {\n // Found it - return this sentence (truncated if too long)\n return truncate(sentence.text, 200);\n }\n }\n\n // Fallback: return a window around the change\n const windowSize = 100;\n const start = Math.max(0, changeIndex - windowSize);\n const end = Math.min(paragraphText.length, changeEnd + windowSize);\n\n let result = paragraphText.slice(start, end);\n if (start > 0) result = '...' + result;\n if (end < paragraphText.length) result = result + '...';\n\n return result;\n}\n\n/**\n * Truncate text with ellipsis\n */\nfunction truncate(text: string, maxLen: number): string {\n if (!text) return '';\n const cleaned = text.replace(/\\s+/g, ' ').trim();\n if (cleaned.length <= maxLen) return cleaned;\n return cleaned.slice(0, maxLen - 3).trim() + '...';\n}\n\n/**\n * Build location info\n */\nfunction buildLocation(context: ExtendedContext): ChangeLocation {\n const nodeType = context.currentNodeType as ChangeLocation['nodeType'];\n\n let description: string;\n if (nodeType === 'heading') {\n description = context.headingLevel === 1 ? 'document title' : 'section heading';\n } else if (nodeType === 'tableCell' && context.tableIndex !== undefined) {\n const colLetter = String.fromCharCode(65 + (context.cellIndex || 0));\n description = `Table ${context.tableIndex}, Cell ${colLetter}${context.rowIndex || 1}`;\n } else if (nodeType === 'listItem' && context.listIndex !== undefined) {\n const depthStr = (context.listDepth || 0) > 1 ? ` (nested, level ${context.listDepth})` : '';\n description = `List ${context.listIndex}, Item ${context.listItemIndex || 1}${depthStr}`;\n } else if (context.currentSection) {\n description = `\"${truncate(context.currentSection, 50)}\" section`;\n } else {\n description = 'document body';\n }\n\n // Add table/list coordinates to location\n const tableCoords = context.currentNodeType === 'tableCell' && context.rowIndex !== undefined\n ? { row: context.rowIndex, column: context.cellIndex || 0 }\n : undefined;\n\n return {\n nodeType,\n headingLevel: context.headingLevel,\n sectionTitle: context.currentSection || undefined,\n description,\n tableCoords,\n listIndex: context.currentNodeType === 'listItem' ? context.listItemIndex : undefined,\n listDepth: context.currentNodeType === 'listItem' ? context.listDepth : undefined,\n };\n}\n\n/**\n * Combine adjacent delete+insert into replacements\n */\nfunction groupReplacements(changes: EnrichedChange[]): EnrichedChange[] {\n const result: EnrichedChange[] = [];\n let i = 0;\n\n while (i < changes.length) {\n const current = changes[i];\n const next = changes[i + 1];\n\n // Check if delete followed by insert (same section = likely replacement)\n if (\n current.type === 'deletion' &&\n next?.type === 'insertion' &&\n current.location.sectionTitle === next.location.sectionTitle\n ) {\n result.push({\n type: 'replacement',\n oldText: current.text,\n newText: next.text,\n location: current.location,\n surroundingText: current.surroundingText || next.surroundingText,\n charCount: (current.charCount || 0) + (next.charCount || 0),\n });\n i += 2;\n } else {\n result.push(current);\n i++;\n }\n }\n\n return result;\n}\n\n","/**\n * Node Aligner Service\n * \n * Aligns nodes between two documents using fingerprints and LCS algorithm.\n * Produces matched pairs, insertions, and deletions.\n */\n\nimport type { ProseMirrorJSON, FingerprintedNode, NodeMatch } from '../types';\nimport {\n extractBlockFingerprints,\n calculateSimilarity,\n getNodeTextSimilarity,\n} from './nodeFingerprint';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Result of aligning two node sequences\n */\nexport interface AlignmentResult {\n /** Nodes that match between documents */\n matched: NodeMatch[];\n /** Nodes only in document A (deleted) */\n deletions: FingerprintedNode[];\n /** Nodes only in document B (inserted) */\n insertions: FingerprintedNode[];\n}\n\n// ============================================================================\n// Configuration\n// ============================================================================\n\n/** Minimum similarity threshold for fuzzy matching */\nconst SIMILARITY_THRESHOLD = 0.7;\n\n// ============================================================================\n// LCS-Based Alignment\n// ============================================================================\n\n/**\n * Find the Longest Common Subsequence of two fingerprint arrays.\n * Returns indices of matched elements.\n */\nfunction findLCS(seqA: string[], seqB: string[]): [number, number][] {\n const m = seqA.length;\n const n = seqB.length;\n\n // Build LCS length table\n const dp: number[][] = Array.from({ length: m + 1 }, () =>\n Array(n + 1).fill(0)\n );\n\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n if (seqA[i - 1] === seqB[j - 1]) {\n dp[i][j] = dp[i - 1][j - 1] + 1;\n } else {\n dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);\n }\n }\n }\n\n // Backtrack to find the actual LCS\n const result: [number, number][] = [];\n let i = m;\n let j = n;\n\n while (i > 0 && j > 0) {\n if (seqA[i - 1] === seqB[j - 1]) {\n result.unshift([i - 1, j - 1]);\n i--;\n j--;\n } else if (dp[i - 1][j] > dp[i][j - 1]) {\n i--;\n } else {\n j--;\n }\n }\n\n return result;\n}\n\n/**\n * Find fuzzy matches for unmatched nodes.\n * Uses text similarity to find partial matches.\n */\nfunction findFuzzyMatches(\n unmatchedA: FingerprintedNode[],\n unmatchedB: FingerprintedNode[],\n threshold: number = SIMILARITY_THRESHOLD\n): { matches: [FingerprintedNode, FingerprintedNode, number][]; remainingA: FingerprintedNode[]; remainingB: FingerprintedNode[] } {\n const matches: [FingerprintedNode, FingerprintedNode, number][] = [];\n const usedA = new Set<number>();\n const usedB = new Set<number>();\n\n // Build similarity matrix\n const similarities: { i: number; j: number; sim: number }[] = [];\n \n for (let i = 0; i < unmatchedA.length; i++) {\n for (let j = 0; j < unmatchedB.length; j++) {\n // Quick check: same type prefix?\n const fpSim = calculateSimilarity(unmatchedA[i].fingerprint, unmatchedB[j].fingerprint);\n if (fpSim === 0) continue;\n\n // Calculate text similarity\n const textSim = getNodeTextSimilarity(unmatchedA[i].node, unmatchedB[j].node);\n if (textSim >= threshold) {\n similarities.push({ i, j, sim: textSim });\n }\n }\n }\n\n // Sort by similarity (highest first) and greedily match\n similarities.sort((a, b) => b.sim - a.sim);\n\n for (const { i, j, sim } of similarities) {\n if (!usedA.has(i) && !usedB.has(j)) {\n matches.push([unmatchedA[i], unmatchedB[j], sim]);\n usedA.add(i);\n usedB.add(j);\n }\n }\n\n // Collect remaining unmatched\n const remainingA = unmatchedA.filter((_, i) => !usedA.has(i));\n const remainingB = unmatchedB.filter((_, j) => !usedB.has(j));\n\n return { matches, remainingA, remainingB };\n}\n\n/**\n * Align two sequences of fingerprinted nodes.\n * Uses LCS for exact matches, then fuzzy matching for similar nodes.\n */\nexport function alignNodes(\n nodesA: FingerprintedNode[],\n nodesB: FingerprintedNode[]\n): AlignmentResult {\n // Extract fingerprints\n const fpsA = nodesA.map((n) => n.fingerprint);\n const fpsB = nodesB.map((n) => n.fingerprint);\n\n // Find exact matches using LCS\n const lcsMatches = findLCS(fpsA, fpsB);\n const matchedIndicesA = new Set(lcsMatches.map(([i]) => i));\n const matchedIndicesB = new Set(lcsMatches.map(([, j]) => j));\n\n // Build matched pairs from LCS\n const matched: NodeMatch[] = lcsMatches.map(([i, j]) => ({\n pathA: nodesA[i].path,\n pathB: nodesB[j].path,\n fingerprint: nodesA[i].fingerprint,\n similarity: 1.0, // Exact match\n }));\n\n // Collect unmatched nodes\n const unmatchedA = nodesA.filter((_, i) => !matchedIndicesA.has(i));\n const unmatchedB = nodesB.filter((_, j) => !matchedIndicesB.has(j));\n\n // Try fuzzy matching on unmatched nodes\n const { matches: fuzzyMatches, remainingA, remainingB } = findFuzzyMatches(\n unmatchedA,\n unmatchedB\n );\n\n // Add fuzzy matches\n for (const [nodeA, nodeB, similarity] of fuzzyMatches) {\n matched.push({\n pathA: nodeA.path,\n pathB: nodeB.path,\n fingerprint: nodeA.fingerprint,\n similarity,\n });\n }\n\n return {\n matched,\n deletions: remainingA,\n insertions: remainingB,\n };\n}\n\n/**\n * Align top-level blocks between two documents.\n */\nexport function alignDocuments(\n docA: ProseMirrorJSON,\n docB: ProseMirrorJSON\n): AlignmentResult {\n const blocksA = extractBlockFingerprints(docA);\n const blocksB = extractBlockFingerprints(docB);\n\n return alignNodes(blocksA, blocksB);\n}\n\n/**\n * Align children of two matched nodes.\n * Used for recursive alignment (e.g., table rows, list items).\n */\nexport function alignChildren(\n nodeA: ProseMirrorJSON,\n nodeB: ProseMirrorJSON,\n basePath: number[] = []\n): AlignmentResult {\n const childrenA = (nodeA.content || []).map((child: ProseMirrorJSON, i: number) => ({\n node: child,\n fingerprint: '', // Will be computed\n path: [...basePath, i],\n }));\n\n const childrenB = (nodeB.content || []).map((child: ProseMirrorJSON, i: number) => ({\n node: child,\n fingerprint: '', // Will be computed\n path: [...basePath, i],\n }));\n\n // Compute fingerprints\n const { generateFingerprint } = require('./nodeFingerprint');\n for (const child of childrenA) {\n child.fingerprint = generateFingerprint(child.node);\n }\n for (const child of childrenB) {\n child.fingerprint = generateFingerprint(child.node);\n }\n\n return alignNodes(childrenA, childrenB);\n}\n\n// ============================================================================\n// Table-Specific Alignment\n// ============================================================================\n\n/**\n * Align table rows between two tables.\n */\nexport function alignTableRows(\n tableA: ProseMirrorJSON,\n tableB: ProseMirrorJSON,\n tablePathA: number[],\n tablePathB: number[]\n): AlignmentResult {\n const rowsA = (tableA.content || []).map((row: ProseMirrorJSON, i: number) => ({\n node: row,\n fingerprint: '', // Will be computed\n path: [...tablePathA, i],\n }));\n\n const rowsB = (tableB.content || []).map((row: ProseMirrorJSON, i: number) => ({\n node: row,\n fingerprint: '', // Will be computed\n path: [...tablePathB, i],\n }));\n\n // Compute fingerprints\n const { generateFingerprint } = require('./nodeFingerprint');\n for (const row of rowsA) {\n row.fingerprint = generateFingerprint(row.node);\n }\n for (const row of rowsB) {\n row.fingerprint = generateFingerprint(row.node);\n }\n\n return alignNodes(rowsA, rowsB);\n}\n\n/**\n * Align table cells between two rows.\n * Cells are typically position-based, but we still check for content matches.\n */\nexport function alignTableCells(\n rowA: ProseMirrorJSON,\n rowB: ProseMirrorJSON,\n rowPathA: number[],\n rowPathB: number[]\n): AlignmentResult {\n const cellsA = (rowA.content || []).map((cell: ProseMirrorJSON, i: number) => ({\n node: cell,\n fingerprint: '', // Will be computed\n path: [...rowPathA, i],\n }));\n\n const cellsB = (rowB.content || []).map((cell: ProseMirrorJSON, i: number) => ({\n node: cell,\n fingerprint: '', // Will be computed\n path: [...rowPathB, i],\n }));\n\n // Compute fingerprints\n const { generateFingerprint } = require('./nodeFingerprint');\n for (const cell of cellsA) {\n cell.fingerprint = generateFingerprint(cell.node);\n }\n for (const cell of cellsB) {\n cell.fingerprint = generateFingerprint(cell.node);\n }\n\n // For cells, prefer position-based matching when counts are equal\n if (cellsA.length === cellsB.length) {\n const matched: NodeMatch[] = [];\n for (let i = 0; i < cellsA.length; i++) {\n const similarity = getNodeTextSimilarity(cellsA[i].node, cellsB[i].node);\n matched.push({\n pathA: cellsA[i].path,\n pathB: cellsB[i].path,\n fingerprint: cellsA[i].fingerprint,\n similarity,\n });\n }\n return { matched, deletions: [], insertions: [] };\n }\n\n // Different cell counts = use LCS-based alignment\n return alignNodes(cellsA, cellsB);\n}\n\n// ============================================================================\n// List-Specific Alignment\n// ============================================================================\n\n/**\n * Align list items between two lists.\n */\nexport function alignListItems(\n listA: ProseMirrorJSON,\n listB: ProseMirrorJSON,\n listPathA: number[],\n listPathB: number[]\n): AlignmentResult {\n const itemsA = (listA.content || []).map((item: ProseMirrorJSON, i: number) => ({\n node: item,\n fingerprint: '', // Will be computed\n path: [...listPathA, i],\n }));\n\n const itemsB = (listB.content || []).map((item: ProseMirrorJSON, i: number) => ({\n node: item,\n fingerprint: '', // Will be computed\n path: [...listPathB, i],\n }));\n\n // Compute fingerprints\n const { generateFingerprint } = require('./nodeFingerprint');\n for (const item of itemsA) {\n item.fingerprint = generateFingerprint(item.node);\n }\n for (const item of itemsB) {\n item.fingerprint = generateFingerprint(item.node);\n }\n\n return alignNodes(itemsA, itemsB);\n}\n","/**\n * Merge Documents Service\n * Applies track change marks to the original document structure\n * based on character-level diff segments.\n */\n\nimport { v4 as uuidv4 } from 'uuid';\nimport type {\n ProseMirrorJSON,\n ProseMirrorNode,\n ProseMirrorMark,\n DiffResult,\n FormatChange,\n TrackChangeAuthor,\n TextSpan,\n} from '../types';\nimport {\n createTrackInsertMark,\n createTrackDeleteMark,\n createTrackFormatMark,\n normalizeMarksForRendering,\n} from './trackChangeInjector';\nimport { DEFAULT_AUTHOR } from '../constants';\n\n/**\n * Deep clone a node\n */\nfunction cloneNode(node: ProseMirrorNode): ProseMirrorNode {\n return JSON.parse(JSON.stringify(node));\n}\n\n/**\n * Get marks from docB spans at a specific character position.\n * Used to preserve styling from the source document for inserted text.\n */\nfunction getMarksFromSpansB(spansB: TextSpan[], position: number): ProseMirrorMark[] {\n for (const span of spansB) {\n if (position >= span.from && position < span.to) {\n return span.marks || [];\n }\n }\n return [];\n}\n\n/**\n * Get mark spans that cover a range of text in docB.\n * Used when inserted text spans multiple differently-styled regions.\n */\nfunction getMarkSpansForRange(\n spansB: TextSpan[],\n start: number,\n end: number\n): { relStart: number; relEnd: number; marks: ProseMirrorMark[] }[] {\n const result: { relStart: number; relEnd: number; marks: ProseMirrorMark[] }[] = [];\n \n for (const span of spansB) {\n // Check if span overlaps with our range\n if (span.to > start && span.from < end) {\n // Calculate relative positions within the insertion range\n const overlapStart = Math.max(span.from, start);\n const overlapEnd = Math.min(span.to, end);\n \n result.push({\n relStart: overlapStart - start,\n relEnd: overlapEnd - start,\n marks: span.marks || [],\n });\n }\n }\n \n return result;\n}\n\n/**\n * Create text nodes for inserted text, preserving marks from docB.\n * \n * If the inserted text spans multiple mark regions in docB, this will\n * create multiple text nodes, each with the appropriate marks from docB\n * plus the trackInsert mark.\n * \n * @param text - The inserted text content\n * @param posB - Position in docB where this text originated (undefined if unknown)\n * @param spansB - Text spans from docB with mark information\n * @param author - Author for track change marks\n * @param replacementId - Optional shared ID for replacement operations\n * @returns Array of text nodes with preserved marks\n */\nfunction createInsertedTextNodes(\n text: string,\n posB: number | undefined,\n spansB: TextSpan[],\n author: TrackChangeAuthor,\n replacementId?: string\n): ProseMirrorNode[] {\n const result: ProseMirrorNode[] = [];\n const trackMark = createTrackInsertMark(author, replacementId);\n \n // If we don't have position info or spans, create a simple node with just trackInsert\n if (posB === undefined || spansB.length === 0) {\n return [{\n type: 'text',\n text,\n marks: [trackMark],\n }];\n }\n \n // Get all mark spans that cover this inserted text range\n const markSpans = getMarkSpansForRange(spansB, posB, posB + text.length);\n \n // If no spans found, create simple node\n if (markSpans.length === 0) {\n return [{\n type: 'text',\n text,\n marks: [trackMark],\n }];\n }\n \n // Sort spans by start position\n markSpans.sort((a, b) => a.relStart - b.relStart);\n \n // Track how much text we've processed\n let processedUpTo = 0;\n \n for (const span of markSpans) {\n // If there's a gap before this span, create a node without marks\n if (span.relStart > processedUpTo) {\n result.push({\n type: 'text',\n text: text.substring(processedUpTo, span.relStart),\n marks: [trackMark],\n });\n }\n \n // Create node with marks from docB plus trackInsert\n // Normalize marks to ensure valid CSS color format (# prefix for hex colors)\n if (span.relEnd > span.relStart) {\n const spanText = text.substring(span.relStart, span.relEnd);\n const normalizedSpanMarks = normalizeMarksForRendering(span.marks);\n const marks = [...normalizedSpanMarks, trackMark];\n \n result.push({\n type: 'text',\n text: spanText,\n marks,\n });\n processedUpTo = span.relEnd;\n }\n }\n \n // Handle any remaining text after the last span\n if (processedUpTo < text.length) {\n result.push({\n type: 'text',\n text: text.substring(processedUpTo),\n marks: [trackMark],\n });\n }\n \n return result;\n}\n\n/**\n * Character state during merge\n */\ninterface CharState {\n type: 'equal' | 'delete' | 'insert';\n insertText?: string;\n /** Shared ID for replacement operations (delete + insert at same position) */\n replacementId?: string;\n}\n\n/**\n * Insertion point during merge\n */\ninterface Insertion {\n afterOffset: number;\n text: string;\n /** Shared ID for replacement operations (delete + insert at same position) */\n replacementId?: string;\n /** Position in docB where this inserted text originated (for mark lookup) */\n posB?: number;\n}\n\n/**\n * Build a merged document by applying diff segments to the original structure.\n *\n * Strategy:\n * 1. Clone docA (original)\n * 2. Walk through diff segments\n * 3. For 'equal' segments: keep original content as-is\n * 4. For 'delete' segments: add trackDelete mark to the corresponding text\n * 5. For 'insert' segments: insert new text nodes with trackInsert mark\n */\nexport function mergeDocuments(\n docA: ProseMirrorNode,\n docB: ProseMirrorNode,\n diffResult: DiffResult,\n author: TrackChangeAuthor = DEFAULT_AUTHOR\n): ProseMirrorNode {\n // Clone the original document\n const merged = cloneNode(docA);\n\n // Build a map of character offset -> segment type\n // This tells us for each character what its state is\n const charStates: CharState[] = [];\n let insertions: Insertion[] = [];\n\n // Store format changes as array for range lookups\n const formatChanges: FormatChange[] = diffResult.formatChanges || [];\n\n // Helper to find format change at a position\n function getFormatChangeAt(pos: number): FormatChange | null {\n for (const fc of formatChanges) {\n if (pos >= fc.from && pos < fc.to) {\n return fc;\n }\n }\n return null;\n }\n\n let docAOffset = 0;\n const segments = diffResult.segments;\n \n for (let segIdx = 0; segIdx < segments.length; segIdx++) {\n const segment = segments[segIdx];\n \n if (segment.type === 'equal') {\n // Mark these characters as equal\n for (let i = 0; i < segment.text.length; i++) {\n charStates[docAOffset + i] = { type: 'equal' };\n }\n docAOffset += segment.text.length;\n } else if (segment.type === 'delete') {\n // Check if next segment is an insert (replacement pattern)\n const nextSegment = segments[segIdx + 1];\n const isReplacement = nextSegment && nextSegment.type === 'insert';\n const replacementId = isReplacement ? uuidv4() : undefined;\n \n // Mark these characters as deleted\n for (let i = 0; i < segment.text.length; i++) {\n charStates[docAOffset + i] = { type: 'delete', replacementId };\n }\n docAOffset += segment.text.length;\n \n // If this is a replacement, process the insert segment now with the same ID\n if (isReplacement && nextSegment) {\n insertions.push({\n afterOffset: docAOffset,\n text: nextSegment.text,\n replacementId,\n posB: nextSegment.posB, // Capture docB position for mark lookup\n });\n segIdx++; // Skip the next segment since we processed it here\n }\n } else if (segment.type === 'insert') {\n // Standalone insert (not part of a replacement)\n insertions.push({\n afterOffset: docAOffset,\n text: segment.text,\n posB: segment.posB, // Capture docB position for mark lookup\n });\n }\n }\n\n // Get docB spans for mark preservation (if available)\n const spansB = diffResult.spansB || [];\n\n // Now we need to transform the document\n // For each text span in the original:\n // 1. Split it based on character states (equal vs delete)\n // 2. Apply trackDelete marks to deleted parts\n // 3. Insert new content where insertions occur\n\n function transformNode(\n node: ProseMirrorNode,\n nodeOffset: number,\n path: number[]\n ): { nodes: ProseMirrorNode[]; consumedLength: number } {\n if (node.type === 'text' && node.text) {\n const text = node.text;\n const result: ProseMirrorNode[] = [];\n let i = 0;\n\n while (i < text.length) {\n const charOffset = nodeOffset + i;\n const charState = charStates[charOffset] || { type: 'equal' };\n\n // Check for insertions at this position\n const insertionsHere = insertions.filter((ins) => ins.afterOffset === charOffset);\n for (const ins of insertionsHere) {\n // Create inserted text nodes, preserving marks from docB\n const insertedNodes = createInsertedTextNodes(\n ins.text,\n ins.posB,\n spansB,\n author,\n ins.replacementId\n );\n result.push(...insertedNodes);\n }\n\n // Find run of same state AND same format change status\n const currentFormatChange = getFormatChangeAt(nodeOffset + i);\n let j = i + 1;\n while (j < text.length) {\n const nextState = charStates[nodeOffset + j] || { type: 'equal' };\n if (nextState.type !== charState.type) break;\n // Also break if there's an insertion point here\n if (insertions.some((ins) => ins.afterOffset === nodeOffset + j)) break;\n // Break if format change status changes\n const nextFormatChange = getFormatChangeAt(nodeOffset + j);\n if (currentFormatChange !== nextFormatChange) break;\n j++;\n }\n\n const chunk = text.substring(i, j);\n let marks = [...(node.marks || [])];\n\n if (charState.type === 'delete') {\n marks.push(createTrackDeleteMark(author, charState.replacementId));\n } else if (charState.type === 'equal') {\n // Check if there's a format change at this position\n if (currentFormatChange) {\n // For format changes, use the NEW marks (after) plus trackFormat\n // Note: createTrackFormatMark already normalizes before/after marks\n const trackFormatMark = createTrackFormatMark(\n currentFormatChange.before,\n currentFormatChange.after,\n author\n );\n // Normalize the after marks to ensure valid CSS color format\n const normalizedAfterMarks = normalizeMarksForRendering(currentFormatChange.after);\n marks = [...normalizedAfterMarks, trackFormatMark];\n }\n }\n\n result.push({\n type: 'text',\n text: chunk,\n marks: marks.length > 0 ? marks : undefined,\n });\n\n i = j;\n }\n\n // Check for insertions at the end of this text node\n const endOffset = nodeOffset + text.length;\n const endInsertions = insertions.filter((ins) => ins.afterOffset === endOffset);\n for (const ins of endInsertions) {\n // Create inserted text nodes, preserving marks from docB\n const insertedNodes = createInsertedTextNodes(\n ins.text,\n ins.posB,\n spansB,\n author,\n ins.replacementId\n );\n result.push(...insertedNodes);\n }\n\n // Remove processed insertions\n insertions = insertions.filter(\n (ins) => ins.afterOffset < nodeOffset || ins.afterOffset > endOffset\n );\n\n return { nodes: result, consumedLength: text.length };\n }\n\n // Non-text node: recursively transform children\n if (node.content && Array.isArray(node.content)) {\n const newContent: ProseMirrorNode[] = [];\n let offset = nodeOffset;\n\n for (const child of node.content) {\n const { nodes, consumedLength } = transformNode(child, offset, path);\n newContent.push(...nodes);\n offset += consumedLength;\n }\n\n return {\n nodes: [{ ...node, content: newContent }],\n consumedLength: offset - nodeOffset,\n };\n }\n\n // Node without content (like hard break)\n return { nodes: [node], consumedLength: 0 };\n }\n\n // Transform the document content\n if (merged.content && Array.isArray(merged.content)) {\n const newContent: ProseMirrorNode[] = [];\n let offset = 0;\n\n for (let i = 0; i < merged.content.length; i++) {\n const child = merged.content[i];\n const { nodes, consumedLength } = transformNode(child, offset, [i]);\n newContent.push(...nodes);\n offset += consumedLength;\n }\n\n merged.content = newContent;\n }\n\n // Handle any remaining insertions (at the very end)\n if (insertions.length > 0) {\n for (const ins of insertions) {\n // Create text nodes with preserved marks from docB\n const insertedNodes = createInsertedTextNodes(\n ins.text,\n ins.posB,\n spansB,\n author,\n ins.replacementId\n );\n \n const insertNode = {\n type: 'paragraph',\n content: [\n {\n type: 'run',\n content: insertedNodes,\n },\n ],\n };\n if (!merged.content) merged.content = [];\n merged.content.push(insertNode);\n }\n }\n\n return merged;\n}\n\n/**\n * Export for compatibility\n */\nexport function createSimpleMergedDocument(\n docA: ProseMirrorNode,\n docB: ProseMirrorNode,\n diffResult: DiffResult,\n author: TrackChangeAuthor = DEFAULT_AUTHOR\n): ProseMirrorNode {\n return mergeDocuments(docA, docB, diffResult, author);\n}\n\n","/**\n * Attribute Comparer Service\n * \n * Deep comparison of node attributes to detect style/formatting changes.\n * Handles nested objects and default value normalization.\n */\n\nimport type { AttrDiff } from '../types';\n\n// ============================================================================\n// Types\n// ============================================================================\n\ntype AttrValue = unknown;\ntype AttrObject = Record<string, AttrValue>;\n\n// ============================================================================\n// Default Values\n// ============================================================================\n\n/**\n * Known default values for common ProseMirror node attributes.\n * Used to normalize comparisons (e.g., missing attr vs explicit default).\n */\nconst KNOWN_DEFAULTS: Record<string, Record<string, AttrValue>> = {\n paragraph: {\n textAlign: 'left',\n indent: 0,\n lineSpacing: 1,\n },\n heading: {\n level: 1,\n textAlign: 'left',\n },\n table: {\n alignment: 'left',\n borderStyle: 'single',\n },\n tableCell: {\n verticalAlign: 'top',\n colspan: 1,\n rowspan: 1,\n },\n listItem: {\n indent: 0,\n },\n image: {\n width: 'auto',\n height: 'auto',\n },\n};\n\n/**\n * Attributes to ignore during comparison.\n * These are internal/computed values that don't represent user changes.\n */\nconst IGNORED_ATTRS = new Set([\n 'id',\n 'class',\n 'data-id',\n 'data-pm-slice',\n '__trackAttrChanges',\n]);\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * Check if a value is a plain object (not array, null, etc.).\n */\nfunction isPlainObject(value: unknown): value is AttrObject {\n return (\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n Object.prototype.toString.call(value) === '[object Object]'\n );\n}\n\n/**\n * Check if two values are deeply equal.\n */\nfunction deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (typeof a !== typeof b) return false;\n if (a === null || b === null) return a === b;\n\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false;\n return a.every((val, i) => deepEqual(val, b[i]));\n }\n\n if (isPlainObject(a) && isPlainObject(b)) {\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n if (keysA.length !== keysB.length) return false;\n return keysA.every((key) => deepEqual(a[key], b[key]));\n }\n\n return false;\n}\n\n/**\n * Normalize an attribute value using known defaults.\n * Returns the default value if the input is undefined/null.\n */\nfunction normalizeValue(\n value: AttrValue,\n key: string,\n nodeType: string\n): AttrValue {\n if (value !== undefined && value !== null) {\n return value;\n }\n\n // Look up default\n const defaults = KNOWN_DEFAULTS[nodeType];\n if (defaults && key in defaults) {\n return defaults[key];\n }\n\n return value;\n}\n\n/**\n * Format a value for display in diff output.\n */\nfunction formatValue(value: unknown): string {\n if (value === undefined) return 'undefined';\n if (value === null) return 'null';\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean') {\n return String(value);\n }\n return JSON.stringify(value);\n}\n\n// ============================================================================\n// Comparison Functions\n// ============================================================================\n\n/**\n * Compare two attribute objects and return differences.\n * \n * @param attrsA - Attributes from original node\n * @param attrsB - Attributes from new node\n * @param nodeType - Type of node (for default normalization)\n * @param prefix - Key prefix for nested comparisons\n * @returns Array of attribute differences\n */\nexport function compareAttrs(\n attrsA: AttrObject | undefined,\n attrsB: AttrObject | undefined,\n nodeType: string = '',\n prefix: string = ''\n): AttrDiff[] {\n const diffs: AttrDiff[] = [];\n \n const a = attrsA || {};\n const b = attrsB || {};\n\n // Collect all keys from both objects\n const allKeys = new Set([...Object.keys(a), ...Object.keys(b)]);\n\n for (const key of allKeys) {\n // Skip ignored attributes\n if (IGNORED_ATTRS.has(key)) continue;\n\n const fullKey = prefix ? `${prefix}.${key}` : key;\n const valueA = normalizeValue(a[key], key, nodeType);\n const valueB = normalizeValue(b[key], key, nodeType);\n\n // If both are objects, recurse\n if (isPlainObject(valueA) && isPlainObject(valueB)) {\n const nestedDiffs = compareAttrs(\n valueA as AttrObject,\n valueB as AttrObject,\n nodeType,\n fullKey\n );\n diffs.push(...nestedDiffs);\n continue;\n }\n\n // Compare values\n if (!deepEqual(valueA, valueB)) {\n diffs.push({\n key: fullKey,\n before: valueA,\n after: valueB,\n });\n }\n }\n\n return diffs;\n}\n\n/**\n * Compare attributes of two nodes and return differences.\n * Convenience wrapper that extracts attrs from nodes.\n */\nexport function compareNodeAttrs(\n nodeA: { type?: string; attrs?: AttrObject },\n nodeB: { type?: string; attrs?: AttrObject }\n): AttrDiff[] {\n const nodeType = nodeA.type || nodeB.type || '';\n return compareAttrs(nodeA.attrs, nodeB.attrs, nodeType);\n}\n\n/**\n * Check if two nodes have different attributes.\n */\nexport function hasAttrChanges(\n nodeA: { type?: string; attrs?: AttrObject },\n nodeB: { type?: string; attrs?: AttrObject }\n): boolean {\n const diffs = compareNodeAttrs(nodeA, nodeB);\n return diffs.length > 0;\n}\n\n// ============================================================================\n// Formatting Functions\n// ============================================================================\n\n/**\n * Format attribute differences for display.\n * Returns human-readable strings like \"Border: black → blue\".\n */\nexport function formatAttrDiffs(diffs: AttrDiff[]): string[] {\n return diffs.map((diff) => {\n const before = formatValue(diff.before);\n const after = formatValue(diff.after);\n \n // Prettify the key name\n const keyParts = diff.key.split('.');\n const prettyKey = keyParts\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(' ');\n\n return `${prettyKey}: ${before} → ${after}`;\n });\n}\n\n/**\n * Get a short summary of attribute changes.\n */\nexport function summarizeAttrChanges(diffs: AttrDiff[]): string {\n if (diffs.length === 0) return '';\n if (diffs.length === 1) {\n const diff = diffs[0];\n return `${diff.key}: ${formatValue(diff.before)} → ${formatValue(diff.after)}`;\n }\n return `${diffs.length} formatting changes`;\n}\n","/**\n * Table Block Differ Service\n * \n * Specialized diffing logic for tables:\n * - Row insertions/deletions\n * - Column insertions/deletions\n * - Cell-level content changes\n * - Table/cell attribute changes\n */\n\nimport type {\n ProseMirrorJSON,\n StructuralChange,\n AttributeChange,\n NodeMatch,\n StructuralChangeType,\n} from '../types';\nimport { v4 as uuidv4 } from 'uuid';\nimport { alignTableRows, alignTableCells } from './nodeAligner';\nimport { compareNodeAttrs } from './attrComparer';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Result of diffing two tables\n */\nexport interface TableDiffResult {\n /** Row-level structural changes */\n rowChanges: StructuralChange[];\n /** Column-level structural changes (detected from cell patterns) */\n columnChanges: StructuralChange[];\n /** Cell-level matches for content diffing */\n cellMatches: NodeMatch[];\n /** Attribute changes on the table itself */\n tableAttrChanges: AttributeChange | null;\n /** Attribute changes on cells */\n cellAttrChanges: AttributeChange[];\n}\n\n// ============================================================================\n// Table Analysis\n// ============================================================================\n\n/**\n * Get the number of columns in a table (based on first row).\n */\nfunction getColumnCount(table: ProseMirrorJSON): number {\n if (!table.content || table.content.length === 0) return 0;\n const firstRow = table.content[0];\n return firstRow.content?.length || 0;\n}\n\n/**\n * Check if a column was inserted or deleted.\n * Compares cell counts across matched rows to detect consistent column changes.\n */\nfunction detectColumnChanges(\n matchedRows: NodeMatch[],\n tableA: ProseMirrorJSON,\n tableB: ProseMirrorJSON,\n tablePathA: number[],\n tablePathB: number[]\n): StructuralChange[] {\n const changes: StructuralChange[] = [];\n \n if (matchedRows.length === 0) return changes;\n\n // Get cell counts from first matched row pair\n const firstMatch = matchedRows[0];\n const rowIdxA = firstMatch.pathA[firstMatch.pathA.length - 1];\n const rowIdxB = firstMatch.pathB[firstMatch.pathB.length - 1];\n \n const rowA = tableA.content?.[rowIdxA];\n const rowB = tableB.content?.[rowIdxB];\n \n if (!rowA || !rowB) return changes;\n \n const cellCountA = rowA.content?.length || 0;\n const cellCountB = rowB.content?.length || 0;\n \n const diff = cellCountB - cellCountA;\n \n if (diff === 0) return changes;\n\n // Verify the pattern is consistent across all matched rows\n let consistent = true;\n for (const match of matchedRows) {\n const idxA = match.pathA[match.pathA.length - 1];\n const idxB = match.pathB[match.pathB.length - 1];\n const rA = tableA.content?.[idxA];\n const rB = tableB.content?.[idxB];\n \n if (!rA || !rB) continue;\n \n const countA = rA.content?.length || 0;\n const countB = rB.content?.length || 0;\n \n if (countB - countA !== diff) {\n consistent = false;\n break;\n }\n }\n\n if (!consistent) return changes;\n\n // Detected consistent column change\n if (diff > 0) {\n // Column(s) inserted\n for (let i = 0; i < diff; i++) {\n changes.push({\n id: uuidv4(),\n type: 'columnInsert',\n nodeType: 'tableColumn',\n path: [...tablePathB],\n node: { type: 'column', position: cellCountA + i },\n });\n }\n } else {\n // Column(s) deleted\n for (let i = 0; i < Math.abs(diff); i++) {\n changes.push({\n id: uuidv4(),\n type: 'columnDelete',\n nodeType: 'tableColumn',\n path: [...tablePathA],\n node: { type: 'column', position: cellCountB + i },\n });\n }\n }\n\n return changes;\n}\n\n// ============================================================================\n// Main Table Diff Function\n// ============================================================================\n\n/**\n * Diff two tables and return all detected changes.\n */\nexport function diffTables(\n tableA: ProseMirrorJSON,\n tableB: ProseMirrorJSON,\n tablePathA: number[],\n tablePathB: number[]\n): TableDiffResult {\n const result: TableDiffResult = {\n rowChanges: [],\n columnChanges: [],\n cellMatches: [],\n tableAttrChanges: null,\n cellAttrChanges: [],\n };\n\n // 1. Compare table-level attributes\n const tableAttrDiffs = compareNodeAttrs(tableA, tableB);\n if (tableAttrDiffs.length > 0) {\n result.tableAttrChanges = {\n id: uuidv4(),\n nodeType: 'table',\n pathA: tablePathA,\n pathB: tablePathB,\n changes: tableAttrDiffs,\n };\n }\n\n // 2. Align rows between tables\n const rowAlignment = alignTableRows(tableA, tableB, tablePathA, tablePathB);\n\n // 3. Process row insertions\n for (const inserted of rowAlignment.insertions) {\n result.rowChanges.push({\n id: uuidv4(),\n type: 'rowInsert',\n nodeType: 'tableRow',\n path: inserted.path,\n node: inserted.node,\n });\n }\n\n // 4. Process row deletions\n for (const deleted of rowAlignment.deletions) {\n result.rowChanges.push({\n id: uuidv4(),\n type: 'rowDelete',\n nodeType: 'tableRow',\n path: deleted.path,\n node: deleted.node,\n });\n }\n\n // 5. Detect column changes from matched rows\n result.columnChanges = detectColumnChanges(\n rowAlignment.matched,\n tableA,\n tableB,\n tablePathA,\n tablePathB\n );\n\n // 6. Process matched rows - align cells within each\n for (const rowMatch of rowAlignment.matched) {\n const rowIdxA = rowMatch.pathA[rowMatch.pathA.length - 1];\n const rowIdxB = rowMatch.pathB[rowMatch.pathB.length - 1];\n \n const rowA = tableA.content?.[rowIdxA];\n const rowB = tableB.content?.[rowIdxB];\n \n if (!rowA || !rowB) continue;\n\n // Align cells within this row pair\n const cellAlignment = alignTableCells(\n rowA,\n rowB,\n rowMatch.pathA,\n rowMatch.pathB\n );\n\n // Add cell matches for content diffing\n result.cellMatches.push(...cellAlignment.matched);\n\n // Check for cell attribute changes on matched cells\n for (const cellMatch of cellAlignment.matched) {\n const cellIdxA = cellMatch.pathA[cellMatch.pathA.length - 1];\n const cellIdxB = cellMatch.pathB[cellMatch.pathB.length - 1];\n \n const cellA = rowA.content?.[cellIdxA];\n const cellB = rowB.content?.[cellIdxB];\n \n if (!cellA || !cellB) continue;\n\n const cellAttrDiffs = compareNodeAttrs(cellA, cellB);\n if (cellAttrDiffs.length > 0) {\n result.cellAttrChanges.push({\n id: uuidv4(),\n nodeType: 'tableCell',\n pathA: cellMatch.pathA,\n pathB: cellMatch.pathB,\n changes: cellAttrDiffs,\n });\n }\n }\n }\n\n return result;\n}\n\n/**\n * Check if a node is a table.\n */\nexport function isTable(node: ProseMirrorJSON): boolean {\n return node?.type === 'table';\n}\n\n/**\n * Check if a node is a table row.\n */\nexport function isTableRow(node: ProseMirrorJSON): boolean {\n return node?.type === 'tableRow';\n}\n\n/**\n * Check if a node is a table cell.\n */\nexport function isTableCell(node: ProseMirrorJSON): boolean {\n return node?.type === 'tableCell' || node?.type === 'tableHeader';\n}\n\n/**\n * Get a human-readable location string for a table.\n */\nexport function getTableLocation(tablePath: number[], tableIndex: number): string {\n return `Table ${tableIndex + 1}`;\n}\n\n/**\n * Get a human-readable location string for a row.\n */\nexport function getRowLocation(\n tablePath: number[],\n rowIndex: number,\n tableIndex: number\n): string {\n return `Table ${tableIndex + 1}, Row ${rowIndex + 1}`;\n}\n\n/**\n * Get a human-readable location string for a cell.\n */\nexport function getCellLocation(\n rowIndex: number,\n cellIndex: number,\n tableIndex: number\n): string {\n // Convert to A1 notation for column\n const colLetter = String.fromCharCode(65 + cellIndex);\n return `Table ${tableIndex + 1}, Cell ${colLetter}${rowIndex + 1}`;\n}\n\n/**\n * Extract text preview from a table row.\n */\nexport function getRowPreview(row: ProseMirrorJSON, maxLength: number = 50): string {\n const cells: string[] = [];\n \n for (const cell of row.content || []) {\n const cellText = extractCellText(cell);\n if (cellText) {\n cells.push(cellText);\n }\n }\n \n const preview = cells.join(' | ');\n if (preview.length > maxLength) {\n return preview.substring(0, maxLength - 3) + '...';\n }\n return preview;\n}\n\n/**\n * Extract text from a table cell.\n */\nfunction extractCellText(cell: ProseMirrorJSON): string {\n if (!cell.content) return '';\n \n const texts: string[] = [];\n \n for (const child of cell.content) {\n if (child.type === 'text') {\n texts.push(child.text || '');\n } else if (child.type === 'paragraph' && child.content) {\n for (const pChild of child.content) {\n if (pChild.type === 'text') {\n texts.push(pChild.text || '');\n }\n }\n }\n }\n \n return texts.join('').trim();\n}\n","/**\n * List Block Differ Service\n * \n * Specialized diffing logic for lists:\n * - List item insertions/deletions\n * - List item reordering detection\n * - Nested list handling\n */\n\nimport type {\n ProseMirrorJSON,\n StructuralChange,\n NodeMatch,\n} from '../types';\nimport { v4 as uuidv4 } from 'uuid';\nimport { alignListItems } from './nodeAligner';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Result of diffing two lists\n */\nexport interface ListDiffResult {\n /** Item-level structural changes */\n itemChanges: StructuralChange[];\n /** Item matches for content diffing */\n itemMatches: NodeMatch[];\n /** Nested list changes (recursive) */\n nestedChanges: ListDiffResult[];\n}\n\n// ============================================================================\n// List Analysis\n// ============================================================================\n\n/**\n * Check if a node is a list (ordered or unordered).\n */\nexport function isList(node: ProseMirrorJSON): boolean {\n return node?.type === 'bulletList' || node?.type === 'orderedList';\n}\n\n/**\n * Check if a node is a list item.\n */\nexport function isListItem(node: ProseMirrorJSON): boolean {\n return node?.type === 'listItem';\n}\n\n/**\n * Get the list type string.\n */\nexport function getListType(node: ProseMirrorJSON): 'ordered' | 'unordered' | null {\n if (node?.type === 'orderedList') return 'ordered';\n if (node?.type === 'bulletList') return 'unordered';\n return null;\n}\n\n/**\n * Extract text content from a list item.\n */\nfunction extractListItemText(item: ProseMirrorJSON): string {\n const texts: string[] = [];\n \n function extract(node: ProseMirrorJSON): void {\n if (!node) return;\n \n if (node.type === 'text') {\n texts.push(node.text || '');\n }\n \n if (node.content && Array.isArray(node.content)) {\n for (const child of node.content) {\n // Skip nested lists when extracting text\n if (!isList(child)) {\n extract(child);\n }\n }\n }\n }\n \n extract(item);\n return texts.join('').trim();\n}\n\n/**\n * Find nested lists within a list item.\n */\nfunction findNestedLists(item: ProseMirrorJSON): ProseMirrorJSON[] {\n const lists: ProseMirrorJSON[] = [];\n \n if (!item.content) return lists;\n \n for (const child of item.content) {\n if (isList(child)) {\n lists.push(child);\n }\n }\n \n return lists;\n}\n\n// ============================================================================\n// Main List Diff Function\n// ============================================================================\n\n/**\n * Diff two lists and return all detected changes.\n */\nexport function diffLists(\n listA: ProseMirrorJSON,\n listB: ProseMirrorJSON,\n listPathA: number[],\n listPathB: number[],\n depth: number = 0\n): ListDiffResult {\n const result: ListDiffResult = {\n itemChanges: [],\n itemMatches: [],\n nestedChanges: [],\n };\n\n // Align list items\n const alignment = alignListItems(listA, listB, listPathA, listPathB);\n\n // Process insertions\n for (const inserted of alignment.insertions) {\n result.itemChanges.push({\n id: uuidv4(),\n type: 'listItemInsert',\n nodeType: 'listItem',\n path: inserted.path,\n node: inserted.node,\n });\n }\n\n // Process deletions\n for (const deleted of alignment.deletions) {\n result.itemChanges.push({\n id: uuidv4(),\n type: 'listItemDelete',\n nodeType: 'listItem',\n path: deleted.path,\n node: deleted.node,\n });\n }\n\n // Store matches for content diffing\n result.itemMatches = alignment.matched;\n\n // Process nested lists in matched items\n for (const match of alignment.matched) {\n const itemIdxA = match.pathA[match.pathA.length - 1];\n const itemIdxB = match.pathB[match.pathB.length - 1];\n \n const itemA = listA.content?.[itemIdxA];\n const itemB = listB.content?.[itemIdxB];\n \n if (!itemA || !itemB) continue;\n\n // Find nested lists\n const nestedA = findNestedLists(itemA);\n const nestedB = findNestedLists(itemB);\n\n // Diff nested lists (simple 1:1 matching by position for now)\n const maxNested = Math.max(nestedA.length, nestedB.length);\n \n for (let i = 0; i < maxNested; i++) {\n const nA = nestedA[i];\n const nB = nestedB[i];\n \n if (nA && nB) {\n // Both exist - recurse\n const nestedResult = diffLists(\n nA,\n nB,\n [...match.pathA, i],\n [...match.pathB, i],\n depth + 1\n );\n result.nestedChanges.push(nestedResult);\n } else if (!nA && nB) {\n // Nested list inserted\n result.itemChanges.push({\n id: uuidv4(),\n type: 'listItemInsert',\n nodeType: 'nestedList',\n path: [...match.pathB, i],\n node: nB,\n });\n } else if (nA && !nB) {\n // Nested list deleted\n result.itemChanges.push({\n id: uuidv4(),\n type: 'listItemDelete',\n nodeType: 'nestedList',\n path: [...match.pathA, i],\n node: nA,\n });\n }\n }\n }\n\n return result;\n}\n\n// ============================================================================\n// Location & Preview Functions\n// ============================================================================\n\n/**\n * Get a human-readable location string for a list.\n */\nexport function getListLocation(listPath: number[], listIndex: number): string {\n return `List ${listIndex + 1}`;\n}\n\n/**\n * Get a human-readable location string for a list item.\n */\nexport function getListItemLocation(\n listPath: number[],\n itemIndex: number,\n listIndex: number,\n depth: number = 0\n): string {\n const depthStr = depth > 0 ? ` (nested, level ${depth + 1})` : '';\n return `List ${listIndex + 1}, Item ${itemIndex + 1}${depthStr}`;\n}\n\n/**\n * Get a text preview from a list item.\n */\nexport function getListItemPreview(item: ProseMirrorJSON, maxLength: number = 50): string {\n const text = extractListItemText(item);\n if (text.length > maxLength) {\n return text.substring(0, maxLength - 3) + '...';\n }\n return text || '(empty item)';\n}\n\n/**\n * Count total items in a list (including nested).\n */\nexport function countListItems(list: ProseMirrorJSON): number {\n let count = 0;\n \n function countRecursive(node: ProseMirrorJSON): void {\n if (isListItem(node)) {\n count++;\n }\n if (node.content) {\n for (const child of node.content) {\n countRecursive(child);\n }\n }\n }\n \n countRecursive(list);\n return count;\n}\n","/**\n * Non-Text Node Differ Service\n * \n * Handles diffing of atomic non-text nodes:\n * - Images\n * - Horizontal rules\n * - Page breaks\n * - Embedded objects (equations, etc.)\n */\n\nimport type {\n ProseMirrorJSON,\n StructuralChange,\n} from '../types';\nimport { v4 as uuidv4 } from 'uuid';\n\n// ============================================================================\n// Node Type Detection\n// ============================================================================\n\n/**\n * Check if a node is an image.\n */\nexport function isImage(node: ProseMirrorJSON): boolean {\n return node?.type === 'image';\n}\n\n/**\n * Check if a node is a horizontal rule.\n */\nexport function isHorizontalRule(node: ProseMirrorJSON): boolean {\n return node?.type === 'horizontalRule' || node?.type === 'hr';\n}\n\n/**\n * Check if a node is a hard break.\n */\nexport function isHardBreak(node: ProseMirrorJSON): boolean {\n return node?.type === 'hardBreak';\n}\n\n/**\n * Check if a node is a page break.\n */\nexport function isPageBreak(node: ProseMirrorJSON): boolean {\n return node?.type === 'pageBreak';\n}\n\n/**\n * Check if a node is an embedded object (equation, chart, etc.).\n */\nexport function isEmbedded(node: ProseMirrorJSON): boolean {\n const embeddedTypes = [\n 'equation',\n 'math',\n 'embed',\n 'chart',\n 'drawing',\n 'shape',\n ];\n return embeddedTypes.includes(node?.type);\n}\n\n/**\n * Check if a node is an atomic (non-text, leaf) node.\n */\nexport function isAtomicNode(node: ProseMirrorJSON): boolean {\n return (\n isImage(node) ||\n isHorizontalRule(node) ||\n isHardBreak(node) ||\n isPageBreak(node) ||\n isEmbedded(node)\n );\n}\n\n// ============================================================================\n// Image Comparison\n// ============================================================================\n\n/**\n * Get image identifier for comparison.\n * Uses src URL or data hash.\n */\nexport function getImageIdentifier(node: ProseMirrorJSON): string {\n if (!isImage(node)) return '';\n \n const attrs = node.attrs || {};\n \n // Prefer src URL\n if (attrs.src) {\n return `src:${attrs.src}`;\n }\n \n // Fall back to data if available\n if (attrs.data) {\n // Hash the data for comparison\n return `data:${simpleHash(attrs.data)}`;\n }\n \n // Use alt text as last resort\n if (attrs.alt) {\n return `alt:${attrs.alt}`;\n }\n \n return 'unknown';\n}\n\n/**\n * Simple hash function for image data.\n */\nfunction simpleHash(str: string): string {\n let hash = 5381;\n const sample = str.substring(0, 1000); // Sample first 1000 chars for speed\n for (let i = 0; i < sample.length; i++) {\n hash = ((hash << 5) + hash) ^ sample.charCodeAt(i);\n }\n return (hash >>> 0).toString(16);\n}\n\n/**\n * Compare two images and determine if they're the same.\n */\nexport function imagesMatch(imgA: ProseMirrorJSON, imgB: ProseMirrorJSON): boolean {\n if (!isImage(imgA) || !isImage(imgB)) return false;\n return getImageIdentifier(imgA) === getImageIdentifier(imgB);\n}\n\n// ============================================================================\n// Image Diff Detection\n// ============================================================================\n\n/**\n * Find images in a document (at any depth).\n */\nexport function findImages(doc: ProseMirrorJSON, basePath: number[] = []): { node: ProseMirrorJSON; path: number[] }[] {\n const images: { node: ProseMirrorJSON; path: number[] }[] = [];\n \n function traverse(node: ProseMirrorJSON, path: number[]): void {\n if (!node) return;\n \n if (isImage(node)) {\n images.push({ node, path: [...path] });\n }\n \n if (node.content && Array.isArray(node.content)) {\n node.content.forEach((child: ProseMirrorJSON, i: number) => {\n traverse(child, [...path, i]);\n });\n }\n }\n \n traverse(doc, basePath);\n return images;\n}\n\n/**\n * Diff images between two documents.\n */\nexport function diffImages(\n docA: ProseMirrorJSON,\n docB: ProseMirrorJSON\n): { inserted: StructuralChange[]; deleted: StructuralChange[] } {\n const imagesA = findImages(docA);\n const imagesB = findImages(docB);\n \n const inserted: StructuralChange[] = [];\n const deleted: StructuralChange[] = [];\n \n // Build identifier sets\n const idsA = new Map<string, { node: ProseMirrorJSON; path: number[] }>();\n const idsB = new Map<string, { node: ProseMirrorJSON; path: number[] }>();\n \n for (const img of imagesA) {\n const id = getImageIdentifier(img.node);\n idsA.set(id, img);\n }\n \n for (const img of imagesB) {\n const id = getImageIdentifier(img.node);\n idsB.set(id, img);\n }\n \n // Find deleted images (in A but not in B)\n for (const [id, img] of idsA) {\n if (!idsB.has(id)) {\n deleted.push({\n id: uuidv4(),\n type: 'imageDelete',\n nodeType: 'image',\n path: img.path,\n node: img.node,\n });\n }\n }\n \n // Find inserted images (in B but not in A)\n for (const [id, img] of idsB) {\n if (!idsA.has(id)) {\n inserted.push({\n id: uuidv4(),\n type: 'imageInsert',\n nodeType: 'image',\n path: img.path,\n node: img.node,\n });\n }\n }\n \n return { inserted, deleted };\n}\n\n// ============================================================================\n// Location & Preview Functions\n// ============================================================================\n\n/**\n * Get a human-readable location for an image.\n */\nexport function getImageLocation(path: number[]): string {\n // Simple location based on path depth\n if (path.length <= 1) {\n return `Image at position ${path[0] + 1}`;\n }\n return `Image (nested at depth ${path.length})`;\n}\n\n/**\n * Get a preview/description for an image.\n */\nexport function getImagePreview(node: ProseMirrorJSON): string {\n if (!isImage(node)) return '';\n \n const attrs = node.attrs || {};\n \n // Use alt text if available\n if (attrs.alt) {\n return `\"${attrs.alt}\"`;\n }\n \n // Use filename from src if available\n if (attrs.src) {\n const src = attrs.src as string;\n const filename = src.split('/').pop()?.split('?')[0];\n if (filename) {\n return filename;\n }\n }\n \n return '(image)';\n}\n\n/**\n * Get a preview for an atomic node.\n */\nexport function getAtomicNodePreview(node: ProseMirrorJSON): string {\n if (isImage(node)) return getImagePreview(node);\n if (isHorizontalRule(node)) return '—— (horizontal rule)';\n if (isPageBreak(node)) return '⏎ (page break)';\n if (isHardBreak(node)) return '↵ (line break)';\n if (isEmbedded(node)) return `[${node.type}]`;\n return `[${node.type || 'unknown'}]`;\n}\n","/**\n * Structural Merger Service\n * \n * Implements structure-aware document merging. Unlike character-level merging,\n * this service aligns blocks first, then applies the appropriate merge strategy\n * for each alignment type:\n * \n * - Matched blocks: Apply character-level diff internally\n * - Inserted blocks: Insert entire node with trackInsert marks\n * - Deleted blocks: Keep node with trackDelete marks\n * \n * This is the CRITICAL piece that makes structural changes visible and actionable.\n */\n\nimport { v4 as uuidv4 } from 'uuid';\nimport type {\n ProseMirrorJSON,\n ProseMirrorNode,\n StructuralChange,\n StructuralChangeInfo,\n TrackChangeAuthor,\n DiffResult,\n} from '../types';\nimport {\n createTrackInsertMark,\n createTrackDeleteMark,\n normalizeMarksForRendering,\n} from './trackChangeInjector';\nimport { alignDocuments, alignTableRows, alignListItems } from './nodeAligner';\nimport { diffDocuments } from './documentDiffer';\nimport { mergeDocuments } from './mergeDocuments';\nimport { isTable, isTableRow } from './tableBlockDiffer';\nimport { isList, isListItem } from './listBlockDiffer';\nimport { isImage } from './nonTextNodeDiffer';\nimport { DEFAULT_AUTHOR } from '../constants';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Result of structural merge\n */\nexport interface StructuralMergeResult {\n /** The merged document with all changes applied */\n mergedDoc: ProseMirrorNode;\n /** Metadata for the structural changes pane */\n structuralInfos: StructuralChangeInfo[];\n /** Summary strings for reporting */\n summary: string[];\n /** Count of text-level changes within matched blocks */\n textChangeCount: number;\n}\n\n/**\n * Operation to perform during merge\n */\ninterface MergeOperation {\n type: 'matched' | 'inserted' | 'deleted';\n nodeA?: ProseMirrorNode;\n nodeB?: ProseMirrorNode;\n pathA?: number[];\n pathB?: number[];\n}\n\n// ============================================================================\n// Node Marking Functions\n// ============================================================================\n\n/**\n * Deep clone a node\n */\nfunction cloneNode(node: ProseMirrorNode): ProseMirrorNode {\n return JSON.parse(JSON.stringify(node));\n}\n\n/**\n * Mark all text in a node as inserted (with shared ID).\n * Normalizes existing marks to ensure valid CSS color format.\n */\nfunction markAllTextAsInserted(\n node: ProseMirrorNode,\n sharedId: string,\n author: TrackChangeAuthor\n): ProseMirrorNode {\n if (node.type === 'text') {\n // Normalize existing marks to ensure valid CSS colors (# prefix for hex)\n const existingMarks = normalizeMarksForRendering(node.marks || []);\n return {\n ...node,\n marks: [...existingMarks, createTrackInsertMark(author, sharedId)],\n };\n }\n\n if (node.content && Array.isArray(node.content)) {\n return {\n ...node,\n content: node.content.map((child: ProseMirrorNode) =>\n markAllTextAsInserted(child, sharedId, author)\n ),\n };\n }\n\n return { ...node };\n}\n\n/**\n * Mark all text in a node as deleted (with shared ID).\n * Normalizes existing marks to ensure valid CSS color format.\n */\nfunction markAllTextAsDeleted(\n node: ProseMirrorNode,\n sharedId: string,\n author: TrackChangeAuthor\n): ProseMirrorNode {\n if (node.type === 'text') {\n // Normalize existing marks to ensure valid CSS colors (# prefix for hex)\n const existingMarks = normalizeMarksForRendering(node.marks || []);\n return {\n ...node,\n marks: [...existingMarks, createTrackDeleteMark(author, sharedId)],\n };\n }\n\n if (node.content && Array.isArray(node.content)) {\n return {\n ...node,\n content: node.content.map((child: ProseMirrorNode) =>\n markAllTextAsDeleted(child, sharedId, author)\n ),\n };\n }\n\n return { ...node };\n}\n\n/**\n * Extract text preview from a node.\n */\nfunction extractTextPreview(node: ProseMirrorNode, maxLength: number = 50): string {\n const texts: string[] = [];\n \n function extract(n: ProseMirrorNode): void {\n if (n.type === 'text') {\n texts.push(n.text || '');\n }\n if (n.content) {\n for (const child of n.content) {\n extract(child);\n }\n }\n }\n \n extract(node);\n const text = texts.join('').trim();\n \n if (text.length > maxLength) {\n return text.substring(0, maxLength - 3) + '...';\n }\n return text || '(empty)';\n}\n\n/**\n * Get human-readable node type description.\n */\nfunction getNodeTypeDescription(node: ProseMirrorNode): string {\n if (isTable(node)) return 'Table';\n if (isList(node)) return 'List';\n if (isListItem(node)) return 'List item';\n if (isTableRow(node)) return 'Table row';\n if (isImage(node)) return 'Image';\n if (node.type === 'heading') return `Heading ${node.attrs?.level || 1}`;\n if (node.type === 'paragraph') return 'Paragraph';\n if (node.type === 'blockquote') return 'Blockquote';\n if (node.type === 'codeBlock') return 'Code block';\n return node.type || 'Block';\n}\n\n// ============================================================================\n// Main Structural Merge Function\n// ============================================================================\n\n/**\n * Merge two documents with structural awareness.\n * \n * This is the main entry point that replaces the character-level-only merge.\n * It aligns blocks first, then processes each alignment appropriately.\n */\nexport function mergeWithStructuralAwareness(\n docA: ProseMirrorJSON,\n docB: ProseMirrorJSON,\n author: TrackChangeAuthor = DEFAULT_AUTHOR\n): StructuralMergeResult {\n const structuralInfos: StructuralChangeInfo[] = [];\n const summary: string[] = [];\n let textChangeCount = 0;\n\n // Align top-level blocks\n const alignment = alignDocuments(docA, docB);\n\n // Build merge operations in document order\n const operations = buildMergeOperations(alignment, docA, docB);\n\n // Process each operation to build merged content\n const mergedContent: ProseMirrorNode[] = [];\n let blockIndex = 0;\n\n for (const op of operations) {\n blockIndex++;\n\n switch (op.type) {\n case 'matched': {\n // Matched blocks: merge content (character-level or recursive structural)\n const { mergedNode, infos, changes } = mergeMatchedBlock(\n op.nodeA!,\n op.nodeB!,\n blockIndex,\n author\n );\n mergedContent.push(mergedNode);\n structuralInfos.push(...infos);\n textChangeCount += changes;\n break;\n }\n\n case 'inserted': {\n // Inserted blocks: add with trackInsert marks\n const { markedNode, info } = createInsertedBlock(\n op.nodeB!,\n blockIndex,\n author\n );\n mergedContent.push(markedNode);\n if (info) {\n structuralInfos.push(info);\n }\n break;\n }\n\n case 'deleted': {\n // Deleted blocks: keep with trackDelete marks\n const { markedNode, info } = createDeletedBlock(\n op.nodeA!,\n blockIndex,\n author\n );\n mergedContent.push(markedNode);\n if (info) {\n structuralInfos.push(info);\n }\n break;\n }\n }\n }\n\n // Build merged document\n const mergedDoc: ProseMirrorNode = {\n type: 'doc',\n content: mergedContent,\n };\n\n // Generate summary\n const insertCount = structuralInfos.filter(i => i.type.includes('Insert')).length;\n const deleteCount = structuralInfos.filter(i => i.type.includes('Delete')).length;\n \n if (insertCount > 0) summary.push(`${insertCount} block(s) inserted`);\n if (deleteCount > 0) summary.push(`${deleteCount} block(s) deleted`);\n if (textChangeCount > 0) summary.push(`${textChangeCount} text change(s)`);\n\n return {\n mergedDoc,\n structuralInfos,\n summary,\n textChangeCount,\n };\n}\n\n// ============================================================================\n// Build Merge Operations\n// ============================================================================\n\n/**\n * Build ordered list of merge operations from alignment result.\n * \n * This determines the order of blocks in the merged document:\n * - Walk through docB to get the \"new\" order\n * - Insert deletions from docA at their relative positions\n */\nfunction buildMergeOperations(\n alignment: ReturnType<typeof alignDocuments>,\n docA: ProseMirrorJSON,\n docB: ProseMirrorJSON\n): MergeOperation[] {\n const operations: MergeOperation[] = [];\n \n // Create maps for quick lookup\n const matchedFromA = new Map<number, { pathB: number[]; similarity: number }>();\n const matchedFromB = new Map<number, { pathA: number[]; similarity: number }>();\n \n for (const match of alignment.matched) {\n const idxA = match.pathA[0];\n const idxB = match.pathB[0];\n matchedFromA.set(idxA, { pathB: match.pathB, similarity: match.similarity });\n matchedFromB.set(idxB, { pathA: match.pathA, similarity: match.similarity });\n }\n\n // Track which deletions we've processed\n const deletedIndices = new Set(alignment.deletions.map(d => d.path[0]));\n const processedDeletions = new Set<number>();\n\n // Walk through docB in order\n const contentB = docB.content || [];\n const contentA = docA.content || [];\n\n for (let idxB = 0; idxB < contentB.length; idxB++) {\n const nodeB = contentB[idxB];\n \n // Check if this B position is matched to an A position\n const match = matchedFromB.get(idxB);\n \n if (match) {\n const idxA = match.pathA[0];\n const nodeA = contentA[idxA];\n \n // Before adding the matched block, check for deletions that came before it in A\n // This handles the case where deleted content should appear before matched content\n for (let checkIdx = 0; checkIdx < idxA; checkIdx++) {\n if (deletedIndices.has(checkIdx) && !processedDeletions.has(checkIdx)) {\n operations.push({\n type: 'deleted',\n nodeA: contentA[checkIdx],\n pathA: [checkIdx],\n });\n processedDeletions.add(checkIdx);\n }\n }\n \n // Add matched block\n operations.push({\n type: 'matched',\n nodeA,\n nodeB,\n pathA: match.pathA,\n pathB: [idxB],\n });\n } else {\n // This is an insertion (only in B)\n operations.push({\n type: 'inserted',\n nodeB,\n pathB: [idxB],\n });\n }\n }\n\n // Add any remaining deletions that weren't processed\n for (const deletion of alignment.deletions) {\n const idxA = deletion.path[0];\n if (!processedDeletions.has(idxA)) {\n operations.push({\n type: 'deleted',\n nodeA: deletion.node,\n pathA: deletion.path,\n });\n }\n }\n\n return operations;\n}\n\n// ============================================================================\n// Process Matched Blocks\n// ============================================================================\n\n/**\n * Merge a matched block pair.\n * For simple blocks (paragraphs), uses character-level diff.\n * For complex blocks (tables, lists), recurses into children.\n */\nfunction mergeMatchedBlock(\n nodeA: ProseMirrorNode,\n nodeB: ProseMirrorNode,\n blockIndex: number,\n author: TrackChangeAuthor\n): { mergedNode: ProseMirrorNode; infos: StructuralChangeInfo[]; changes: number } {\n const infos: StructuralChangeInfo[] = [];\n let changes = 0;\n\n // Handle tables: recurse into rows\n if (isTable(nodeA) && isTable(nodeB)) {\n const { mergedTable, tableInfos, changeCount } = mergeMatchedTable(\n nodeA,\n nodeB,\n blockIndex,\n author\n );\n return { mergedNode: mergedTable, infos: tableInfos, changes: changeCount };\n }\n\n // Handle lists: recurse into items\n if (isList(nodeA) && isList(nodeB)) {\n const { mergedList, listInfos, changeCount } = mergeMatchedList(\n nodeA,\n nodeB,\n blockIndex,\n author\n );\n return { mergedNode: mergedList, infos: listInfos, changes: changeCount };\n }\n\n // For other blocks (paragraphs, headings, etc.): use character-level diff\n const diff = diffDocuments(\n { type: 'doc', content: [nodeA] },\n { type: 'doc', content: [nodeB] }\n );\n\n // Count changes\n changes = diff.segments.filter(s => s.type !== 'equal').length;\n changes += diff.formatChanges?.length || 0;\n\n // Merge using existing character-level merger\n const merged = mergeDocuments(\n { type: 'doc', content: [nodeA] },\n { type: 'doc', content: [nodeB] },\n diff,\n author\n );\n\n // Extract the merged node (first content item)\n const mergedNode = merged.content?.[0] || cloneNode(nodeB);\n\n return { mergedNode, infos, changes };\n}\n\n// ============================================================================\n// Table Merging\n// ============================================================================\n\n/**\n * Merge matched tables by aligning and processing rows.\n */\nfunction mergeMatchedTable(\n tableA: ProseMirrorNode,\n tableB: ProseMirrorNode,\n tableIndex: number,\n author: TrackChangeAuthor\n): { mergedTable: ProseMirrorNode; tableInfos: StructuralChangeInfo[]; changeCount: number } {\n const tableInfos: StructuralChangeInfo[] = [];\n let changeCount = 0;\n\n // Align rows\n const rowAlignment = alignTableRows(tableA, tableB, [tableIndex - 1], [tableIndex - 1]);\n\n // Build merge operations for rows\n const mergedRows: ProseMirrorNode[] = [];\n \n // Create index maps\n const matchedFromA = new Map<number, number>();\n const matchedFromB = new Map<number, number>();\n \n for (const match of rowAlignment.matched) {\n const idxA = match.pathA[match.pathA.length - 1];\n const idxB = match.pathB[match.pathB.length - 1];\n matchedFromA.set(idxA, idxB);\n matchedFromB.set(idxB, idxA);\n }\n\n const deletedIndices = new Set(rowAlignment.deletions.map(d => d.path[d.path.length - 1]));\n const processedDeletions = new Set<number>();\n \n const rowsA = tableA.content || [];\n const rowsB = tableB.content || [];\n\n // Process rows in B's order\n for (let idxB = 0; idxB < rowsB.length; idxB++) {\n const rowB = rowsB[idxB];\n const matchedIdxA = matchedFromB.get(idxB);\n\n if (matchedIdxA !== undefined) {\n const rowA = rowsA[matchedIdxA];\n \n // Insert any deletions that should appear before this row\n for (let checkIdx = 0; checkIdx < matchedIdxA; checkIdx++) {\n if (deletedIndices.has(checkIdx) && !processedDeletions.has(checkIdx)) {\n const deletedRow = rowsA[checkIdx];\n const changeId = uuidv4();\n \n mergedRows.push(markAllTextAsDeleted(cloneNode(deletedRow), changeId, author));\n \n tableInfos.push({\n id: changeId,\n type: 'rowDelete',\n nodeType: 'tableRow',\n location: `Table ${tableIndex}, Row ${checkIdx + 1}`,\n preview: extractTextPreview(deletedRow),\n author,\n date: new Date().toISOString(),\n });\n \n processedDeletions.add(checkIdx);\n }\n }\n \n // Merge matched row (character-level diff on cells)\n const { mergedNode, changes } = mergeMatchedBlock(rowA, rowB, idxB, author);\n mergedRows.push(mergedNode);\n changeCount += changes;\n } else {\n // Inserted row\n const changeId = uuidv4();\n mergedRows.push(markAllTextAsInserted(cloneNode(rowB), changeId, author));\n \n tableInfos.push({\n id: changeId,\n type: 'rowInsert',\n nodeType: 'tableRow',\n location: `Table ${tableIndex}, Row ${idxB + 1}`,\n preview: extractTextPreview(rowB),\n author,\n date: new Date().toISOString(),\n });\n }\n }\n\n // Add remaining deletions\n for (const deletion of rowAlignment.deletions) {\n const idxA = deletion.path[deletion.path.length - 1];\n if (!processedDeletions.has(idxA)) {\n const changeId = uuidv4();\n \n mergedRows.push(markAllTextAsDeleted(cloneNode(deletion.node), changeId, author));\n \n tableInfos.push({\n id: changeId,\n type: 'rowDelete',\n nodeType: 'tableRow',\n location: `Table ${tableIndex}, Row ${idxA + 1}`,\n preview: extractTextPreview(deletion.node),\n author,\n date: new Date().toISOString(),\n });\n }\n }\n\n const mergedTable: ProseMirrorNode = {\n ...tableB,\n content: mergedRows,\n };\n\n return { mergedTable, tableInfos, changeCount };\n}\n\n// ============================================================================\n// List Merging\n// ============================================================================\n\n/**\n * Merge matched lists by aligning and processing items.\n */\nfunction mergeMatchedList(\n listA: ProseMirrorNode,\n listB: ProseMirrorNode,\n listIndex: number,\n author: TrackChangeAuthor\n): { mergedList: ProseMirrorNode; listInfos: StructuralChangeInfo[]; changeCount: number } {\n const listInfos: StructuralChangeInfo[] = [];\n let changeCount = 0;\n\n // Align list items\n const itemAlignment = alignListItems(listA, listB, [listIndex - 1], [listIndex - 1]);\n\n // Build merge operations for items\n const mergedItems: ProseMirrorNode[] = [];\n \n // Create index maps\n const matchedFromA = new Map<number, number>();\n const matchedFromB = new Map<number, number>();\n \n for (const match of itemAlignment.matched) {\n const idxA = match.pathA[match.pathA.length - 1];\n const idxB = match.pathB[match.pathB.length - 1];\n matchedFromA.set(idxA, idxB);\n matchedFromB.set(idxB, idxA);\n }\n\n const deletedIndices = new Set(itemAlignment.deletions.map(d => d.path[d.path.length - 1]));\n const processedDeletions = new Set<number>();\n \n const itemsA = listA.content || [];\n const itemsB = listB.content || [];\n\n // Process items in B's order\n for (let idxB = 0; idxB < itemsB.length; idxB++) {\n const itemB = itemsB[idxB];\n const matchedIdxA = matchedFromB.get(idxB);\n\n if (matchedIdxA !== undefined) {\n const itemA = itemsA[matchedIdxA];\n \n // Insert any deletions that should appear before this item\n for (let checkIdx = 0; checkIdx < matchedIdxA; checkIdx++) {\n if (deletedIndices.has(checkIdx) && !processedDeletions.has(checkIdx)) {\n const deletedItem = itemsA[checkIdx];\n const changeId = uuidv4();\n \n mergedItems.push(markAllTextAsDeleted(cloneNode(deletedItem), changeId, author));\n \n listInfos.push({\n id: changeId,\n type: 'listItemDelete',\n nodeType: 'listItem',\n location: `List ${listIndex}, Item ${checkIdx + 1}`,\n preview: extractTextPreview(deletedItem),\n author,\n date: new Date().toISOString(),\n });\n \n processedDeletions.add(checkIdx);\n }\n }\n \n // Merge matched item (character-level diff on content)\n const { mergedNode, changes } = mergeMatchedBlock(itemA, itemB, idxB, author);\n mergedItems.push(mergedNode);\n changeCount += changes;\n } else {\n // Inserted item\n const changeId = uuidv4();\n mergedItems.push(markAllTextAsInserted(cloneNode(itemB), changeId, author));\n \n listInfos.push({\n id: changeId,\n type: 'listItemInsert',\n nodeType: 'listItem',\n location: `List ${listIndex}, Item ${idxB + 1}`,\n preview: extractTextPreview(itemB),\n author,\n date: new Date().toISOString(),\n });\n }\n }\n\n // Add remaining deletions\n for (const deletion of itemAlignment.deletions) {\n const idxA = deletion.path[deletion.path.length - 1];\n if (!processedDeletions.has(idxA)) {\n const changeId = uuidv4();\n \n mergedItems.push(markAllTextAsDeleted(cloneNode(deletion.node), changeId, author));\n \n listInfos.push({\n id: changeId,\n type: 'listItemDelete',\n nodeType: 'listItem',\n location: `List ${listIndex}, Item ${idxA + 1}`,\n preview: extractTextPreview(deletion.node),\n author,\n date: new Date().toISOString(),\n });\n }\n }\n\n const mergedList: ProseMirrorNode = {\n ...listB,\n content: mergedItems,\n };\n\n return { mergedList, listInfos, changeCount };\n}\n\n// ============================================================================\n// Create Inserted/Deleted Blocks\n// ============================================================================\n\n/**\n * Create an inserted block with trackInsert marks on all text.\n */\nfunction createInsertedBlock(\n node: ProseMirrorNode,\n blockIndex: number,\n author: TrackChangeAuthor\n): { markedNode: ProseMirrorNode; info: StructuralChangeInfo | null } {\n const changeId = uuidv4();\n const markedNode = markAllTextAsInserted(cloneNode(node), changeId, author);\n \n const nodeDesc = getNodeTypeDescription(node);\n \n const info: StructuralChangeInfo = {\n id: changeId,\n type: isTable(node) ? 'rowInsert' : \n isList(node) ? 'listItemInsert' : \n isImage(node) ? 'imageInsert' : 'paragraphInsert',\n nodeType: node.type || 'unknown',\n location: `${nodeDesc} inserted at position ${blockIndex}`,\n preview: extractTextPreview(node),\n author,\n date: new Date().toISOString(),\n };\n\n return { markedNode, info };\n}\n\n/**\n * Create a deleted block with trackDelete marks on all text.\n */\nfunction createDeletedBlock(\n node: ProseMirrorNode,\n blockIndex: number,\n author: TrackChangeAuthor\n): { markedNode: ProseMirrorNode; info: StructuralChangeInfo | null } {\n const changeId = uuidv4();\n const markedNode = markAllTextAsDeleted(cloneNode(node), changeId, author);\n \n const nodeDesc = getNodeTypeDescription(node);\n \n const info: StructuralChangeInfo = {\n id: changeId,\n type: isTable(node) ? 'rowDelete' : \n isList(node) ? 'listItemDelete' : \n isImage(node) ? 'imageDelete' : 'paragraphDelete',\n nodeType: node.type || 'unknown',\n location: `${nodeDesc} deleted from position ${blockIndex}`,\n preview: extractTextPreview(node),\n author,\n date: new Date().toISOString(),\n };\n\n return { markedNode, info };\n}\n","/**\n * DocxDiffEditor Component\n *\n * A React component for DOCX document comparison with track changes visualization.\n * Wraps SuperDoc editor and provides methods for setting source, comparing documents,\n * and extracting change context for LLM processing.\n */\n\nimport {\n useCallback,\n useRef,\n useState,\n useEffect,\n useImperativeHandle,\n forwardRef,\n} from 'react';\n\nimport type {\n DocxDiffEditorProps,\n DocxDiffEditorRef,\n DocxContent,\n ProseMirrorJSON,\n SuperDocInstance,\n DiffSegment,\n DiffResult,\n ComparisonResult,\n EnrichedChange,\n DocumentInfo,\n DocumentProperties,\n StructuralChangeInfo,\n} from './types';\n\nimport { StructuralChangesPane } from './components/StructuralChangesPane';\n\nimport { parseDocxFile, parseHtmlToJson, detectContentType, isProseMirrorJSON } from './services/contentResolver';\nimport { diffDocuments } from './services/documentDiffer';\nimport { mergeDocuments } from './services/mergeDocuments';\nimport { extractEnrichedChanges } from './services/changeContextExtractor';\nimport { processStructuralChanges, generateStructuralChangeSummary } from './services/blockLevelMerger';\nimport { mergeWithStructuralAwareness } from './services/structuralMerger';\nimport { normalizeRunProperties } from './services/runPropertiesSync';\nimport { DEFAULT_AUTHOR, DEFAULT_SUPERDOC_USER, TRACK_CHANGE_PERMISSIONS, TIMEOUTS } from './constants';\n\n/**\n * Permission resolver that allows accepting/rejecting all track changes\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst permissionResolver = ({ permission }: any) => {\n return TRACK_CHANGE_PERMISSIONS.includes(permission) ? true : undefined;\n};\n\n/**\n * Accept all track changes in a ProseMirror JSON document.\n * - Removes text with trackDelete marks\n * - Keeps text with trackInsert marks (removes the mark)\n * - Keeps text with trackFormat marks with new formatting (removes the mark)\n */\nfunction acceptAllChangesInJson(node: ProseMirrorJSON): ProseMirrorJSON | null {\n if (!node) return null;\n\n // Handle text nodes\n if (node.type === 'text') {\n const marks = node.marks || [];\n \n // Check if this text has a trackDelete mark - if so, remove entirely\n if (marks.some((m: { type: string }) => m.type === 'trackDelete')) {\n return null;\n }\n\n // Filter out track marks, keep other marks\n const cleanMarks = marks.filter(\n (m: { type: string }) => !['trackInsert', 'trackDelete', 'trackFormat'].includes(m.type)\n );\n\n return {\n ...node,\n marks: cleanMarks.length > 0 ? cleanMarks : undefined,\n };\n }\n\n // Handle nodes with content\n if (node.content && Array.isArray(node.content)) {\n const cleanContent = node.content\n .map((child: ProseMirrorJSON) => acceptAllChangesInJson(child))\n .filter((child: ProseMirrorJSON | null): child is ProseMirrorJSON => child !== null);\n\n return {\n ...node,\n content: cleanContent.length > 0 ? cleanContent : undefined,\n };\n }\n\n return node;\n}\n\n/**\n * DocxDiffEditor Component\n */\nexport const DocxDiffEditor = forwardRef<DocxDiffEditorRef, DocxDiffEditorProps>(\n function DocxDiffEditor(\n {\n initialSource,\n templateDocx,\n showRulers = false,\n showToolbar = true,\n author = DEFAULT_AUTHOR,\n onReady,\n onSourceLoaded,\n onComparisonComplete,\n onError,\n className = '',\n toolbarClassName = '',\n editorClassName = '',\n // Structural Changes Pane options\n structuralPanePosition = 'bottom-right',\n structuralPaneCollapsed = false,\n hideStructuralPane = false,\n },\n ref\n ) {\n // Refs\n const containerRef = useRef<HTMLDivElement>(null);\n const toolbarRef = useRef<HTMLDivElement>(null);\n const superdocRef = useRef<SuperDocInstance | null>(null);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const SuperDocRef = useRef<any>(null);\n const mountedRef = useRef(true);\n const initRef = useRef(false);\n const readyRef = useRef(false);\n\n // State\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [sourceJson, setSourceJson] = useState<ProseMirrorJSON | null>(null);\n const [mergedJson, setMergedJson] = useState<ProseMirrorJSON | null>(null);\n const [diffResult, setDiffResult] = useState<DiffResult | null>(null);\n \n // Structural changes pane state\n const [structuralChanges, setStructuralChanges] = useState<StructuralChangeInfo[]>([]);\n const [isPaneDismissed, setIsPaneDismissed] = useState(false);\n \n // Ref to track structural change IDs for bubble sync\n // (needed because onCommentsUpdate callback captures stale state)\n const structuralChangeIdsRef = useRef<Set<string>>(new Set());\n\n // Keep the ref in sync with state\n useEffect(() => {\n structuralChangeIdsRef.current = new Set(structuralChanges.map((c) => c.id));\n }, [structuralChanges]);\n\n // Generate unique IDs for this instance\n const instanceId = useRef(`dde-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`);\n const editorId = `dde-editor-${instanceId.current}`;\n const toolbarId = `dde-toolbar-${instanceId.current}`;\n\n /**\n * Set content in the editor using ProseMirror transaction\n */\n const setEditorContent = useCallback((editor: SuperDocInstance, json: ProseMirrorJSON) => {\n const { state, view } = editor;\n if (state?.doc && view && json.content) {\n const newDoc = state.schema.nodeFromJSON(json);\n const tr = state.tr.replaceWith(0, state.doc.content.size, newDoc.content);\n view.dispatch(tr);\n }\n }, []);\n\n /**\n * Enable track changes review mode\n */\n const enableReviewMode = useCallback((sd: SuperDocInstance) => {\n if (sd.setTrackedChangesPreferences) {\n sd.setTrackedChangesPreferences({ mode: 'review', enabled: true });\n } else if (sd.activeEditor?.commands?.enableTrackChanges) {\n sd.activeEditor.commands.enableTrackChanges();\n }\n }, []);\n\n /**\n * Set editing mode (normal mode - shows original without track changes)\n */\n const setEditingMode = useCallback((sd: SuperDocInstance) => {\n if (sd.setTrackedChangesPreferences) {\n // Use 'off' mode with track changes disabled for clean editing view\n // Valid modes (superdoc 1.3+): 'review', 'original', 'final', 'off'\n sd.setTrackedChangesPreferences({ mode: 'off', enabled: false });\n }\n }, []);\n\n /**\n * Handle errors\n */\n const handleError = useCallback(\n (err: Error | string) => {\n const error = err instanceof Error ? err : new Error(err);\n setError(error.message);\n onError?.(error);\n },\n [onError]\n );\n\n // =========================================================================\n // Structural Changes Pane Handlers\n // =========================================================================\n\n /**\n * Accept a structural change by ID\n */\n const handleAcceptStructuralChange = useCallback((changeId: string) => {\n const editor = superdocRef.current?.activeEditor;\n if (editor?.commands?.acceptTrackedChangeById) {\n editor.commands.acceptTrackedChangeById(changeId);\n // Remove from state\n setStructuralChanges((prev) => prev.filter((c) => c.id !== changeId));\n }\n }, []);\n\n /**\n * Reject a structural change by ID\n */\n const handleRejectStructuralChange = useCallback((changeId: string) => {\n const editor = superdocRef.current?.activeEditor;\n if (editor?.commands?.rejectTrackedChangeById) {\n editor.commands.rejectTrackedChangeById(changeId);\n // Remove from state\n setStructuralChanges((prev) => prev.filter((c) => c.id !== changeId));\n }\n }, []);\n\n /**\n * Accept all structural changes\n */\n const handleAcceptAllStructural = useCallback(() => {\n const editor = superdocRef.current?.activeEditor;\n if (editor?.commands?.acceptTrackedChangeById) {\n for (const change of structuralChanges) {\n editor.commands.acceptTrackedChangeById(change.id);\n }\n setStructuralChanges([]);\n }\n }, [structuralChanges]);\n\n /**\n * Reject all structural changes\n */\n const handleRejectAllStructural = useCallback(() => {\n const editor = superdocRef.current?.activeEditor;\n if (editor?.commands?.rejectTrackedChangeById) {\n for (const change of structuralChanges) {\n editor.commands.rejectTrackedChangeById(change.id);\n }\n setStructuralChanges([]);\n }\n }, [structuralChanges]);\n\n /**\n * Navigate to a structural change in the document\n */\n const handleNavigateToChange = useCallback((changeId: string) => {\n // Find the change\n const change = structuralChanges.find((c) => c.id === changeId);\n if (!change) return;\n\n // Try to scroll to the change using SuperDoc's API\n const editor = superdocRef.current?.activeEditor;\n if (editor?.commands?.focus) {\n // Focus the editor first\n editor.commands.focus();\n }\n \n // Note: Actual scroll-to-change would require knowing the position\n // in the document. This is a placeholder for future enhancement.\n // For now, the visual highlight from the track change marks\n // should help users locate the change.\n }, [structuralChanges]);\n\n /**\n * Handle pane dismiss\n */\n const handlePaneDismiss = useCallback(() => {\n setIsPaneDismissed(true);\n }, []);\n\n /**\n * Handle SuperDoc comments update (for bubble sync)\n * When user accepts/rejects via SuperDoc bubbles, we sync our state\n */\n const handleCommentsUpdate = useCallback(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (event: any) => {\n // Check if this is a resolved track change event\n if (event?.type === 'resolved' && event?.comment?.trackedChange) {\n const commentId = event.comment.commentId;\n \n // Check if this is one of our structural changes\n if (structuralChangeIdsRef.current.has(commentId)) {\n // Remove from our state - the change was handled via SuperDoc bubble\n setStructuralChanges((prev) => prev.filter((c) => c.id !== commentId));\n }\n }\n },\n []\n );\n\n /**\n * Destroy current SuperDoc instance\n */\n const destroySuperdoc = useCallback(() => {\n if (superdocRef.current) {\n try {\n superdocRef.current.destroy?.();\n } catch {\n // Ignore cleanup errors\n }\n superdocRef.current = null;\n }\n readyRef.current = false;\n }, []);\n\n /**\n * Create a new SuperDoc instance with the given options.\n * Accepts either a DOCX File/Blob or HTML string.\n * \n * Track bubbles are enabled by calling processLoadedDocxComments after\n * setting merged content (see compareWith method).\n */\n const createSuperdoc = useCallback(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async (options: { document?: File | Blob; html?: string }): Promise<{ superdoc: SuperDocInstance; json: ProseMirrorJSON }> => {\n if (!SuperDocRef.current) {\n throw new Error('SuperDoc not loaded');\n }\n if (!containerRef.current) {\n throw new Error('Container not available');\n }\n\n // Clear containers to avoid Vue \"already mounted\" warning\n containerRef.current.innerHTML = '';\n if (toolbarRef.current) {\n toolbarRef.current.innerHTML = '';\n }\n\n // Set IDs on DOM elements\n containerRef.current.id = editorId;\n if (toolbarRef.current) {\n toolbarRef.current.id = toolbarId;\n }\n\n return new Promise((resolve, reject) => {\n let resolved = false;\n \n try {\n // Build SuperDoc config - use document OR html, not both\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const superdocConfig: any = {\n selector: `#${editorId}`,\n toolbar: showToolbar ? `#${toolbarId}` : undefined,\n documentMode: 'editing',\n role: 'editor',\n rulers: showRulers,\n user: DEFAULT_SUPERDOC_USER,\n permissionResolver,\n // Bubble sync: listen for track changes resolved via SuperDoc bubbles\n onCommentsUpdate: handleCommentsUpdate,\n };\n\n if (options.document) {\n superdocConfig.document = options.document;\n } else if (options.html) {\n superdocConfig.html = options.html;\n }\n // If neither document nor html provided, SuperDoc creates blank document\n\n const superdoc = new SuperDocRef.current({\n ...superdocConfig,\n onReady: ({ superdoc: sd }: { superdoc: SuperDocInstance }) => {\n if (resolved) return;\n resolved = true;\n \n superdocRef.current = sd;\n readyRef.current = true;\n\n // Extract JSON from the loaded document\n let json: ProseMirrorJSON = { type: 'doc', content: [] };\n if (sd?.activeEditor) {\n try {\n json = sd.activeEditor.getJSON();\n } catch (err) {\n console.error('Failed to extract JSON:', err);\n }\n }\n\n resolve({ superdoc: sd, json });\n },\n onException: ({ error: err }: { error: Error }) => {\n if (resolved) return;\n resolved = true;\n console.error('SuperDoc error:', err);\n reject(err);\n },\n });\n\n superdocRef.current = superdoc;\n\n // Timeout\n setTimeout(() => {\n if (!resolved) {\n resolved = true;\n reject(new Error('SuperDoc initialization timed out'));\n }\n }, TIMEOUTS.PARSE_TIMEOUT);\n } catch (err) {\n if (!resolved) {\n resolved = true;\n reject(err);\n }\n }\n });\n },\n [editorId, toolbarId, showToolbar, showRulers]\n );\n\n /**\n * Initialize SuperDoc instance\n */\n const initialize = useCallback(async () => {\n if (initRef.current || !containerRef.current || !mountedRef.current) return;\n if (!showToolbar && !toolbarRef.current) {\n // Continue without toolbar\n } else if (showToolbar && !toolbarRef.current) {\n return;\n }\n\n initRef.current = true;\n\n // Small delay for React to settle\n await new Promise((resolve) => setTimeout(resolve, TIMEOUTS.INIT_DELAY));\n\n if (!mountedRef.current || !containerRef.current) {\n initRef.current = false;\n return;\n }\n\n setIsLoading(true);\n setError(null);\n destroySuperdoc();\n\n try {\n // Note: superdoc CSS is bundled in dist/styles.css - user must import 'docx-diff-editor/styles.css'\n const { SuperDoc } = await import('superdoc');\n SuperDocRef.current = SuperDoc;\n\n // Determine initialization options based on initialSource\n let initOptions: { document?: File | Blob; html?: string } = {};\n\n if (initialSource) {\n const contentType = detectContentType(initialSource);\n if (contentType === 'file') {\n initOptions = { document: initialSource as File };\n } else if (contentType === 'html') {\n // Use SuperDoc's native HTML support\n initOptions = { html: initialSource as string };\n } else if (contentType === 'json') {\n // For JSON, we need a document first, then set content\n // Use template if provided, otherwise SuperDoc will create blank\n initOptions = templateDocx ? { document: templateDocx } : {};\n }\n } else if (templateDocx) {\n initOptions = { document: templateDocx };\n }\n // If no initialSource and no template, SuperDoc creates a blank document\n\n const { superdoc: sd, json } = await createSuperdoc(initOptions);\n\n // For JSON content, set it after initialization\n if (initialSource && detectContentType(initialSource) === 'json') {\n if (sd?.activeEditor && isProseMirrorJSON(initialSource)) {\n setEditorContent(sd.activeEditor, initialSource as ProseMirrorJSON);\n setSourceJson(initialSource as ProseMirrorJSON);\n onSourceLoaded?.(initialSource as ProseMirrorJSON);\n }\n } else {\n // Use JSON extracted from the loaded document\n setSourceJson(json);\n onSourceLoaded?.(json);\n }\n\n setIsLoading(false);\n onReady?.();\n } catch (err) {\n console.error('Failed to initialize SuperDoc:', err);\n handleError(err instanceof Error ? err : new Error('Failed to load editor'));\n setIsLoading(false);\n // Allow retry on error\n initRef.current = false;\n }\n // Note: initRef stays true on success to prevent re-initialization\n }, [\n initialSource,\n showRulers,\n showToolbar,\n templateDocx,\n onReady,\n onSourceLoaded,\n destroySuperdoc,\n createSuperdoc,\n setEditorContent,\n handleError,\n ]);\n\n // Initialize on mount - only once\n useEffect(() => {\n mountedRef.current = true;\n \n // Only initialize once\n if (!initRef.current) {\n initialize();\n }\n\n return () => {\n mountedRef.current = false;\n destroySuperdoc();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []); // Empty deps - only run on mount\n\n // =========================================================================\n // Imperative API\n // =========================================================================\n\n useImperativeHandle(\n ref,\n () => ({\n /**\n * Update content in the existing editor without recreating SuperDoc instance.\n * Preserves the DOCX template/styling. Ideal for replacing content with translated JSON.\n */\n updateContent(json: ProseMirrorJSON): void {\n const editor = superdocRef.current?.activeEditor;\n if (!editor) {\n throw new Error('Editor not ready');\n }\n\n setEditorContent(editor, json);\n setSourceJson(json);\n setMergedJson(null);\n setDiffResult(null);\n onSourceLoaded?.(json);\n },\n\n /**\n * Set the source/base document.\n * Accepts File (DOCX), HTML string, or ProseMirror JSON.\n * Note: This destroys and recreates the SuperDoc instance.\n * For JSON content updates, prefer updateContent() to preserve the existing template.\n */\n async setSource(content: DocxContent): Promise<void> {\n if (!SuperDocRef.current) {\n throw new Error('Editor not initialized');\n }\n\n setIsLoading(true);\n setError(null);\n\n try {\n const contentType = detectContentType(content);\n let json: ProseMirrorJSON;\n\n // Destroy current instance and create new one\n destroySuperdoc();\n\n if (contentType === 'file') {\n // Initialize with DOCX file\n const result = await createSuperdoc({ document: content as File });\n json = result.json;\n } else if (contentType === 'html') {\n // Use SuperDoc's native HTML support\n const result = await createSuperdoc({ html: content as string });\n json = result.json;\n } else {\n // JSON content - initialize with template or blank, then set content\n const result = await createSuperdoc(templateDocx ? { document: templateDocx } : {});\n if (result.superdoc?.activeEditor && isProseMirrorJSON(content)) {\n setEditorContent(result.superdoc.activeEditor, content as ProseMirrorJSON);\n json = content as ProseMirrorJSON;\n } else {\n json = result.json;\n }\n }\n\n setSourceJson(json);\n setMergedJson(null);\n setDiffResult(null);\n setEditingMode(superdocRef.current!);\n onSourceLoaded?.(json);\n } catch (err) {\n handleError(err instanceof Error ? err : new Error('Failed to set source'));\n throw err;\n } finally {\n setIsLoading(false);\n }\n },\n\n /**\n * Compare current editor content with new content, show track changes.\n * \n * The comparison uses the current editor state (with any existing track\n * changes accepted/stripped) as the baseline. This means if you've made\n * edits or accepted previous comparisons, those become the new baseline.\n * \n * To compare against the original source document, call setSource() again\n * before compareWith().\n */\n async compareWith(content: DocxContent): Promise<ComparisonResult> {\n if (!SuperDocRef.current) {\n throw new Error('Editor not initialized');\n }\n if (!superdocRef.current?.activeEditor) {\n throw new Error('Editor not ready. Ensure a document is loaded first.');\n }\n\n setIsLoading(true);\n try {\n // Get current editor content and strip any existing track marks\n // to create a clean baseline for comparison\n const currentEditorJson = superdocRef.current.activeEditor.getJSON();\n const cleanBaseline = acceptAllChangesInJson(currentEditorJson) || { type: 'doc', content: [] };\n \n // Update sourceJson to reflect this new baseline\n // (so getSourceContent() returns what was used for comparison)\n setSourceJson(cleanBaseline);\n const contentType = detectContentType(content);\n let newJson: ProseMirrorJSON;\n\n if (contentType === 'file') {\n // Parse DOCX file using hidden SuperDoc instance\n newJson = await parseDocxFile(content as File, SuperDocRef.current);\n } else if (contentType === 'html') {\n // Parse HTML using a temporary SuperDoc instance\n const tempContainer = document.createElement('div');\n tempContainer.style.cssText = 'position:absolute;top:-9999px;left:-9999px;width:800px;height:600px;visibility:hidden;';\n document.body.appendChild(tempContainer);\n\n try {\n newJson = await new Promise((resolve, reject) => {\n const tempSuperdoc = new SuperDocRef.current({\n selector: tempContainer,\n html: content as string,\n documentMode: 'viewing',\n rulers: false,\n user: { name: 'Parser', email: 'parser@local' },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onReady: ({ superdoc: sd }: { superdoc: any }) => {\n try {\n const json = sd?.activeEditor?.getJSON() || { type: 'doc', content: [] };\n setTimeout(() => {\n try { sd?.destroy?.(); } catch { /* ignore */ }\n tempContainer.parentNode?.removeChild(tempContainer);\n }, 100);\n resolve(json);\n } catch (err) {\n reject(err);\n }\n },\n onException: ({ error: err }: { error: Error }) => {\n tempContainer.parentNode?.removeChild(tempContainer);\n reject(err);\n },\n });\n\n setTimeout(() => {\n try { tempSuperdoc?.destroy?.(); } catch { /* ignore */ }\n tempContainer.parentNode?.removeChild(tempContainer);\n reject(new Error('HTML parsing timed out'));\n }, TIMEOUTS.PARSE_TIMEOUT);\n });\n } catch (err) {\n tempContainer.parentNode?.removeChild(tempContainer);\n throw err;\n }\n } else {\n // JSON content - use directly\n if (!isProseMirrorJSON(content)) {\n throw new Error('Invalid ProseMirror JSON structure');\n }\n newJson = content as ProseMirrorJSON;\n }\n\n // =========================================================\n // STRUCTURAL MERGE (Phase 6b)\n // Instead of character-level-only merge, we now use the\n // structure-aware merger which:\n // 1. Aligns blocks first (tables, lists, paragraphs)\n // 2. Inserts/deletes entire blocks with track marks\n // 3. Applies character-level diff within matched blocks\n // =========================================================\n \n // Normalize runProperties on the new document to ensure\n // styles from marks are synced to runProperties for rendering.\n // This is a safety net for content that didn't come through parseHtml.\n const normalizedNewJson = normalizeRunProperties(newJson);\n \n // Use structural merger for the main merge\n const structuralResult = mergeWithStructuralAwareness(\n cleanBaseline,\n normalizedNewJson,\n author\n );\n \n const merged = structuralResult.mergedDoc;\n const structInfos = structuralResult.structuralInfos;\n \n setMergedJson(merged);\n \n // Also keep the text-level diff for getDiffSegments() backward compat\n const diff = diffDocuments(cleanBaseline, newJson);\n setDiffResult(diff);\n\n // Update editor with merged content and enable review mode\n if (superdocRef.current?.activeEditor) {\n setEditorContent(superdocRef.current.activeEditor, merged);\n enableReviewMode(superdocRef.current);\n \n // CRITICAL FIX: Trigger comment creation for track marks\n // SuperDoc's track bubbles require comment entries in commentsStore.\n // When we inject JSON with track marks via setEditorContent, no comments\n // are created automatically. We need to call processLoadedDocxComments\n // which internally calls createCommentForTrackChanges to:\n // 1. Scan the document for track marks using getTrackChanges\n // 2. Create comment entries for each track mark\n // 3. This populates getFloatingComments which renders the bubbles\n //\n // Source reference: superdoc/dist/chunks/index-1n6qegaQ.es.js\n // - Line 4212: processLoadedDocxComments function\n // - Line 4247: setTimeout(() => createCommentForTrackChanges(editor))\n // - Line 4250: createCommentForTrackChanges scans for track marks\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const sd = superdocRef.current as any;\n if (sd.commentsStore?.processLoadedDocxComments) {\n // Small delay to ensure editor state is fully updated\n setTimeout(() => {\n try {\n sd.commentsStore.processLoadedDocxComments({\n superdoc: sd,\n editor: sd.activeEditor,\n comments: [], // Empty array - we just want to trigger createCommentForTrackChanges\n documentId: sd.activeEditor?.options?.documentId || 'primary',\n });\n } catch (err) {\n console.warn('[DocxDiffEditor] Failed to process track changes for bubbles:', err);\n }\n }, 50);\n }\n }\n\n // Store structural changes for the pane\n setStructuralChanges(structInfos);\n setIsPaneDismissed(false); // Reset dismissed state on new comparison\n\n // Build result\n // Note: insertions/deletions from text diff for backward compat,\n // but structuralChanges now contains the actual block changes\n const insertions = diff.segments.filter((s) => s.type === 'insert').length;\n const deletions = diff.segments.filter((s) => s.type === 'delete').length;\n const formatChanges = diff.formatChanges?.length || 0;\n const structuralChangeCount = structInfos.length;\n\n // Combine summaries\n const combinedSummary = [...structuralResult.summary];\n if (diff.summary.length > 0 && structuralResult.summary.length === 0) {\n // Only add text-level summary if no structural changes\n combinedSummary.push(...diff.summary);\n }\n\n const result: ComparisonResult = {\n totalChanges: insertions + deletions + formatChanges + structuralChangeCount,\n insertions,\n deletions,\n formatChanges,\n structuralChanges: structuralChangeCount,\n summary: combinedSummary,\n mergedJson: merged,\n structuralChangeInfos: structInfos,\n };\n\n onComparisonComplete?.(result);\n return result;\n } catch (err) {\n handleError(err instanceof Error ? err : new Error('Comparison failed'));\n throw err;\n } finally {\n setIsLoading(false);\n }\n },\n\n /**\n * Get raw diff segments\n */\n getDiffSegments(): DiffSegment[] {\n return diffResult?.segments || [];\n },\n\n /**\n * Get enriched changes with context for LLM processing\n */\n getEnrichedChangesContext(): EnrichedChange[] {\n if (!mergedJson) return [];\n return extractEnrichedChanges(mergedJson);\n },\n\n /**\n * Get current document content as JSON\n */\n getContent(): ProseMirrorJSON {\n if (superdocRef.current?.activeEditor) {\n return superdocRef.current.activeEditor.getJSON();\n }\n return mergedJson || sourceJson || { type: 'doc', content: [] };\n },\n\n /**\n * Get source document JSON (before comparison)\n */\n getSourceContent(): ProseMirrorJSON | null {\n return sourceJson;\n },\n\n /**\n * Export current document to DOCX blob\n */\n async exportDocx(): Promise<Blob> {\n if (!superdocRef.current?.activeEditor) {\n throw new Error('Editor not ready');\n }\n\n const blob = await superdocRef.current.activeEditor.exportDocx({\n isFinalDoc: false,\n });\n\n if (!blob) {\n throw new Error('Export returned no data');\n }\n\n return blob;\n },\n\n /**\n * Reset to source state (clear comparison)\n */\n resetComparison(): void {\n if (sourceJson && superdocRef.current?.activeEditor) {\n setEditorContent(superdocRef.current.activeEditor, sourceJson);\n setEditingMode(superdocRef.current);\n setMergedJson(null);\n setDiffResult(null);\n }\n },\n\n /**\n * Accept all track changes and return the clean document\n */\n async acceptAllChanges(): Promise<ProseMirrorJSON> {\n const editor = superdocRef.current?.activeEditor;\n const sd = superdocRef.current;\n if (!editor || !sd) {\n throw new Error('Editor not ready');\n }\n\n // Try different API paths with fallback\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const editorAny = editor as any;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const sdAny = sd as any;\n\n let cleanJson: ProseMirrorJSON;\n\n if (typeof editorAny.commands?.acceptAllChanges === 'function') {\n editorAny.commands.acceptAllChanges();\n cleanJson = editor.getJSON();\n } else if (typeof sdAny.commands?.acceptAllChanges === 'function') {\n sdAny.commands.acceptAllChanges();\n cleanJson = editor.getJSON();\n } else if (typeof sdAny.acceptAllChanges === 'function') {\n sdAny.acceptAllChanges();\n cleanJson = editor.getJSON();\n } else {\n // Fallback: process JSON manually to accept all changes\n const currentJson = editor.getJSON();\n cleanJson = acceptAllChangesInJson(currentJson) || { type: 'doc', content: [] };\n }\n\n // Clear comparison state since changes are now accepted\n setMergedJson(null);\n setDiffResult(null);\n\n return cleanJson;\n },\n\n /**\n * Check if editor is ready\n */\n isReady(): boolean {\n return readyRef.current;\n },\n\n /**\n * Get the current page count from the presentation editor.\n * Returns 0 if editor is not ready or pages are unavailable.\n */\n getPages(): number {\n if (!readyRef.current || !superdocRef.current) {\n return 0;\n }\n\n try {\n // Access the document from the superdoc store\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const sd = superdocRef.current as any;\n const doc = sd.superdocStore?.documents?.[0];\n \n if (!doc) {\n return 0;\n }\n\n // Get the PresentationEditor and retrieve page count\n const presentationEditor = doc.getPresentationEditor?.();\n const pages = presentationEditor?.getPages?.();\n \n return pages?.length ?? 0;\n } catch (err) {\n console.warn('[DocxDiffEditor] Failed to get page count:', err);\n return 0;\n }\n },\n\n /**\n * Get combined document metadata and statistics.\n * Returns null if editor is not ready.\n */\n getDocumentInfo(): DocumentInfo | null {\n if (!readyRef.current || !superdocRef.current) {\n return null;\n }\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const sd = superdocRef.current as any;\n const doc = sd.superdocStore?.documents?.[0];\n \n if (!doc) {\n return null;\n }\n\n // Get the editor instance\n const editor = doc.getEditor?.();\n \n // Get metadata\n const metadata = editor?.getMetadata?.() ?? {};\n \n // Get stats\n const stats = editor?.commands?.getDocumentStats?.() ?? {};\n \n // Get page count\n const presentationEditor = doc.getPresentationEditor?.();\n const pages = presentationEditor?.getPages?.();\n const pageCount = pages?.length ?? 0;\n\n return {\n // Metadata\n documentGuid: metadata.documentGuid ?? null,\n isModified: metadata.isModified ?? false,\n version: metadata.version ?? null,\n // Stats\n words: stats.words ?? 0,\n characters: stats.characters ?? 0,\n paragraphs: stats.paragraphs ?? 0,\n // Pages\n pages: pageCount,\n };\n } catch (err) {\n console.warn('[DocxDiffEditor] Failed to get document info:', err);\n return null;\n }\n },\n\n /**\n * Get document core properties from docProps/core.xml.\n * Returns null if editor is not ready or properties unavailable.\n */\n async getProperties(): Promise<DocumentProperties | null> {\n if (!readyRef.current || !superdocRef.current) {\n return null;\n }\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const sd = superdocRef.current as any;\n const doc = sd.superdocStore?.documents?.[0];\n \n if (!doc) {\n return null;\n }\n\n const editor = doc.getEditor?.();\n if (!editor) {\n return null;\n }\n\n // Access core.xml via converter.convertedXml\n const coreXml = editor.converter?.convertedXml?.['docProps/core.xml'];\n if (!coreXml?.elements?.[0]?.elements) {\n return null;\n }\n\n // The root element is cp:coreProperties, get its children\n const elements = coreXml.elements[0].elements;\n\n // Property mapping from XML element names to our interface\n const xmlToKey: Record<string, keyof DocumentProperties> = {\n 'dc:title': 'title',\n 'dc:creator': 'author',\n 'dc:subject': 'subject',\n 'dc:description': 'description',\n 'cp:keywords': 'keywords',\n 'cp:category': 'category',\n 'cp:lastModifiedBy': 'lastModifiedBy',\n 'cp:revision': 'revision',\n 'dcterms:created': 'created',\n 'dcterms:modified': 'modified',\n };\n\n const props: DocumentProperties = {};\n\n // Parse elements from the core properties\n for (const el of elements) {\n const key = xmlToKey[el.name];\n if (key) {\n const textValue = el.elements?.[0]?.text;\n if (textValue !== undefined && textValue !== null) {\n if (key === 'created' || key === 'modified') {\n // Convert ISO string to Date object\n props[key] = new Date(textValue);\n } else {\n props[key] = textValue;\n }\n }\n }\n }\n\n return props;\n } catch (err) {\n console.warn('[DocxDiffEditor] Failed to get properties:', err);\n return null;\n }\n },\n\n /**\n * Set document core properties (partial update).\n * Only provided properties will be updated; others are preserved.\n * Preserves XML namespaces and structure for valid DOCX output.\n * Returns true on success, false on failure.\n */\n async setProperties(properties: Partial<DocumentProperties>): Promise<boolean> {\n if (!readyRef.current || !superdocRef.current) {\n return false;\n }\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const sd = superdocRef.current as any;\n const doc = sd.superdocStore?.documents?.[0];\n \n if (!doc) {\n return false;\n }\n\n const editor = doc.getEditor?.();\n if (!editor) {\n return false;\n }\n\n // Access core.xml via converter.convertedXml\n const coreXml = editor.converter?.convertedXml?.['docProps/core.xml'];\n if (!coreXml?.elements?.[0]?.elements) {\n console.warn('[DocxDiffEditor] docProps/core.xml not found or invalid structure');\n return false;\n }\n\n // The root element is cp:coreProperties, get its children\n const coreProperties = coreXml.elements[0];\n const elements = coreProperties.elements;\n\n // Property mapping from our interface to XML element names\n const keyToXml: Record<string, string> = {\n title: 'dc:title',\n author: 'dc:creator',\n subject: 'dc:subject',\n description: 'dc:description',\n keywords: 'cp:keywords',\n category: 'cp:category',\n lastModifiedBy: 'cp:lastModifiedBy',\n revision: 'cp:revision',\n created: 'dcterms:created',\n modified: 'dcterms:modified',\n };\n\n // Update or add properties\n for (const [key, value] of Object.entries(properties)) {\n if (value === undefined) continue;\n\n const xmlName = keyToXml[key];\n if (!xmlName) continue;\n\n // Convert Date objects to ISO strings\n const textValue = value instanceof Date ? value.toISOString() : String(value);\n\n // Find existing element\n const existingProp = elements.find((el: { name: string }) => el.name === xmlName);\n\n if (existingProp) {\n // Update existing - preserve structure, only change text\n if (!existingProp.elements) {\n existingProp.elements = [];\n }\n if (existingProp.elements[0]) {\n existingProp.elements[0].text = textValue;\n } else {\n existingProp.elements.push({ type: 'text', text: textValue });\n }\n } else {\n // Add new property element\n elements.push({\n type: 'element',\n name: xmlName,\n elements: [{ type: 'text', text: textValue }],\n });\n }\n }\n\n // Mark document as modified\n if (editor.converter) {\n editor.converter.documentModified = true;\n }\n\n // Serialize and register for export\n // This ensures changes are included when downloading the DOCX\n if (editor.converter?.schemaToXml) {\n const serialized = editor.converter.schemaToXml(coreXml.elements[0]);\n \n if (!editor.options) {\n editor.options = {};\n }\n if (!editor.options.customUpdatedFiles) {\n editor.options.customUpdatedFiles = {};\n }\n \n editor.options.customUpdatedFiles['docProps/core.xml'] = String(serialized);\n editor.options.isCustomXmlChanged = true;\n }\n\n return true;\n } catch (err) {\n console.warn('[DocxDiffEditor] Failed to set properties:', err);\n return false;\n }\n },\n\n /**\n * Parse HTML string to ProseMirror JSON using a hidden SuperDoc instance.\n * Useful for converting HTML content before using with other methods.\n */\n async parseHtml(html: string): Promise<ProseMirrorJSON> {\n if (!SuperDocRef.current) {\n throw new Error('Editor not initialized');\n }\n\n return parseHtmlToJson(html, SuperDocRef.current);\n },\n }),\n [\n sourceJson,\n mergedJson,\n diffResult,\n templateDocx,\n author,\n destroySuperdoc,\n createSuperdoc,\n setEditorContent,\n enableReviewMode,\n setEditingMode,\n onSourceLoaded,\n onComparisonComplete,\n handleError,\n ]\n );\n\n // =========================================================================\n // Render\n // =========================================================================\n\n return (\n <div className={`dde-container ${className}`.trim()}>\n {/* Loading overlay */}\n {isLoading && (\n <div className=\"dde-loading\">\n <div className=\"dde-loading__spinner\" />\n <p className=\"dde-loading__text\">Loading document...</p>\n </div>\n )}\n\n {/* Error overlay */}\n {error && (\n <div className=\"dde-error\">\n <div className=\"dde-error__icon\">\n <svg\n className=\"dde-error__svg\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"2\"\n d=\"M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"\n />\n </svg>\n </div>\n <p className=\"dde-error__title\">Failed to load document</p>\n <p className=\"dde-error__message\">{error}</p>\n </div>\n )}\n\n {/* Toolbar */}\n {showToolbar && (\n <div\n ref={toolbarRef}\n className={`dde-toolbar ${toolbarClassName}`.trim()}\n />\n )}\n\n {/* Editor container */}\n <div\n ref={containerRef}\n className={`dde-editor ${editorClassName}`.trim()}\n />\n\n {/* Structural Changes Pane */}\n {!hideStructuralPane && !isPaneDismissed && structuralChanges.length > 0 && (\n <StructuralChangesPane\n changes={structuralChanges}\n position={structuralPanePosition}\n initiallyCollapsed={structuralPaneCollapsed}\n onAccept={handleAcceptStructuralChange}\n onReject={handleRejectStructuralChange}\n onAcceptAll={handleAcceptAllStructural}\n onRejectAll={handleRejectAllStructural}\n onNavigate={handleNavigateToChange}\n onDismiss={handlePaneDismiss}\n />\n )}\n </div>\n );\n }\n);\n\nexport default DocxDiffEditor;\n","/**\n * Services barrel export\n */\n\nexport {\n detectContentType,\n parseDocxFile,\n parseHtmlToJson,\n isProseMirrorJSON,\n} from './contentResolver';\n\nexport { diffDocuments } from './documentDiffer';\n\nexport { mergeDocuments, createSimpleMergedDocument } from './mergeDocuments';\n\nexport {\n createTrackInsertMark,\n createTrackDeleteMark,\n createTrackFormatMark,\n addMarkToTextNode,\n createTextNode,\n markAllAsDeleted,\n markAllAsInserted,\n cloneNode,\n normalizeMarksForRendering,\n} from './trackChangeInjector';\n\nexport {\n extractEnrichedChanges,\n extractEnrichedChangesWithStructural,\n} from './changeContextExtractor';\n\n// Block-level diffing services\nexport {\n generateFingerprint,\n buildFingerprintTree,\n extractBlockFingerprints,\n calculateSimilarity,\n calculateTextSimilarity,\n getNodeTextSimilarity,\n} from './nodeFingerprint';\n\nexport {\n alignNodes,\n alignDocuments,\n alignChildren,\n alignTableRows,\n alignTableCells,\n alignListItems,\n} from './nodeAligner';\n\nexport type { AlignmentResult } from './nodeAligner';\n\nexport {\n compareAttrs,\n compareNodeAttrs,\n hasAttrChanges,\n formatAttrDiffs,\n summarizeAttrChanges,\n} from './attrComparer';\n\nexport {\n diffTables,\n isTable,\n isTableRow,\n isTableCell,\n getTableLocation,\n getRowLocation,\n getCellLocation,\n getRowPreview,\n} from './tableBlockDiffer';\n\nexport type { TableDiffResult } from './tableBlockDiffer';\n\nexport {\n diffLists,\n isList,\n isListItem,\n getListType,\n getListLocation,\n getListItemLocation,\n getListItemPreview,\n countListItems,\n} from './listBlockDiffer';\n\nexport type { ListDiffResult } from './listBlockDiffer';\n\nexport {\n isImage,\n isHorizontalRule,\n isHardBreak,\n isPageBreak,\n isEmbedded,\n isAtomicNode,\n getImageIdentifier,\n imagesMatch,\n findImages,\n diffImages,\n getImageLocation,\n getImagePreview,\n getAtomicNodePreview,\n} from './nonTextNodeDiffer';\n\nexport {\n processStructuralChanges,\n buildMergedDocumentWithStructuralChanges,\n generateStructuralChangeSummary,\n} from './blockLevelMerger';\n\nexport type { BlockMergeResult } from './blockLevelMerger';\n\n// Structural merger (Phase 6b - structure-aware merge)\nexport { mergeWithStructuralAwareness } from './structuralMerger';\n\nexport type { StructuralMergeResult } from './structuralMerger';\n\n// Run properties sync (ensures marks are synced to runProperties for rendering)\nexport { marksToRunProperties, normalizeRunProperties } from './runPropertiesSync';\n\n// Color utilities (shared color conversion functions)\nexport {\n CSS_NAMED_COLORS,\n colorToHexWithoutHash,\n ensureValidCssColor,\n isNamedColor,\n} from './colorUtils';\n","/**\n * Block Level Merger Service\n * \n * Handles merging of structural changes (tables, lists, images)\n * with shared IDs for all marks within a structural change.\n * \n * This allows the Structural Changes Pane to accept/reject\n * entire structural units (e.g., a whole table row) with a single action.\n */\n\nimport { v4 as uuidv4 } from 'uuid';\nimport type {\n ProseMirrorJSON,\n ProseMirrorNode,\n StructuralChange,\n StructuralChangeInfo,\n TrackChangeAuthor,\n HybridDiffResult,\n} from '../types';\nimport {\n createTrackInsertMark,\n createTrackDeleteMark,\n normalizeMarksForRendering,\n} from './trackChangeInjector';\nimport { alignDocuments } from './nodeAligner';\nimport { diffTables, isTable, getRowLocation, getRowPreview } from './tableBlockDiffer';\nimport { diffLists, isList, getListItemLocation, getListItemPreview } from './listBlockDiffer';\nimport { diffImages, getImageLocation, getImagePreview } from './nonTextNodeDiffer';\nimport { DEFAULT_AUTHOR } from '../constants';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Result of block-level merging\n */\nexport interface BlockMergeResult {\n /** The merged document */\n mergedDoc: ProseMirrorNode;\n /** Structural change metadata for the pane */\n structuralChangeInfos: StructuralChangeInfo[];\n /** Summary of structural changes */\n structuralChangeSummary: string[];\n}\n\n// ============================================================================\n// Node Marking Functions\n// ============================================================================\n\n/**\n * Mark all text in a node as inserted (with shared ID).\n * Used for inserted blocks (rows, paragraphs, list items).\n * Normalizes existing marks to ensure valid CSS color format.\n */\nfunction markAllTextAsInserted(\n node: ProseMirrorNode,\n sharedId: string,\n author: TrackChangeAuthor\n): ProseMirrorNode {\n if (node.type === 'text') {\n // Normalize existing marks to ensure valid CSS colors (# prefix for hex)\n const existingMarks = normalizeMarksForRendering(node.marks || []);\n return {\n ...node,\n marks: [...existingMarks, createTrackInsertMark(author, sharedId)],\n };\n }\n\n if (node.content && Array.isArray(node.content)) {\n return {\n ...node,\n content: node.content.map((child: ProseMirrorNode) =>\n markAllTextAsInserted(child, sharedId, author)\n ),\n };\n }\n\n return node;\n}\n\n/**\n * Mark all text in a node as deleted (with shared ID).\n * Used for deleted blocks (rows, paragraphs, list items).\n * Normalizes existing marks to ensure valid CSS color format.\n */\nfunction markAllTextAsDeleted(\n node: ProseMirrorNode,\n sharedId: string,\n author: TrackChangeAuthor\n): ProseMirrorNode {\n if (node.type === 'text') {\n // Normalize existing marks to ensure valid CSS colors (# prefix for hex)\n const existingMarks = normalizeMarksForRendering(node.marks || []);\n return {\n ...node,\n marks: [...existingMarks, createTrackDeleteMark(author, sharedId)],\n };\n }\n\n if (node.content && Array.isArray(node.content)) {\n return {\n ...node,\n content: node.content.map((child: ProseMirrorNode) =>\n markAllTextAsDeleted(child, sharedId, author)\n ),\n };\n }\n\n return node;\n}\n\n/**\n * Deep clone a node.\n */\nfunction cloneNode(node: ProseMirrorNode): ProseMirrorNode {\n return JSON.parse(JSON.stringify(node));\n}\n\n/**\n * Extract text content from a node for preview.\n */\nfunction extractTextPreview(node: ProseMirrorNode, maxLength: number = 50): string {\n const texts: string[] = [];\n \n function extract(n: ProseMirrorNode): void {\n if (n.type === 'text') {\n texts.push(n.text || '');\n }\n if (n.content) {\n for (const child of n.content) {\n extract(child);\n }\n }\n }\n \n extract(node);\n const text = texts.join('').trim();\n \n if (text.length > maxLength) {\n return text.substring(0, maxLength - 3) + '...';\n }\n return text || '(empty)';\n}\n\n// ============================================================================\n// Block-Level Merge Functions\n// ============================================================================\n\n/**\n * Process structural changes and generate marked blocks with shared IDs.\n */\nexport function processStructuralChanges(\n docA: ProseMirrorNode,\n docB: ProseMirrorNode,\n author: TrackChangeAuthor = DEFAULT_AUTHOR\n): { changes: StructuralChange[]; infos: StructuralChangeInfo[] } {\n const changes: StructuralChange[] = [];\n const infos: StructuralChangeInfo[] = [];\n\n // Align top-level blocks\n const alignment = alignDocuments(docA, docB);\n\n // Track table and list indices for location strings\n let tableIndex = 0;\n let listIndex = 0;\n let paragraphIndex = 0;\n\n // Process top-level insertions\n for (const inserted of alignment.insertions) {\n const node = inserted.node;\n const sharedId = uuidv4();\n const date = new Date().toISOString();\n\n let type: StructuralChangeInfo['type'] = 'paragraphInsert';\n let location = '';\n let preview = '';\n\n if (isTable(node)) {\n type = 'rowInsert'; // Treat as table insertion (could add 'tableInsert' type)\n location = `New table at position ${inserted.path[0] + 1}`;\n preview = `Table with ${node.content?.length || 0} rows`;\n tableIndex++;\n } else if (isList(node)) {\n type = 'listItemInsert';\n location = `New list at position ${inserted.path[0] + 1}`;\n preview = `List with ${node.content?.length || 0} items`;\n listIndex++;\n } else {\n type = 'paragraphInsert';\n paragraphIndex++;\n location = `Paragraph ${paragraphIndex}`;\n preview = extractTextPreview(node);\n }\n\n changes.push({\n id: sharedId,\n type,\n nodeType: node.type,\n path: inserted.path,\n node: markAllTextAsInserted(cloneNode(node), sharedId, author),\n });\n\n infos.push({\n id: sharedId,\n type,\n nodeType: node.type,\n location,\n preview,\n author,\n date,\n });\n }\n\n // Process top-level deletions\n for (const deleted of alignment.deletions) {\n const node = deleted.node;\n const sharedId = uuidv4();\n const date = new Date().toISOString();\n\n let type: StructuralChangeInfo['type'] = 'paragraphDelete';\n let location = '';\n let preview = '';\n\n if (isTable(node)) {\n type = 'rowDelete';\n location = `Deleted table at position ${deleted.path[0] + 1}`;\n preview = `Table with ${node.content?.length || 0} rows`;\n } else if (isList(node)) {\n type = 'listItemDelete';\n location = `Deleted list at position ${deleted.path[0] + 1}`;\n preview = `List with ${node.content?.length || 0} items`;\n } else {\n type = 'paragraphDelete';\n location = `Deleted paragraph`;\n preview = extractTextPreview(node);\n }\n\n changes.push({\n id: sharedId,\n type,\n nodeType: node.type,\n path: deleted.path,\n node: markAllTextAsDeleted(cloneNode(node), sharedId, author),\n });\n\n infos.push({\n id: sharedId,\n type,\n nodeType: node.type,\n location,\n preview,\n author,\n date,\n });\n }\n\n // Process matched blocks for internal changes (tables, lists)\n for (const match of alignment.matched) {\n const nodeA = docA.content?.[match.pathA[0]];\n const nodeB = docB.content?.[match.pathB[0]];\n\n if (!nodeA || !nodeB) continue;\n\n // Check for table-specific changes\n if (isTable(nodeA) && isTable(nodeB)) {\n tableIndex++;\n const tableResult = diffTables(nodeA, nodeB, match.pathA, match.pathB);\n\n // Process row changes\n for (const rowChange of tableResult.rowChanges) {\n const sharedId = rowChange.id;\n const date = new Date().toISOString();\n const rowIndex = rowChange.path[rowChange.path.length - 1];\n\n const isInsert = rowChange.type === 'rowInsert';\n const location = getRowLocation(rowChange.path, rowIndex, tableIndex - 1);\n const preview = getRowPreview(rowChange.node);\n\n // Update the node with marks\n const markedNode = isInsert\n ? markAllTextAsInserted(cloneNode(rowChange.node), sharedId, author)\n : markAllTextAsDeleted(cloneNode(rowChange.node), sharedId, author);\n\n changes.push({\n ...rowChange,\n node: markedNode,\n });\n\n infos.push({\n id: sharedId,\n type: rowChange.type,\n nodeType: 'tableRow',\n location,\n preview,\n author,\n date,\n });\n }\n }\n\n // Check for list-specific changes\n if (isList(nodeA) && isList(nodeB)) {\n listIndex++;\n const listResult = diffLists(nodeA, nodeB, match.pathA, match.pathB);\n\n // Process item changes\n for (const itemChange of listResult.itemChanges) {\n const sharedId = itemChange.id;\n const date = new Date().toISOString();\n const itemIndex = itemChange.path[itemChange.path.length - 1];\n\n const isInsert = itemChange.type === 'listItemInsert';\n const location = getListItemLocation(itemChange.path, itemIndex, listIndex - 1);\n const preview = getListItemPreview(itemChange.node);\n\n // Update the node with marks\n const markedNode = isInsert\n ? markAllTextAsInserted(cloneNode(itemChange.node), sharedId, author)\n : markAllTextAsDeleted(cloneNode(itemChange.node), sharedId, author);\n\n changes.push({\n ...itemChange,\n node: markedNode,\n });\n\n infos.push({\n id: sharedId,\n type: itemChange.type,\n nodeType: 'listItem',\n location,\n preview,\n author,\n date,\n });\n }\n }\n }\n\n // Process image changes\n const imageChanges = diffImages(docA, docB);\n\n for (const imgInsert of imageChanges.inserted) {\n const sharedId = imgInsert.id;\n const date = new Date().toISOString();\n\n infos.push({\n id: sharedId,\n type: 'imageInsert',\n nodeType: 'image',\n location: getImageLocation(imgInsert.path),\n preview: getImagePreview(imgInsert.node),\n author,\n date,\n });\n\n changes.push(imgInsert);\n }\n\n for (const imgDelete of imageChanges.deleted) {\n const sharedId = imgDelete.id;\n const date = new Date().toISOString();\n\n infos.push({\n id: sharedId,\n type: 'imageDelete',\n nodeType: 'image',\n location: getImageLocation(imgDelete.path),\n preview: getImagePreview(imgDelete.node),\n author,\n date,\n });\n\n changes.push(imgDelete);\n }\n\n return { changes, infos };\n}\n\n/**\n * Build the merged document with structural changes applied.\n * Combines the original character-level merge with block-level changes.\n */\nexport function buildMergedDocumentWithStructuralChanges(\n baseMergedDoc: ProseMirrorNode,\n structuralChanges: StructuralChange[],\n docA: ProseMirrorNode,\n docB: ProseMirrorNode\n): ProseMirrorNode {\n // For now, the structural changes are already marked in processStructuralChanges\n // The merged document from the base merge already contains most changes\n // We need to integrate the structural changes into the document\n \n // Clone the base merged document\n const result = cloneNode(baseMergedDoc);\n\n // Insert structural insertions at appropriate positions\n // Delete structural deletions by including them with delete marks\n \n // This is a simplified approach - full implementation would need\n // careful position tracking. For now, structural changes are\n // handled through the existing merge process, and this function\n // serves as an integration point for future enhancements.\n\n return result;\n}\n\n/**\n * Generate a summary of structural changes.\n */\nexport function generateStructuralChangeSummary(\n infos: StructuralChangeInfo[]\n): string[] {\n const summary: string[] = [];\n\n const rowInserts = infos.filter((i) => i.type === 'rowInsert').length;\n const rowDeletes = infos.filter((i) => i.type === 'rowDelete').length;\n const paragraphInserts = infos.filter((i) => i.type === 'paragraphInsert').length;\n const paragraphDeletes = infos.filter((i) => i.type === 'paragraphDelete').length;\n const listItemInserts = infos.filter((i) => i.type === 'listItemInsert').length;\n const listItemDeletes = infos.filter((i) => i.type === 'listItemDelete').length;\n const imageInserts = infos.filter((i) => i.type === 'imageInsert').length;\n const imageDeletes = infos.filter((i) => i.type === 'imageDelete').length;\n\n if (rowInserts > 0) summary.push(`${rowInserts} row(s) inserted`);\n if (rowDeletes > 0) summary.push(`${rowDeletes} row(s) deleted`);\n if (paragraphInserts > 0) summary.push(`${paragraphInserts} paragraph(s) inserted`);\n if (paragraphDeletes > 0) summary.push(`${paragraphDeletes} paragraph(s) deleted`);\n if (listItemInserts > 0) summary.push(`${listItemInserts} list item(s) inserted`);\n if (listItemDeletes > 0) summary.push(`${listItemDeletes} list item(s) deleted`);\n if (imageInserts > 0) summary.push(`${imageInserts} image(s) inserted`);\n if (imageDeletes > 0) summary.push(`${imageDeletes} image(s) deleted`);\n\n return summary;\n}\n","/**\n * Embedded DOCX template\n *\n * This is a base64-encoded blank DOCX file created with Microsoft Word.\n * It provides the complete schema, styles, themes, and fonts needed to\n * initialize SuperDoc when working with HTML or JSON content.\n *\n * The DOCX contains all standard Word document components:\n * - [Content_Types].xml\n * - _rels/.rels\n * - word/document.xml\n * - word/_rels/document.xml.rels\n * - word/styles.xml (full Word styles)\n * - word/settings.xml\n * - word/fontTable.xml\n * - word/webSettings.xml\n * - word/theme/theme1.xml\n * - docProps/core.xml\n * - docProps/app.xml\n */\n\n/**\n * Base64-encoded blank DOCX file created with Microsoft Word.\n */\nconst BLANK_DOCX_BASE64 = `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`;\n\n/**\n * Convert base64 string to Blob\n */\nfunction base64ToBlob(base64: string, mimeType: string): Blob {\n const byteCharacters = atob(base64.replace(/\\s/g, ''));\n const byteNumbers = new Array(byteCharacters.length);\n\n for (let i = 0; i < byteCharacters.length; i++) {\n byteNumbers[i] = byteCharacters.charCodeAt(i);\n }\n\n const byteArray = new Uint8Array(byteNumbers);\n return new Blob([byteArray], { type: mimeType });\n}\n\n/**\n * Convert base64 string to File\n */\nfunction base64ToFile(base64: string, filename: string, mimeType: string): File {\n const blob = base64ToBlob(base64, mimeType);\n return new File([blob], filename, { type: mimeType });\n}\n\n/**\n * Get the blank DOCX template as a File object\n */\nexport function getBlankTemplateFile(): File {\n return base64ToFile(\n BLANK_DOCX_BASE64,\n 'blank-template.docx',\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'\n );\n}\n\n/**\n * Get the blank DOCX template as a Blob\n */\nexport function getBlankTemplateBlob(): Blob {\n return base64ToBlob(\n BLANK_DOCX_BASE64,\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'\n );\n}\n\n/**\n * Check if a File is a valid DOCX file (basic check)\n */\nexport function isValidDocxFile(file: File): boolean {\n const validTypes = [\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n 'application/msword',\n ];\n return validTypes.includes(file.type) || file.name.endsWith('.docx');\n}\n"]}