@reogrid/pro 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/pro-react.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/pro/react/index.tsx","../src/app/domIds.ts","../src/app/styles.ts","../src/core/worksheet/gridDefaults.ts","../src/core/cell/selectionRange.ts","../src/core/formula/formulaEngine.ts","../src/core/style/cellStyle.ts","../src/core/style/numberFormat.ts","../src/core/worksheet/cellKey.ts","../src/core/worksheet/gridGeometry.ts","../src/core/border/types.ts","../src/core/border/borderManager.ts","../src/core/merge/mergeManager.ts","../src/core/worksheet/worksheet.ts","../src/render/sheetRenderer.ts","../src/render/viewports.ts","../src/io/unzip.ts","../src/io/xml.ts","../src/io/xlsx.ts","../src/io/xlsxImporter.ts","../src/io/zipWriter.ts","../src/io/xlsxWriter.ts","../src/core/worksheet/handles.ts","../src/core/worksheet/canvasWorksheet.ts","../src/render/controllers/pointerController.ts","../src/render/editor/cellEditor.ts","../src/render/controllers/keyboardController.ts","../src/render/layers/imageLayer.ts","../src/index.ts","../src/pro/index.ts"],"sourcesContent":["import {\n forwardRef,\n useEffect,\n useRef,\n type CSSProperties,\n} from 'react';\nimport { createReogrid, type ReogridInstance, type ReogridOptions } from '../index';\n\nexport type { ReogridInstance };\n\nexport interface ReogridProps {\n className?: string;\n style?: CSSProperties;\n /**\n * Called once after the grid is initialized, with the full ReogridInstance.\n * Useful for setting initial cell values, styles, or loading an xlsx file.\n */\n onReady?: (instance: ReogridInstance) => void;\n /**\n * Options forwarded to createReogrid(). `workspace` is managed internally\n * and will be ignored if supplied.\n */\n options?: Omit<ReogridOptions, 'workspace'>;\n}\n\n/**\n * React component that mounts a ReoGrid Pro canvas spreadsheet.\n * No row/column restrictions. Full xlsx import/export support.\n *\n * The ref exposes the full `ReogridInstance` (worksheet, api, etc.).\n *\n * @example\n * ```tsx\n * const gridRef = useRef<ReogridInstance>(null);\n * <Reogrid ref={gridRef} style={{ flex: 1 }} onReady={(inst) => {\n * inst.api.setCellValue('A1', 'Hello from ReoGrid Pro!');\n * }} />\n * ```\n */\nexport const Reogrid = forwardRef<ReogridInstance, ReogridProps>(\n ({ className, style, onReady, options }, ref) => {\n const containerRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!containerRef.current) return;\n\n const instance = createReogrid({\n ...options,\n workspace: containerRef.current,\n });\n\n if (typeof ref === 'function') {\n ref(instance);\n } else if (ref) {\n ref.current = instance;\n }\n\n onReady?.(instance);\n\n return () => {\n instance.destroy();\n if (typeof ref === 'function') {\n ref(null);\n } else if (ref) {\n ref.current = null;\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return <div ref={containerRef} className={className} style={style} />;\n },\n);\n\nReogrid.displayName = 'Reogrid';\n","export const WORKSPACE_ID = 'reogrid-workspace';\nexport const CANVAS_ID = 'reogrid-canvas';\n","const DEFAULT_STYLE_ID = 'reogrid-base-styles';\nconst FONT_LINK_ID = 'reogrid-font-roboto';\nconst FONT_STYLESHEET_URL =\n 'https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap';\n\nexport const WORKSPACE_CLASS = 'reogrid-workspace';\nexport const WORKBOOK_CLASS = 'workbook';\nexport const WORKSHEET_CONTAINER_CLASS = 'worksheet-container';\nexport const GRID_SCROLL_CLASS = 'grid-scroll';\nexport const GRID_SPACER_CLASS = 'grid-spacer';\nexport const GRID_LAYER_CLASS = 'grid-layer';\n\nconst BASE_STYLES = `\n.${WORKSPACE_CLASS} {\n position: relative;\n overflow: hidden;\n background: #e2e8f0;\n display: flex;\n flex-direction: column;\n}\n\n.${WORKSPACE_CLASS} .${WORKBOOK_CLASS} {\n flex: 1;\n display: flex;\n flex-direction: column;\n position: relative;\n}\n\n.${WORKSPACE_CLASS} .${WORKSHEET_CONTAINER_CLASS} {\n flex: 1;\n position: relative;\n background: #ffffff;\n overflow: hidden;\n}\n\n.${WORKSPACE_CLASS} .${GRID_SCROLL_CLASS} {\n position: absolute;\n inset: 0;\n overflow: auto;\n overscroll-behavior: contain;\n background: transparent;\n z-index: 2;\n}\n\n.${WORKSPACE_CLASS} .${GRID_SPACER_CLASS} {\n width: 100%;\n height: 100%;\n min-width: 100%;\n min-height: 100%;\n pointer-events: none;\n}\n\n.${WORKSPACE_CLASS} canvas.${GRID_LAYER_CLASS} {\n position: absolute;\n inset: 0;\n z-index: 1;\n background: transparent;\n}\n`.trim();\n\nexport function ensureWorkspaceStyles(styleId: string = DEFAULT_STYLE_ID): void {\n if (typeof document === 'undefined') {\n return;\n }\n ensureFontStyles();\n if (document.getElementById(styleId)) {\n return;\n }\n const style = document.createElement('style');\n style.id = styleId;\n style.textContent = BASE_STYLES;\n document.head.appendChild(style);\n}\n\nfunction ensureFontStyles(): void {\n if (document.getElementById(FONT_LINK_ID)) {\n return;\n }\n const link = document.createElement('link');\n link.id = FONT_LINK_ID;\n link.rel = 'stylesheet';\n link.href = FONT_STYLESHEET_URL;\n document.head.appendChild(link);\n}\n","export const DEFAULT_ROWS = 40;\nexport const DEFAULT_COLUMNS = 26;\nexport const DEFAULT_COLUMN_WIDTH = 80;\nexport const DEFAULT_ROW_HEIGHT = 22;\nexport const HEADER_COLUMN_WIDTH = 60;\nexport const HEADER_ROW_HEIGHT = 24;\n","import type { Worksheet } from '../worksheet/worksheet';\nimport type { RangeRect } from '../worksheet/types';\n\ntype SelectionBounds = RangeRect & {\n topRow: number;\n bottomRow: number;\n leftColumn: number;\n rightColumn: number;\n};\n\nexport class SelectionRange {\nprivate readonly worksheet: Worksheet;\n\n private startRow: number | null = null;\n\n private startColumn: number | null = null;\n\n private endRow: number | null = null;\n\n private endColumn: number | null = null;\n\n private anchorBounds: { top: number; bottom: number; left: number; right: number } | null = null;\n\n constructor(worksheet: Worksheet) {\n this.worksheet = worksheet;\n this.reset();\n }\n\n reset(): void {\n this.startRow = null;\n this.startColumn = null;\n this.endRow = null;\n this.endColumn = null;\n this.anchorBounds = null;\n }\n\n begin(row: number, column: number): void {\n const clamped = this.clampCell(row, column);\n const bounds = this.worksheet.getCellMergeBounds(clamped.row, clamped.column);\n this.startRow = bounds.topRow;\n this.startColumn = bounds.leftColumn;\n this.endRow = bounds.bottomRow;\n this.endColumn = bounds.rightColumn;\n this.anchorBounds = {\n top: bounds.topRow,\n bottom: bounds.bottomRow,\n left: bounds.leftColumn,\n right: bounds.rightColumn,\n };\n }\n\n update(row: number, column: number): void {\n if (!this.isActive() || !this.anchorBounds) {\n return;\n }\n\n const clamped = this.clampCell(row, column);\n const target = this.worksheet.getCellMergeBounds(clamped.row, clamped.column);\n const union = {\n top: Math.min(this.anchorBounds.top, target.topRow),\n bottom: Math.max(this.anchorBounds.bottom, target.bottomRow),\n left: Math.min(this.anchorBounds.left, target.leftColumn),\n right: Math.max(this.anchorBounds.right, target.rightColumn),\n };\n\n const bounds = this.worksheet.expandSelectionWithMergedCells({\n top: union.top,\n bottom: union.bottom,\n left: union.left,\n right: union.right,\n });\n this.startRow = bounds.top;\n this.startColumn = bounds.left;\n this.endRow = bounds.bottom;\n this.endColumn = bounds.right;\n }\n\n isActive(): boolean {\n return this.startRow !== null && this.startColumn !== null;\n }\n\n clampCell(row: number, column: number): { row: number; column: number } {\n const clampedRow = Math.min(Math.max(row, 0), this.worksheet.rows - 1);\n const clampedColumn = Math.min(Math.max(column, 0), this.worksheet.columns - 1);\n return { row: clampedRow, column: clampedColumn };\n }\n\n setRange(startRow: number, startColumn: number, endRow: number, endColumn: number): void {\n const start = this.clampCell(startRow, startColumn);\n const end = this.clampCell(endRow, endColumn);\n this.startRow = start.row;\n this.startColumn = start.column;\n this.endRow = end.row;\n this.endColumn = end.column;\n this.anchorBounds = {\n top: start.row,\n bottom: start.row,\n left: start.column,\n right: start.column,\n };\n }\n\n selectRows(startRow: number, endRow: number = startRow): void {\n const top = Math.min(startRow, endRow);\n const bottom = Math.max(startRow, endRow);\n const expanded = this.worksheet.expandSelectionWithMergedCells({\n top,\n bottom,\n left: 0,\n right: this.worksheet.columns - 1,\n });\n this.setRange(expanded.top, expanded.left, expanded.bottom, expanded.right);\n }\n\n selectColumns(startColumn: number, endColumn: number = startColumn): void {\n const left = Math.min(startColumn, endColumn);\n const right = Math.max(startColumn, endColumn);\n const expanded = this.worksheet.expandSelectionWithMergedCells({\n top: 0,\n bottom: this.worksheet.rows - 1,\n left,\n right,\n });\n this.setRange(expanded.top, expanded.left, expanded.bottom, expanded.right);\n }\n\n selectAll(): void {\n this.setRange(0, 0, this.worksheet.rows - 1, this.worksheet.columns - 1);\n }\n\n getNormalizedBounds(): SelectionBounds | null {\n if (!this.isActive() || this.startRow === null || this.startColumn === null || this.endRow === null || this.endColumn === null) {\n return null;\n }\n\n const topRow = Math.min(this.startRow, this.endRow);\n const bottomRow = Math.max(this.startRow, this.endRow);\n const leftColumn = Math.min(this.startColumn, this.endColumn);\n const rightColumn = Math.max(this.startColumn, this.endColumn);\n\n const rect = this.worksheet.getRangeRect(topRow, leftColumn, bottomRow, rightColumn);\n return { ...rect, topRow, leftColumn, bottomRow, rightColumn };\n }\n\n draw(ctx: CanvasRenderingContext2D): void {\n const bounds = this.getNormalizedBounds();\n if (!bounds) {\n return;\n }\n\n ctx.save();\n ctx.fillStyle = 'rgba(33, 150, 243, 0.2)';\n ctx.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);\n\n const pixelRatio = this.worksheet.getPixelRatio();\n const inset = 0.5 / pixelRatio;\n ctx.strokeStyle = '#2196f3';\n ctx.lineWidth = 2 / pixelRatio;\n ctx.strokeRect(\n bounds.x + inset,\n bounds.y + inset,\n Math.max(0, bounds.width - inset * 2),\n Math.max(0, bounds.height - inset * 2),\n );\n ctx.restore();\n }\n\n getActiveCell(): { row: number; column: number } | null {\n if (this.startRow === null || this.startColumn === null) {\n return null;\n }\n return { row: this.startRow, column: this.startColumn };\n }\n\n moveActiveCell(rowDelta: number, columnDelta: number): { row: number; column: number } {\n const current = this.getActiveCell() ?? { row: 0, column: 0 };\n const currentRange = this.worksheet.getMergedRange(current.row, current.column);\n let baseRow = current.row;\n let baseColumn = current.column;\n if (currentRange) {\n if (rowDelta > 0) {\n baseRow = currentRange.bottomRow;\n } else if (rowDelta < 0) {\n baseRow = currentRange.topRow;\n }\n if (columnDelta > 0) {\n baseColumn = currentRange.rightColumn;\n } else if (columnDelta < 0) {\n baseColumn = currentRange.leftColumn;\n }\n }\n const next = this.clampCell(baseRow + rowDelta, baseColumn + columnDelta);\n const bounds = this.worksheet.expandSelectionWithMergedCells({\n top: next.row,\n bottom: next.row,\n left: next.column,\n right: next.column,\n });\n this.startRow = bounds.top;\n this.startColumn = bounds.left;\n this.endRow = bounds.bottom;\n this.endColumn = bounds.right;\n this.anchorBounds = {\n top: bounds.top,\n bottom: bounds.bottom,\n left: bounds.left,\n right: bounds.right,\n };\n return { row: this.startRow, column: this.startColumn };\n }\n}\n","import type { Worksheet } from '../worksheet/worksheet';\n\ntype TokenType =\n | 'number'\n | 'identifier'\n | 'plus'\n | 'minus'\n | 'multiply'\n | 'divide'\n | 'lparen'\n | 'rparen'\n | 'comma'\n | 'colon'\n | 'eof';\n\ninterface Token {\n type: TokenType;\n value?: string;\n}\n\nexport class FormulaEngine {\n private readonly worksheet: Worksheet;\n\n constructor(worksheet: Worksheet) {\n this.worksheet = worksheet;\n }\n\n getDisplayValue(row: number, column: number): string {\n const raw = this.worksheet.getCellInput(row, column);\n if (!raw || raw.length === 0) {\n return '';\n }\n\n if (!raw.startsWith('=')) {\n return raw;\n }\n\n const expression = raw.slice(1);\n try {\n const value = this.evaluateExpression(expression, row, column, new Set());\n if (typeof value === 'number') {\n return Number.isFinite(value) ? String(value) : '#ERR';\n }\n return value ?? '';\n } catch (error) {\n if (error instanceof Error && error.message === 'CYCLE') {\n return '#CYCLE!';\n }\n return '#ERR';\n }\n }\n\n private evaluateExpression(\n expression: string,\n row: number,\n column: number,\n visited: Set<string>,\n ): number | string {\n const lexer = new Lexer(expression);\n const parser = new Parser(lexer, (refRow, refCol) => this.getCellNumericValue(refRow, refCol, visited));\n const value = parser.parseExpression();\n if (parser.currentToken.type !== 'eof') {\n throw new Error('Unexpected token');\n }\n return value;\n }\n\n private getCellNumericValue(row: number, column: number, visited: Set<string>): number {\n const key = `${row}:${column}`;\n if (visited.has(key)) {\n throw new Error('CYCLE');\n }\n visited.add(key);\n\n const raw = this.worksheet.getCellInput(row, column);\n let result: number;\n if (!raw || raw.length === 0) {\n result = 0;\n } else if (raw.startsWith('=')) {\n const value = this.evaluateExpression(raw.slice(1), row, column, visited);\n result = coerceToNumber(value);\n } else {\n result = coerceToNumber(raw);\n }\n\n visited.delete(key);\n return result;\n }\n}\n\nclass Lexer {\n private readonly input: string;\n\n private position = 0;\n\n constructor(input: string) {\n this.input = input.trim();\n }\n\n nextToken(): Token {\n this.skipWhitespace();\n if (this.position >= this.input.length) {\n return { type: 'eof' };\n }\n\n const char = this.currentChar();\n if (isDigit(char) || (char === '.' && isDigit(this.peekChar()))) {\n return this.readNumber();\n }\n if (isAlpha(char)) {\n return this.readIdentifier();\n }\n\n this.position += 1;\n switch (char) {\n case '+':\n return { type: 'plus' };\n case '-':\n return { type: 'minus' };\n case '*':\n return { type: 'multiply' };\n case '/':\n return { type: 'divide' };\n case '(':\n return { type: 'lparen' };\n case ')':\n return { type: 'rparen' };\n case ',':\n return { type: 'comma' };\n case ':':\n return { type: 'colon' };\n default:\n throw new Error(`Unexpected character: ${char}`);\n }\n }\n\n private readNumber(): Token {\n const start = this.position;\n while (isDigit(this.currentChar())) {\n this.position += 1;\n }\n if (this.currentChar() === '.' && isDigit(this.peekChar())) {\n this.position += 1;\n while (isDigit(this.currentChar())) {\n this.position += 1;\n }\n }\n const value = this.input.slice(start, this.position);\n return { type: 'number', value };\n }\n\n private readIdentifier(): Token {\n const start = this.position;\n while (isAlphaNumeric(this.currentChar())) {\n this.position += 1;\n }\n const value = this.input.slice(start, this.position);\n return { type: 'identifier', value };\n }\n\n private skipWhitespace(): void {\n while (this.position < this.input.length && /\\s/.test(this.currentChar())) {\n this.position += 1;\n }\n }\n\n private currentChar(): string {\n if (this.position >= this.input.length) {\n return '';\n }\n return this.input[this.position];\n }\n\n private peekChar(): string {\n const index = this.position + 1;\n if (index >= this.input.length) {\n return '';\n }\n return this.input[index];\n }\n}\n\nclass Parser {\n private readonly lexer: Lexer;\n\n private readonly referenceResolver: (row: number, column: number) => number;\n\n public currentToken: Token;\n\n private lookaheadToken: Token;\n\n constructor(lexer: Lexer, referenceResolver: (row: number, column: number) => number) {\n this.lexer = lexer;\n this.referenceResolver = referenceResolver;\n this.currentToken = this.lexer.nextToken();\n this.lookaheadToken = this.lexer.nextToken();\n }\n\n parseExpression(): number {\n let value = this.parseTerm();\n while (this.currentToken.type === 'plus' || this.currentToken.type === 'minus') {\n const operator = this.currentToken.type;\n this.eat(operator);\n const nextTerm = this.parseTerm();\n value = operator === 'plus' ? value + nextTerm : value - nextTerm;\n }\n return value;\n }\n\n private parseTerm(): number {\n let value = this.parseFactor();\n while (this.currentToken.type === 'multiply' || this.currentToken.type === 'divide') {\n const operator = this.currentToken.type;\n this.eat(operator);\n const nextFactor = this.parseFactor();\n value = operator === 'multiply' ? value * nextFactor : value / nextFactor;\n }\n return value;\n }\n\n private parseFactor(): number {\n if (this.currentToken.type === 'plus') {\n this.eat('plus');\n return this.parseFactor();\n }\n if (this.currentToken.type === 'minus') {\n this.eat('minus');\n return -this.parseFactor();\n }\n return this.parsePrimary();\n }\n\n private parsePrimary(): number {\n switch (this.currentToken.type) {\n case 'number': {\n const value = parseFloat(this.currentToken.value ?? '0');\n this.eat('number');\n return value;\n }\n case 'identifier': {\n const identifier = this.currentToken.value ?? '';\n this.eat('identifier');\n if (this.currentToken.type === 'lparen') {\n return this.parseFunctionCall(identifier);\n }\n const reference = parseCellReference(identifier);\n if (!reference) {\n throw new Error(`Invalid reference: ${identifier}`);\n }\n return this.referenceResolver(reference.row, reference.column);\n }\n case 'lparen': {\n this.eat('lparen');\n const value = this.parseExpression();\n this.eat('rparen');\n return value;\n }\n default:\n throw new Error('Unexpected token in expression');\n }\n }\n\n private parseFunctionCall(name: string): number {\n this.eat('lparen');\n const args: number[] = [];\n if (this.currentToken.type !== 'rparen') {\n args.push(...this.parseFunctionArgumentValues());\n while (this.currentToken.type === 'comma') {\n this.eat('comma');\n args.push(...this.parseFunctionArgumentValues());\n }\n }\n this.eat('rparen');\n switch (name.toUpperCase()) {\n case 'SUM':\n return args.reduce((acc, value) => acc + value, 0);\n case 'AVERAGE':\n return args.length ? args.reduce((acc, value) => acc + value, 0) / args.length : 0;\n default:\n throw new Error(`Unsupported function: ${name}`);\n }\n }\n\n private parseFunctionArgumentValues(): number[] {\n if (this.currentToken.type === 'identifier' && this.lookaheadToken.type === 'colon') {\n const startRef = parseCellReference(this.currentToken.value ?? '');\n if (!startRef) {\n throw new Error(`Invalid reference: ${this.currentToken.value ?? ''}`);\n }\n this.eat('identifier');\n this.eat('colon');\n if (this.currentToken.type !== 'identifier') {\n throw new Error('Expected cell reference after \":\"');\n }\n const endRef = parseCellReference(this.currentToken.value ?? '');\n if (!endRef) {\n throw new Error(`Invalid reference: ${this.currentToken.value ?? ''}`);\n }\n this.eat('identifier');\n return this.expandRange(startRef, endRef);\n }\n\n return [this.parseExpression()];\n }\n\n private expandRange(\n start: { row: number; column: number },\n end: { row: number; column: number },\n ): number[] {\n const values: number[] = [];\n const startRow = Math.min(start.row, end.row);\n const endRow = Math.max(start.row, end.row);\n const startColumn = Math.min(start.column, end.column);\n const endColumn = Math.max(start.column, end.column);\n\n for (let r = startRow; r <= endRow; r += 1) {\n for (let c = startColumn; c <= endColumn; c += 1) {\n values.push(this.referenceResolver(r, c));\n }\n }\n\n return values;\n }\n\n private eat(type: TokenType): void {\n if (this.currentToken.type !== type) {\n throw new Error(`Expected token ${type}, got ${this.currentToken.type}`);\n }\n this.currentToken = this.lookaheadToken;\n this.lookaheadToken = this.lexer.nextToken();\n }\n}\n\nfunction isDigit(char: string): boolean {\n return /[0-9]/.test(char);\n}\n\nfunction isAlpha(char: string): boolean {\n return /[a-zA-Z]/.test(char);\n}\n\nfunction isAlphaNumeric(char: string): boolean {\n return /[a-zA-Z0-9]/.test(char);\n}\n\nfunction parseCellReference(identifier: string): { row: number; column: number } | null {\n const match = /^([A-Za-z]+)([0-9]+)$/.exec(identifier);\n if (!match) {\n return null;\n }\n const [, columnLabel, rowPart] = match;\n const column = columnLabel\n .toUpperCase()\n .split('')\n .reduce((acc, char) => acc * 26 + (char.charCodeAt(0) - 64), 0);\n return { row: parseInt(rowPart, 10) - 1, column: column - 1 };\n}\n\nfunction coerceToNumber(value: unknown): number {\n if (typeof value === 'number') {\n return value;\n }\n if (typeof value === 'string') {\n const parsed = parseFloat(value);\n return Number.isNaN(parsed) ? 0 : parsed;\n }\n return 0;\n}\n","export type TextAlign = 'left' | 'center' | 'right';\nexport type VerticalAlign = 'top' | 'middle' | 'bottom';\nexport type TextWrapMode = 'none' | 'wrap' | 'break-word';\n\nexport interface CellStyle {\n fontFamily: string;\n fontSize: number;\n bold: boolean;\n italic: boolean;\n underline: boolean;\n backgroundColor: string;\n color: string;\n textAlign: TextAlign;\n verticalAlign: VerticalAlign;\n textWrapMode: TextWrapMode;\n}\n\nexport const DEFAULT_CELL_STYLE: CellStyle = {\n fontFamily: 'Arial',\n fontSize: 10,\n bold: false,\n italic: false,\n underline: false,\n backgroundColor: '#ffffff',\n color: '#2c3e50',\n textAlign: 'left',\n verticalAlign: 'bottom',\n textWrapMode: 'none',\n};\n","export function formatNumberWithFormat(value: number, formatCode: string): string | null {\n if (!formatCode || formatCode.toLowerCase() === 'general') {\n return null;\n }\n const sections = formatCode.split(';');\n let section = sections[0] ?? formatCode;\n let workingValue = value;\n if (value < 0 && sections.length > 1) {\n section = sections[1] ?? section;\n workingValue = Math.abs(value);\n } else if (value === 0 && sections.length > 2 && sections[2]) {\n section = sections[2];\n workingValue = 0;\n }\n if (isDateFormatSection(section)) {\n return formatDateSection(workingValue, section);\n }\n return applyNumberFormatSection(workingValue, section);\n}\n\nfunction applyNumberFormatSection(value: number, section: string): string | null {\n if (!section) {\n return null;\n }\n if (/[eE][+-]?0+/.test(section)) {\n return null;\n }\n let sanitized = sanitizeFormatSection(section);\n const placeholders = [...sanitized.matchAll(/[0#?]/g)];\n if (!placeholders.length) {\n return null;\n }\n const firstIndex = placeholders[0].index ?? 0;\n const lastIndex = placeholders[placeholders.length - 1].index ?? firstIndex;\n const prefix = sanitized.slice(0, firstIndex);\n const suffix = sanitized.slice(lastIndex + 1);\n const core = sanitized.slice(firstIndex, lastIndex + 1);\n if (!core) {\n return null;\n }\n const hasPercent = section.includes('%');\n let workingValue = value;\n if (hasPercent) {\n workingValue *= 100;\n }\n const { useGrouping, minFraction, maxFraction } = extractNumericPattern(core);\n try {\n const formatter = new Intl.NumberFormat(undefined, {\n useGrouping,\n minimumFractionDigits: minFraction,\n maximumFractionDigits: maxFraction,\n });\n const formattedNumber = formatter.format(workingValue);\n return `${prefix}${formattedNumber}${suffix}`;\n } catch {\n return null;\n }\n}\n\nfunction sanitizeFormatSection(section: string): string {\n let sanitized = section;\n sanitized = sanitized.replace(/\\[\\$([^-\\]]+)(?:-[^\\]]+)?\\]/g, '$1');\n sanitized = sanitized.replace(/\\[[^\\]]+\\]/g, '');\n sanitized = sanitized.replace(/\"([^\"]*)\"/g, '$1');\n sanitized = sanitized.replace(/_./g, '');\n sanitized = sanitized.replace(/\\*./g, '');\n sanitized = sanitized.replace(/\\\\(.)/g, '$1');\n return sanitized;\n}\n\nfunction extractNumericPattern(core: string): {\n useGrouping: boolean;\n minFraction: number;\n maxFraction: number;\n} {\n const decimalPoint = core.indexOf('.');\n let integerPart = core;\n let fractionPart = '';\n if (decimalPoint >= 0) {\n integerPart = core.slice(0, decimalPoint);\n fractionPart = core.slice(decimalPoint + 1);\n }\n const useGrouping = integerPart.includes(',');\n const normalizedFraction = fractionPart.replace(/[^0#?]/g, '');\n const minFraction = (normalizedFraction.match(/0/g) ?? []).length;\n const maxFraction = normalizedFraction.length;\n return {\n useGrouping,\n minFraction,\n maxFraction: Math.max(minFraction, maxFraction),\n };\n}\n\nfunction isDateFormatSection(section: string): boolean {\n const stripped = stripLiterals(section).toLowerCase();\n if (!stripped) {\n return false;\n }\n if (stripped.includes('am/pm') || stripped.includes('a/p')) {\n return true;\n }\n if (/[yd]/.test(stripped)) {\n return true;\n }\n if (/[hs]/.test(stripped) && stripped.includes('m')) {\n return true;\n }\n return false;\n}\n\nfunction stripLiterals(section: string): string {\n let result = '';\n for (let i = 0; i < section.length; i += 1) {\n const char = section[i];\n if (char === '\"') {\n while (i + 1 < section.length && section[i + 1] !== '\"') {\n i += 1;\n }\n continue;\n }\n if (char === '\\\\') {\n i += 1;\n continue;\n }\n if (char === '[') {\n while (i + 1 < section.length && section[i + 1] !== ']') {\n i += 1;\n }\n continue;\n }\n if (char === '_') {\n i += 1;\n continue;\n }\n if (char === '*') {\n i += 1;\n continue;\n }\n result += char;\n }\n return result;\n}\n\nconst MONTH_NAMES = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n];\n\nconst MONTH_NAMES_SHORT = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\nconst DAY_NAMES = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];\nconst DAY_NAMES_SHORT = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];\n\nfunction formatDateSection(value: number, section: string): string | null {\n const date = excelSerialToDate(value);\n if (!date) {\n return null;\n }\n const lowerSection = section.toLowerCase();\n const hasAmPm = lowerSection.includes('am/pm') || lowerSection.includes('a/p');\n let result = '';\n let i = 0;\n while (i < section.length) {\n const char = section[i];\n if (char === '\"') {\n const end = section.indexOf('\"', i + 1);\n if (end === -1) {\n break;\n }\n result += section.slice(i + 1, end);\n i = end + 1;\n continue;\n }\n if (char === '\\\\') {\n if (i + 1 < section.length) {\n result += section[i + 1];\n i += 2;\n } else {\n i += 1;\n }\n continue;\n }\n if (char === '[') {\n const end = section.indexOf(']', i + 1);\n i = end === -1 ? section.length : end + 1;\n continue;\n }\n const token = matchDateToken(section, i);\n if (token) {\n result += applyDateToken(token, date, hasAmPm);\n i += token.length;\n continue;\n }\n const lower = section.slice(i).toLowerCase();\n if (lower.startsWith('am/pm')) {\n result += date.getHours() >= 12 ? 'PM' : 'AM';\n i += 5;\n continue;\n }\n if (lower.startsWith('a/p')) {\n result += date.getHours() >= 12 ? 'P' : 'A';\n i += 3;\n continue;\n }\n result += char;\n i += 1;\n }\n return result;\n}\n\nfunction matchDateToken(section: string, index: number): string | null {\n const candidates = [\n 'yyyy',\n 'yyy',\n 'yy',\n 'y',\n 'mmmm',\n 'mmm',\n 'mm',\n 'm',\n 'dddd',\n 'ddd',\n 'dd',\n 'd',\n 'hh',\n 'h',\n 'ss',\n 's',\n ];\n for (const token of candidates) {\n if (section.length - index < token.length) {\n continue;\n }\n const slice = section.slice(index, index + token.length);\n if (slice.toLowerCase() === token.toLowerCase()) {\n return slice;\n }\n }\n return null;\n}\n\nfunction applyDateToken(token: string, date: Date, hasAmPm: boolean): string {\n const lower = token.toLowerCase();\n switch (lower) {\n case 'yyyy':\n return String(date.getFullYear()).padStart(token.length, '0');\n case 'yyy':\n case 'yy':\n return String(date.getFullYear()).slice(-token.length).padStart(token.length, '0');\n case 'y':\n return String(date.getFullYear() % 10);\n case 'mmmm':\n return MONTH_NAMES[date.getMonth()];\n case 'mmm':\n return MONTH_NAMES_SHORT[date.getMonth()];\n case 'mm':\n case 'm': {\n const month = date.getMonth() + 1;\n return lower === 'mm' ? String(month).padStart(2, '0') : String(month);\n }\n case 'dddd':\n return DAY_NAMES[date.getDay()];\n case 'ddd':\n return DAY_NAMES_SHORT[date.getDay()];\n case 'dd':\n case 'd': {\n const day = date.getDate();\n return lower === 'dd' ? String(day).padStart(2, '0') : String(day);\n }\n case 'hh':\n case 'h': {\n let hours = date.getHours();\n if (hasAmPm) {\n hours = hours % 12;\n if (hours === 0) {\n hours = 12;\n }\n }\n const value = lower === 'hh' ? String(hours).padStart(2, '0') : String(hours);\n return value;\n }\n case 'ss':\n case 's': {\n const seconds = date.getSeconds();\n const value = lower === 'ss' ? String(seconds).padStart(2, '0') : String(seconds);\n return value;\n }\n default:\n return token;\n }\n}\n\nfunction excelSerialToDate(serial: number): Date | null {\n if (!Number.isFinite(serial)) {\n return null;\n }\n const millisecondsPerDay = 24 * 60 * 60 * 1000;\n const epoch = Date.UTC(1899, 11, 30);\n let wholeDays = Math.trunc(serial);\n let fractional = serial - wholeDays;\n if (serial < 0 && fractional !== 0) {\n wholeDays -= 1;\n fractional = serial - wholeDays;\n }\n if (wholeDays >= 60) {\n wholeDays -= 1;\n }\n const ms = epoch + wholeDays * millisecondsPerDay + Math.round(fractional * millisecondsPerDay);\n return new Date(ms);\n}\n","export function cellKey(row: number, column: number): string {\n return `${row}:${column}`;\n}\n\nexport function parseCellKey(key: string): { row: number; column: number } | null {\n const [rowStr, columnStr] = key.split(':');\n const row = Number(rowStr);\n const column = Number(columnStr);\n if (!Number.isFinite(row) || !Number.isFinite(column)) {\n return null;\n }\n return { row, column };\n}\n","import type { RangeRect } from './types';\n\n/** Builds a cumulative boundary array from a list of sizes. Result has length sizes.length + 1. */\nexport function buildBoundaries(sizes: number[]): number[] {\n const boundaries = [0];\n let acc = 0;\n for (let i = 0; i < sizes.length; i += 1) {\n acc += sizes[i];\n boundaries.push(acc);\n }\n return boundaries;\n}\n\n/** Returns the index (0-based) of the segment containing `offset`, or null if out of range. */\nexport function getIndexAtOffset(offset: number, boundaries: number[]): number | null {\n for (let i = 0; i < boundaries.length - 1; i += 1) {\n if (offset >= boundaries[i] && offset < boundaries[i + 1]) {\n return i;\n }\n }\n return null;\n}\n\n/**\n * Binary-searches for the segment index that contains `offset`.\n * `count` is the number of segments (boundaries.length - 1).\n * Clamps to [0, count - 1].\n */\nexport function findIndexByOffset(offset: number, count: number, boundaries: number[]): number {\n if (count === 0) {\n return 0;\n }\n const total = boundaries[boundaries.length - 1] ?? 0;\n const clamped = Math.min(Math.max(0, offset), Math.max(0, total - 1e-3));\n let low = 0;\n let high = count - 1;\n while (low <= high) {\n const mid = (low + high) >> 1;\n if (clamped < boundaries[mid]) {\n high = mid - 1;\n } else if (clamped >= boundaries[mid + 1]) {\n low = mid + 1;\n } else {\n return mid;\n }\n }\n return Math.max(0, Math.min(count - 1, low));\n}\n\n/** Computes x/y/width/height of a cell range in canvas coordinates. */\nexport function computeRangeRect(\n topRow: number,\n leftColumn: number,\n bottomRow: number,\n rightColumn: number,\n columnBoundaries: readonly number[],\n rowBoundaries: readonly number[],\n headerColumnWidth: number,\n headerRowHeight: number,\n scrollX: number,\n scrollY: number,\n): RangeRect {\n const x = headerColumnWidth - scrollX + columnBoundaries[leftColumn];\n const y = headerRowHeight - scrollY + rowBoundaries[topRow];\n const width = columnBoundaries[rightColumn + 1] - columnBoundaries[leftColumn];\n const height = rowBoundaries[bottomRow + 1] - rowBoundaries[topRow];\n return { x, y, width, height };\n}\n","export type BorderSide = 'top' | 'right' | 'bottom' | 'left';\nexport type RangeBorderSide = BorderSide | 'outside';\n\nexport type BorderLineStyle = 'solid' | 'dashed' | 'dotted';\n\nexport interface BorderLineOptions {\n style: BorderLineStyle;\n color?: string;\n width?: number;\n}\n\nexport interface CellBorderDefinition {\n top?: BorderLine;\n right?: BorderLine;\n bottom?: BorderLine;\n left?: BorderLine;\n}\n\nexport interface BorderLine {\n style: BorderLineStyle;\n color: string;\n width: number;\n appliedAt?: number;\n}\n\nexport const ALL_BORDER_SIDES: BorderSide[] = ['top', 'right', 'bottom', 'left'];\nexport const DEFAULT_BORDER_COLOR = '#1f2933';\nexport const DEFAULT_BORDER_WIDTH = 1;\n","import type {\n BorderSide,\n RangeBorderSide,\n CellBorderDefinition,\n BorderLine,\n BorderLineOptions,\n} from './types';\nimport { ALL_BORDER_SIDES, DEFAULT_BORDER_COLOR, DEFAULT_BORDER_WIDTH } from './types';\nimport { cellKey, parseCellKey } from '../worksheet/cellKey';\n\nexport class BorderManager {\n private readonly data: Map<string, CellBorderDefinition> = new Map();\n private sequence = 0;\n\n constructor(\n private readonly getRows: () => number,\n private readonly getColumns: () => number,\n ) {}\n\n get size(): number {\n return this.data.size;\n }\n\n entries(): Iterable<[string, CellBorderDefinition]> {\n return this.data;\n }\n\n getCell(row: number, column: number): CellBorderDefinition | undefined {\n return this.data.get(cellKey(row, column));\n }\n\n applyAll(borders: Map<string, CellBorderDefinition>): void {\n this.data.clear();\n this.sequence = 0;\n for (const [key, border] of borders) {\n const cloned: CellBorderDefinition = {};\n if (border.top) {\n cloned.top = { ...border.top, appliedAt: this.nextSequence() };\n }\n if (border.right) {\n cloned.right = { ...border.right, appliedAt: this.nextSequence() };\n }\n if (border.bottom) {\n cloned.bottom = { ...border.bottom, appliedAt: this.nextSequence() };\n }\n if (border.left) {\n cloned.left = { ...border.left, appliedAt: this.nextSequence() };\n }\n this.data.set(key, cloned);\n }\n }\n\n setRange(\n topRow: number,\n leftColumn: number,\n bottomRow: number,\n rightColumn: number,\n border: BorderLineOptions,\n sides?: RangeBorderSide[],\n ): void {\n const line = this.normalizeLine(border);\n const normalizedSides = this.normalizeSides(sides ?? ALL_BORDER_SIDES);\n if (!normalizedSides.length) {\n return;\n }\n\n const bounds = this.normalizeBounds(topRow, leftColumn, bottomRow, rightColumn);\n if (!bounds) {\n return;\n }\n\n if (normalizedSides.includes('top')) {\n for (let col = bounds.left; col <= bounds.right; col += 1) {\n this.assignBorder(bounds.top, col, 'top', line);\n }\n }\n if (normalizedSides.includes('bottom')) {\n for (let col = bounds.left; col <= bounds.right; col += 1) {\n this.assignBorder(bounds.bottom, col, 'bottom', line);\n }\n }\n if (normalizedSides.includes('left')) {\n for (let row = bounds.top; row <= bounds.bottom; row += 1) {\n this.assignBorder(row, bounds.left, 'left', line);\n }\n }\n if (normalizedSides.includes('right')) {\n for (let row = bounds.top; row <= bounds.bottom; row += 1) {\n this.assignBorder(row, bounds.right, 'right', line);\n }\n }\n }\n\n pruneOutsideGrid(): void {\n for (const key of Array.from(this.data.keys())) {\n const pos = parseCellKey(key);\n if (!pos || !this.isCellInBounds(pos.row, pos.column)) {\n this.data.delete(key);\n }\n }\n }\n\n private assignBorder(row: number, column: number, side: BorderSide, line: BorderLine): void {\n if (line.width <= 0) {\n this.removeBorderSide(row, column, side);\n this.removeAdjacentBorder(row, column, side);\n return;\n }\n const border = this.getOrCreate(row, column);\n border[side] = { ...line, appliedAt: this.nextSequence() };\n }\n\n private removeBorderSide(row: number, column: number, side: BorderSide): void {\n if (!this.isCellInBounds(row, column)) {\n return;\n }\n const key = cellKey(row, column);\n const existing = this.data.get(key);\n if (!existing || existing[side] === undefined) {\n return;\n }\n delete existing[side];\n if (!existing.top && !existing.right && !existing.bottom && !existing.left) {\n this.data.delete(key);\n }\n }\n\n private removeAdjacentBorder(row: number, column: number, side: BorderSide): void {\n const adjacent = this.getAdjacentCell(row, column, side);\n if (!adjacent) {\n return;\n }\n this.removeBorderSide(adjacent.row, adjacent.column, this.oppositeSide(side));\n }\n\n private getAdjacentCell(\n row: number,\n column: number,\n side: BorderSide,\n ): { row: number; column: number } | null {\n const rows = this.getRows();\n const columns = this.getColumns();\n switch (side) {\n case 'top':\n return row > 0 ? { row: row - 1, column } : null;\n case 'bottom':\n return row < rows - 1 ? { row: row + 1, column } : null;\n case 'left':\n return column > 0 ? { row, column: column - 1 } : null;\n case 'right':\n return column < columns - 1 ? { row, column: column + 1 } : null;\n default:\n return null;\n }\n }\n\n private oppositeSide(side: BorderSide): BorderSide {\n switch (side) {\n case 'top':\n return 'bottom';\n case 'bottom':\n return 'top';\n case 'left':\n return 'right';\n case 'right':\n default:\n return 'left';\n }\n }\n\n private getOrCreate(row: number, column: number): CellBorderDefinition {\n const key = cellKey(row, column);\n const existing = this.data.get(key);\n if (existing) {\n return existing;\n }\n const created: CellBorderDefinition = {};\n this.data.set(key, created);\n return created;\n }\n\n private normalizeLine(border: BorderLineOptions): BorderLine {\n return {\n style: border.style,\n color: border.color ?? DEFAULT_BORDER_COLOR,\n width: border.width ?? DEFAULT_BORDER_WIDTH,\n };\n }\n\n private normalizeSides(sides: RangeBorderSide[]): BorderSide[] {\n if (!sides.length) {\n return [...ALL_BORDER_SIDES];\n }\n const resolved = new Set<BorderSide>();\n for (const side of sides) {\n if (side === 'outside') {\n for (const actual of ALL_BORDER_SIDES) {\n resolved.add(actual);\n }\n continue;\n }\n resolved.add(side);\n }\n return Array.from(resolved);\n }\n\n private normalizeBounds(\n topRow: number,\n leftColumn: number,\n bottomRow: number,\n rightColumn: number,\n ): { top: number; left: number; bottom: number; right: number } | null {\n const rows = this.getRows();\n const columns = this.getColumns();\n if (rows === 0 || columns === 0) {\n return null;\n }\n const clampRow = (r: number) => Math.min(Math.max(Math.floor(r), 0), rows - 1);\n const clampCol = (c: number) => Math.min(Math.max(Math.floor(c), 0), columns - 1);\n const r1 = clampRow(topRow);\n const r2 = clampRow(bottomRow);\n const c1 = clampCol(leftColumn);\n const c2 = clampCol(rightColumn);\n return { top: Math.min(r1, r2), bottom: Math.max(r1, r2), left: Math.min(c1, c2), right: Math.max(c1, c2) };\n }\n\n private isCellInBounds(row: number, column: number): boolean {\n return row >= 0 && row < this.getRows() && column >= 0 && column < this.getColumns();\n }\n\n private nextSequence(): number {\n this.sequence += 1;\n return this.sequence;\n }\n}\n","import type { MergedCellRange } from '../cell/types';\nimport { cellKey, parseCellKey } from '../worksheet/cellKey';\n\nexport class MergeManager {\n /** Maps every cell key in a merged range to that range's descriptor. */\n private readonly cells: Map<string, MergedCellRange> = new Map();\n\n /** Maps only anchor (top-left) cell keys to their merged range descriptor. */\n private readonly anchors: Map<string, MergedCellRange> = new Map();\n\n constructor(\n private readonly getRows: () => number,\n private readonly getColumns: () => number,\n ) {}\n\n get anchorCount(): number {\n return this.anchors.size;\n }\n\n iterateAnchors(): IterableIterator<MergedCellRange> {\n return this.anchors.values();\n }\n\n get(row: number, column: number): MergedCellRange | null {\n return this.cells.get(cellKey(row, column)) ?? null;\n }\n\n isAnchor(row: number, column: number): boolean {\n return this.anchors.has(cellKey(row, column));\n }\n\n getBounds(row: number, column: number): {\n topRow: number;\n bottomRow: number;\n leftColumn: number;\n rightColumn: number;\n } {\n const merged = this.get(row, column);\n if (merged) {\n return { ...merged };\n }\n const rows = this.getRows();\n const columns = this.getColumns();\n if (rows === 0 || columns === 0) {\n return { topRow: row, bottomRow: row, leftColumn: column, rightColumn: column };\n }\n const clampedRow = Math.min(Math.max(Math.floor(row), 0), rows - 1);\n const clampedCol = Math.min(Math.max(Math.floor(column), 0), columns - 1);\n return {\n topRow: clampedRow,\n bottomRow: clampedRow,\n leftColumn: clampedCol,\n rightColumn: clampedCol,\n };\n }\n\n setAll(ranges: Iterable<MergedCellRange>): void {\n this.cells.clear();\n this.anchors.clear();\n for (const range of ranges) {\n const normalized = this.normalizeRange(range);\n if (normalized) {\n this.applyRange(normalized);\n }\n }\n }\n\n add(topRow: number, leftColumn: number, bottomRow: number, rightColumn: number): void {\n const normalized = this.normalizeRange({ topRow, leftColumn, bottomRow, rightColumn });\n if (!normalized) {\n return;\n }\n this.removeOverlapping(normalized);\n this.applyRange(normalized);\n }\n\n remove(topRow: number, leftColumn: number, bottomRow: number, rightColumn: number): boolean {\n const bounds = this.normalizeBounds(topRow, leftColumn, bottomRow, rightColumn);\n if (!bounds) {\n return false;\n }\n return this.removeOverlapping({\n topRow: bounds.top,\n bottomRow: bounds.bottom,\n leftColumn: bounds.left,\n rightColumn: bounds.right,\n });\n }\n\n clear(): boolean {\n if (this.cells.size === 0 && this.anchors.size === 0) {\n return false;\n }\n this.cells.clear();\n this.anchors.clear();\n return true;\n }\n\n expandSelection(bounds: {\n top: number;\n bottom: number;\n left: number;\n right: number;\n }): { top: number; bottom: number; left: number; right: number } {\n if (!this.anchors.size) {\n return { ...bounds };\n }\n let expanded = { ...bounds };\n let changed = false;\n do {\n changed = false;\n const selectionRange: MergedCellRange = {\n topRow: expanded.top,\n bottomRow: expanded.bottom,\n leftColumn: expanded.left,\n rightColumn: expanded.right,\n };\n for (const merged of this.anchors.values()) {\n if (!this.rangesOverlap(merged, selectionRange)) {\n continue;\n }\n const nextTop = Math.min(expanded.top, merged.topRow);\n const nextBottom = Math.max(expanded.bottom, merged.bottomRow);\n const nextLeft = Math.min(expanded.left, merged.leftColumn);\n const nextRight = Math.max(expanded.right, merged.rightColumn);\n if (\n nextTop !== expanded.top ||\n nextBottom !== expanded.bottom ||\n nextLeft !== expanded.left ||\n nextRight !== expanded.right\n ) {\n expanded = { top: nextTop, bottom: nextBottom, left: nextLeft, right: nextRight };\n changed = true;\n }\n }\n } while (changed);\n return expanded;\n }\n\n getMergedLineGaps(): {\n horizontal: Map<number, Array<{ startColumnBoundary: number; endColumnBoundary: number }>>;\n vertical: Map<number, Array<{ startRowBoundary: number; endRowBoundary: number }>>;\n } {\n const horizontal = new Map<\n number,\n Array<{ startColumnBoundary: number; endColumnBoundary: number }>\n >();\n const vertical = new Map<\n number,\n Array<{ startRowBoundary: number; endRowBoundary: number }>\n >();\n\n if (!this.anchors.size) {\n return { horizontal, vertical };\n }\n\n for (const range of this.anchors.values()) {\n if (range.bottomRow > range.topRow) {\n for (let row = range.topRow + 1; row <= range.bottomRow; row += 1) {\n let list = horizontal.get(row);\n if (!list) {\n list = [];\n horizontal.set(row, list);\n }\n list.push({\n startColumnBoundary: range.leftColumn,\n endColumnBoundary: range.rightColumn + 1,\n });\n }\n }\n if (range.rightColumn > range.leftColumn) {\n for (let column = range.leftColumn + 1; column <= range.rightColumn; column += 1) {\n let list = vertical.get(column);\n if (!list) {\n list = [];\n vertical.set(column, list);\n }\n list.push({\n startRowBoundary: range.topRow,\n endRowBoundary: range.bottomRow + 1,\n });\n }\n }\n }\n\n return { horizontal, vertical };\n }\n\n pruneOutsideGrid(): void {\n if (!this.anchors.size) {\n return;\n }\n const rows = this.getRows();\n const columns = this.getColumns();\n const toRemove: MergedCellRange[] = [];\n for (const range of this.anchors.values()) {\n if (\n range.topRow < 0 ||\n range.leftColumn < 0 ||\n range.bottomRow >= rows ||\n range.rightColumn >= columns\n ) {\n toRemove.push(range);\n }\n }\n for (const range of toRemove) {\n this.removeRange(range);\n }\n }\n\n allAnchors(): MergedCellRange[] {\n return Array.from(this.anchors.values());\n }\n\n private applyRange(range: MergedCellRange): void {\n const stored: MergedCellRange = { ...range };\n this.anchors.set(cellKey(stored.topRow, stored.leftColumn), stored);\n for (let r = stored.topRow; r <= stored.bottomRow; r += 1) {\n for (let c = stored.leftColumn; c <= stored.rightColumn; c += 1) {\n this.cells.set(cellKey(r, c), stored);\n }\n }\n }\n\n private removeRange(range: MergedCellRange): void {\n this.anchors.delete(cellKey(range.topRow, range.leftColumn));\n for (let r = range.topRow; r <= range.bottomRow; r += 1) {\n for (let c = range.leftColumn; c <= range.rightColumn; c += 1) {\n this.cells.delete(cellKey(r, c));\n }\n }\n }\n\n private removeOverlapping(range: MergedCellRange): boolean {\n const toRemove: MergedCellRange[] = [];\n for (const existing of this.anchors.values()) {\n if (this.rangesOverlap(existing, range)) {\n toRemove.push(existing);\n }\n }\n if (!toRemove.length) {\n return false;\n }\n for (const merged of toRemove) {\n this.removeRange(merged);\n }\n return true;\n }\n\n private rangesOverlap(a: MergedCellRange, b: MergedCellRange): boolean {\n return !(\n a.bottomRow < b.topRow ||\n a.topRow > b.bottomRow ||\n a.rightColumn < b.leftColumn ||\n a.leftColumn > b.rightColumn\n );\n }\n\n private normalizeRange(range: MergedCellRange): MergedCellRange | null {\n const bounds = this.normalizeBounds(\n range.topRow,\n range.leftColumn,\n range.bottomRow,\n range.rightColumn,\n );\n if (!bounds) {\n return null;\n }\n if (bounds.top === bounds.bottom && bounds.left === bounds.right) {\n return null;\n }\n return {\n topRow: bounds.top,\n bottomRow: bounds.bottom,\n leftColumn: bounds.left,\n rightColumn: bounds.right,\n };\n }\n\n private normalizeBounds(\n topRow: number,\n leftColumn: number,\n bottomRow: number,\n rightColumn: number,\n ): { top: number; left: number; bottom: number; right: number } | null {\n const rows = this.getRows();\n const columns = this.getColumns();\n if (rows === 0 || columns === 0) {\n return null;\n }\n const clampRow = (r: number) => Math.min(Math.max(Math.floor(r), 0), rows - 1);\n const clampCol = (c: number) => Math.min(Math.max(Math.floor(c), 0), columns - 1);\n const r1 = clampRow(topRow);\n const r2 = clampRow(bottomRow);\n const c1 = clampCol(leftColumn);\n const c2 = clampCol(rightColumn);\n return { top: Math.min(r1, r2), bottom: Math.max(r1, r2), left: Math.min(c1, c2), right: Math.max(c1, c2) };\n }\n}\n\n/** Prunes map entries whose keys are not valid cell positions within the given grid bounds. */\nexport function pruneMapOutsideGrid(\n map: Map<string, unknown>,\n rows: number,\n columns: number,\n): void {\n for (const key of Array.from(map.keys())) {\n const pos = parseCellKey(key);\n if (!pos || pos.row < 0 || pos.row >= rows || pos.column < 0 || pos.column >= columns) {\n map.delete(key);\n }\n }\n}\n","import {\n DEFAULT_COLUMNS,\n DEFAULT_ROWS,\n DEFAULT_COLUMN_WIDTH,\n DEFAULT_ROW_HEIGHT,\n HEADER_COLUMN_WIDTH,\n HEADER_ROW_HEIGHT,\n} from './gridDefaults';\nimport { SelectionRange } from '../cell/selectionRange';\nimport { FormulaEngine } from '../formula/formulaEngine';\nimport type { RangeRect, HitTestResult } from './types';\nimport {\n DEFAULT_CELL_STYLE,\n type CellStyle,\n type TextAlign,\n type TextWrapMode,\n type VerticalAlign,\n} from '../style/cellStyle';\nimport { formatNumberWithFormat } from '../style/numberFormat';\nimport type { CellInputValue, MergedCellRange } from '../cell/types';\nimport type { BorderLineOptions, RangeBorderSide, CellBorderDefinition } from '../border/types';\nimport type { RichTextRun } from '../../types/richText';\nimport { cellKey, parseCellKey } from './cellKey';\nimport { buildBoundaries, getIndexAtOffset, findIndexByOffset, computeRangeRect } from './gridGeometry';\nimport { BorderManager } from '../border/borderManager';\nimport { MergeManager, pruneMapOutsideGrid } from '../merge/mergeManager';\n\nexport const MIN_COLUMN_WIDTH = 24;\nexport const MIN_ROW_HEIGHT = 18;\nexport const HEADER_RESIZE_TOLERANCE = 4;\nexport const CELL_TEXT_PADDING = 4;\n\ntype SelectionChangeListener = (cell: { row: number; column: number } | null) => void;\ntype CellValueChangeListener = (payload: { row: number; column: number; value: string }) => void;\ntype ViewportSizeListener = (size: { width: number; height: number }) => void;\ntype ScrollChangeListener = (offset: { x: number; y: number }) => void;\n\nexport type WorksheetExportCell = {\n row: number;\n column: number;\n value?: string;\n style?: CellStyle;\n};\n\nexport interface WorksheetExportSnapshot {\n cells: WorksheetExportCell[];\n merges: MergedCellRange[];\n columnWidths: number[];\n rowHeights: number[];\n rows: number;\n columns: number;\n}\n\nexport class Worksheet {\n protected pixelRatio = 1;\n\n private readonly pointToPixelRatio = 96 / 72;\n\n protected viewportWidth = 0;\n\n protected viewportHeight = 0;\n\n public rows: number;\n\n public columns: number;\n\n public readonly columnWidths: number[];\n\n private readonly columnCustomWidths: boolean[];\n\n public readonly rowHeights: number[];\n\n private readonly rowCustomHeights: boolean[];\n\n private columnBoundaries: number[];\n\n private rowBoundaries: number[];\n\n public headerColumnWidth: number;\n\n public headerRowHeight: number;\n\n public readonly selection: SelectionRange;\n\n private readonly cellInputs: Map<string, string>;\n\n private readonly cellRichText: Map<string, RichTextRun[]>;\n\n private readonly cellDisplayOverrides: Map<string, string>;\n\n private readonly cellNumberFormats: Map<string, string>;\n\n private readonly cellFormatting: Map<string, Partial<CellStyle>>;\n\n protected readonly borders: BorderManager;\n\n protected readonly merges: MergeManager;\n\n private readonly selectionChangeListeners: Set<SelectionChangeListener> = new Set();\n\n private readonly cellValueListeners: Set<CellValueChangeListener> = new Set();\n\n private readonly viewportSizeListeners: Set<ViewportSizeListener> = new Set();\n\n private readonly scrollListeners: Set<ScrollChangeListener> = new Set();\n\n private readonly structureListeners: Set<() => void> = new Set();\n\n private readonly defaultStyle: CellStyle = { ...DEFAULT_CELL_STYLE };\n\n private _showGridLines = true;\n\n protected resizeGuide: { type: 'column' | 'row'; position: number } | null = null;\n\n private readonly formulaEngine: FormulaEngine;\n\n protected scrollX = 0;\n\n protected scrollY = 0;\n\n private contentWidth = 0;\n\n private contentHeight = 0;\n\n constructor() {\n this.rows = DEFAULT_ROWS;\n this.columns = DEFAULT_COLUMNS;\n this.columnWidths = new Array(this.columns).fill(DEFAULT_COLUMN_WIDTH);\n this.columnCustomWidths = new Array(this.columns).fill(false);\n this.rowHeights = new Array(this.rows).fill(DEFAULT_ROW_HEIGHT);\n this.rowCustomHeights = new Array(this.rows).fill(false);\n this.columnBoundaries = [];\n this.rowBoundaries = [];\n\n this.headerColumnWidth = HEADER_COLUMN_WIDTH;\n this.headerRowHeight = HEADER_ROW_HEIGHT;\n\n this.selection = new SelectionRange(this);\n\n this.cellInputs = new Map();\n this.cellRichText = new Map();\n this.cellDisplayOverrides = new Map();\n this.cellNumberFormats = new Map();\n this.cellFormatting = new Map();\n\n this.borders = new BorderManager(() => this.rows, () => this.columns);\n this.merges = new MergeManager(() => this.rows, () => this.columns);\n\n this.formulaEngine = new FormulaEngine(this);\n }\n\n public render(): void {\n // Override in rendering subclasses.\n }\n\n // ---------------------------------------------------------------------------\n // Scroll & viewport\n // ---------------------------------------------------------------------------\n\n getScrollContentSize(): { width: number; height: number } {\n this.ensureBoundaries();\n return {\n width: this.headerColumnWidth + this.contentWidth,\n height: this.headerRowHeight + this.contentHeight,\n };\n }\n\n getScrollOffset(): { x: number; y: number } {\n return { x: this.scrollX, y: this.scrollY };\n }\n\n setScrollOffset(x: number, y: number): void {\n const clamped = this.clampScrollOffset(x, y);\n if (clamped.x === this.scrollX && clamped.y === this.scrollY) {\n return;\n }\n this.scrollX = clamped.x;\n this.scrollY = clamped.y;\n this.emitScrollChange();\n this.render();\n }\n\n onViewportSizeChange(listener: ViewportSizeListener): () => void {\n this.viewportSizeListeners.add(listener);\n return () => {\n this.viewportSizeListeners.delete(listener);\n };\n }\n\n onScrollChange(listener: ScrollChangeListener): () => void {\n this.scrollListeners.add(listener);\n return () => {\n this.scrollListeners.delete(listener);\n };\n }\n\n onStructureChange(listener: () => void): () => void {\n this.structureListeners.add(listener);\n return () => {\n this.structureListeners.delete(listener);\n };\n }\n\n // ---------------------------------------------------------------------------\n // Hit testing & geometry\n // ---------------------------------------------------------------------------\n\n getCellFromPoint(x: number, y: number): { row: number; column: number } | null {\n const hit = this.hitTest(x, y);\n if (hit && hit.type === 'cell') {\n return { row: hit.row, column: hit.column };\n }\n return null;\n }\n\n hitTest(x: number, y: number): HitTestResult | null {\n if (x < 0 || y < 0) {\n return null;\n }\n\n this.ensureBoundaries();\n\n const bodyLeft = this.headerColumnWidth;\n const bodyTop = this.headerRowHeight;\n const bodyRight = bodyLeft + this.getBodyViewportWidth();\n const bodyBottom = bodyTop + this.getBodyViewportHeight();\n\n const withinBodyX = x >= bodyLeft && x < bodyRight;\n const withinBodyY = y >= bodyTop && y < bodyBottom;\n\n if (withinBodyX && withinBodyY) {\n const bodyX = x - bodyLeft + this.scrollX;\n const bodyY = y - bodyTop + this.scrollY;\n const column = getIndexAtOffset(bodyX, this.columnBoundaries);\n const row = getIndexAtOffset(bodyY, this.rowBoundaries);\n if (column !== null && row !== null) {\n const merged = this.getMergedRange(row, column);\n if (merged) {\n return { type: 'cell', row: merged.topRow, column: merged.leftColumn };\n }\n return { type: 'cell', row, column };\n }\n return null;\n }\n\n const withinColumnHeaders =\n y >= 0 && y < this.headerRowHeight && x >= bodyLeft && x < bodyRight;\n if (withinColumnHeaders) {\n const bodyX = x - bodyLeft + this.scrollX;\n const column = getIndexAtOffset(bodyX, this.columnBoundaries);\n if (column !== null) {\n return { type: 'column-header', column };\n }\n }\n\n const withinRowHeaders =\n x >= 0 && x < this.headerColumnWidth && y >= bodyTop && y < bodyBottom;\n if (withinRowHeaders) {\n const bodyY = y - bodyTop + this.scrollY;\n const row = getIndexAtOffset(bodyY, this.rowBoundaries);\n if (row !== null) {\n return { type: 'row-header', row };\n }\n }\n\n const withinCorner =\n x >= 0 && x < this.headerColumnWidth && y >= 0 && y < this.headerRowHeight;\n if (withinCorner) {\n return { type: 'corner' };\n }\n\n return null;\n }\n\n updateBoundaries(): void {\n const previousWidth = this.contentWidth;\n const previousHeight = this.contentHeight;\n this.columnBoundaries = buildBoundaries(this.columnWidths);\n this.rowBoundaries = buildBoundaries(this.rowHeights);\n this.contentWidth =\n this.columnBoundaries.length > 0\n ? this.columnBoundaries[this.columnBoundaries.length - 1]\n : 0;\n this.contentHeight =\n this.rowBoundaries.length > 0 ? this.rowBoundaries[this.rowBoundaries.length - 1] : 0;\n if (this.contentWidth !== previousWidth || this.contentHeight !== previousHeight) {\n this.emitViewportSizeChange();\n this.clampScrollOffsetInPlace();\n }\n }\n\n ensureBoundaries(): void {\n if (!this.columnBoundaries.length || !this.rowBoundaries.length) {\n this.updateBoundaries();\n }\n }\n\n protected getColumnBoundaries(): readonly number[] {\n return this.columnBoundaries;\n }\n\n protected getRowBoundaries(): readonly number[] {\n return this.rowBoundaries;\n }\n\n protected getColumnWidths(): readonly number[] {\n return this.columnWidths;\n }\n\n protected getRowHeights(): readonly number[] {\n return this.rowHeights;\n }\n\n protected getCellBorders(): Iterable<[string, CellBorderDefinition]> {\n return this.borders.entries();\n }\n\n public getBodyViewportWidth(): number {\n return Math.max(0, this.viewportWidth - this.headerColumnWidth);\n }\n\n public getBodyViewportHeight(): number {\n return Math.max(0, this.viewportHeight - this.headerRowHeight);\n }\n\n private clampScrollOffset(x: number, y: number): { x: number; y: number } {\n const maxX = Math.max(0, this.contentWidth - this.getBodyViewportWidth());\n const maxY = Math.max(0, this.contentHeight - this.getBodyViewportHeight());\n return {\n x: Math.min(Math.max(0, x), maxX),\n y: Math.min(Math.max(0, y), maxY),\n };\n }\n\n protected clampScrollOffsetInPlace(): void {\n const clamped = this.clampScrollOffset(this.scrollX, this.scrollY);\n if (clamped.x !== this.scrollX || clamped.y !== this.scrollY) {\n this.scrollX = clamped.x;\n this.scrollY = clamped.y;\n this.emitScrollChange();\n }\n }\n\n getRangeRect(topRow: number, leftColumn: number, bottomRow: number, rightColumn: number): RangeRect {\n this.ensureBoundaries();\n return computeRangeRect(\n topRow,\n leftColumn,\n bottomRow,\n rightColumn,\n this.columnBoundaries,\n this.rowBoundaries,\n this.headerColumnWidth,\n this.headerRowHeight,\n this.scrollX,\n this.scrollY,\n );\n }\n\n getCellRect(row: number, column: number): RangeRect {\n const bounds = this.getCellMergeBounds(row, column);\n return this.getRangeRect(bounds.topRow, bounds.leftColumn, bounds.bottomRow, bounds.rightColumn);\n }\n\n public getVisibleRowRange(padding = 1): { start: number; end: number } {\n if (this.rows === 0) {\n return { start: 0, end: -1 };\n }\n const bodyHeight = this.getBodyViewportHeight();\n const start = findIndexByOffset(this.scrollY, this.rows, this.rowBoundaries);\n const end = findIndexByOffset(this.scrollY + bodyHeight, this.rows, this.rowBoundaries);\n return {\n start: Math.max(0, start - padding),\n end: Math.min(this.rows - 1, end + padding),\n };\n }\n\n public getVisibleColumnRange(padding = 1): { start: number; end: number } {\n if (this.columns === 0) {\n return { start: 0, end: -1 };\n }\n const bodyWidth = this.getBodyViewportWidth();\n const start = findIndexByOffset(this.scrollX, this.columns, this.columnBoundaries);\n const end = findIndexByOffset(this.scrollX + bodyWidth, this.columns, this.columnBoundaries);\n return {\n start: Math.max(0, start - padding),\n end: Math.min(this.columns - 1, end + padding),\n };\n }\n\n public getVisibleRowIndices(): number[] {\n const padded = this.getVisibleRowRange();\n const viewportRows = this.getVisibleRowRange(0);\n const viewportCols = this.getVisibleColumnRange(0);\n const rows = new Set<number>();\n for (let r = padded.start; r <= padded.end; r += 1) {\n rows.add(r);\n }\n if (this.merges.anchorCount > 0) {\n for (const merged of this.merges.iterateAnchors()) {\n const overlapsViewport =\n merged.bottomRow >= viewportRows.start &&\n merged.topRow <= viewportRows.end &&\n merged.rightColumn >= viewportCols.start &&\n merged.leftColumn <= viewportCols.end;\n const anchorOutsidePadded = merged.topRow < padded.start || merged.topRow > padded.end;\n if (overlapsViewport && anchorOutsidePadded) {\n rows.add(merged.topRow);\n }\n }\n }\n return Array.from(rows).sort((a, b) => a - b);\n }\n\n public getVisibleColumnIndices(): number[] {\n const padded = this.getVisibleColumnRange();\n const viewportCols = this.getVisibleColumnRange(0);\n const viewportRows = this.getVisibleRowRange(0);\n const columns = new Set<number>();\n for (let c = padded.start; c <= padded.end; c += 1) {\n columns.add(c);\n }\n if (this.merges.anchorCount > 0) {\n for (const merged of this.merges.iterateAnchors()) {\n const overlapsViewport =\n merged.bottomRow >= viewportRows.start &&\n merged.topRow <= viewportRows.end &&\n merged.rightColumn >= viewportCols.start &&\n merged.leftColumn <= viewportCols.end;\n const anchorOutsidePadded =\n merged.leftColumn < padded.start || merged.leftColumn > padded.end;\n if (overlapsViewport && anchorOutsidePadded) {\n columns.add(merged.leftColumn);\n }\n }\n }\n return Array.from(columns).sort((a, b) => a - b);\n }\n\n getColumnResizeHandle(x: number, y: number, tolerance = HEADER_RESIZE_TOLERANCE): number | null {\n if (y < 0 || y > this.headerRowHeight) {\n return null;\n }\n if (x < this.headerColumnWidth) {\n return null;\n }\n this.ensureBoundaries();\n for (let i = 1; i < this.columnBoundaries.length; i += 1) {\n const boundaryX = this.headerColumnWidth + this.columnBoundaries[i];\n if (Math.abs(boundaryX - x) <= tolerance) {\n return Math.min(i - 1, this.columns - 1);\n }\n }\n return null;\n }\n\n getRowResizeHandle(x: number, y: number, tolerance = HEADER_RESIZE_TOLERANCE): number | null {\n if (x < 0 || x > this.headerColumnWidth) {\n return null;\n }\n if (y < this.headerRowHeight) {\n return null;\n }\n this.ensureBoundaries();\n for (let i = 1; i < this.rowBoundaries.length; i += 1) {\n const boundaryY = this.headerRowHeight + this.rowBoundaries[i];\n if (Math.abs(boundaryY - y) <= tolerance) {\n return Math.min(i - 1, this.rows - 1);\n }\n }\n return null;\n }\n\n getColumnStart(column: number): number {\n this.ensureBoundaries();\n const clamped = Math.max(0, Math.min(column, this.columnBoundaries.length - 1));\n return this.headerColumnWidth + this.columnBoundaries[clamped];\n }\n\n getRowStart(row: number): number {\n this.ensureBoundaries();\n const clamped = Math.max(0, Math.min(row, this.rowBoundaries.length - 1));\n return this.headerRowHeight + this.rowBoundaries[clamped];\n }\n\n // ---------------------------------------------------------------------------\n // Cell data\n // ---------------------------------------------------------------------------\n\n getCellInput(row: number, column: number): string | undefined {\n return this.cellInputs.get(cellKey(row, column));\n }\n\n protected getRichTextRuns(row: number, column: number): RichTextRun[] | undefined {\n return this.cellRichText.get(cellKey(row, column));\n }\n\n setCellInput(row: number, column: number, value: string): void {\n const merged = this.getMergedRange(row, column);\n const targetRow = merged ? merged.topRow : row;\n const targetColumn = merged ? merged.leftColumn : column;\n const key = cellKey(targetRow, targetColumn);\n this.cellRichText.delete(key);\n if (value.length === 0) {\n this.cellInputs.delete(key);\n } else {\n this.cellInputs.set(key, value);\n }\n this.updateCellDisplayValue(targetRow, targetColumn);\n this.render();\n this.emitCellValueChange(targetRow, targetColumn);\n }\n\n loadCells(cells: Iterable<CellInputValue>): void {\n this.cellInputs.clear();\n this.cellRichText.clear();\n this.cellDisplayOverrides.clear();\n this.cellNumberFormats.clear();\n this.cellFormatting.clear();\n const changedCells: CellInputValue[] = [];\n for (const cell of cells) {\n if (!this.isCellInBounds(cell.row, cell.column)) {\n continue;\n }\n const normalized = cell.value ?? '';\n const hasValue = normalized.length > 0;\n const hasFormatting =\n !!cell.style || !!cell.displayValue || !!cell.richText?.length || !!cell.numberFormat;\n if (!hasValue && !hasFormatting) {\n continue;\n }\n const key = cellKey(cell.row, cell.column);\n if (hasValue) {\n this.cellInputs.set(key, normalized);\n }\n if (cell.richText && cell.richText.length > 0) {\n this.cellRichText.set(\n key,\n cell.richText.map((run) => ({ ...run })),\n );\n }\n if (cell.numberFormat) {\n this.cellNumberFormats.set(key, cell.numberFormat);\n }\n this.updateCellDisplayValue(cell.row, cell.column, cell.displayValue);\n if (cell.style) {\n this.setCellFormatting(cell.row, cell.column, cell.style);\n }\n if (hasValue) {\n changedCells.push({ row: cell.row, column: cell.column, value: normalized });\n }\n }\n this.render();\n for (const cell of changedCells) {\n this.emitCellValueChange(cell.row, cell.column);\n }\n const active = this.selection.getActiveCell();\n if (active) {\n this.emitCellValueChange(active.row, active.column);\n }\n }\n\n private updateCellDisplayValue(row: number, column: number, fallback?: string): void {\n const key = cellKey(row, column);\n const raw = this.cellInputs.get(key);\n const formatCode = this.cellNumberFormats.get(key);\n let display: string | null | undefined;\n if (formatCode && raw !== undefined) {\n const numeric = Number(raw);\n if (Number.isFinite(numeric)) {\n display = formatNumberWithFormat(numeric, formatCode);\n }\n }\n if ((display === null || display === undefined) && fallback !== undefined) {\n display = fallback;\n }\n if (display && display.length > 0) {\n this.cellDisplayOverrides.set(key, display);\n } else {\n this.cellDisplayOverrides.delete(key);\n }\n }\n\n protected getCellText(row: number, column: number): string | null {\n const key = cellKey(row, column);\n if (this.cellDisplayOverrides.has(key)) {\n const display = this.cellDisplayOverrides.get(key) ?? '';\n return display.length ? display : null;\n }\n const value = this.formulaEngine.getDisplayValue(row, column);\n return value && value.length > 0 ? value : null;\n }\n\n // ---------------------------------------------------------------------------\n // Cell style\n // ---------------------------------------------------------------------------\n\n getComputedCellStyle(row: number, column: number): CellStyle {\n const key = cellKey(row, column);\n const formatting = this.cellFormatting.get(key);\n return {\n fontFamily: formatting?.fontFamily ?? this.defaultStyle.fontFamily,\n fontSize: formatting?.fontSize ?? this.defaultStyle.fontSize,\n bold: formatting?.bold ?? this.defaultStyle.bold,\n italic: formatting?.italic ?? this.defaultStyle.italic,\n underline: formatting?.underline ?? this.defaultStyle.underline,\n backgroundColor: formatting?.backgroundColor ?? this.defaultStyle.backgroundColor,\n color: formatting?.color ?? this.defaultStyle.color,\n textAlign: formatting?.textAlign ?? this.defaultStyle.textAlign,\n verticalAlign: formatting?.verticalAlign ?? this.defaultStyle.verticalAlign,\n textWrapMode: formatting?.textWrapMode ?? this.defaultStyle.textWrapMode,\n };\n }\n\n getActiveCellStyle(): CellStyle {\n const active = this.selection.getActiveCell();\n if (!active) {\n return { ...this.defaultStyle };\n }\n return this.getComputedCellStyle(active.row, active.column);\n }\n\n getDefaultCellStyle(): CellStyle {\n return { ...this.defaultStyle };\n }\n\n setCellStyle(row: number, column: number, style: Partial<CellStyle>): void {\n if (!this.isCellInBounds(row, column)) {\n throw new Error(`Cell (${row}, ${column}) is outside of the worksheet bounds.`);\n }\n this.setCellFormatting(row, column, style);\n this.render();\n }\n\n private setCellFormatting(row: number, column: number, style: Partial<CellStyle>): void {\n const key = cellKey(row, column);\n const existing = this.cellFormatting.get(key) ?? {};\n const next: Partial<CellStyle> = { ...existing, ...style };\n const cleaned: Partial<CellStyle> = {};\n if (next.fontFamily !== undefined) { cleaned.fontFamily = next.fontFamily; }\n if (next.fontSize !== undefined) { cleaned.fontSize = next.fontSize; }\n if (next.bold !== undefined) { cleaned.bold = next.bold; }\n if (next.italic !== undefined) { cleaned.italic = next.italic; }\n if (next.underline !== undefined) { cleaned.underline = next.underline; }\n if (next.backgroundColor !== undefined) { cleaned.backgroundColor = next.backgroundColor; }\n if (next.color !== undefined) { cleaned.color = next.color; }\n if (next.textAlign !== undefined) { cleaned.textAlign = next.textAlign; }\n if (next.verticalAlign !== undefined) { cleaned.verticalAlign = next.verticalAlign; }\n if (next.textWrapMode !== undefined) { cleaned.textWrapMode = next.textWrapMode; }\n const hasFormatting = Object.keys(cleaned).length > 0;\n if (!hasFormatting) {\n this.cellFormatting.delete(key);\n } else {\n this.cellFormatting.set(key, cleaned);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Selection style operations\n // ---------------------------------------------------------------------------\n\n setSelectionFontFamily(fontFamily: string): void {\n this.applyToSelection((row, column) => { this.setCellFormatting(row, column, { fontFamily }); });\n this.render();\n }\n\n setSelectionFontSize(fontSize: number): void {\n this.applyToSelection((row, column) => { this.setCellFormatting(row, column, { fontSize }); });\n this.render();\n }\n\n setSelectionFontBold(enabled: boolean): void {\n this.applyToSelection((row, column) => { this.setCellFormatting(row, column, { bold: enabled }); });\n this.render();\n }\n\n setSelectionFontItalic(enabled: boolean): void {\n this.applyToSelection((row, column) => { this.setCellFormatting(row, column, { italic: enabled }); });\n this.render();\n }\n\n setSelectionUnderline(enabled: boolean): void {\n this.applyToSelection((row, column) => { this.setCellFormatting(row, column, { underline: enabled }); });\n this.render();\n }\n\n setSelectionBackgroundColor(color: string): void {\n this.applyToSelection((row, column) => { this.setCellFormatting(row, column, { backgroundColor: color }); });\n this.render();\n }\n\n setSelectionHorizontalAlignment(alignment: TextAlign): void {\n this.applyToSelection((row, column) => { this.setCellFormatting(row, column, { textAlign: alignment }); });\n this.render();\n }\n\n setSelectionVerticalAlignment(alignment: VerticalAlign): void {\n this.applyToSelection((row, column) => { this.setCellFormatting(row, column, { verticalAlign: alignment }); });\n this.render();\n }\n\n setSelectionTextWrapMode(mode: TextWrapMode): void {\n this.applyToSelection((row, column) => { this.setCellFormatting(row, column, { textWrapMode: mode }); });\n this.render();\n }\n\n setRangeBackgroundColor(\n topRow: number,\n leftColumn: number,\n bottomRow: number,\n rightColumn: number,\n color: string,\n ): void {\n const bounds = this.normalizeRangeBounds(topRow, leftColumn, bottomRow, rightColumn);\n if (!bounds) {\n return;\n }\n for (let r = bounds.top; r <= bounds.bottom; r += 1) {\n for (let c = bounds.left; c <= bounds.right; c += 1) {\n this.setCellFormatting(r, c, { backgroundColor: color });\n }\n }\n this.render();\n }\n\n // ---------------------------------------------------------------------------\n // Selection\n // ---------------------------------------------------------------------------\n\n setSelectionRange(topRow: number, leftColumn: number, bottomRow: number, rightColumn: number): void {\n const bounds = this.normalizeRangeBounds(topRow, leftColumn, bottomRow, rightColumn);\n if (!bounds) {\n return;\n }\n const expanded = this.merges.expandSelection(bounds);\n this.selection.setRange(expanded.top, expanded.left, expanded.bottom, expanded.right);\n this.render();\n this.notifySelectionChanged();\n }\n\n onSelectionChange(listener: SelectionChangeListener): () => void {\n this.selectionChangeListeners.add(listener);\n return () => {\n this.selectionChangeListeners.delete(listener);\n };\n }\n\n onCellValueChange(listener: CellValueChangeListener): () => void {\n this.cellValueListeners.add(listener);\n return () => {\n this.cellValueListeners.delete(listener);\n };\n }\n\n notifySelectionChanged(): void {\n this.emitSelectionChange();\n }\n\n isActiveCell(row: number, column: number): boolean {\n const active = this.selection.getActiveCell();\n return !!active && active.row === row && active.column === column;\n }\n\n private applyToSelection(callback: (row: number, column: number) => void): void {\n const bounds = this.selection.getNormalizedBounds();\n if (!bounds) {\n const active = this.selection.getActiveCell();\n if (active) {\n callback(active.row, active.column);\n return;\n }\n this.selection.begin(0, 0);\n this.emitSelectionChange();\n callback(0, 0);\n return;\n }\n for (let r = bounds.topRow; r <= bounds.bottomRow; r += 1) {\n for (let c = bounds.leftColumn; c <= bounds.rightColumn; c += 1) {\n callback(r, c);\n }\n }\n }\n\n // ---------------------------------------------------------------------------\n // Merge management (delegates to MergeManager)\n // ---------------------------------------------------------------------------\n\n setMergedRanges(ranges: Iterable<MergedCellRange>): void {\n this.merges.setAll(ranges);\n this.render();\n }\n\n mergeCells(topRow: number, leftColumn: number, bottomRow: number, rightColumn: number): void {\n this.merges.add(topRow, leftColumn, bottomRow, rightColumn);\n this.render();\n }\n\n unmergeCells(topRow: number, leftColumn: number, bottomRow: number, rightColumn: number): void {\n if (this.merges.remove(topRow, leftColumn, bottomRow, rightColumn)) {\n this.render();\n }\n }\n\n clearMergedRanges(): void {\n if (this.merges.clear()) {\n this.render();\n }\n }\n\n getMergedRange(row: number, column: number): MergedCellRange | null {\n return this.merges.get(row, column);\n }\n\n isMergedCellAnchor(row: number, column: number): boolean {\n return this.merges.isAnchor(row, column);\n }\n\n getCellMergeBounds(row: number, column: number): {\n topRow: number;\n bottomRow: number;\n leftColumn: number;\n rightColumn: number;\n } {\n return this.merges.getBounds(row, column);\n }\n\n expandSelectionWithMergedCells(bounds: {\n top: number;\n bottom: number;\n left: number;\n right: number;\n }): { top: number; bottom: number; left: number; right: number } {\n return this.merges.expandSelection(bounds);\n }\n\n protected getMergedLineGaps(): {\n horizontal: Map<number, Array<{ startColumnBoundary: number; endColumnBoundary: number }>>;\n vertical: Map<number, Array<{ startRowBoundary: number; endRowBoundary: number }>>;\n } {\n return this.merges.getMergedLineGaps();\n }\n\n // ---------------------------------------------------------------------------\n // Border management (delegates to BorderManager)\n // ---------------------------------------------------------------------------\n\n getCellBorder(row: number, column: number): CellBorderDefinition | undefined {\n return this.borders.getCell(row, column);\n }\n\n applyCellBorders(borders: Map<string, CellBorderDefinition>): void {\n this.borders.applyAll(borders);\n this.render();\n }\n\n setRangeBorder(\n topRow: number,\n leftColumn: number,\n bottomRow: number,\n rightColumn: number,\n border: BorderLineOptions,\n sides?: RangeBorderSide[],\n ): void {\n this.borders.setRange(topRow, leftColumn, bottomRow, rightColumn, border, sides);\n this.render();\n }\n\n // ---------------------------------------------------------------------------\n // Column/row sizing\n // ---------------------------------------------------------------------------\n\n getColumnWidth(column: number): number {\n if (column < 0 || column >= this.columns) {\n return DEFAULT_COLUMN_WIDTH;\n }\n return this.columnWidths[column];\n }\n\n setColumnWidth(column: number, width: number): void {\n if (column < 0 || column >= this.columns) {\n return;\n }\n const normalizedWidth = Math.max(MIN_COLUMN_WIDTH, width);\n if (this.columnWidths[column] === normalizedWidth) {\n return;\n }\n this.columnWidths[column] = normalizedWidth;\n this.columnCustomWidths[column] = true;\n this.render();\n this.emitStructureChange();\n }\n\n getRowHeight(row: number): number {\n if (row < 0 || row >= this.rows) {\n return DEFAULT_ROW_HEIGHT;\n }\n return this.rowHeights[row];\n }\n\n setRowHeight(row: number, height: number): void {\n if (row < 0 || row >= this.rows) {\n return;\n }\n const normalizedHeight = Math.max(MIN_ROW_HEIGHT, height);\n if (this.rowHeights[row] === normalizedHeight) {\n return;\n }\n this.rowHeights[row] = normalizedHeight;\n this.rowCustomHeights[row] = true;\n this.render();\n this.emitStructureChange();\n }\n\n applyColumnWidths(\n widths: Map<number, number>,\n options?: { customColumns?: Set<number>; enforceMinColumnWidth?: boolean },\n ): void {\n let changed = false;\n for (let column = 0; column < this.columns; column += 1) {\n const width = widths.get(column);\n const minWidth = options?.enforceMinColumnWidth ?? true ? MIN_COLUMN_WIDTH : 0;\n const normalized = Math.max(minWidth, width ?? DEFAULT_COLUMN_WIDTH);\n if (this.columnWidths[column] !== normalized) {\n this.columnWidths[column] = normalized;\n changed = true;\n }\n if (options?.customColumns) {\n this.columnCustomWidths[column] = options.customColumns.has(column);\n }\n }\n if (changed) {\n this.updateBoundaries();\n this.emitStructureChange();\n }\n }\n\n applyRowHeights(heights: Map<number, number>, options?: { customRows?: Set<number> }): void {\n let changed = false;\n for (let row = 0; row < this.rows; row += 1) {\n const height = heights.get(row);\n const normalized = Math.max(MIN_ROW_HEIGHT, height ?? DEFAULT_ROW_HEIGHT);\n if (this.rowHeights[row] !== normalized) {\n this.rowHeights[row] = normalized;\n if (options?.customRows?.has(row)) {\n this.rowCustomHeights[row] = true;\n }\n changed = true;\n } else if (options?.customRows?.has(row)) {\n this.rowCustomHeights[row] = true;\n }\n }\n if (changed) {\n this.updateBoundaries();\n this.emitStructureChange();\n }\n }\n\n autoFitColumns(options: { columns?: number[]; respectCustomWidth?: boolean } = {}): void {\n const respectCustom = options.respectCustomWidth ?? true;\n const targetColumns =\n options.columns ?? Array.from({ length: this.columns }, (_, index) => index);\n let changed = false;\n for (const column of targetColumns) {\n if (column < 0 || column >= this.columns) {\n continue;\n }\n if (respectCustom && this.columnCustomWidths[column]) {\n continue;\n }\n const measured = this.measureColumnWidth(column);\n const normalized = Math.max(MIN_COLUMN_WIDTH, measured);\n if (Math.abs(normalized - this.columnWidths[column]) > 0.5) {\n this.columnWidths[column] = normalized;\n this.columnCustomWidths[column] = true;\n changed = true;\n }\n }\n if (changed) {\n this.updateBoundaries();\n this.emitStructureChange();\n this.render();\n }\n }\n\n autoFitRows(options: { rows?: number[]; respectCustomHeight?: boolean } = {}): void {\n const respectCustom = options.respectCustomHeight ?? true;\n const targetRows =\n options.rows ?? Array.from({ length: this.rows }, (_, index) => index);\n let changed = false;\n for (const row of targetRows) {\n if (row < 0 || row >= this.rows) {\n continue;\n }\n if (respectCustom && this.rowCustomHeights[row]) {\n continue;\n }\n const measured = this.measureRowHeight(row);\n const normalized = Math.max(DEFAULT_ROW_HEIGHT, measured);\n if (Math.abs(normalized - this.rowHeights[row]) > 0.5) {\n this.rowHeights[row] = normalized;\n changed = true;\n }\n }\n if (changed) {\n this.updateBoundaries();\n this.emitStructureChange();\n this.render();\n }\n }\n\n protected measureColumnWidth(_column: number): number {\n return MIN_COLUMN_WIDTH;\n }\n\n protected measureRowHeight(_row: number): number {\n return DEFAULT_ROW_HEIGHT;\n }\n\n protected measureCellContentHeight(_row: number, _column: number, _style: CellStyle): number {\n return 0;\n }\n\n protected measureCellContentWidth(_row: number, _column: number, _style: CellStyle): number {\n return MIN_COLUMN_WIDTH;\n }\n\n // ---------------------------------------------------------------------------\n // Grid size\n // ---------------------------------------------------------------------------\n\n setGridSize(rows: number, columns: number): void {\n const normalizedRows = Math.max(1, Math.floor(rows));\n const normalizedColumns = Math.max(1, Math.floor(columns));\n if (normalizedRows === this.rows && normalizedColumns === this.columns) {\n return;\n }\n this.rows = normalizedRows;\n this.columns = normalizedColumns;\n\n this.ensureArrayLength(this.columnWidths, normalizedColumns, DEFAULT_COLUMN_WIDTH);\n this.ensureArrayLength(this.columnCustomWidths, normalizedColumns, false);\n this.ensureArrayLength(this.rowHeights, normalizedRows, DEFAULT_ROW_HEIGHT);\n this.ensureArrayLength(this.rowCustomHeights, normalizedRows, false);\n\n this.updateBoundaries();\n this.pruneCellDataOutsideGrid();\n this.merges.pruneOutsideGrid();\n this.clampSelectionToBounds();\n\n this.render();\n this.emitStructureChange();\n }\n\n // ---------------------------------------------------------------------------\n // Grid lines & resize guide\n // ---------------------------------------------------------------------------\n\n setShowGridLines(visible: boolean): void {\n if (this._showGridLines === visible) {\n return;\n }\n this._showGridLines = visible;\n this.render();\n }\n\n getShowGridLines(): boolean {\n return this._showGridLines;\n }\n\n protected shouldRenderGridLines(): boolean {\n return this._showGridLines;\n }\n\n setResizeGuide(\n guide: { type: 'column' | 'row'; position: number } | null,\n shouldRender = true,\n ): void {\n const existing = this.resizeGuide;\n const guidesMatch =\n existing !== null &&\n guide !== null &&\n existing.type === guide.type &&\n Math.abs(existing.position - guide.position) <= 1e-3;\n const shouldUpdate = !guidesMatch && guide !== existing;\n if (shouldUpdate) {\n this.resizeGuide = guide;\n } else if (guide === null && existing !== null) {\n this.resizeGuide = null;\n }\n if (shouldRender && (shouldUpdate || (guide === null && existing !== null))) {\n this.render();\n }\n }\n\n // ---------------------------------------------------------------------------\n // Unit conversion\n // ---------------------------------------------------------------------------\n\n getPixelRatio(): number {\n return this.pixelRatio;\n }\n\n pointsToPixels(points: number): number {\n if (!Number.isFinite(points)) {\n return this.pointToPixelRatio;\n }\n return Math.max(1, points * this.pointToPixelRatio);\n }\n\n // ---------------------------------------------------------------------------\n // Export\n // ---------------------------------------------------------------------------\n\n public getExportSnapshot(): WorksheetExportSnapshot {\n const cells = new Map<string, WorksheetExportCell>();\n const defaultStyle = this.getDefaultCellStyle();\n\n const getCellEntry = (row: number, column: number): WorksheetExportCell => {\n const key = cellKey(row, column);\n let entry = cells.get(key);\n if (!entry) {\n entry = { row, column };\n cells.set(key, entry);\n }\n return entry;\n };\n\n const styleMatchesDefault = (style: CellStyle): boolean =>\n style.fontFamily === defaultStyle.fontFamily &&\n style.fontSize === defaultStyle.fontSize &&\n style.bold === defaultStyle.bold &&\n style.italic === defaultStyle.italic &&\n style.underline === defaultStyle.underline &&\n style.backgroundColor === defaultStyle.backgroundColor &&\n style.color === defaultStyle.color &&\n style.textAlign === defaultStyle.textAlign &&\n style.verticalAlign === defaultStyle.verticalAlign &&\n style.textWrapMode === defaultStyle.textWrapMode;\n\n for (const [key, value] of this.cellInputs) {\n const position = parseCellKey(key);\n if (!position || !this.isCellInBounds(position.row, position.column)) {\n continue;\n }\n getCellEntry(position.row, position.column).value = value;\n }\n\n for (const key of this.cellFormatting.keys()) {\n const position = parseCellKey(key);\n if (!position || !this.isCellInBounds(position.row, position.column)) {\n continue;\n }\n const computedStyle = this.getComputedCellStyle(position.row, position.column);\n if (styleMatchesDefault(computedStyle)) {\n continue;\n }\n getCellEntry(position.row, position.column).style = computedStyle;\n }\n\n return {\n cells: Array.from(cells.values()),\n merges: this.merges.allAnchors().map((range) => ({ ...range })),\n columnWidths: [...this.columnWidths],\n rowHeights: [...this.rowHeights],\n rows: this.rows,\n columns: this.columns,\n };\n }\n\n // ---------------------------------------------------------------------------\n // Protected helpers (used by subclasses and SheetRendererContext)\n // ---------------------------------------------------------------------------\n\n protected parseCellKey(key: string): { row: number; column: number } | null {\n return parseCellKey(key);\n }\n\n // ---------------------------------------------------------------------------\n // Private helpers\n // ---------------------------------------------------------------------------\n\n private isCellInBounds(row: number, column: number): boolean {\n return row >= 0 && row < this.rows && column >= 0 && column < this.columns;\n }\n\n private clampRow(row: number): number {\n return Math.min(Math.max(Math.floor(row), 0), this.rows - 1);\n }\n\n private clampColumn(column: number): number {\n return Math.min(Math.max(Math.floor(column), 0), this.columns - 1);\n }\n\n normalizeRangeBounds(\n topRow: number,\n leftColumn: number,\n bottomRow: number,\n rightColumn: number,\n ): { top: number; left: number; bottom: number; right: number } | null {\n if (this.rows === 0 || this.columns === 0) {\n return null;\n }\n const r1 = this.clampRow(topRow);\n const r2 = this.clampRow(bottomRow);\n const c1 = this.clampColumn(leftColumn);\n const c2 = this.clampColumn(rightColumn);\n return {\n top: Math.min(r1, r2),\n bottom: Math.max(r1, r2),\n left: Math.min(c1, c2),\n right: Math.max(c1, c2),\n };\n }\n\n private clampSelectionToBounds(): void {\n const bounds = this.selection.getNormalizedBounds();\n if (bounds) {\n const topRow = Math.min(bounds.topRow, this.rows - 1);\n const bottomRow = Math.min(bounds.bottomRow, this.rows - 1);\n const leftColumn = Math.min(bounds.leftColumn, this.columns - 1);\n const rightColumn = Math.min(bounds.rightColumn, this.columns - 1);\n this.selection.setRange(topRow, leftColumn, bottomRow, rightColumn);\n return;\n }\n const active = this.selection.getActiveCell();\n if (active && !this.isCellInBounds(active.row, active.column)) {\n this.selection.begin(0, 0);\n }\n }\n\n private pruneCellDataOutsideGrid(): void {\n pruneMapOutsideGrid(this.cellInputs, this.rows, this.columns);\n pruneMapOutsideGrid(this.cellRichText, this.rows, this.columns);\n pruneMapOutsideGrid(this.cellDisplayOverrides, this.rows, this.columns);\n pruneMapOutsideGrid(this.cellNumberFormats, this.rows, this.columns);\n pruneMapOutsideGrid(this.cellFormatting, this.rows, this.columns);\n this.borders.pruneOutsideGrid();\n }\n\n private ensureArrayLength<T>(array: T[], target: number, fillValue: T): void {\n if (array.length > target) {\n array.length = target;\n return;\n }\n while (array.length < target) {\n array.push(fillValue);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Event emission\n // ---------------------------------------------------------------------------\n\n private emitSelectionChange(): void {\n const active = this.selection.getActiveCell();\n for (const listener of this.selectionChangeListeners) {\n listener(active ? { ...active } : null);\n }\n }\n\n private emitCellValueChange(row: number, column: number): void {\n const value = this.getCellInput(row, column) ?? '';\n for (const listener of this.cellValueListeners) {\n listener({ row, column, value });\n }\n }\n\n private emitViewportSizeChange(): void {\n const size = this.getScrollContentSize();\n for (const listener of this.viewportSizeListeners) {\n listener({ ...size });\n }\n }\n\n private emitScrollChange(): void {\n const offset = { x: this.scrollX, y: this.scrollY };\n for (const listener of this.scrollListeners) {\n listener({ ...offset });\n }\n }\n\n private emitStructureChange(): void {\n for (const listener of this.structureListeners) {\n listener();\n }\n }\n}\n","import type { RangeRect } from '../core/worksheet/types';\nimport type { CellStyle, TextAlign } from '../core/style/cellStyle';\nimport type { RichTextRun } from '../types/richText';\nimport type { MergedCellRange } from '../core/cell/types';\nimport type { CellBorderDefinition, BorderLine, BorderLineStyle } from '../core/border/types';\nimport type { CellsViewport, WorksheetViewports } from './viewports';\n\ntype RichTextLine = { runs: ResolvedRichRun[]; width: number; lineHeight: number; ascent: number };\ntype ResolvedRichRun = {\n text: string;\n fontFamily: string;\n fontSize: number;\n bold: boolean;\n italic: boolean;\n color: string;\n underline: boolean;\n};\n\ntype PendingHorizontalEdge = {\n boundaryIndex: number;\n fromColumn: number;\n toColumn: number;\n line: BorderLine;\n};\n\ntype PendingVerticalEdge = {\n boundaryIndex: number;\n fromRow: number;\n toRow: number;\n line: BorderLine;\n};\n\ntype MergedLineGaps = {\n horizontal: Map<number, Array<{ startColumnBoundary: number; endColumnBoundary: number }>>;\n vertical: Map<number, Array<{ startRowBoundary: number; endRowBoundary: number }>>;\n};\n\nexport interface SheetRendererContext {\n getContext(): CanvasRenderingContext2D;\n getPixelRatio(): number;\n getBodyViewportWidth(): number;\n getBodyViewportHeight(): number;\n getHeaderColumnWidth(): number;\n getHeaderRowHeight(): number;\n getScrollOffset(): { x: number; y: number };\n getColumnBoundaries(): readonly number[];\n getRowBoundaries(): readonly number[];\n getColumnWidths(): readonly number[];\n getRowHeights(): readonly number[];\n getVisibleColumnRange(padding: number): { start: number; end: number };\n getVisibleRowRange(padding: number): { start: number; end: number };\n getVisibleRowIndices(): number[];\n getVisibleColumnIndices(): number[];\n getDefaultCellStyle(): CellStyle;\n getComputedCellStyle(row: number, column: number): CellStyle;\n getMergedRange(row: number, column: number): MergedCellRange | null;\n getRangeRect(topRow: number, leftColumn: number, bottomRow: number, rightColumn: number): RangeRect;\n getRichTextRuns(row: number, column: number): RichTextRun[] | undefined;\n getCellText(row: number, column: number): string | null;\n pointsToPixels(points: number): number;\n withBodyClip(callback: () => void): void;\n getMergedLineGaps(): MergedLineGaps;\n hasCellBorders(): boolean;\n getCellBorders(): Iterable<[string, CellBorderDefinition]>;\n parseCellKey(key: string): { row: number; column: number } | null;\n getCellMergeBounds(row: number, column: number): {\n topRow: number;\n bottomRow: number;\n leftColumn: number;\n rightColumn: number;\n };\n getCellTextPadding(): number;\n ensureBoundaries(): void;\n shouldRenderGridLines(): boolean;\n}\n\nexport class SheetRenderer {\n constructor(private readonly context: SheetRendererContext) {}\n\n drawHeaders(viewports?: WorksheetViewports): void {\n const ctx = this.context.getContext();\n const bodyWidth = viewports?.cells.rect.width ?? this.context.getBodyViewportWidth();\n const bodyHeight = viewports?.cells.rect.height ?? this.context.getBodyViewportHeight();\n const { x: scrollX, y: scrollY } = this.context.getScrollOffset();\n const headerColumnWidth = this.context.getHeaderColumnWidth();\n const headerRowHeight = this.context.getHeaderRowHeight();\n const offsetX = headerColumnWidth - scrollX;\n const offsetY = headerRowHeight - scrollY;\n const viewportRight = headerColumnWidth + bodyWidth;\n const viewportBottom = headerRowHeight + bodyHeight;\n\n ctx.save();\n ctx.fillStyle = '#f5f5f5';\n ctx.fillRect(headerColumnWidth, 0, bodyWidth, headerRowHeight);\n ctx.fillRect(0, headerRowHeight, headerColumnWidth, bodyHeight);\n\n ctx.fillStyle = '#e0e0e0';\n ctx.fillRect(0, 0, headerColumnWidth, headerRowHeight);\n\n const pixelRatio = this.context.getPixelRatio();\n const pixelAdjust = 0.5 / pixelRatio;\n ctx.strokeStyle = '#c0c0c0';\n ctx.lineWidth = 1 / pixelRatio;\n ctx.beginPath();\n ctx.moveTo(headerColumnWidth + pixelAdjust, 0);\n ctx.lineTo(headerColumnWidth + pixelAdjust, headerRowHeight + bodyHeight);\n ctx.moveTo(0, headerRowHeight + pixelAdjust);\n ctx.lineTo(headerColumnWidth + bodyWidth, headerRowHeight + pixelAdjust);\n ctx.stroke();\n\n ctx.font = '12px sans-serif';\n ctx.fillStyle = '#1f2933';\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n\n const columnRange = viewports?.columnHeader.columns ?? this.context.getVisibleColumnRange(0);\n const columnBoundaries = this.context.getColumnBoundaries();\n const columnWidths = this.context.getColumnWidths();\n const columnHeaderClip = viewports?.columnHeader.rect;\n if (columnHeaderClip) {\n ctx.save();\n ctx.beginPath();\n ctx.rect(\n columnHeaderClip.x,\n columnHeaderClip.y,\n columnHeaderClip.width,\n columnHeaderClip.height,\n );\n ctx.clip();\n }\n for (let c = columnRange.start; c <= columnRange.end; c += 1) {\n const columnLeft = offsetX + columnBoundaries[c];\n const columnWidth = columnWidths[c];\n const columnRight = columnLeft + columnWidth;\n if (columnRight < headerColumnWidth || columnLeft > viewportRight) {\n continue;\n }\n const centerX = columnLeft + columnWidth / 2;\n const centerY = headerRowHeight / 2;\n ctx.save();\n ctx.beginPath();\n ctx.rect(columnLeft, 0, columnWidth, headerRowHeight);\n ctx.clip();\n ctx.fillText(columnIndexToName(c), centerX, centerY);\n ctx.restore();\n }\n if (columnHeaderClip) {\n ctx.restore();\n }\n\n const rowRange = viewports?.rowHeader.rows ?? this.context.getVisibleRowRange(0);\n const rowBoundaries = this.context.getRowBoundaries();\n const rowHeights = this.context.getRowHeights();\n const rowHeaderClip = viewports?.rowHeader.rect;\n if (rowHeaderClip) {\n ctx.save();\n ctx.beginPath();\n ctx.rect(rowHeaderClip.x, rowHeaderClip.y, rowHeaderClip.width, rowHeaderClip.height);\n ctx.clip();\n }\n for (let r = rowRange.start; r <= rowRange.end; r += 1) {\n const rowTop = offsetY + rowBoundaries[r];\n const rowHeight = rowHeights[r];\n const rowBottom = rowTop + rowHeight;\n if (rowBottom < headerRowHeight || rowTop > viewportBottom) {\n continue;\n }\n const centerX = headerColumnWidth / 2;\n const centerY = rowTop + rowHeight / 2;\n ctx.fillText(String(r + 1), centerX, centerY);\n }\n if (rowHeaderClip) {\n ctx.restore();\n }\n\n ctx.restore();\n }\n\n drawCells(viewport?: CellsViewport): void {\n const bodyWidth = viewport?.rect.width ?? this.context.getBodyViewportWidth();\n const bodyHeight = viewport?.rect.height ?? this.context.getBodyViewportHeight();\n if (bodyWidth <= 0 || bodyHeight <= 0) {\n return;\n }\n const { x: scrollX, y: scrollY } = this.context.getScrollOffset();\n const headerColumnWidth = this.context.getHeaderColumnWidth();\n const headerRowHeight = this.context.getHeaderRowHeight();\n const offsetX = headerColumnWidth - scrollX;\n const offsetY = headerRowHeight - scrollY;\n const viewportRight = headerColumnWidth + bodyWidth;\n const viewportBottom = headerRowHeight + bodyHeight;\n\n const rowIndices = viewport?.rowIndices ?? this.context.getVisibleRowIndices();\n const columnIndices = viewport?.columnIndices ?? this.context.getVisibleColumnIndices();\n if (!rowIndices.length || !columnIndices.length) {\n return;\n }\n\n const ctx = this.context.getContext();\n const rowBoundaries = this.context.getRowBoundaries();\n const rowHeights = this.context.getRowHeights();\n const columnBoundaries = this.context.getColumnBoundaries();\n const columnWidths = this.context.getColumnWidths();\n const defaultStyle = this.context.getDefaultCellStyle();\n const cellPadding = this.context.getCellTextPadding();\n const pixelRatio = this.context.getPixelRatio();\n\n this.context.withBodyClip(() => {\n\n for (const r of rowIndices) {\n const rowTop = rowBoundaries[r];\n const rowHeight = rowHeights[r];\n const rowY = offsetY + rowTop;\n if (rowY > viewportBottom) {\n break;\n }\n for (const c of columnIndices) {\n const columnLeft = columnBoundaries[c];\n const columnWidth = columnWidths[c];\n const columnX = offsetX + columnLeft;\n if (columnX > viewportRight) {\n break;\n }\n const style = this.context.getComputedCellStyle(r, c);\n const merged = this.context.getMergedRange(r, c);\n const isAnchor = !merged || (merged.topRow === r && merged.leftColumn === c);\n const cellRect = {\n x: columnX,\n y: rowY,\n width: columnWidth,\n height: rowHeight,\n };\n const drawRect = merged\n ? this.context.getRangeRect(\n merged.topRow,\n merged.leftColumn,\n merged.bottomRow,\n merged.rightColumn,\n )\n : cellRect;\n\n const hasCustomBackground = style.backgroundColor !== defaultStyle.backgroundColor;\n if ((!merged || isAnchor) && hasCustomBackground) {\n this.fillCellBackground(\n ctx,\n drawRect.x,\n drawRect.y,\n drawRect.width,\n drawRect.height,\n style.backgroundColor,\n );\n }\n }\n }\n\n const previousBaseline = ctx.textBaseline;\n ctx.textBaseline = 'alphabetic';\n\n for (const r of rowIndices) {\n const rowTop = rowBoundaries[r];\n const rowHeight = rowHeights[r];\n const rowY = offsetY + rowTop;\n if (rowY > viewportBottom) {\n break;\n }\n for (const c of columnIndices) {\n const columnLeft = columnBoundaries[c];\n const columnWidth = columnWidths[c];\n const columnX = offsetX + columnLeft;\n if (columnX > viewportRight) {\n break;\n }\n const style = this.context.getComputedCellStyle(r, c);\n const merged = this.context.getMergedRange(r, c);\n const isAnchor = !merged || (merged.topRow === r && merged.leftColumn === c);\n const cellRect = {\n x: columnX,\n y: rowY,\n width: columnWidth,\n height: rowHeight,\n };\n const drawRect = merged\n ? this.context.getRangeRect(\n merged.topRow,\n merged.leftColumn,\n merged.bottomRow,\n merged.rightColumn,\n )\n : cellRect;\n\n if (!isAnchor) {\n continue;\n }\n\n const richTextRuns = this.context.getRichTextRuns(r, c);\n if (richTextRuns && richTextRuns.length > 0) {\n this.drawRichText(drawRect, style, richTextRuns);\n continue;\n }\n\n const text = this.context.getCellText(r, c);\n if (text === null) {\n continue;\n }\n const fontFamily = style.fontFamily.includes(' ')\n ? `\"${style.fontFamily}\"`\n : style.fontFamily;\n const fontSizePx = this.context.pointsToPixels(style.fontSize);\n const composedFont = this.composeFont({\n text: '',\n fontFamily,\n fontSize: fontSizePx,\n bold: style.bold,\n italic: style.italic,\n color: style.color ?? defaultStyle.color,\n underline: false,\n });\n ctx.font = composedFont;\n const lineHeight = fontSizePx + cellPadding;\n const lines = this.layoutPlainTextLines(text, style, drawRect);\n ctx.fillStyle = style.color ?? defaultStyle.color;\n const contentHeight = lineHeight * lines.length;\n let firstLineY = drawRect.y + cellPadding;\n if (style.verticalAlign === 'middle') {\n firstLineY = drawRect.y + (drawRect.height - contentHeight) / 2;\n } else if (style.verticalAlign === 'bottom') {\n firstLineY = drawRect.y + drawRect.height - contentHeight - cellPadding;\n }\n const minY = drawRect.y + cellPadding;\n const maxY = drawRect.y + drawRect.height - cellPadding - contentHeight;\n firstLineY = Math.min(firstLineY, maxY);\n firstLineY = Math.max(firstLineY, minY);\n const baselineOffset = fontSizePx;\n for (let i = 0; i < lines.length; i += 1) {\n const lineTop = firstLineY + i * lineHeight;\n if (lineTop > drawRect.y + drawRect.height - cellPadding) {\n break;\n }\n const lineMetrics = ctx.measureText(lines[i]);\n const lineWidth = lineMetrics.width;\n const textX = this.computeAlignedX(drawRect, lineWidth, style.textAlign);\n const baseline = lineTop + baselineOffset;\n ctx.fillText(lines[i], textX, baseline);\n if (style.underline) {\n this.drawUnderline(ctx, textX, lineWidth, baseline, fontSizePx);\n }\n }\n }\n }\n ctx.textBaseline = previousBaseline;\n\n if (this.context.shouldRenderGridLines()) {\n const pixelAdjust = 0.5 / pixelRatio;\n const mergedLineGaps = this.context.getMergedLineGaps();\n ctx.strokeStyle = '#d0d0d0';\n ctx.lineWidth = 1 / pixelRatio;\n ctx.beginPath();\n\n const rowLineStart = Math.max(0, rowIndices[0]);\n const rowLineEnd = Math.min(\n rowBoundaries.length - 1,\n rowIndices[rowIndices.length - 1] + 1,\n );\n const lastRowBoundary = Math.min(\n rowBoundaries.length - 1,\n rowIndices[rowIndices.length - 1] + 1,\n );\n const maxBodyY = headerRowHeight + rowBoundaries[lastRowBoundary];\n const maxColumnBoundary = Math.min(\n columnBoundaries.length - 1,\n columnIndices[columnIndices.length - 1] + 1,\n );\n const maxBodyX = headerColumnWidth + columnBoundaries[maxColumnBoundary];\n for (let r = rowLineStart; r <= rowLineEnd; r += 1) {\n const absolute = rowBoundaries[r];\n const y = offsetY + absolute + pixelAdjust;\n if (y < headerRowHeight || y > viewportBottom + pixelAdjust) {\n continue;\n }\n const gaps = mergedLineGaps.horizontal.get(r);\n if (!gaps || gaps.length === 0) {\n ctx.moveTo(headerColumnWidth, y);\n ctx.lineTo(maxBodyX, y);\n continue;\n }\n const segments = this.buildVisibleLineSegments(\n gaps.map((gap) => ({\n start: offsetX + columnBoundaries[gap.startColumnBoundary],\n end: offsetX + columnBoundaries[gap.endColumnBoundary],\n })),\n headerColumnWidth,\n maxBodyX,\n );\n for (const segment of segments) {\n ctx.moveTo(segment.start, y);\n ctx.lineTo(segment.end, y);\n }\n }\n\n const columnLineStart = Math.max(0, columnIndices[0]);\n const columnLineEnd = Math.min(\n columnBoundaries.length - 1,\n columnIndices[columnIndices.length - 1] + 1,\n );\n for (let c = columnLineStart; c <= columnLineEnd; c += 1) {\n const absolute = columnBoundaries[c];\n const x = offsetX + absolute + pixelAdjust;\n if (x < headerColumnWidth || x > maxBodyX + pixelAdjust) {\n continue;\n }\n const gaps = mergedLineGaps.vertical.get(c);\n if (!gaps || gaps.length === 0) {\n ctx.moveTo(x, headerRowHeight);\n const maxBodyHeight =\n headerRowHeight + rowBoundaries[Math.min(rowBoundaries.length - 1, rowIndices[rowIndices.length - 1] + 1)];\n ctx.lineTo(x, Math.min(viewportBottom, maxBodyHeight));\n continue;\n }\n const segments = this.buildVisibleLineSegments(\n gaps.map((gap) => ({\n start: offsetY + rowBoundaries[gap.startRowBoundary],\n end: offsetY + rowBoundaries[gap.endRowBoundary],\n })),\n headerRowHeight,\n Math.min(viewportBottom, maxBodyY),\n );\n for (const segment of segments) {\n ctx.moveTo(x, segment.start);\n ctx.lineTo(x, segment.end);\n }\n }\n\n ctx.stroke();\n }\n });\n }\n\n drawCustomBorders(viewport?: CellsViewport): void {\n if (!this.context.hasCellBorders()) {\n return;\n }\n const bodyWidth = viewport?.rect.width ?? this.context.getBodyViewportWidth();\n const bodyHeight = viewport?.rect.height ?? this.context.getBodyViewportHeight();\n if (bodyWidth <= 0 || bodyHeight <= 0) {\n return;\n }\n this.context.ensureBoundaries();\n const ctx = this.context.getContext();\n const viewportRows = viewport?.rows ?? this.context.getVisibleRowRange(0);\n const viewportCols = viewport?.columns ?? this.context.getVisibleColumnRange(0);\n const horizontalEdges = new Map<string, PendingHorizontalEdge>();\n const verticalEdges = new Map<string, PendingVerticalEdge>();\n\n for (const [key, borders] of this.context.getCellBorders()) {\n const coords = this.context.parseCellKey(key);\n if (!coords) {\n continue;\n }\n const bounds = this.context.getCellMergeBounds(coords.row, coords.column);\n const overlapsViewport =\n bounds.bottomRow >= viewportRows.start &&\n bounds.topRow <= viewportRows.end &&\n bounds.rightColumn >= viewportCols.start &&\n bounds.leftColumn <= viewportCols.end;\n if (!overlapsViewport) {\n continue;\n }\n this.addHorizontalEdge(horizontalEdges, bounds.topRow, bounds.leftColumn, bounds.rightColumn, borders.top);\n this.addHorizontalEdge(\n horizontalEdges,\n bounds.bottomRow + 1,\n bounds.leftColumn,\n bounds.rightColumn,\n borders.bottom,\n );\n this.addVerticalEdge(verticalEdges, bounds.leftColumn, bounds.topRow, bounds.bottomRow, borders.left);\n this.addVerticalEdge(\n verticalEdges,\n bounds.rightColumn + 1,\n bounds.topRow,\n bounds.bottomRow,\n borders.right,\n );\n }\n\n if (!horizontalEdges.size && !verticalEdges.size) {\n return;\n }\n\n this.context.withBodyClip(() => {\n ctx.lineCap = 'butt';\n ctx.lineJoin = 'miter';\n for (const edge of horizontalEdges.values()) {\n this.drawHorizontalBorderEdge(ctx, edge);\n }\n for (const edge of verticalEdges.values()) {\n this.drawVerticalBorderEdge(ctx, edge);\n }\n });\n }\n\n layoutRichText(runs: RichTextRun[], baseStyle: CellStyle): RichTextLine[] {\n const baseFontPx = this.context.pointsToPixels(baseStyle.fontSize);\n const resolvedRuns = runs.map((run) => this.resolveRichTextRun(run, baseStyle));\n const lines: RichTextLine[] = [];\n let currentRuns: ResolvedRichRun[] = [];\n for (const run of resolvedRuns) {\n const text = run.text.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n');\n const segments = text.split('\\n');\n segments.forEach((segment, index) => {\n if (segment.length > 0) {\n currentRuns.push({ ...run, text: segment });\n }\n if (index < segments.length - 1) {\n lines.push(this.measureRichTextLine(currentRuns, baseFontPx));\n currentRuns = [];\n }\n });\n }\n if (currentRuns.length > 0 || lines.length === 0) {\n lines.push(this.measureRichTextLine(currentRuns, baseFontPx));\n }\n return lines;\n }\n\n private layoutPlainTextLines(text: string, style: CellStyle, rect: RangeRect): string[] {\n const padding = this.context.getCellTextPadding();\n const availableWidth = Math.max(0, rect.width - padding * 2);\n const wrapMode = style.textWrapMode ?? 'none';\n const shouldWrap = wrapMode !== 'none' && availableWidth > 0;\n const rawLines = text.split(/\\r\\n|\\r|\\n/);\n const lines: string[] = [];\n for (const rawLine of rawLines) {\n if (!shouldWrap) {\n lines.push(rawLine);\n continue;\n }\n const segments = this.wrapPlainLine(rawLine, availableWidth, wrapMode === 'break-word');\n if (segments.length === 0) {\n lines.push('');\n } else {\n lines.push(...segments);\n }\n }\n return lines;\n }\n\n private wrapPlainLine(line: string, maxWidth: number, breakAnywhere: boolean): string[] {\n if (!line) {\n return [''];\n }\n if (maxWidth <= 0) {\n return [line];\n }\n const ctx = this.context.getContext();\n const tokens = breakAnywhere ? Array.from(line) : line.split(/(\\s+)/);\n const lines: string[] = [];\n let current = '';\n for (const token of tokens) {\n if (!token) {\n continue;\n }\n const candidate = current ? current + token : token;\n if (this.measureTextWidth(candidate, ctx) <= maxWidth) {\n current = candidate;\n continue;\n }\n if (current) {\n lines.push(current);\n current = '';\n }\n if (this.measureTextWidth(token, ctx) <= maxWidth) {\n current = token;\n continue;\n }\n const broken = this.breakSegment(token, maxWidth, ctx);\n if (broken.length) {\n lines.push(...broken);\n }\n }\n if (current) {\n lines.push(current);\n }\n if (!lines.length) {\n lines.push('');\n }\n return lines;\n }\n\n private breakSegment(value: string, maxWidth: number, ctx: CanvasRenderingContext2D): string[] {\n const segments: string[] = [];\n let buffer = '';\n for (const char of value) {\n const candidate = buffer ? buffer + char : char;\n if (this.measureTextWidth(candidate, ctx) <= maxWidth) {\n buffer = candidate;\n continue;\n }\n if (buffer) {\n segments.push(buffer);\n }\n buffer = char;\n if (this.measureTextWidth(buffer, ctx) > maxWidth) {\n segments.push(buffer);\n buffer = '';\n }\n }\n if (buffer) {\n segments.push(buffer);\n }\n return segments;\n }\n\n private measureTextWidth(value: string, ctx: CanvasRenderingContext2D): number {\n return ctx.measureText(value).width;\n }\n\n private drawRichText(rect: RangeRect, style: CellStyle, runs: RichTextRun[]): void {\n const lines = this.layoutRichText(runs, style);\n if (!lines.length) {\n return;\n }\n const ctx = this.context.getContext();\n const previousAlign = ctx.textAlign;\n ctx.textAlign = 'left';\n const padding = this.context.getCellTextPadding();\n const contentHeight = lines.reduce((sum, line) => sum + line.lineHeight, 0);\n let firstLineY = rect.y + padding;\n if (style.verticalAlign === 'middle') {\n firstLineY = rect.y + (rect.height - contentHeight) / 2;\n } else if (style.verticalAlign === 'bottom') {\n firstLineY = rect.y + rect.height - contentHeight - padding;\n }\n const minY = rect.y + padding;\n const maxY = rect.y + rect.height - padding - contentHeight;\n firstLineY = Math.min(firstLineY, maxY);\n firstLineY = Math.max(firstLineY, minY);\n let lineTop = firstLineY;\n for (const line of lines) {\n const textX = this.computeAlignedX(rect, line.width, style.textAlign);\n let cursorX = textX;\n const baseline = lineTop + line.ascent;\n for (const run of line.runs) {\n const ctxFont = this.composeFont(run);\n ctx.font = ctxFont;\n ctx.fillStyle = run.color;\n const metrics = ctx.measureText(run.text);\n ctx.fillText(run.text, cursorX, baseline);\n if (run.underline) {\n this.drawUnderline(ctx, cursorX, metrics.width, baseline, run.fontSize);\n }\n cursorX += metrics.width;\n }\n lineTop += line.lineHeight;\n }\n ctx.textAlign = previousAlign;\n }\n\n private resolveRichTextRun(run: RichTextRun, baseStyle: CellStyle): ResolvedRichRun {\n const fontFamily = run.fontFamily ?? baseStyle.fontFamily;\n const fontSize = this.context.pointsToPixels(run.fontSize ?? baseStyle.fontSize);\n const fallbackColor = baseStyle.color ?? this.context.getDefaultCellStyle().color ?? '#000000';\n return {\n text: run.text,\n fontFamily,\n fontSize,\n bold: !!run.bold,\n italic: !!run.italic,\n color: run.color ?? fallbackColor,\n underline: !!run.underline,\n };\n }\n\n private measureRichTextLine(runs: ResolvedRichRun[], baseFontPx: number): RichTextLine {\n const ctx = this.context.getContext();\n const padding = this.context.getCellTextPadding();\n const lineRuns = runs.map((run) => ({ ...run }));\n let width = 0;\n let maxFont = baseFontPx;\n if (lineRuns.length === 0) {\n return {\n runs: [],\n width: 0,\n lineHeight: baseFontPx + padding,\n ascent: baseFontPx,\n };\n }\n for (const run of lineRuns) {\n maxFont = Math.max(maxFont, run.fontSize);\n ctx.font = this.composeFont(run);\n width += ctx.measureText(run.text).width;\n }\n return {\n runs: lineRuns,\n width,\n lineHeight: maxFont + padding,\n ascent: maxFont,\n };\n }\n\n private composeFont(run: ResolvedRichRun): string {\n const parts: string[] = [];\n if (run.italic) {\n parts.push('italic');\n }\n if (run.bold) {\n parts.push('bold');\n }\n parts.push(`${run.fontSize}px`);\n const family = run.fontFamily.includes(' ') ? `\"${run.fontFamily}\"` : run.fontFamily;\n parts.push(family);\n return parts.join(' ');\n }\n\n private drawUnderline(\n ctx: CanvasRenderingContext2D,\n x: number,\n width: number,\n baseline: number,\n fontSize: number,\n ): void {\n if (width <= 0) {\n return;\n }\n const thickness = Math.max(1, Math.round(fontSize / 15));\n const offset = Math.max(thickness, fontSize * 0.05);\n ctx.fillRect(x, baseline + offset, width, thickness);\n }\n\n private computeAlignedX(rect: RangeRect, contentWidth: number, alignment: TextAlign): number {\n const padding = this.context.getCellTextPadding();\n if (alignment === 'center') {\n return rect.x + rect.width / 2 - contentWidth / 2;\n }\n if (alignment === 'right') {\n return rect.x + rect.width - padding - contentWidth;\n }\n return rect.x + padding;\n }\n\n private fillCellBackground(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n width: number,\n height: number,\n color: string,\n ): void {\n ctx.save();\n ctx.fillStyle = color;\n ctx.fillRect(x, y, Math.max(0, width), Math.max(0, height));\n ctx.restore();\n }\n\n private buildVisibleLineSegments(\n gaps: Array<{ start: number; end: number }>,\n lineStart: number,\n lineEnd: number,\n ): Array<{ start: number; end: number }> {\n if (gaps.length === 0) {\n return [{ start: lineStart, end: lineEnd }];\n }\n const normalizedGaps = gaps\n .map((gap) => ({\n start: Math.max(lineStart, Math.min(gap.start, gap.end)),\n end: Math.min(lineEnd, Math.max(gap.start, gap.end)),\n }))\n .filter((gap) => gap.start < gap.end)\n .sort((a, b) => a.start - b.start);\n\n const segments: Array<{ start: number; end: number }> = [];\n let cursor = lineStart;\n for (const gap of normalizedGaps) {\n if (gap.start > cursor) {\n segments.push({ start: cursor, end: gap.start });\n }\n cursor = Math.max(cursor, gap.end);\n if (cursor >= lineEnd) {\n break;\n }\n }\n if (cursor < lineEnd) {\n segments.push({ start: cursor, end: lineEnd });\n }\n return segments.length > 0 ? segments : [];\n }\n\n private addHorizontalEdge(\n edges: Map<string, PendingHorizontalEdge>,\n boundaryIndex: number,\n fromColumn: number,\n toColumn: number,\n line?: BorderLine,\n ): void {\n if (!line || line.width <= 0) {\n return;\n }\n const key = this.buildHorizontalEdgeKey(boundaryIndex, fromColumn, toColumn);\n const existing = edges.get(key);\n if (!existing) {\n edges.set(key, { boundaryIndex, fromColumn, toColumn, line });\n return;\n }\n const winner = this.pickDominantBorderLine(existing.line, line);\n if (winner === existing.line) {\n return;\n }\n edges.set(key, { boundaryIndex, fromColumn, toColumn, line: winner });\n }\n\n private addVerticalEdge(\n edges: Map<string, PendingVerticalEdge>,\n boundaryIndex: number,\n fromRow: number,\n toRow: number,\n line?: BorderLine,\n ): void {\n if (!line || line.width <= 0) {\n return;\n }\n const key = this.buildVerticalEdgeKey(boundaryIndex, fromRow, toRow);\n const existing = edges.get(key);\n if (!existing) {\n edges.set(key, { boundaryIndex, fromRow, toRow, line });\n return;\n }\n const winner = this.pickDominantBorderLine(existing.line, line);\n if (winner === existing.line) {\n return;\n }\n edges.set(key, { boundaryIndex, fromRow, toRow, line: winner });\n }\n\n private buildHorizontalEdgeKey(boundaryIndex: number, fromColumn: number, toColumn: number): string {\n return `h:${boundaryIndex}:${fromColumn}:${toColumn}`;\n }\n\n private buildVerticalEdgeKey(boundaryIndex: number, fromRow: number, toRow: number): string {\n return `v:${boundaryIndex}:${fromRow}:${toRow}`;\n }\n\n private pickDominantBorderLine(existing: BorderLine, candidate: BorderLine): BorderLine {\n if (candidate.width > existing.width) {\n return candidate;\n }\n if (candidate.width < existing.width) {\n return existing;\n }\n const existingPriority = this.getBorderStylePriority(existing.style);\n const candidatePriority = this.getBorderStylePriority(candidate.style);\n if (candidatePriority > existingPriority) {\n return candidate;\n }\n if (candidatePriority < existingPriority) {\n return existing;\n }\n const existingOrder = existing.appliedAt ?? 0;\n const candidateOrder = candidate.appliedAt ?? 0;\n return candidateOrder >= existingOrder ? candidate : existing;\n }\n\n private getBorderStylePriority(style: BorderLineStyle): number {\n switch (style) {\n case 'solid':\n return 3;\n case 'dashed':\n return 2;\n case 'dotted':\n default:\n return 1;\n }\n }\n\n private drawHorizontalBorderEdge(ctx: CanvasRenderingContext2D, edge: PendingHorizontalEdge): void {\n const dash = this.getDashPattern(edge.line.style, edge.line.width);\n ctx.setLineDash(dash);\n ctx.strokeStyle = edge.line.color;\n ctx.lineWidth = edge.line.width / this.context.getPixelRatio();\n const columnBoundaries = this.context.getColumnBoundaries();\n const rowBoundaries = this.context.getRowBoundaries();\n const { x: scrollX, y: scrollY } = this.context.getScrollOffset();\n const headerColumnWidth = this.context.getHeaderColumnWidth();\n const headerRowHeight = this.context.getHeaderRowHeight();\n const pixelAdjust = 0.5 / this.context.getPixelRatio();\n const xStart = headerColumnWidth - scrollX + columnBoundaries[edge.fromColumn];\n const xEnd = headerColumnWidth - scrollX + columnBoundaries[edge.toColumn + 1];\n const y = headerRowHeight - scrollY + rowBoundaries[edge.boundaryIndex] + pixelAdjust;\n\n ctx.beginPath();\n ctx.moveTo(xStart, y);\n ctx.lineTo(xEnd, y);\n ctx.stroke();\n ctx.setLineDash([]);\n }\n\n private drawVerticalBorderEdge(ctx: CanvasRenderingContext2D, edge: PendingVerticalEdge): void {\n const dash = this.getDashPattern(edge.line.style, edge.line.width);\n ctx.setLineDash(dash);\n ctx.strokeStyle = edge.line.color;\n ctx.lineWidth = edge.line.width / this.context.getPixelRatio();\n const columnBoundaries = this.context.getColumnBoundaries();\n const rowBoundaries = this.context.getRowBoundaries();\n const { x: scrollX, y: scrollY } = this.context.getScrollOffset();\n const headerColumnWidth = this.context.getHeaderColumnWidth();\n const headerRowHeight = this.context.getHeaderRowHeight();\n const pixelAdjust = 0.5 / this.context.getPixelRatio();\n const x = headerColumnWidth - scrollX + columnBoundaries[edge.boundaryIndex] + pixelAdjust;\n const yStart = headerRowHeight - scrollY + rowBoundaries[edge.fromRow];\n const yEnd = headerRowHeight - scrollY + rowBoundaries[edge.toRow + 1];\n\n ctx.beginPath();\n ctx.moveTo(x, yStart);\n ctx.lineTo(x, yEnd);\n ctx.stroke();\n ctx.setLineDash([]);\n }\n\n private getDashPattern(style: BorderLineStyle, width: number): number[] {\n switch (style) {\n case 'dashed':\n return [4 * width, 2 * width];\n case 'dotted':\n return [width, width];\n case 'solid':\n default:\n return [];\n }\n }\n}\n\nfunction columnIndexToName(index: number): string {\n let name = '';\n let n = index;\n do {\n const remainder = n % 26;\n name = String.fromCharCode(65 + remainder) + name;\n n = Math.floor(n / 26) - 1;\n } while (n >= 0);\n return name;\n}\n","export type ViewportRange = { start: number; end: number };\n\nexport type ViewportRect = { x: number; y: number; width: number; height: number };\n\nexport interface WorksheetViewportSource {\n headerColumnWidth: number;\n headerRowHeight: number;\n getBodyViewportWidth(): number;\n getBodyViewportHeight(): number;\n getVisibleRowRange(padding?: number): ViewportRange;\n getVisibleColumnRange(padding?: number): ViewportRange;\n getVisibleRowIndices(): number[];\n getVisibleColumnIndices(): number[];\n}\n\nclass BaseViewport {\n rect: ViewportRect = { x: 0, y: 0, width: 0, height: 0 };\n rows: ViewportRange = { start: 0, end: -1 };\n columns: ViewportRange = { start: 0, end: -1 };\n\n setRect(rect: ViewportRect): void {\n this.rect = rect;\n }\n}\n\nexport class ColumnHeaderViewport extends BaseViewport {\n setRenderRange(columns: ViewportRange): void {\n this.columns = columns;\n // Column headers render on the first row of the sheet.\n this.rows = { start: 0, end: 0 };\n }\n}\n\nexport class RowHeaderViewport extends BaseViewport {\n setRenderRange(rows: ViewportRange): void {\n this.rows = rows;\n // Row headers render on the first column of the sheet.\n this.columns = { start: 0, end: 0 };\n }\n}\n\nexport class CellsViewport extends BaseViewport {\n rowIndices: number[] = [];\n columnIndices: number[] = [];\n\n setRenderRange(\n rows: ViewportRange,\n columns: ViewportRange,\n rowIndices: number[],\n columnIndices: number[],\n ): void {\n this.rows = rows;\n this.columns = columns;\n this.rowIndices = rowIndices;\n this.columnIndices = columnIndices;\n }\n}\n\nexport type WorksheetViewports = {\n columnHeader: ColumnHeaderViewport;\n rowHeader: RowHeaderViewport;\n cells: CellsViewport;\n};\n\nexport class ViewportController {\n readonly columnHeader = new ColumnHeaderViewport();\n readonly rowHeader = new RowHeaderViewport();\n readonly cells = new CellsViewport();\n\n constructor(private readonly worksheet: WorksheetViewportSource) {}\n\n update(): WorksheetViewports {\n this.updateLayout();\n this.updateRanges();\n return {\n columnHeader: this.columnHeader,\n rowHeader: this.rowHeader,\n cells: this.cells,\n };\n }\n\n private updateLayout(): void {\n const bodyWidth = this.worksheet.getBodyViewportWidth();\n const bodyHeight = this.worksheet.getBodyViewportHeight();\n this.columnHeader.setRect({\n x: this.worksheet.headerColumnWidth,\n y: 0,\n width: bodyWidth,\n height: this.worksheet.headerRowHeight,\n });\n this.rowHeader.setRect({\n x: 0,\n y: this.worksheet.headerRowHeight,\n width: this.worksheet.headerColumnWidth,\n height: bodyHeight,\n });\n this.cells.setRect({\n x: this.worksheet.headerColumnWidth,\n y: this.worksheet.headerRowHeight,\n width: bodyWidth,\n height: bodyHeight,\n });\n }\n\n private updateRanges(): void {\n const visibleRows = this.worksheet.getVisibleRowRange(0);\n const visibleColumns = this.worksheet.getVisibleColumnRange(0);\n\n this.columnHeader.setRenderRange(visibleColumns);\n this.rowHeader.setRenderRange(visibleRows);\n\n const rowIndices = this.worksheet.getVisibleRowIndices();\n const columnIndices = this.worksheet.getVisibleColumnIndices();\n this.cells.setRenderRange(visibleRows, visibleColumns, rowIndices, columnIndices);\n }\n}\n","/* eslint-disable no-bitwise */\n/**\n * Portions of the DEFLATE implementation are adapted from SheetJS (MIT License).\n * https://github.com/SheetJS/sheetjs\n */\n\nconst EOCD_SIGNATURE = 0x06054b50;\nconst CENTRAL_DIR_SIGNATURE = 0x02014b50;\nconst LOCAL_FILE_HEADER_SIGNATURE = 0x04034b50;\n\nconst textDecoder: TextDecoder | null = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8') : null;\n\ntype ZipEntry = {\n name: string;\n compression: number;\n compressedSize: number;\n uncompressedSize: number;\n localHeaderOffset: number;\n};\n\nexport type ZipMap = Record<string, Uint8Array>;\n\nexport function unzip(data: Uint8Array): ZipMap {\n const entries = readCentralDirectory(data);\n const files: ZipMap = {};\n for (const entry of entries) {\n if (entry.name.endsWith('/')) {\n continue;\n }\n files[entry.name] = extractEntry(data, entry);\n }\n return files;\n}\n\nfunction readCentralDirectory(bytes: Uint8Array): ZipEntry[] {\n const eocdOffset = findEndOfCentralDirectory(bytes);\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n const totalEntries = view.getUint16(eocdOffset + 10, true);\n const centralDirOffset = view.getUint32(eocdOffset + 16, true);\n const entries: ZipEntry[] = [];\n let offset = centralDirOffset;\n for (let i = 0; i < totalEntries; i += 1) {\n const signature = view.getUint32(offset, true);\n if (signature !== CENTRAL_DIR_SIGNATURE) {\n throw new Error('Invalid central directory signature.');\n }\n const compression = view.getUint16(offset + 10, true);\n const compressedSize = view.getUint32(offset + 20, true);\n const uncompressedSize = view.getUint32(offset + 24, true);\n const nameLength = view.getUint16(offset + 28, true);\n const extraLength = view.getUint16(offset + 30, true);\n const commentLength = view.getUint16(offset + 32, true);\n const localHeaderOffset = view.getUint32(offset + 42, true);\n const nameBytes = bytes.subarray(offset + 46, offset + 46 + nameLength);\n const name = normalizePath(decodeUtf8(nameBytes));\n entries.push({\n name,\n compression,\n compressedSize,\n uncompressedSize,\n localHeaderOffset,\n });\n offset += 46 + nameLength + extraLength + commentLength;\n }\n return entries;\n}\n\nfunction findEndOfCentralDirectory(bytes: Uint8Array): number {\n for (let i = bytes.length - 22; i >= 0; i -= 1) {\n if (\n bytes[i] === 0x50 &&\n bytes[i + 1] === 0x4b &&\n bytes[i + 2] === 0x05 &&\n bytes[i + 3] === 0x06\n ) {\n return i;\n }\n }\n throw new Error('End of central directory record was not found.');\n}\n\nfunction extractEntry(bytes: Uint8Array, entry: ZipEntry): Uint8Array {\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n let offset = entry.localHeaderOffset;\n const signature = view.getUint32(offset, true);\n if (signature !== LOCAL_FILE_HEADER_SIGNATURE) {\n throw new Error(`Invalid local file header for ${entry.name}.`);\n }\n offset += 4; // signature\n offset += 2; // version\n const flags = view.getUint16(offset, true);\n offset += 2;\n const compression = view.getUint16(offset, true);\n offset += 2;\n offset += 8; // mod time/date + crc\n const _compressedSize = view.getUint32(offset, true);\n offset += 4;\n const _uncompressedSize = view.getUint32(offset, true);\n offset += 4;\n const nameLength = view.getUint16(offset, true);\n offset += 2;\n const extraLength = view.getUint16(offset, true);\n offset += 2;\n const dataStart = entry.localHeaderOffset + 30 + nameLength + extraLength;\n const compressedSize = flags & 0x0008 ? entry.compressedSize : _compressedSize;\n const uncompressedSize = flags & 0x0008 ? entry.uncompressedSize : _uncompressedSize;\n const compressed = bytes.subarray(dataStart, dataStart + compressedSize);\n if (compression === 0) {\n return compressed.slice();\n }\n if (compression === 8) {\n return inflateRaw(compressed, uncompressedSize);\n }\n throw new Error(`Unsupported ZIP compression method ${compression} in ${entry.name}.`);\n}\n\nfunction normalizePath(path: string): string {\n const withoutLeading = path.replace(/^[./\\\\]+/, '');\n return withoutLeading.replace(/\\\\/g, '/');\n}\n\nfunction decodeUtf8(bytes: Uint8Array): string {\n if (textDecoder) {\n return textDecoder.decode(bytes);\n }\n let result = '';\n for (let i = 0; i < bytes.length; i += 1) {\n result += String.fromCharCode(bytes[i]);\n }\n return result;\n}\n\n// -- Deflate implementation -------------------------------------------------\n\nconst CLEN_ORDER = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15];\nconst LEN_LN = [3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258];\nconst DST_LN = [1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577];\n\nconst bitswap8 = new Uint8Array(1 << 8);\nfor (let i = 0; i < bitswap8.length; i += 1) {\n bitswap8[i] = bitSwap8(i);\n}\n\nconst dynLiteralMap = new Uint16Array(32768);\nconst dynDistanceMap = new Uint16Array(32768);\nconst dynCodeMap = new Uint16Array(128);\nlet dynLiteralMax = 1;\nlet dynDistanceMax = 1;\n\nfunction inflateRaw(data: Uint8Array, expectedSize: number): Uint8Array {\n const [result] = inflate(data, expectedSize);\n return expectedSize ? result.slice(0, expectedSize) : result;\n}\n\nfunction inflate(data: Uint8Array, expectedSize: number): [Uint8Array, number] {\n if (data[0] === 3 && (data[1] & 3) === 0) {\n return [new Uint8Array(expectedSize), 2];\n }\n let bitOffset = 0;\n let header = 0;\n let outBuffer = createBuffer(expectedSize || 1 << 18);\n let writeOffset = 0;\n let maxLiteralBits = 0;\n let maxDistanceBits = 0;\n\n const literalMap = fixedLiteralMap;\n const distanceMap = fixedDistanceMap;\n\n while ((header & 1) === 0) {\n header = readBits3(data, bitOffset);\n bitOffset += 3;\n if ((header >>> 1) === 0) {\n if (bitOffset & 7) {\n bitOffset += 8 - (bitOffset & 7);\n }\n let size = data[bitOffset >>> 3] | (data[(bitOffset >>> 3) + 1] << 8);\n bitOffset += 32;\n if (size > 0) {\n if (!expectedSize && outBuffer.length < writeOffset + size) {\n outBuffer = growBuffer(outBuffer, writeOffset + size);\n }\n while (size > 0) {\n outBuffer[writeOffset++] = data[bitOffset >>> 3];\n bitOffset += 8;\n size -= 1;\n }\n }\n continue;\n }\n if ((header >> 1) === 1) {\n maxLiteralBits = 9;\n maxDistanceBits = 5;\n } else {\n bitOffset = buildDynamicTrees(data, bitOffset);\n maxLiteralBits = dynLiteralMax;\n maxDistanceBits = dynDistanceMax;\n }\n\n for (;;) {\n if (!expectedSize && outBuffer.length < writeOffset + 32767) {\n outBuffer = growBuffer(outBuffer, writeOffset + 32767);\n }\n const literalBits = readBitsN(data, bitOffset, maxLiteralBits);\n const literalCode =\n (header >>> 1) === 1 ? literalMap[literalBits] : dynLiteralMap[literalBits];\n bitOffset += literalCode & 15;\n let code = literalCode >>> 4;\n if ((code >>> 8 & 255) === 0) {\n outBuffer[writeOffset++] = code;\n continue;\n }\n if (code === 256) {\n break;\n }\n code -= 257;\n let lengthExtraBits = code < 8 ? 0 : (code - 4) >> 2;\n if (lengthExtraBits > 5) {\n lengthExtraBits = 0;\n }\n let target = writeOffset + LEN_LN[code];\n if (lengthExtraBits > 0) {\n target += readBitsN(data, bitOffset, lengthExtraBits);\n bitOffset += lengthExtraBits;\n }\n const distBits = readBitsN(data, bitOffset, maxDistanceBits);\n let distCode =\n (header >>> 1) === 1 ? distanceMap[distBits] : dynDistanceMap[distBits];\n bitOffset += distCode & 15;\n distCode >>>= 4;\n let distExtraBits = distCode < 4 ? 0 : (distCode - 2) >> 1;\n let distance = DST_LN[distCode];\n if (distExtraBits > 0) {\n distance += readBitsN(data, bitOffset, distExtraBits);\n bitOffset += distExtraBits;\n }\n if (!expectedSize && outBuffer.length < target) {\n outBuffer = growBuffer(outBuffer, target + 100);\n }\n while (writeOffset < target) {\n outBuffer[writeOffset] = outBuffer[writeOffset - distance];\n writeOffset += 1;\n }\n }\n }\n if (expectedSize) {\n return [outBuffer, (bitOffset + 7) >>> 3];\n }\n return [outBuffer.slice(0, writeOffset), (bitOffset + 7) >>> 3];\n}\n\nfunction buildDynamicTrees(data: Uint8Array, bitOffset: number): number {\n const HLIT = readBits5(data, bitOffset) + 257;\n bitOffset += 5;\n const HDIST = readBits5(data, bitOffset) + 1;\n bitOffset += 5;\n const HCLEN = readBits4(data, bitOffset) + 4;\n bitOffset += 4;\n\n const codeLengths = new Uint8Array(19);\n let maxLen = 1;\n const bitCounts = new Uint8Array(8);\n const nextCodes = new Uint8Array(8);\n for (let i = 0; i < HCLEN; i += 1) {\n const value = readBits3(data, bitOffset);\n const index = CLEN_ORDER[i];\n codeLengths[index] = value;\n if (maxLen < value) {\n maxLen = value;\n }\n bitCounts[value] += 1;\n bitOffset += 3;\n }\n let code = 0;\n bitCounts[0] = 0;\n for (let i = 1; i <= maxLen; i += 1) {\n nextCodes[i] = code = (code + bitCounts[i - 1]) << 1;\n }\n const codeTree = new Uint16Array(19);\n for (let i = 0; i < codeLengths.length; i += 1) {\n const len = codeLengths[i];\n if (len !== 0) {\n codeTree[i] = nextCodes[len]++;\n }\n }\n const codeMap = dynCodeMap;\n codeMap.fill(0);\n for (let i = 0; i < codeLengths.length; i += 1) {\n const len = codeLengths[i];\n if (len !== 0) {\n const swapped = bitswap8[codeTree[i]] >> (8 - len);\n for (let j = (1 << (7 - len)) - 1; j >= 0; --j) {\n codeMap[swapped | (j << len)] = (len & 7) | (i << 3);\n }\n }\n }\n const hCodes: number[] = [];\n maxLen = 1;\n while (hCodes.length < HLIT + HDIST) {\n let symbol = codeMap[readBits7(data, bitOffset)];\n bitOffset += symbol & 7;\n symbol >>>= 3;\n if (symbol === 16) {\n let repeat = 3 + readBits2(data, bitOffset);\n bitOffset += 2;\n const last = hCodes[hCodes.length - 1];\n while (repeat-- > 0) {\n hCodes.push(last);\n }\n } else if (symbol === 17) {\n let repeat = 3 + readBits3(data, bitOffset);\n bitOffset += 3;\n while (repeat-- > 0) {\n hCodes.push(0);\n }\n } else if (symbol === 18) {\n let repeat = 11 + readBits7(data, bitOffset);\n bitOffset += 7;\n while (repeat-- > 0) {\n hCodes.push(0);\n }\n } else {\n hCodes.push(symbol);\n if (maxLen < symbol) {\n maxLen = symbol;\n }\n }\n }\n const literalLengths = hCodes.slice(0, HLIT);\n const distanceLengths = hCodes.slice(HLIT);\n while (literalLengths.length < 286) literalLengths.push(0);\n while (distanceLengths.length < 30) distanceLengths.push(0);\n dynLiteralMax = buildTree(literalLengths, dynLiteralMap, 286);\n dynDistanceMax = buildTree(distanceLengths, dynDistanceMap, 30);\n return bitOffset;\n}\n\nfunction buildTree(codeLengths: number[], target: Uint16Array, maxSymbols: number): number {\n let maxLen = 1;\n const counts = new Uint16Array(32);\n for (let i = 0; i < codeLengths.length; i += 1) {\n const len = codeLengths[i] || 0;\n codeLengths[i] = len;\n counts[len] += 1;\n if (maxLen < len) {\n maxLen = len;\n }\n }\n counts[0] = 0;\n let code = 0;\n const nextCode = new Uint16Array(32);\n for (let i = 1; i <= maxLen; i += 1) {\n nextCode[i] = code = (code + counts[i - 1]) << 1;\n }\n for (let i = 0; i < maxSymbols; i += 1) {\n const len = codeLengths[i] || 0;\n if (len !== 0) {\n const val = bitSwapN(nextCode[len], maxLen) >> (maxLen - len);\n nextCode[len] += 1;\n for (let j = (1 << (maxLen + 4 - len)) - 1; j >= 0; --j) {\n target[val | (j << len)] = (len & 15) | (i << 4);\n }\n }\n }\n return maxLen;\n}\n\nconst fixedLiteralMap = new Uint16Array(512);\nconst fixedDistanceMap = new Uint16Array(32);\n\n(function initializeFixedTables() {\n const distLens: number[] = [];\n for (let i = 0; i < 32; i += 1) distLens.push(5);\n buildTree(distLens, fixedDistanceMap, 32);\n\n const literalLens: number[] = [];\n for (let i = 0; i <= 143; i += 1) literalLens.push(8);\n for (let i = 144; i <= 255; i += 1) literalLens.push(9);\n for (let i = 256; i <= 279; i += 1) literalLens.push(7);\n for (let i = 280; i <= 287; i += 1) literalLens.push(8);\n buildTree(literalLens, fixedLiteralMap, 288);\n})();\n\nfunction growBuffer(buffer: Uint8Array, size: number): Uint8Array {\n if (buffer.length >= size) {\n return buffer;\n }\n const next = new Uint8Array(Math.max(buffer.length * 2, size));\n next.set(buffer);\n return next;\n}\n\nfunction createBuffer(size: number): Uint8Array {\n return new Uint8Array(size);\n}\n\nfunction bitSwap8(value: number): number {\n const t =\n (((value << 1) | (value << 11)) & 139536) |\n (((value << 5) | (value << 15)) & 558144);\n return ((t >> 16) | (t >> 8) | t) & 255;\n}\n\nfunction bitSwapN(value: number, bits: number): number {\n let rev = bitswap8[value & 0xff];\n if (bits <= 8) {\n return rev >>> (8 - bits);\n }\n rev = (rev << 8) | bitswap8[(value >> 8) & 0xff];\n if (bits <= 16) {\n return rev >>> (16 - bits);\n }\n rev = (rev << 8) | bitswap8[(value >> 16) & 0xff];\n return rev >>> (24 - bits);\n}\n\nfunction readBits2(buf: Uint8Array, bitOffset: number): number {\n const w = bitOffset & 7;\n const h = bitOffset >>> 3;\n return (buf[h] | (w <= 6 ? 0 : buf[h + 1] << 8)) >>> w & 3;\n}\n\nfunction readBits3(buf: Uint8Array, bitOffset: number): number {\n const w = bitOffset & 7;\n const h = bitOffset >>> 3;\n return (buf[h] | (w <= 5 ? 0 : buf[h + 1] << 8)) >>> w & 7;\n}\n\nfunction readBits4(buf: Uint8Array, bitOffset: number): number {\n const w = bitOffset & 7;\n const h = bitOffset >>> 3;\n return (buf[h] | (w <= 4 ? 0 : buf[h + 1] << 8)) >>> w & 15;\n}\n\nfunction readBits5(buf: Uint8Array, bitOffset: number): number {\n const w = bitOffset & 7;\n const h = bitOffset >>> 3;\n return (buf[h] | (w <= 3 ? 0 : buf[h + 1] << 8)) >>> w & 31;\n}\n\nfunction readBits7(buf: Uint8Array, bitOffset: number): number {\n const w = bitOffset & 7;\n const h = bitOffset >>> 3;\n return (buf[h] | (w <= 1 ? 0 : buf[h + 1] << 8)) >>> w & 127;\n}\n\nfunction readBitsN(buf: Uint8Array, bitOffset: number, n: number): number {\n const w = bitOffset & 7;\n const h = bitOffset >>> 3;\n const mask = (1 << n) - 1;\n let value = buf[h] >>> w;\n if (n < 8 - w) {\n return value & mask;\n }\n value |= buf[h + 1] << (8 - w);\n if (n < 16 - w) {\n return value & mask;\n }\n value |= buf[h + 2] << (16 - w);\n if (n < 24 - w) {\n return value & mask;\n }\n value |= buf[h + 3] << (24 - w);\n return value & mask;\n}\n","export interface XmlNode {\n name: string;\n attributes: Record<string, string>;\n children: XmlNode[];\n text: string;\n}\n\nconst XML_ENTITY_MAP: Record<string, string> = {\n amp: '&',\n lt: '<',\n gt: '>',\n quot: '\"',\n apos: \"'\",\n};\n\n/**\n * Extremely small XML parser that is sufficient for the subset of OpenXML data\n * we need. It is not a full XML implementation but supports attributes,\n * self-closing tags, CDATA, namespaces, and nested nodes.\n */\nexport function parseXml(xml: string): XmlNode {\n const root: XmlNode = { name: '__root__', attributes: {}, children: [], text: '' };\n const stack: XmlNode[] = [root];\n const tokenRegex = /<!\\[CDATA\\[([\\s\\S]*?)\\]\\]>|<!--[\\s\\S]*?-->|<[^>]+>|[^<]+/g;\n let match: RegExpExecArray | null;\n\n while ((match = tokenRegex.exec(xml)) !== null) {\n // CDATA block\n if (match[1] !== undefined) {\n stack[stack.length - 1].text += match[1];\n continue;\n }\n\n const token = match[0];\n if (!token) {\n continue;\n }\n\n if (token.startsWith('<!--')) {\n continue;\n }\n\n if (token.startsWith('<?') || token.startsWith('<!')) {\n continue;\n }\n\n if (token.startsWith('</')) {\n stack.pop();\n continue;\n }\n\n if (token.startsWith('<')) {\n const selfClosing = token.endsWith('/>');\n const content = token.slice(1, selfClosing ? -2 : -1).trim();\n if (!content) {\n continue;\n }\n const nameMatch = /^[^\\s/>]+/.exec(content);\n if (!nameMatch) {\n continue;\n }\n const tagName = nameMatch[0];\n const attrString = content.slice(tagName.length).trim();\n const node: XmlNode = {\n name: tagName,\n attributes: parseAttributes(attrString),\n children: [],\n text: '',\n };\n stack[stack.length - 1].children.push(node);\n if (!selfClosing) {\n stack.push(node);\n }\n continue;\n }\n\n const text = decodeXmlEntities(token);\n if (!text.length) {\n continue;\n }\n const target = stack[stack.length - 1];\n if (!/\\S/.test(text) && target.attributes['xml:space'] !== 'preserve') {\n continue;\n }\n target.text += text;\n }\n\n return root;\n}\n\nexport function localName(name: string): string {\n const index = name.indexOf(':');\n return index >= 0 ? name.slice(index + 1) : name;\n}\n\nexport function findChildren(node: XmlNode, tagName: string): XmlNode[] {\n const target = localName(tagName);\n return node.children.filter((child) => localName(child.name) === target);\n}\n\nexport function findChild(node: XmlNode, tagName: string): XmlNode | undefined {\n const target = localName(tagName);\n return node.children.find((child) => localName(child.name) === target);\n}\n\nexport function getTextContent(node: XmlNode): string {\n let output = node.text ?? '';\n for (const child of node.children) {\n output += getTextContent(child);\n }\n return output;\n}\n\nfunction parseAttributes(input: string): Record<string, string> {\n if (!input) {\n return {};\n }\n const attributes: Record<string, string> = {};\n const regex = /([^\\s=]+)\\s*=\\s*(\"([^\"]*)\"|'([^']*)')/g;\n let match: RegExpExecArray | null;\n while ((match = regex.exec(input)) !== null) {\n const [, key, , doubleValue, singleValue] = match;\n attributes[key] = decodeXmlEntities(doubleValue ?? singleValue ?? '');\n }\n return attributes;\n}\n\nfunction decodeXmlEntities(text: string): string {\n return text.replace(/&(#\\d+|#x[0-9a-fA-F]+|\\w+);/g, (match, entity) => {\n if (entity[0] === '#') {\n const codePoint = entity[1] === 'x' || entity[1] === 'X' ? parseInt(entity.slice(2), 16) : parseInt(entity.slice(1), 10);\n if (!Number.isNaN(codePoint)) {\n return String.fromCodePoint(codePoint);\n }\n return '';\n }\n return XML_ENTITY_MAP[entity] ?? match;\n });\n}\n","import { unzip } from './unzip';\nimport { findChild, findChildren, getTextContent, localName, parseXml, type XmlNode } from './xml';\nimport type { RichTextRun } from '../types/richText';\n\nexport type Range = { s: { r: number; c: number }; e: { r: number; c: number } };\nexport type WorksheetMergeRange = { s: { r: number; c: number }; e: { r: number; c: number } };\n\nexport type ColumnInfo = { wpx?: number; wch?: number; width?: number; custom?: boolean };\nexport type RowInfo = { hpx?: number; hpt?: number; custom?: boolean };\nexport type SheetFormatProperties = {\n defaultRowHeight?: number;\n defaultColWidth?: number;\n customHeight?: boolean;\n};\nexport type SheetView = { showGridLines?: boolean };\n\nexport type DrawingAnchorPosition = {\n row: number;\n column: number;\n rowOffset: number;\n columnOffset: number;\n};\n\nexport type WorksheetImageAnchor =\n | { type: 'oneCell'; from: DrawingAnchorPosition; width: number; height: number }\n | { type: 'twoCell'; from: DrawingAnchorPosition; to: DrawingAnchorPosition };\n\nexport type WorksheetImage = {\n id: string;\n imagePath: string;\n format: string;\n mimeType: string;\n data: Uint8Array;\n anchor: WorksheetImageAnchor;\n};\n\nexport type ExcelFont = {\n name?: string;\n size?: number;\n color?: ExcelColor;\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n};\n\nexport type CellStyle = {\n alignment?: { horizontal?: string; vertical?: string };\n font?: ExcelFont;\n numFmtId?: number;\n formatCode?: string;\n};\n\nexport type CellObject = {\n v: string | number | boolean | null;\n value?: string | number | boolean | null;\n t: string;\n s?: CellStyle;\n richText?: RichTextRun[];\n};\n\nexport type WorkSheet = {\n [address: string]:\n | CellObject\n | string\n | ColumnInfo[]\n | RowInfo[]\n | WorksheetMergeRange[]\n | SheetFormatProperties\n | WorksheetImage[]\n | SheetView\n | undefined;\n '!ref'?: string;\n '!cols'?: ColumnInfo[];\n '!rows'?: RowInfo[];\n '!merges'?: WorksheetMergeRange[];\n '!sheetFormat'?: SheetFormatProperties;\n '!images'?: WorksheetImage[];\n '!sheetView'?: SheetView;\n};\n\ntype SharedStringEntry = { text: string; richText?: RichTextRun[] };\n\nexport type ExcelBorderLine = { style?: string; color?: ExcelColor };\nexport type ExcelBorder = {\n left?: ExcelBorderLine;\n right?: ExcelBorderLine;\n top?: ExcelBorderLine;\n bottom?: ExcelBorderLine;\n};\nexport type ExcelColor = { rgb?: string; indexed?: number; theme?: number; tint?: number };\nexport type ExcelFill = { patternType?: string; fgColor?: ExcelColor; bgColor?: ExcelColor };\n\nexport type CellXfRecord = {\n borderId?: number;\n fillId?: number;\n fontId?: number;\n numFmtId?: number;\n alignment?: { horizontal?: string; vertical?: string };\n};\n\ntype WorkbookColors = {\n indexed?: Array<string | null>;\n};\n\nexport type WorkbookStyles = {\n CellXf?: CellXfRecord[];\n Borders?: ExcelBorder[];\n Fills?: Array<ExcelFill | undefined>;\n Fonts?: ExcelFont[];\n NumberFormats?: Map<number, string>;\n Colors?: WorkbookColors;\n};\n\nexport type WorkBook = {\n SheetNames: string[];\n Sheets: Record<string, WorkSheet>;\n Styles?: WorkbookStyles;\n Directory?: { sheets?: string[] };\n files?: Record<string, { content?: string } | string>;\n};\n\nexport type SheetToJsonOptions = {\n header?: 1;\n defval?: string | number | boolean | null;\n raw?: boolean;\n};\n\nexport type ReadOptions = {\n type?: 'binary' | 'array';\n cellStyles?: boolean;\n bookFiles?: boolean;\n};\n\nconst textDecoder: TextDecoder | null = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8') : null;\n\nexport const utils = {\n sheet_to_json,\n encode_cell: encodeCell,\n decode_cell: decodeCell,\n decode_range: decodeRange,\n};\n\nexport function read(data: ArrayBuffer | Uint8Array | string, _options?: ReadOptions): WorkBook {\n const bytes = normalizeInput(data);\n const zipEntries = unzip(bytes);\n const workbookXml = readXml(zipEntries, 'xl/workbook.xml');\n const workbookDoc = parseXml(workbookXml);\n const workbookNode = workbookDoc.children.find((child) => localName(child.name) === 'workbook') ?? workbookDoc.children[0];\n if (!workbookNode) {\n throw new Error('Workbook XML is invalid.');\n }\n const sheetsNode = findChild(workbookNode, 'sheets');\n if (!sheetsNode) {\n throw new Error('Workbook does not contain sheets metadata.');\n }\n const sheetNodes = findChildren(sheetsNode, 'sheet');\n if (!sheetNodes.length) {\n throw new Error('Workbook does not contain any sheets.');\n }\n const relationships = readWorkbookRelationships(zipEntries);\n const sharedStrings = readSharedStrings(zipEntries);\n const styles = readStyles(zipEntries);\n\n const workbook: WorkBook = {\n SheetNames: [],\n Sheets: {},\n Styles: styles,\n Directory: { sheets: [] },\n files: {},\n };\n\n sheetNodes.forEach((sheetNode) => {\n const name = sheetNode.attributes.name;\n const relId = sheetNode.attributes['r:id'];\n if (!name || !relId) {\n return;\n }\n const path = relationships.get(relId);\n if (!path) {\n throw new Error(`Unable to resolve worksheet path for ${name}.`);\n }\n const sheetXml = readXml(zipEntries, path);\n const worksheet = readWorksheet(sheetXml, sharedStrings, styles, zipEntries, path);\n workbook.SheetNames.push(name);\n workbook.Sheets[name] = worksheet;\n workbook.Directory?.sheets?.push(path);\n workbook.files![path] = sheetXml;\n });\n\n return workbook;\n}\n\nfunction readWorksheet(\n xml: string,\n sharedStrings: SharedStringEntry[],\n styles: WorkbookStyles | undefined,\n zipEntries: Record<string, Uint8Array>,\n sheetPath: string,\n): WorkSheet {\n const doc = parseXml(xml);\n const root = doc.children.find((child) => localName(child.name) === 'worksheet') ?? doc.children[0];\n if (!root) {\n throw new Error('Worksheet XML is invalid.');\n }\n const worksheet: WorkSheet = {};\n const dimensionRef = findChild(root, 'dimension')?.attributes.ref;\n const sheetFormatNode = findChild(root, 'sheetFormatPr');\n const sheetViewsNode = findChild(root, 'sheetViews');\n if (sheetViewsNode) {\n const viewNode = findChild(sheetViewsNode, 'sheetView');\n if (viewNode?.attributes) {\n const showGridLinesAttr =\n viewNode.attributes.showGridLines ?? viewNode.attributes.showgridlines;\n const showGridLines = parseBooleanAttribute(showGridLinesAttr);\n if (showGridLines !== null) {\n worksheet['!sheetView'] = { showGridLines };\n }\n }\n }\n if (sheetFormatNode) {\n const format: SheetFormatProperties = {};\n const defaultRowHeight = parseFloat(sheetFormatNode.attributes.defaultRowHeight ?? '');\n if (Number.isFinite(defaultRowHeight)) {\n format.defaultRowHeight = defaultRowHeight;\n }\n const defaultColWidth = parseFloat(sheetFormatNode.attributes.defaultColWidth ?? '');\n if (Number.isFinite(defaultColWidth)) {\n format.defaultColWidth = defaultColWidth;\n }\n if (sheetFormatNode.attributes.customHeight !== undefined) {\n format.customHeight = sheetFormatNode.attributes.customHeight === '1';\n }\n if (Object.keys(format).length > 0) {\n worksheet['!sheetFormat'] = format;\n }\n }\n const colsNode = findChild(root, 'cols');\n if (colsNode) {\n worksheet['!cols'] = readColumns(colsNode);\n }\n const sheetDataNode = findChild(root, 'sheetData');\n const { minRow, minCol, maxRow, maxCol } = readSheetData(sheetDataNode, worksheet, sharedStrings, styles);\n const mergesNode = findChild(root, 'mergeCells');\n if (mergesNode) {\n worksheet['!merges'] = readMerges(mergesNode);\n }\n const rowsNode = sheetDataNode ? findChildren(sheetDataNode, 'row') : [];\n if (rowsNode.length) {\n worksheet['!rows'] = readRowsInfo(rowsNode);\n }\n const images = readWorksheetImages(root, zipEntries, sheetPath);\n if (images.length) {\n worksheet['!images'] = images;\n }\n worksheet['!ref'] =\n dimensionRef ??\n encodeRange({\n s: { r: Math.max(minRow, 0), c: Math.max(minCol, 0) },\n e: { r: Math.max(maxRow, 0), c: Math.max(maxCol, 0) },\n });\n return worksheet;\n}\n\nfunction readColumns(colsNode: XmlNode): ColumnInfo[] {\n const columns: ColumnInfo[] = [];\n const colNodes = findChildren(colsNode, 'col');\n for (const colNode of colNodes) {\n const min = Math.max(parseInt(colNode.attributes.min ?? '1', 10) - 1, 0);\n const max = Math.max(parseInt(colNode.attributes.max ?? String(min + 1), 10) - 1, min);\n const width = colNode.attributes.width ? Number(colNode.attributes.width) : undefined;\n const wpx = typeof width === 'number' ? charWidthToPixels(width) : undefined;\n const customAttr = colNode.attributes.customWidth ?? colNode.attributes.customwidth;\n const custom =\n customAttr !== undefined\n ? customAttr === '1' || customAttr.toLowerCase() === 'true'\n : undefined;\n for (let idx = min; idx <= max; idx += 1) {\n columns[idx] = {\n width,\n wch: width,\n wpx,\n custom,\n };\n }\n }\n return columns;\n}\n\nfunction readRowsInfo(rowNodes: XmlNode[]): RowInfo[] {\n const rows: RowInfo[] = [];\n for (const rowNode of rowNodes) {\n const rowIndex = Math.max(parseInt(rowNode.attributes.r ?? '1', 10) - 1, 0);\n const info: RowInfo = {};\n if (rowNode.attributes.ht) {\n const height = Number(rowNode.attributes.ht);\n if (Number.isFinite(height)) {\n info.hpt = height;\n info.hpx = height * (96 / 72);\n }\n }\n if (rowNode.attributes.customHeight !== undefined) {\n info.custom = rowNode.attributes.customHeight === '1' || rowNode.attributes.customHeight === 'true';\n }\n rows[rowIndex] = info;\n }\n return rows;\n}\n\nfunction readWorksheetImages(\n root: XmlNode,\n zipEntries: Record<string, Uint8Array>,\n sheetPath: string,\n): WorksheetImage[] {\n const drawingNodes = findChildren(root, 'drawing');\n if (!drawingNodes.length) {\n return [];\n }\n const relationships = readPartRelationships(zipEntries, sheetPath);\n if (!relationships.size) {\n return [];\n }\n const images: WorksheetImage[] = [];\n for (const drawingNode of drawingNodes) {\n const relId = drawingNode.attributes['r:id'];\n if (!relId) {\n continue;\n }\n const drawingPath = relationships.get(relId);\n if (!drawingPath) {\n continue;\n }\n images.push(...readDrawingImages(zipEntries, drawingPath));\n }\n return images;\n}\n\nfunction readDrawingImages(\n zipEntries: Record<string, Uint8Array>,\n drawingPath: string,\n): WorksheetImage[] {\n if (!zipEntries[drawingPath]) {\n return [];\n }\n const xml = readXml(zipEntries, drawingPath);\n const doc = parseXml(xml);\n const root = doc.children.find((child) => localName(child.name) === 'wsDr') ?? doc.children[0];\n if (!root) {\n return [];\n }\n const relationships = readPartRelationships(zipEntries, drawingPath);\n if (!relationships.size) {\n return [];\n }\n const anchors = root.children.filter((node) => {\n const name = localName(node.name);\n return name === 'oneCellAnchor' || name === 'twoCellAnchor';\n });\n const images: WorksheetImage[] = [];\n anchors.forEach((anchorNode, index) => {\n const picNode = findChild(anchorNode, 'pic');\n if (!picNode) {\n return;\n }\n const blipFill = findChild(picNode, 'blipFill');\n const blip = blipFill ? findChild(blipFill, 'blip') : undefined;\n const embedId =\n blip?.attributes['r:embed'] ??\n blip?.attributes['r:Embed'] ??\n blip?.attributes['r:EMBED'] ??\n blip?.attributes['r:id'];\n if (!embedId) {\n return;\n }\n const imagePath = relationships.get(embedId);\n if (!imagePath) {\n return;\n }\n const anchor = parseDrawingAnchor(anchorNode);\n if (!anchor) {\n return;\n }\n const mediaEntry = zipEntries[imagePath];\n if (!mediaEntry) {\n return;\n }\n const data = new Uint8Array(mediaEntry);\n images.push({\n id: `${drawingPath}#${embedId}#${index}`,\n imagePath,\n format: imagePath.split('.').pop()?.toLowerCase() ?? 'image',\n mimeType: guessMimeType(imagePath),\n data,\n anchor,\n });\n });\n return images;\n}\n\nfunction guessMimeType(path: string): string {\n const ext = path.split('.').pop()?.toLowerCase();\n switch (ext) {\n case 'png':\n return 'image/png';\n case 'jpg':\n case 'jpeg':\n return 'image/jpeg';\n case 'gif':\n return 'image/gif';\n case 'bmp':\n return 'image/bmp';\n case 'svg':\n return 'image/svg+xml';\n case 'tif':\n case 'tiff':\n return 'image/tiff';\n case 'webp':\n return 'image/webp';\n default:\n return 'application/octet-stream';\n }\n}\n\nfunction parseDrawingAnchor(anchorNode: XmlNode): WorksheetImageAnchor | null {\n const fromNode = findChild(anchorNode, 'from');\n const from = parseAnchorPosition(fromNode);\n if (!from) {\n return null;\n }\n const anchorType = localName(anchorNode.name);\n if (anchorType === 'oneCellAnchor') {\n const extNode = findChild(anchorNode, 'ext');\n const width = extNode?.attributes.cx ? Number(extNode.attributes.cx) : 0;\n const height = extNode?.attributes.cy ? Number(extNode.attributes.cy) : 0;\n return {\n type: 'oneCell',\n from,\n width: Number.isFinite(width) ? width : 0,\n height: Number.isFinite(height) ? height : 0,\n };\n }\n if (anchorType === 'twoCellAnchor') {\n const toNode = findChild(anchorNode, 'to');\n const to = parseAnchorPosition(toNode);\n if (!to) {\n return null;\n }\n return {\n type: 'twoCell',\n from,\n to,\n };\n }\n return null;\n}\n\nfunction parseAnchorPosition(node: XmlNode | undefined): DrawingAnchorPosition | null {\n if (!node) {\n return null;\n }\n const column = Number.parseInt(findChild(node, 'col')?.text ?? '0', 10);\n const row = Number.parseInt(findChild(node, 'row')?.text ?? '0', 10);\n const columnOffset = Number.parseInt(findChild(node, 'colOff')?.text ?? '0', 10);\n const rowOffset = Number.parseInt(findChild(node, 'rowOff')?.text ?? '0', 10);\n if (\n Number.isNaN(column) ||\n Number.isNaN(row) ||\n column < 0 ||\n row < 0 ||\n Number.isNaN(columnOffset) ||\n Number.isNaN(rowOffset)\n ) {\n return null;\n }\n return {\n row,\n column,\n rowOffset,\n columnOffset,\n };\n}\n\nfunction readRichTextRuns(node: XmlNode): RichTextRun[] {\n const runNodes = findChildren(node, 'r');\n if (!runNodes.length) {\n const textNode = findChild(node, 't');\n const text = textNode ? getTextContent(textNode) : getTextContent(node);\n return text ? [{ text }] : [];\n }\n const runs: RichTextRun[] = [];\n for (const runNode of runNodes) {\n const textNode = findChild(runNode, 't');\n const text = textNode ? getTextContent(textNode) : '';\n const run: RichTextRun = { text };\n const propsNode = findChild(runNode, 'rPr');\n if (propsNode) {\n const fontNode = findChild(propsNode, 'rFont');\n const fontFamily = fontNode?.attributes.val;\n if (fontFamily) {\n run.fontFamily = fontFamily;\n }\n const sizeNode = findChild(propsNode, 'sz');\n if (sizeNode?.attributes.val) {\n const size = Number(sizeNode.attributes.val);\n if (Number.isFinite(size) && size > 0) {\n run.fontSize = size;\n }\n }\n const boldNode = findChild(propsNode, 'b');\n if (boldNode) {\n run.bold = boldNode.attributes.val === undefined || boldNode.attributes.val !== '0';\n }\n const italicNode = findChild(propsNode, 'i');\n if (italicNode) {\n run.italic = italicNode.attributes.val === undefined || italicNode.attributes.val !== '0';\n }\n const underlineNode = findChild(propsNode, 'u');\n if (underlineNode) {\n const val = underlineNode.attributes.val ?? 'single';\n run.underline = val !== 'none' && val !== '0';\n }\n const colorNode = findChild(propsNode, 'color');\n const rgb = colorNode?.attributes.rgb;\n if (rgb) {\n run.color = convertRichTextColor(rgb);\n }\n }\n runs.push(run);\n }\n return runs;\n}\n\nfunction convertRichTextColor(rgb: string): string {\n if (rgb.length === 8) {\n return `#${rgb.slice(2)}`;\n }\n if (rgb.length === 6) {\n return `#${rgb}`;\n }\n return '#000000';\n}\n\nfunction readSheetData(\n sheetData: XmlNode | undefined,\n worksheet: WorkSheet,\n sharedStrings: SharedStringEntry[],\n styles: WorkbookStyles | undefined,\n): { minRow: number; minCol: number; maxRow: number; maxCol: number } {\n if (!sheetData) {\n return { minRow: 0, minCol: 0, maxRow: 0, maxCol: 0 };\n }\n const rows = findChildren(sheetData, 'row');\n let minRow = Number.MAX_SAFE_INTEGER;\n let minCol = Number.MAX_SAFE_INTEGER;\n let maxRow = 0;\n let maxCol = 0;\n for (const row of rows) {\n const rowIndex = Math.max(parseInt(row.attributes.r ?? '1', 10) - 1, 0);\n const cellNodes = findChildren(row, 'c');\n let fallbackColumn = 0;\n for (const cellNode of cellNodes) {\n const address = cellNode.attributes.r;\n const position = address ? decodeCell(address) : { r: rowIndex, c: fallbackColumn };\n fallbackColumn = position.c + 1;\n const cellType = cellNode.attributes.t ?? 'n';\n const styleIndex = cellNode.attributes.s ? Number(cellNode.attributes.s) : undefined;\n const decoded = readCellValue(cellNode, cellType, sharedStrings);\n const value = decoded.value;\n if (value === null || value === undefined || value === '') {\n continue;\n }\n const cell: CellObject = {\n v: value,\n value,\n t: normalizeCellType(cellType),\n };\n if (decoded.richText && decoded.richText.length > 0) {\n cell.richText = decoded.richText;\n }\n const cellStyle = resolveCellStyle(styleIndex, styles);\n if (cellStyle) {\n cell.s = cellStyle;\n }\n const key = encodeCell(position);\n worksheet[key] = cell;\n minRow = Math.min(minRow, position.r);\n minCol = Math.min(minCol, position.c);\n maxRow = Math.max(maxRow, position.r);\n maxCol = Math.max(maxCol, position.c);\n }\n }\n if (minRow === Number.MAX_SAFE_INTEGER) {\n minRow = 0;\n minCol = 0;\n }\n return { minRow, minCol, maxRow, maxCol };\n}\n\ntype DecodedCellValue = { value: string | number | boolean | null; richText?: RichTextRun[] };\n\nfunction readCellValue(\n cellNode: XmlNode,\n cellType: string,\n sharedStrings: SharedStringEntry[],\n): DecodedCellValue {\n if (cellType === 's') {\n const valueNode = findChild(cellNode, 'v');\n if (!valueNode?.text) {\n return { value: '' };\n }\n const index = Number(valueNode.text);\n const entry = sharedStrings[index];\n return entry ? { value: entry.text, richText: entry.richText } : { value: '' };\n }\n if (cellType === 'inlineStr') {\n const inlineNode = findChild(cellNode, 'is') ?? cellNode;\n const runs = readRichTextRuns(inlineNode);\n if (runs.length > 0) {\n return { value: runs.map((run) => run.text).join(''), richText: runs };\n }\n const textNode = findChild(inlineNode, 't');\n if (textNode) {\n return { value: getTextContent(textNode) };\n }\n return { value: getTextContent(inlineNode) };\n }\n if (cellType === 'b') {\n const valueNode = findChild(cellNode, 'v');\n if (!valueNode?.text) {\n return { value: false };\n }\n return { value: valueNode.text === '1' };\n }\n const valueNode = findChild(cellNode, 'v');\n if (!valueNode) {\n return { value: null };\n }\n if (cellType === 'n' || cellType === 'd') {\n const parsed = Number(valueNode.text);\n if (Number.isFinite(parsed)) {\n return { value: parsed };\n }\n }\n return { value: valueNode.text ?? '' };\n}\n\nfunction normalizeCellType(cellType: string): string {\n if (cellType === 'inlineStr') {\n return 's';\n }\n return cellType;\n}\n\nfunction readMerges(mergeNode: XmlNode): WorksheetMergeRange[] {\n const merges: WorksheetMergeRange[] = [];\n const mergeCells = findChildren(mergeNode, 'mergeCell');\n for (const mergeCell of mergeCells) {\n const ref = mergeCell.attributes.ref;\n if (!ref) {\n continue;\n }\n const range = decodeRange(ref);\n merges.push(range);\n }\n return merges;\n}\n\nfunction readSharedStrings(zipEntries: Record<string, Uint8Array>): SharedStringEntry[] {\n const sharedStrings: SharedStringEntry[] = [];\n const path = 'xl/sharedStrings.xml';\n if (!zipEntries[path]) {\n return sharedStrings;\n }\n const xml = readXml(zipEntries, path);\n const doc = parseXml(xml);\n const root = doc.children.find((child) => localName(child.name) === 'sst');\n if (!root) {\n return sharedStrings;\n }\n const siNodes = findChildren(root, 'si');\n for (const siNode of siNodes) {\n const runs = readRichTextRuns(siNode);\n if (runs.length > 0) {\n sharedStrings.push({ text: runs.map((run) => run.text).join(''), richText: runs });\n continue;\n }\n sharedStrings.push({ text: getTextContent(siNode) });\n }\n return sharedStrings;\n}\n\nfunction readStyles(zipEntries: Record<string, Uint8Array>): WorkbookStyles | undefined {\n const path = 'xl/styles.xml';\n if (!zipEntries[path]) {\n return undefined;\n }\n const xml = readXml(zipEntries, path);\n const doc = parseXml(xml);\n const root = doc.children.find((child) => localName(child.name) === 'styleSheet');\n if (!root) {\n return undefined;\n }\n const styles: WorkbookStyles = {\n CellXf: [],\n Borders: [],\n Fills: [],\n Fonts: [],\n NumberFormats: new Map(),\n };\n const numFmtsNode = findChild(root, 'numFmts');\n if (numFmtsNode) {\n const customFormats = readNumberFormats(numFmtsNode);\n customFormats.forEach((code, id) => {\n styles.NumberFormats?.set(id, code);\n });\n }\n const bordersNode = findChild(root, 'borders');\n if (bordersNode) {\n const borderNodes = findChildren(bordersNode, 'border');\n styles.Borders = borderNodes.map(readBorder);\n }\n const fontsNode = findChild(root, 'fonts');\n if (fontsNode) {\n const fontNodes = findChildren(fontsNode, 'font');\n styles.Fonts = fontNodes.map(readFont);\n }\n const colorsNode = findChild(root, 'colors');\n if (colorsNode) {\n const colors = readColors(colorsNode);\n if (colors.indexed && colors.indexed.length > 0) {\n styles.Colors = colors;\n }\n }\n const fillsNode = findChild(root, 'fills');\n if (fillsNode) {\n const fillNodes = findChildren(fillsNode, 'fill');\n styles.Fills = fillNodes.map((fillNode) => readFill(fillNode));\n }\n const cellXfsNode = findChild(root, 'cellXfs');\n if (cellXfsNode) {\n const xfNodes = findChildren(cellXfsNode, 'xf');\n styles.CellXf = xfNodes.map((xfNode) => {\n const xf: CellXfRecord = {};\n const borderIndex = parseIndexAttribute(xfNode.attributes.borderId ?? xfNode.attributes.borderid);\n if (borderIndex !== null) {\n xf.borderId = borderIndex;\n }\n const fillIndex = parseIndexAttribute(xfNode.attributes.fillId ?? xfNode.attributes.fillid);\n if (fillIndex !== null) {\n xf.fillId = fillIndex;\n }\n const fontIndex = parseIndexAttribute(xfNode.attributes.fontId ?? xfNode.attributes.fontid);\n if (fontIndex !== null) {\n xf.fontId = fontIndex;\n }\n const numFmtId = parseIndexAttribute(xfNode.attributes.numFmtId ?? xfNode.attributes.numfmtid);\n if (numFmtId !== null) {\n xf.numFmtId = numFmtId;\n }\n const alignmentNode = findChild(xfNode, 'alignment');\n if (alignmentNode?.attributes) {\n const horizontal = alignmentNode.attributes.horizontal;\n const vertical = alignmentNode.attributes.vertical;\n if (horizontal || vertical) {\n xf.alignment = {};\n if (horizontal) {\n xf.alignment.horizontal = horizontal;\n }\n if (vertical) {\n xf.alignment.vertical = vertical;\n }\n }\n }\n return xf;\n });\n }\n return styles;\n}\n\nfunction parseIndexAttribute(value: string | undefined): number | null {\n if (value === undefined) {\n return null;\n }\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : null;\n}\n\nfunction parseBooleanAttribute(value: string | undefined): boolean | null {\n if (value === undefined) {\n return null;\n }\n if (value === '1') {\n return true;\n }\n if (value === '0') {\n return false;\n }\n const normalized = value.trim().toLowerCase();\n if (normalized === 'true') {\n return true;\n }\n if (normalized === 'false') {\n return false;\n }\n return null;\n}\n\nfunction readColors(colorsNode: XmlNode): WorkbookColors {\n const colors: WorkbookColors = {};\n const indexedNode = findChild(colorsNode, 'indexedColors');\n if (indexedNode) {\n const rgbNodes = findChildren(indexedNode, 'rgbColor');\n colors.indexed = rgbNodes.map((node) => normalizeRgbAttribute(node.attributes.rgb));\n }\n return colors;\n}\n\nfunction normalizeRgbAttribute(rgb: string | undefined): string | null {\n if (!rgb) {\n return null;\n }\n const hex = rgb.replace(/^#/, '');\n if (hex.length === 8) {\n return `#${hex.slice(2)}`;\n }\n if (hex.length === 6) {\n return `#${hex}`;\n }\n return null;\n}\n\nfunction readBorder(borderNode: XmlNode): ExcelBorder {\n return {\n left: readBorderEdge(findChild(borderNode, 'left')),\n right: readBorderEdge(findChild(borderNode, 'right')),\n top: readBorderEdge(findChild(borderNode, 'top')),\n bottom: readBorderEdge(findChild(borderNode, 'bottom')),\n };\n}\n\nfunction readBorderEdge(edgeNode: XmlNode | undefined): ExcelBorderLine | undefined {\n if (!edgeNode) {\n return undefined;\n }\n const style = edgeNode.attributes.style;\n const colorNode = findChild(edgeNode, 'color');\n const color = readColor(colorNode);\n if (!style && !color) {\n return undefined;\n }\n return { style, color };\n}\n\nfunction readFill(fillNode: XmlNode): ExcelFill | undefined {\n const patternNode = findChild(fillNode, 'patternFill');\n if (!patternNode) {\n return undefined;\n }\n const patternType = patternNode.attributes.patternType ?? patternNode.attributes.patterntype;\n const fgColorNode = findChild(patternNode, 'fgColor');\n const bgColorNode = findChild(patternNode, 'bgColor');\n const fgColor = readColor(fgColorNode);\n const bgColor = readColor(bgColorNode);\n if (!patternType && !fgColor && !bgColor) {\n return undefined;\n }\n return { patternType, fgColor, bgColor };\n}\n\nfunction readColor(colorNode: XmlNode | undefined): ExcelColor | undefined {\n if (!colorNode) {\n return undefined;\n }\n const color: ExcelColor = {};\n if (colorNode.attributes.rgb) {\n color.rgb = colorNode.attributes.rgb;\n }\n const indexed = parseIndexAttribute(colorNode.attributes.indexed);\n if (indexed !== null) {\n color.indexed = indexed;\n }\n const theme = parseIndexAttribute(colorNode.attributes.theme);\n if (theme !== null) {\n color.theme = theme;\n }\n if (colorNode.attributes.tint !== undefined) {\n const tint = Number(colorNode.attributes.tint);\n if (Number.isFinite(tint)) {\n color.tint = tint;\n }\n }\n return Object.keys(color).length ? color : undefined;\n}\n\nfunction readNumberFormats(numFmtsNode: XmlNode): Map<number, string> {\n const formats = new Map<number, string>();\n const numFmtNodes = findChildren(numFmtsNode, 'numFmt');\n for (const fmtNode of numFmtNodes) {\n const id = parseIndexAttribute(fmtNode.attributes.numFmtId ?? fmtNode.attributes.numfmtid);\n const code = fmtNode.attributes.formatCode ?? fmtNode.attributes.formatcode;\n if (id === null || !code) {\n continue;\n }\n formats.set(id, code);\n }\n return formats;\n}\n\nfunction readFont(fontNode: XmlNode): ExcelFont {\n const font: ExcelFont = {};\n const nameNode = findChild(fontNode, 'name');\n if (nameNode?.attributes.val) {\n font.name = nameNode.attributes.val;\n }\n const sizeNode = findChild(fontNode, 'sz');\n if (sizeNode?.attributes.val) {\n const parsed = Number(sizeNode.attributes.val);\n if (Number.isFinite(parsed)) {\n font.size = parsed;\n }\n }\n const colorNode = findChild(fontNode, 'color');\n const color = readColor(colorNode);\n if (color) {\n font.color = color;\n }\n const boldNode = findChild(fontNode, 'b');\n if (boldNode) {\n font.bold = boldNode.attributes.val === undefined || boldNode.attributes.val !== '0';\n }\n const italicNode = findChild(fontNode, 'i');\n if (italicNode) {\n font.italic = italicNode.attributes.val === undefined || italicNode.attributes.val !== '0';\n }\n const underlineNode = findChild(fontNode, 'u');\n if (underlineNode) {\n const val = underlineNode.attributes.val ?? 'single';\n font.underline = val !== 'none' && val !== '0';\n }\n return font;\n}\n\nfunction readWorkbookRelationships(zipEntries: Record<string, Uint8Array>): Map<string, string> {\n return readPartRelationships(zipEntries, 'xl/workbook.xml');\n}\n\nfunction readPartRelationships(\n zipEntries: Record<string, Uint8Array>,\n partPath: string,\n): Map<string, string> {\n const relationships = new Map<string, string>();\n const relsPath = getRelationshipsPath(partPath);\n if (!zipEntries[relsPath]) {\n return relationships;\n }\n const xml = readXml(zipEntries, relsPath);\n const doc = parseXml(xml);\n const root = doc.children.find((child) => localName(child.name) === 'Relationships');\n if (!root) {\n return relationships;\n }\n const relationNodes = findChildren(root, 'Relationship');\n for (const rel of relationNodes) {\n const id = rel.attributes.Id;\n const target = rel.attributes.Target;\n if (!id || !target) {\n continue;\n }\n relationships.set(id, resolveRelationshipTarget(partPath, target));\n }\n return relationships;\n}\n\nfunction getRelationshipsPath(partPath: string): string {\n const lastSlash = partPath.lastIndexOf('/');\n const directory = lastSlash >= 0 ? partPath.slice(0, lastSlash + 1) : '';\n const file = lastSlash >= 0 ? partPath.slice(lastSlash + 1) : partPath;\n return `${directory}_rels/${file}.rels`.replace(/\\/+/g, '/');\n}\n\nfunction resolveRelationshipTarget(basePath: string, target: string): string {\n if (target.startsWith('/')) {\n return target.replace(/^\\//, '');\n }\n const baseParts = basePath.split('/');\n baseParts.pop();\n const segments = target.split('/');\n for (const segment of segments) {\n if (!segment || segment === '.') {\n continue;\n }\n if (segment === '..') {\n if (baseParts.length) {\n baseParts.pop();\n }\n } else {\n baseParts.push(segment);\n }\n }\n return baseParts.join('/');\n}\n\nfunction readXml(zipEntries: Record<string, Uint8Array>, path: string): string {\n const entry = zipEntries[path];\n if (!entry) {\n throw new Error(`File \"${path}\" was not found in the archive.`);\n }\n return decodeUtf8(entry);\n}\n\nfunction decodeUtf8(bytes: Uint8Array): string {\n if (textDecoder) {\n return textDecoder.decode(bytes);\n }\n let result = '';\n for (let i = 0; i < bytes.length; i += 1) {\n result += String.fromCharCode(bytes[i]);\n }\n return result;\n}\n\nfunction normalizeInput(input: ArrayBuffer | Uint8Array | string): Uint8Array {\n if (typeof input === 'string') {\n const buffer = new Uint8Array(input.length);\n for (let i = 0; i < input.length; i += 1) {\n buffer[i] = input.charCodeAt(i) & 0xff;\n }\n return buffer;\n }\n if (input instanceof Uint8Array) {\n return input;\n }\n return new Uint8Array(input);\n}\n\nfunction sheet_to_json<T = (string | number | boolean | null)[]>(sheet: WorkSheet, options?: SheetToJsonOptions): T[] {\n if (options?.header !== 1) {\n throw new Error('sheet_to_json currently supports header: 1 only.');\n }\n const defval = options?.defval ?? null;\n const raw = options?.raw ?? true;\n const rangeRef = sheet['!ref'] ?? inferSheetRange(sheet);\n const range = decodeRange(rangeRef);\n const maxRow = Math.max(range.e.r, 0);\n const maxCol = Math.max(range.e.c, 0);\n const totalRows = maxRow + 1;\n const totalCols = maxCol + 1;\n const rows: (string | number | boolean | null)[][] = new Array(totalRows);\n\n for (let r = range.s.r; r <= range.e.r; r += 1) {\n const row = ensureRow(rows, r, totalCols, defval);\n for (let c = range.s.c; c <= range.e.c; c += 1) {\n const address = encodeCell({ r, c });\n const cell = sheet[address] as CellObject | undefined;\n if (!cell) {\n continue;\n }\n row[c] = raw === false ? formatCell(cell) : (cell.v ?? defval);\n }\n }\n\n for (let r = 0; r < totalRows; r += 1) {\n ensureRow(rows, r, totalCols, defval);\n }\n\n return rows as unknown as T[];\n}\n\nfunction formatCell(cell: CellObject): string {\n if (cell.t === 'b') {\n return cell.v ? 'TRUE' : 'FALSE';\n }\n return cell.v !== null && cell.v !== undefined ? String(cell.v) : '';\n}\n\nfunction inferSheetRange(sheet: WorkSheet): string {\n let minRow = Number.MAX_SAFE_INTEGER;\n let minCol = Number.MAX_SAFE_INTEGER;\n let maxRow = 0;\n let maxCol = 0;\n Object.keys(sheet).forEach((key) => {\n if (!/^[A-Z]+[0-9]+$/.test(key)) {\n return;\n }\n const position = decodeCell(key);\n minRow = Math.min(minRow, position.r);\n minCol = Math.min(minCol, position.c);\n maxRow = Math.max(maxRow, position.r);\n maxCol = Math.max(maxCol, position.c);\n });\n if (minRow === Number.MAX_SAFE_INTEGER) {\n return 'A1:A1';\n }\n return encodeRange({\n s: { r: minRow, c: minCol },\n e: { r: maxRow, c: maxCol },\n });\n}\n\nfunction ensureRow(\n rows: (string | number | boolean | null)[][],\n index: number,\n columnCount: number,\n defval: string | number | boolean | null,\n): (string | number | boolean | null)[] {\n if (!rows[index]) {\n const row: (string | number | boolean | null)[] = new Array(columnCount);\n for (let i = 0; i < columnCount; i += 1) {\n row[i] = defval;\n }\n rows[index] = row;\n }\n return rows[index];\n}\n\nfunction resolveCellStyle(\n styleIndex: number | undefined,\n styles: WorkbookStyles | undefined,\n): CellStyle | undefined {\n if (!styles || typeof styleIndex !== 'number') {\n return undefined;\n }\n const xf = styles.CellXf?.[styleIndex];\n if (!xf) {\n return undefined;\n }\n const style: CellStyle = {};\n if (xf.alignment?.horizontal || xf.alignment?.vertical) {\n style.alignment = {};\n if (xf.alignment.horizontal) {\n style.alignment.horizontal = xf.alignment.horizontal;\n }\n if (xf.alignment.vertical) {\n style.alignment.vertical = xf.alignment.vertical;\n }\n }\n if (typeof xf.numFmtId === 'number') {\n style.numFmtId = xf.numFmtId;\n const customFormat = styles.NumberFormats?.get(xf.numFmtId);\n if (customFormat) {\n style.formatCode = customFormat;\n }\n }\n if (typeof xf.fontId === 'number' && xf.fontId >= 0) {\n const font = styles.Fonts?.[xf.fontId];\n if (font) {\n const normalizedFont: ExcelFont = {};\n if (font.name) {\n normalizedFont.name = font.name;\n }\n if (typeof font.size === 'number' && Number.isFinite(font.size)) {\n normalizedFont.size = font.size;\n }\n if (font.color) {\n normalizedFont.color = { ...font.color };\n }\n if (normalizedFont.name || normalizedFont.size || normalizedFont.color) {\n style.font = normalizedFont;\n }\n }\n }\n return style.alignment || style.font || style.numFmtId !== undefined ? style : undefined;\n}\n\nfunction encodeRange(range: Range): string {\n return `${encodeCell(range.s)}:${encodeCell(range.e)}`;\n}\n\nfunction decodeRange(ref: string): Range {\n const parts = ref.split(':');\n if (parts.length === 1) {\n const pos = decodeCell(parts[0]);\n return { s: pos, e: pos };\n }\n return { s: decodeCell(parts[0]), e: decodeCell(parts[1]) };\n}\n\nfunction encodeCell(position: { r: number; c: number }): string {\n return `${encodeCol(position.c)}${encodeRow(position.r)}`;\n}\n\nfunction decodeCell(address: string): { r: number; c: number } {\n const match = /^([A-Z]+)(\\d+)$/.exec(address.toUpperCase());\n if (!match) {\n throw new Error(`Invalid cell address \"${address}\".`);\n }\n return {\n c: decodeCol(match[1]),\n r: Number(match[2]) - 1,\n };\n}\n\nfunction encodeCol(columnIndex: number): string {\n let column = '';\n let index = columnIndex;\n while (index >= 0) {\n column = String.fromCharCode((index % 26) + 65) + column;\n index = Math.floor(index / 26) - 1;\n }\n return column;\n}\n\nfunction encodeRow(rowIndex: number): string {\n return String(rowIndex + 1);\n}\n\nfunction decodeCol(col: string): number {\n let result = 0;\n for (let i = 0; i < col.length; i += 1) {\n result = result * 26 + (col.charCodeAt(i) - 64);\n }\n return result - 1;\n}\n\nfunction charWidthToPixels(measure: number): number {\n if (!Number.isFinite(measure) || measure <= 0) {\n return 0;\n }\n const MAX_DIGIT_WIDTH = 7;\n const CELL_PADDING = 5;\n if (measure < 1) {\n return Math.floor(measure * (MAX_DIGIT_WIDTH + CELL_PADDING));\n }\n return Math.floor(measure * MAX_DIGIT_WIDTH + CELL_PADDING);\n}\n","import {\n read,\n utils,\n type WorkBook,\n type WorkSheet,\n type CellObject,\n type SheetFormatProperties,\n type DrawingAnchorPosition,\n type WorksheetImage,\n} from './xlsx';\nimport { DEFAULT_COLUMNS, DEFAULT_ROWS } from '../core/worksheet/gridDefaults';\nimport { type CellStyle, type TextAlign, type VerticalAlign } from '../core/style/cellStyle';\nimport { formatNumberWithFormat } from '../core/style/numberFormat';\nimport type { CellInputValue, MergedCellRange } from '../core/cell/types';\nimport type { BorderLineOptions, CellBorderDefinition } from '../core/border/types';\n\n// ---------------------------------------------------------------------------\n// Built-in Excel number format codes (numFmtId → format string)\n// ---------------------------------------------------------------------------\n\nconst BUILTIN_NUMBER_FORMATS: Record<number, string> = {\n 0: 'General',\n 1: '0',\n 2: '0.00',\n 3: '#,##0',\n 4: '#,##0.00',\n 5: '$#,##0_);($#,##0)',\n 6: '$#,##0_);[Red]($#,##0)',\n 7: '$#,##0.00_);($#,##0.00)',\n 8: '$#,##0.00_);[Red]($#,##0.00)',\n 9: '0%',\n 10: '0.00%',\n 11: '0.00E+00',\n 12: '# ?/?',\n 13: '# ??/??',\n 14: 'm/d/yy',\n 15: 'd-mmm-yy',\n 16: 'd-mmm',\n 17: 'mmm-yy',\n 18: 'h:mm AM/PM',\n 19: 'h:mm:ss AM/PM',\n 20: 'h:mm',\n 21: 'h:mm:ss',\n 22: 'm/d/yy h:mm',\n 37: '#,##0 ;(#,##0)',\n 38: '#,##0 ;[Red](#,##0)',\n 39: '#,##0.00;(#,##0.00)',\n 40: '#,##0.00;[Red](#,##0.00)',\n 41: '_(* #,##0_);_(* (#,##0);_(* \"-\"_);_(@_)',\n 42: '_(\"$\"* #,##0_);_(\"$\"* (#,##0);_(\"$\"* \"-\"_);_(@_)',\n 43: '_(* #,##0.00_);_(* (#,##0.00);_(* \"-\"??_);_(@_)',\n 44: '_(\"$\"* #,##0.00_);_(\"$\"* (#,##0.00);_(\"$\"* \"-\"??_);_(@_)',\n 45: 'mm:ss',\n 46: '[h]:mm:ss',\n 47: 'mm:ss.0',\n 48: '##0.0E+0',\n 49: '@',\n};\n\n// ---------------------------------------------------------------------------\n// Internal Excel type aliases\n// ---------------------------------------------------------------------------\n\ntype WorksheetMergeRange = { s: { r: number; c: number }; e: { r: number; c: number } };\ntype ColumnInfo = { wpx?: number; wch?: number; width?: number; custom?: boolean };\ntype RowInfo = { hpx?: number; hpt?: number; custom?: boolean };\ntype ExcelBorder = {\n left?: ExcelBorderLine;\n right?: ExcelBorderLine;\n top?: ExcelBorderLine;\n bottom?: ExcelBorderLine;\n};\ntype ExcelBorderLine = { style?: string; color?: ExcelColor };\ntype ExcelColor = { rgb?: string; indexed?: number; theme?: number; tint?: number };\ntype ExcelFontDefinition = {\n sz?: number;\n name?: string;\n color?: ExcelColor;\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n};\ntype ExcelFill = { patternType?: string; fgColor?: ExcelColor; bgColor?: ExcelColor };\ntype AlignmentStyle = { horizontal?: TextAlign; vertical?: VerticalAlign };\n\nconst CELL_ADDRESS_REGEX = /^[A-Z]+[0-9]+$/i;\nconst EMUS_PER_PIXEL = 914400 / 96;\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport type LoadXlsxOptions = { sheetName?: string };\n\n/** Shape of the return value from XlsxImporter.load(). */\nexport type LoadXlsxResult = { images: WorksheetImage[] };\n\n/**\n * Minimal interface of the worksheet object that the importer writes to.\n * Keeping this narrow makes the importer independent of the full Worksheet class.\n */\nexport interface XlsxImportTarget {\n rows: number;\n columns: number;\n setGridSize(rows: number, columns: number): void;\n setShowGridLines(visible: boolean): void;\n applyColumnWidths(\n widths: Map<number, number>,\n options?: { customColumns?: Set<number>; enforceMinColumnWidth?: boolean },\n ): void;\n applyRowHeights(heights: Map<number, number>, options?: { customRows?: Set<number> }): void;\n applyCellBorders(borders: Map<string, CellBorderDefinition>): void;\n setMergedRanges(ranges: Iterable<MergedCellRange>): void;\n loadCells(cells: Iterable<CellInputValue>): void;\n setScrollOffset(x: number, y: number): void;\n autoFitRows(options?: { rows?: number[]; respectCustomHeight?: boolean }): void;\n}\n\n// ---------------------------------------------------------------------------\n// XlsxImporter\n// ---------------------------------------------------------------------------\n\n/**\n * Parses an xlsx file and loads its data into an XlsxImportTarget (typically a Worksheet).\n * Create a new instance per load operation.\n */\nexport class XlsxImporter {\n private readonly binaryDecoder: TextDecoder | null =\n typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8') : null;\n\n private indexedColors: Map<number, string> | null = null;\n\n constructor(private readonly worksheet: XlsxImportTarget) {}\n\n load(data: ArrayBuffer | Uint8Array | string, options?: LoadXlsxOptions): LoadXlsxResult {\n this.indexedColors = null;\n const workbook = this.readWorkbook(data);\n this.indexedColors = this.buildIndexedColorMap(workbook);\n\n const sheetName = options?.sheetName ?? workbook.SheetNames[0];\n if (!sheetName) {\n throw new Error('Workbook does not contain any sheets.');\n }\n const sheet = workbook.Sheets[sheetName];\n if (!sheet) {\n throw new Error(`Sheet \"${sheetName}\" was not found.`);\n }\n\n const { rows, columns } = this.determineSheetDimensions(sheet);\n this.worksheet.setGridSize(rows, columns);\n\n const sheetIndex = workbook.SheetNames.indexOf(sheetName);\n if (sheetIndex < 0) {\n throw new Error(`Unable to resolve sheet index for \"${sheetName}\".`);\n }\n\n const showGridLines = this.resolveSheetGridLineVisibility(sheet);\n this.worksheet.setShowGridLines(showGridLines ?? true);\n\n const { widths: columnWidths, customColumns } = this.extractColumnWidths(sheet);\n const { heights: rowHeights, customRows } = this.extractRowHeights(sheet);\n this.worksheet.applyColumnWidths(columnWidths, {\n customColumns,\n enforceMinColumnWidth: false,\n });\n this.worksheet.applyRowHeights(rowHeights, { customRows });\n\n const styleIndexes = this.extractCellStyleIndexes(workbook, sheetIndex);\n const cellBorders = this.extractCellBorders(workbook, styleIndexes);\n const numberFormats = this.buildStyleNumberFormatMap(workbook);\n const styleAlignments = this.buildStyleAlignmentMap(workbook);\n const styleFills = this.buildStyleFillMap(workbook);\n const styleFonts = this.buildStyleFontMap(workbook);\n this.worksheet.applyCellBorders(cellBorders);\n\n const sheetMerges = (sheet['!merges'] as WorksheetMergeRange[] | undefined) ?? [];\n const cells = this.extractCells(\n sheet,\n sheetMerges,\n styleIndexes,\n numberFormats,\n styleAlignments,\n styleFills,\n styleFonts,\n );\n const mergedRanges = this.extractMergedRanges(sheetMerges);\n this.worksheet.setMergedRanges(mergedRanges);\n this.worksheet.loadCells(cells);\n this.worksheet.setScrollOffset(0, 0);\n this.worksheet.autoFitRows({ respectCustomHeight: true });\n\n const sheetImages = (sheet['!images'] as WorksheetImage[] | undefined) ?? [];\n const images = sheetImages.map((image) => ({\n ...image,\n data: new Uint8Array(image.data),\n }));\n\n return { images };\n }\n\n private readWorkbook(data: ArrayBuffer | Uint8Array | string): WorkBook {\n if (typeof data === 'string') {\n return read(data, { type: 'binary', cellStyles: true, bookFiles: true });\n }\n const buffer = data instanceof Uint8Array ? data : new Uint8Array(data);\n return read(buffer, { type: 'array', cellStyles: true, bookFiles: true });\n }\n\n private determineSheetDimensions(sheet: WorkSheet): { rows: number; columns: number } {\n const ref = sheet['!ref'];\n if (typeof ref === 'string') {\n const range = utils.decode_range(ref);\n return { rows: Math.max(1, range.e.r + 1), columns: Math.max(1, range.e.c + 1) };\n }\n let maxRow = -1;\n let maxCol = -1;\n for (const address of Object.keys(sheet)) {\n if (!CELL_ADDRESS_REGEX.test(address)) {\n continue;\n }\n const position = utils.decode_cell(address);\n maxRow = Math.max(maxRow, position.r);\n maxCol = Math.max(maxCol, position.c);\n }\n if (maxRow < 0 || maxCol < 0) {\n return { rows: DEFAULT_ROWS, columns: DEFAULT_COLUMNS };\n }\n return { rows: maxRow + 1, columns: maxCol + 1 };\n }\n\n private resolveSheetGridLineVisibility(sheet: WorkSheet): boolean | null {\n const flag = sheet['!sheetView']?.showGridLines;\n return typeof flag === 'boolean' ? flag : null;\n }\n\n private extractCells(\n sheet: WorkSheet,\n merges: WorksheetMergeRange[],\n styleIndexes: Map<string, number>,\n numberFormats: Map<number, string>,\n styleAlignments: Map<number, AlignmentStyle>,\n styleFills: Map<number, string>,\n styleFonts: Map<\n number,\n {\n color?: string;\n fontFamily?: string;\n fontSize?: number;\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n }\n >,\n ): CellInputValue[] {\n const rows = utils.sheet_to_json<(string | number | boolean | null)[]>(sheet, {\n header: 1,\n raw: true,\n defval: '',\n });\n\n const maxRows = Math.min(rows.length, this.worksheet.rows);\n const cells: CellInputValue[] = [];\n for (let r = 0; r < maxRows; r += 1) {\n const row = rows[r];\n const maxColumns = Math.min(row.length, this.worksheet.columns);\n for (let c = 0; c < maxColumns; c += 1) {\n const cellValue = row[c];\n const address = utils.encode_cell({ r, c });\n const cellMeta = sheet[address] as CellObject | undefined;\n const styleIndex = styleIndexes.get(address);\n const styleAlignment =\n styleIndex !== undefined ? styleAlignments.get(styleIndex) : undefined;\n const textAlign = this.getHorizontalAlignment(\n cellMeta,\n merges,\n r,\n c,\n styleAlignment?.horizontal,\n );\n const verticalAlign = this.getVerticalAlignment(\n cellMeta,\n merges,\n r,\n c,\n styleAlignment?.vertical,\n );\n const backgroundColor = styleIndex !== undefined ? styleFills.get(styleIndex) : undefined;\n const fontOverrides = styleIndex !== undefined ? styleFonts.get(styleIndex) : undefined;\n const style = this.buildCellStyle(\n cellMeta,\n textAlign,\n verticalAlign,\n backgroundColor,\n fontOverrides,\n );\n const formatCode = styleIndex !== undefined ? numberFormats.get(styleIndex) : undefined;\n const rawString = this.serializeRawCellValue(cellValue ?? null);\n const formattedValue =\n typeof cellValue === 'number' && formatCode\n ? formatNumberWithFormat(cellValue, formatCode)\n : null;\n const richText = cellMeta?.richText;\n const hasValue = rawString !== null && rawString.length > 0;\n if (!hasValue && !style && !richText?.length) {\n continue;\n }\n cells.push({\n row: r,\n column: c,\n value: rawString ?? '',\n displayValue: formattedValue ?? undefined,\n numberFormat: formatCode,\n style,\n richText: richText && richText.length ? richText.map((run) => ({ ...run })) : undefined,\n });\n }\n }\n return cells;\n }\n\n private extractMergedRanges(merges: WorksheetMergeRange[]): MergedCellRange[] {\n const normalized: MergedCellRange[] = [];\n for (const merge of merges) {\n const top = Math.min(Math.max(merge.s.r, 0), this.worksheet.rows - 1);\n const bottom = Math.min(Math.max(merge.e.r, 0), this.worksheet.rows - 1);\n const left = Math.min(Math.max(merge.s.c, 0), this.worksheet.columns - 1);\n const right = Math.min(Math.max(merge.e.c, 0), this.worksheet.columns - 1);\n const normalizedTop = Math.min(top, bottom);\n const normalizedBottom = Math.max(top, bottom);\n const normalizedLeft = Math.min(left, right);\n const normalizedRight = Math.max(left, right);\n if (normalizedTop === normalizedBottom && normalizedLeft === normalizedRight) {\n continue;\n }\n normalized.push({\n topRow: normalizedTop,\n bottomRow: normalizedBottom,\n leftColumn: normalizedLeft,\n rightColumn: normalizedRight,\n });\n }\n return normalized;\n }\n\n private extractColumnWidths(sheet: WorkSheet): {\n widths: Map<number, number>;\n customColumns: Set<number>;\n } {\n const output = new Map<number, number>();\n const customColumns = new Set<number>();\n const sheetFormat = this.getSheetFormat(sheet);\n const defaultWidth = this.normalizeDefaultColumnWidth(sheetFormat?.defaultColWidth);\n if (defaultWidth !== null) {\n for (let column = 0; column < this.worksheet.columns; column += 1) {\n output.set(column, defaultWidth);\n }\n }\n const columns = sheet['!cols'] as ColumnInfo[] | undefined;\n if (!Array.isArray(columns)) {\n return { widths: output, customColumns };\n }\n for (let index = 0; index < columns.length && index < this.worksheet.columns; index += 1) {\n const col = columns[index];\n if (!col) {\n continue;\n }\n const width = this.normalizeColumnWidth(col);\n if (width !== null) {\n output.set(index, width);\n }\n if (col.custom) {\n customColumns.add(index);\n }\n }\n return { widths: output, customColumns };\n }\n\n private extractRowHeights(sheet: WorkSheet): {\n heights: Map<number, number>;\n customRows: Set<number>;\n } {\n const output = new Map<number, number>();\n const customRows = new Set<number>();\n const sheetFormat = this.getSheetFormat(sheet);\n const defaultHeight = this.normalizeDefaultRowHeight(sheetFormat?.defaultRowHeight);\n if (defaultHeight !== null) {\n for (let row = 0; row < this.worksheet.rows; row += 1) {\n output.set(row, defaultHeight);\n }\n }\n const rows = sheet['!rows'] as RowInfo[] | undefined;\n if (!Array.isArray(rows)) {\n return { heights: output, customRows };\n }\n for (let index = 0; index < rows.length && index < this.worksheet.rows; index += 1) {\n const row = rows[index];\n if (!row) {\n continue;\n }\n const height = this.normalizeRowHeight(row);\n if (height !== null) {\n output.set(index, height);\n if (row.custom) {\n customRows.add(index);\n }\n }\n }\n return { heights: output, customRows };\n }\n\n private extractCellStyleIndexes(workbook: WorkBook, sheetIndex: number): Map<string, number> {\n const xml = this.getSheetXml(workbook, sheetIndex);\n if (!xml) {\n return new Map();\n }\n const regex = /<c\\b([^>]*)>/g;\n const map = new Map<string, number>();\n let match: RegExpExecArray | null;\n while ((match = regex.exec(xml)) !== null) {\n const attrs = match[1];\n const refMatch = /r=\"([^\"]+)\"/.exec(attrs);\n const styleMatch = /s=\"([^\"]+)\"/.exec(attrs);\n if (!refMatch || !styleMatch) {\n continue;\n }\n const styleIndex = Number(styleMatch[1]);\n if (!Number.isFinite(styleIndex)) {\n continue;\n }\n map.set(refMatch[1], styleIndex);\n }\n return map;\n }\n\n private extractCellBorders(\n workbook: WorkBook,\n styleIndexes: Map<string, number>,\n ): Map<string, CellBorderDefinition> {\n if (!styleIndexes.size) {\n return new Map();\n }\n const styles = this.buildStyleBorderMap(workbook);\n if (!styles.size) {\n return new Map();\n }\n const borders = new Map<string, CellBorderDefinition>();\n for (const [address, styleIndex] of styleIndexes.entries()) {\n const border = styles.get(styleIndex);\n if (!border) {\n continue;\n }\n const decoded = utils.decode_cell(address);\n if (\n decoded.r < 0 ||\n decoded.c < 0 ||\n decoded.r >= this.worksheet.rows ||\n decoded.c >= this.worksheet.columns\n ) {\n continue;\n }\n borders.set(`${decoded.r}:${decoded.c}`, border);\n }\n return borders;\n }\n\n private buildStyleNumberFormatMap(workbook: WorkBook): Map<number, string> {\n const map = new Map<number, string>();\n const styles = workbook.Styles;\n const cellXfs = styles?.CellXf ?? [];\n cellXfs.forEach((xf, index) => {\n const numFmtId = this.parseIndex(xf.numFmtId);\n if (numFmtId === null) {\n return;\n }\n const code = styles?.NumberFormats?.get(numFmtId) ?? BUILTIN_NUMBER_FORMATS[numFmtId];\n if (code) {\n map.set(index, code);\n }\n });\n return map;\n }\n\n private buildStyleAlignmentMap(workbook: WorkBook): Map<number, AlignmentStyle> {\n const workbookAny = workbook as unknown as {\n Styles?: { CellXf?: Array<{ alignment?: { horizontal?: string; vertical?: string } }> };\n };\n const cellXfs = workbookAny.Styles?.CellXf ?? [];\n const map = new Map<number, AlignmentStyle>();\n cellXfs.forEach((xf, index) => {\n const horizontal = this.normalizeHorizontalAlignment(xf.alignment?.horizontal);\n const vertical = this.normalizeVerticalAlignment(xf.alignment?.vertical);\n if (horizontal || vertical) {\n map.set(index, { horizontal, vertical });\n }\n });\n return map;\n }\n\n private buildStyleFillMap(workbook: WorkBook): Map<number, string> {\n const workbookAny = workbook as unknown as {\n Styles?: {\n CellXf?: Array<{ fillId?: number | string; [key: string]: unknown }>;\n Fills?: Array<ExcelFill | undefined>;\n };\n };\n const cellXfs = workbookAny.Styles?.CellXf ?? [];\n const fills = (workbookAny.Styles?.Fills ?? []) as Array<ExcelFill | undefined>;\n const map = new Map<number, string>();\n cellXfs.forEach((xf, index) => {\n const fillIndex = this.parseIndex(xf.fillId ?? xf.fillid);\n if (fillIndex === null) {\n return;\n }\n const fill = fills[fillIndex];\n const color = this.convertExcelFill(fill);\n if (color) {\n map.set(index, color);\n }\n });\n return map;\n }\n\n private buildStyleFontMap(workbook: WorkBook): Map<\n number,\n {\n color?: string;\n fontFamily?: string;\n fontSize?: number;\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n }\n > {\n const workbookAny = workbook as unknown as {\n Styles?: {\n CellXf?: Array<{ fontId?: number | string; [key: string]: unknown }>;\n Fonts?: Array<ExcelFontDefinition | undefined>;\n };\n };\n const cellXfs = workbookAny.Styles?.CellXf ?? [];\n const fonts = (workbookAny.Styles?.Fonts ?? []) as Array<ExcelFontDefinition | undefined>;\n const map = new Map<\n number,\n {\n color?: string;\n fontFamily?: string;\n fontSize?: number;\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n }\n >();\n cellXfs.forEach((xf, index) => {\n const fontIndex = this.parseIndex(xf.fontId ?? xf.fontid);\n if (fontIndex === null) {\n return;\n }\n const font = fonts[fontIndex];\n if (!font) {\n return;\n }\n const color = this.extractFontColor(font) ?? undefined;\n const fontFamily = font?.name;\n const fontSize = typeof font?.sz === 'number' ? font.sz : undefined;\n const bold = typeof font?.bold === 'boolean' ? font.bold : undefined;\n const italic = typeof font?.italic === 'boolean' ? font.italic : undefined;\n const underline = typeof font?.underline === 'boolean' ? font.underline : undefined;\n if (color || fontFamily || fontSize || bold !== undefined || italic !== undefined || underline !== undefined) {\n map.set(index, { color, fontFamily, fontSize, bold, italic, underline });\n }\n });\n return map;\n }\n\n private buildStyleBorderMap(workbook: WorkBook): Map<number, CellBorderDefinition> {\n const workbookAny = workbook as unknown as {\n Styles?: {\n CellXf?: Array<{ borderId?: number | string; [key: string]: unknown }>;\n Borders?: ExcelBorder[];\n };\n };\n const cellXfs = (workbookAny.Styles?.CellXf ?? []) as Array<{\n borderId?: number | string;\n [key: string]: unknown;\n }>;\n const borders = (workbookAny.Styles?.Borders ?? []) as ExcelBorder[];\n const map = new Map<number, CellBorderDefinition>();\n cellXfs.forEach((xf, index) => {\n const borderIndex = this.parseIndex(xf.borderId ?? xf.borderid);\n if (borderIndex === null) {\n return;\n }\n const excelBorder = borders[borderIndex];\n const converted = this.convertExcelBorder(excelBorder);\n if (converted) {\n map.set(index, converted);\n }\n });\n return map;\n }\n\n private convertExcelFill(fill?: ExcelFill): string | null {\n if (!fill) {\n return null;\n }\n const patternType = fill.patternType?.toLowerCase();\n if (patternType && patternType !== 'solid') {\n return null;\n }\n const color = fill.fgColor ?? fill.bgColor;\n if (!color) {\n return null;\n }\n return this.convertExcelColor(color, '#ffffff');\n }\n\n private convertExcelBorder(border?: ExcelBorder): CellBorderDefinition | null {\n if (!border) {\n return null;\n }\n const result: CellBorderDefinition = {};\n const top = this.convertExcelBorderLine(border.top);\n const right = this.convertExcelBorderLine(border.right);\n const bottom = this.convertExcelBorderLine(border.bottom);\n const left = this.convertExcelBorderLine(border.left);\n if (top) {\n result.top = top;\n }\n if (right) {\n result.right = right;\n }\n if (bottom) {\n result.bottom = bottom;\n }\n if (left) {\n result.left = left;\n }\n return Object.keys(result).length ? result : null;\n }\n\n private convertExcelBorderLine(edge?: ExcelBorderLine) {\n if (!edge || !edge.style) {\n return undefined;\n }\n const { style, width } = this.mapExcelBorderStyle(edge.style);\n const color = this.convertExcelColor(edge.color);\n return { style, width, color };\n }\n\n private mapExcelBorderStyle(excelStyle: string): {\n style: BorderLineOptions['style'];\n width: number;\n } {\n switch (excelStyle) {\n case 'dotted':\n return { style: 'dotted', width: 1 };\n case 'dashDot':\n case 'dashDotDot':\n case 'dashed':\n return { style: 'dashed', width: 1 };\n case 'mediumDashDot':\n case 'mediumDashDotDot':\n case 'mediumDashed':\n return { style: 'dashed', width: 2 };\n case 'thick':\n case 'double':\n return { style: 'solid', width: 3 };\n case 'medium':\n return { style: 'solid', width: 2 };\n case 'hair':\n case 'thin':\n default:\n return { style: 'solid', width: 1 };\n }\n }\n\n private convertExcelColor(color?: ExcelColor, fallback = '#1f2933'): string {\n return this.resolveExcelColor(color) ?? fallback;\n }\n\n private resolveExcelColor(color?: ExcelColor): string | null {\n if (!color) {\n return null;\n }\n if (color.rgb) {\n const normalized = this.normalizeColorHex(color.rgb);\n if (normalized) {\n return normalized;\n }\n }\n if (color.indexed !== undefined) {\n const paletteColor = this.indexedColors?.get(color.indexed);\n if (paletteColor) {\n return paletteColor;\n }\n }\n return null;\n }\n\n private normalizeColorHex(value: string | null | undefined): string | null {\n if (!value) {\n return null;\n }\n const hex = value.replace(/^#/, '');\n if (hex.length === 8) {\n return `#${hex.slice(2)}`;\n }\n if (hex.length === 6) {\n return `#${hex}`;\n }\n return null;\n }\n\n private extractFontColor(font?: ExcelFontDefinition): string | null {\n if (!font?.color) {\n return null;\n }\n return this.convertExcelColor(font.color);\n }\n\n private buildIndexedColorMap(workbook: WorkBook): Map<number, string> | null {\n const indexed = workbook.Styles?.Colors?.indexed;\n if (!indexed || indexed.length === 0) {\n return null;\n }\n const map = new Map<number, string>();\n indexed.forEach((value, index) => {\n const normalized = this.normalizeColorHex(value);\n if (normalized) {\n map.set(index, normalized);\n }\n });\n return map.size ? map : null;\n }\n\n private getSheetXml(workbook: WorkBook, sheetIndex: number): string | null {\n const workbookAny = workbook as unknown as {\n Directory?: { sheets?: string[] };\n files?: Record<string, { content?: unknown } | ArrayBuffer | Uint8Array | string>;\n };\n const sheets = workbookAny.Directory?.sheets;\n if (!sheets || sheetIndex < 0 || sheetIndex >= sheets.length) {\n return null;\n }\n const path = sheets[sheetIndex]?.replace(/^\\/+/, '');\n if (!path) {\n return null;\n }\n const fileRecord = workbookAny.files?.[path];\n if (!fileRecord) {\n return null;\n }\n const raw = (fileRecord as { content?: unknown }).content ?? fileRecord;\n return this.decodeBinaryString(raw);\n }\n\n private decodeBinaryString(data: unknown): string | null {\n if (!data) {\n return null;\n }\n if (typeof data === 'string') {\n return data;\n }\n if (data instanceof ArrayBuffer) {\n return this.decodeWithTextDecoder(new Uint8Array(data));\n }\n if (ArrayBuffer.isView(data)) {\n const view = data as ArrayBufferView;\n const array = new Uint8Array(view.buffer, view.byteOffset, view.byteLength);\n return this.decodeWithTextDecoder(array);\n }\n return null;\n }\n\n private decodeWithTextDecoder(bytes: Uint8Array): string {\n if (this.binaryDecoder) {\n return this.binaryDecoder.decode(bytes);\n }\n let result = '';\n for (let i = 0; i < bytes.length; i += 1) {\n result += String.fromCharCode(bytes[i]);\n }\n return result;\n }\n\n private parseIndex(value: unknown): number | null {\n const parsed = typeof value === 'string' ? Number.parseInt(value, 10) : Number(value);\n return Number.isFinite(parsed) ? parsed : null;\n }\n\n private getSheetFormat(sheet: WorkSheet): SheetFormatProperties | undefined {\n const format = sheet['!sheetFormat'];\n if (format && typeof format === 'object') {\n return format as SheetFormatProperties;\n }\n return undefined;\n }\n\n private normalizeColumnWidth(column: ColumnInfo): number | null {\n if (typeof column.wpx === 'number' && column.wpx > 0) {\n return column.wpx;\n }\n if (typeof column.width === 'number' && column.width > 0) {\n return this.charWidthToPixels(column.width);\n }\n if (typeof column.wch === 'number' && column.wch > 0) {\n return this.charWidthToPixels(column.wch);\n }\n return null;\n }\n\n private normalizeRowHeight(row: RowInfo): number | null {\n if (typeof row.hpx === 'number' && row.hpx > 0) {\n return row.hpx;\n }\n if (typeof row.hpt === 'number' && row.hpt > 0) {\n return row.hpt * (96 / 72);\n }\n return null;\n }\n\n private normalizeDefaultColumnWidth(width?: number): number | null {\n if (typeof width !== 'number' || Number.isNaN(width) || width <= 0) {\n return null;\n }\n return this.charWidthToPixels(width);\n }\n\n private normalizeDefaultRowHeight(height?: number): number | null {\n if (typeof height !== 'number' || Number.isNaN(height) || height <= 0) {\n return null;\n }\n return height * (96 / 72);\n }\n\n private charWidthToPixels(measure: number): number {\n if (!Number.isFinite(measure) || measure <= 0) {\n return 0;\n }\n const MAX_DIGIT_WIDTH = 7; // Excel default for Calibri 11\n const CELL_PADDING = 5; // Excel adds ~5px padding to each column\n if (measure < 1) {\n return Math.floor(measure * (MAX_DIGIT_WIDTH + CELL_PADDING));\n }\n return Math.floor(measure * MAX_DIGIT_WIDTH + CELL_PADDING);\n }\n\n private getHorizontalAlignment(\n cell: CellObject | undefined,\n merges: WorksheetMergeRange[],\n row: number,\n column: number,\n styleAlignment?: TextAlign,\n ): TextAlign | undefined {\n const explicit =\n styleAlignment ??\n this.normalizeHorizontalAlignment(\n (cell?.s as { alignment?: { horizontal?: string } } | undefined)?.alignment?.horizontal,\n );\n if (explicit) {\n return explicit;\n }\n if (cell && (cell.t === 'n' || cell.t === 'd')) {\n return 'right';\n }\n return undefined;\n }\n\n private getVerticalAlignment(\n cell: CellObject | undefined,\n merges: WorksheetMergeRange[],\n row: number,\n column: number,\n styleAlignment?: VerticalAlign,\n ): VerticalAlign | undefined {\n return (\n styleAlignment ??\n this.normalizeVerticalAlignment(\n (cell?.s as { alignment?: { vertical?: string } } | undefined)?.alignment?.vertical,\n )\n );\n }\n\n private buildCellStyle(\n cell: CellObject | undefined,\n textAlign: TextAlign | undefined,\n verticalAlign: VerticalAlign | undefined,\n backgroundColor: string | undefined,\n fontOverrides?: {\n color?: string;\n fontFamily?: string;\n fontSize?: number;\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n },\n ): Partial<CellStyle> | undefined {\n const style: Partial<CellStyle> = {};\n if (textAlign) {\n style.textAlign = textAlign;\n }\n if (verticalAlign) {\n style.verticalAlign = verticalAlign;\n }\n if (backgroundColor) {\n style.backgroundColor = backgroundColor;\n }\n const resolvedFontColor = this.getCellFontColor(cell) ?? fontOverrides?.color;\n if (resolvedFontColor) {\n style.color = resolvedFontColor;\n }\n const fontFamily = this.getCellFontFamily(cell) ?? fontOverrides?.fontFamily;\n if (fontFamily) {\n style.fontFamily = fontFamily;\n }\n const fontSize = this.getCellFontSize(cell) ?? fontOverrides?.fontSize;\n if (fontSize) {\n style.fontSize = fontSize;\n }\n const fontBold = this.getCellFontBold(cell) ?? fontOverrides?.bold;\n if (fontBold !== undefined) {\n style.bold = fontBold;\n }\n const fontItalic = this.getCellFontItalic(cell) ?? fontOverrides?.italic;\n if (fontItalic !== undefined) {\n style.italic = fontItalic;\n }\n const fontUnderline = this.getCellFontUnderline(cell) ?? fontOverrides?.underline;\n if (fontUnderline !== undefined) {\n style.underline = fontUnderline;\n }\n return Object.keys(style).length ? style : undefined;\n }\n\n private getCellFontColor(cell: CellObject | undefined): string | undefined {\n const fontColor = (cell?.s as { font?: { color?: ExcelColor } } | undefined)?.font?.color;\n if (!fontColor) {\n return undefined;\n }\n return this.convertExcelColor(fontColor);\n }\n\n private getCellFontFamily(cell: CellObject | undefined): string | undefined {\n const fontName = (cell?.s as { font?: { name?: string } } | undefined)?.font?.name;\n if (typeof fontName === 'string' && fontName.trim().length > 0) {\n return fontName;\n }\n return undefined;\n }\n\n private getCellFontSize(cell: CellObject | undefined): number | undefined {\n const fontSize = (cell?.s as { font?: { size?: number } } | undefined)?.font?.size;\n if (typeof fontSize !== 'number' || Number.isNaN(fontSize) || fontSize <= 0) {\n return undefined;\n }\n return fontSize;\n }\n\n private getCellFontBold(cell: CellObject | undefined): boolean | undefined {\n const fontBold = (cell?.s as { font?: { bold?: boolean } } | undefined)?.font?.bold;\n return typeof fontBold === 'boolean' ? fontBold : undefined;\n }\n\n private getCellFontItalic(cell: CellObject | undefined): boolean | undefined {\n const fontItalic = (cell?.s as { font?: { italic?: boolean } } | undefined)?.font?.italic;\n return typeof fontItalic === 'boolean' ? fontItalic : undefined;\n }\n\n private getCellFontUnderline(cell: CellObject | undefined): boolean | undefined {\n const fontUnderline = (cell?.s as { font?: { underline?: boolean } } | undefined)?.font?.underline;\n return typeof fontUnderline === 'boolean' ? fontUnderline : undefined;\n }\n\n private normalizeHorizontalAlignment(value?: string): TextAlign | undefined {\n switch (value) {\n case 'center':\n case 'centerContinuous':\n case 'distributed':\n case 'justify':\n return 'center';\n case 'right':\n return 'right';\n case 'left':\n return 'left';\n default:\n return undefined;\n }\n }\n\n private normalizeVerticalAlignment(value?: string): VerticalAlign | undefined {\n switch (value) {\n case 'center':\n case 'centerContinuous':\n case 'distributed':\n case 'justify':\n case 'middle':\n return 'middle';\n case 'bottom':\n return 'bottom';\n case 'top':\n return 'top';\n default:\n return undefined;\n }\n }\n\n private serializeRawCellValue(value: string | number | boolean | null): string | null {\n if (value === null || value === undefined) {\n return null;\n }\n if (typeof value === 'string') {\n return value;\n }\n if (typeof value === 'number') {\n return Number.isFinite(value) ? value.toString() : null;\n }\n if (typeof value === 'boolean') {\n return value ? 'TRUE' : 'FALSE';\n }\n return null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Image URL helpers (used by WorksheetAPI after import)\n// ---------------------------------------------------------------------------\n\nexport type WorksheetImageAnchorPosition = {\n row: number;\n column: number;\n offsetX: number;\n offsetY: number;\n};\n\nexport type WorksheetImagePlacement =\n | { type: 'oneCell'; from: WorksheetImageAnchorPosition; width: number; height: number }\n | { type: 'twoCell'; from: WorksheetImageAnchorPosition; to: WorksheetImageAnchorPosition };\n\nexport type WorksheetImageInfo = {\n id: string;\n mimeType: string;\n data: Uint8Array;\n anchor: WorksheetImagePlacement;\n};\n\nexport function convertImageInfo(image: WorksheetImage): WorksheetImageInfo {\n return {\n id: image.id,\n mimeType: image.mimeType,\n data: image.data,\n anchor: convertAnchor(image.anchor),\n };\n}\n\nfunction convertAnchor(anchor: WorksheetImage['anchor']): WorksheetImagePlacement {\n if (anchor.type === 'oneCell') {\n return {\n type: 'oneCell',\n from: convertAnchorPosition(anchor.from),\n width: emuToPixels(anchor.width),\n height: emuToPixels(anchor.height),\n };\n }\n return {\n type: 'twoCell',\n from: convertAnchorPosition(anchor.from),\n to: convertAnchorPosition(anchor.to),\n };\n}\n\nfunction convertAnchorPosition(position: DrawingAnchorPosition): WorksheetImageAnchorPosition {\n return {\n row: position.row,\n column: position.column,\n offsetX: emuToPixels(position.columnOffset),\n offsetY: emuToPixels(position.rowOffset),\n };\n}\n\nfunction emuToPixels(value: number): number {\n return Number.isFinite(value) ? value / EMUS_PER_PIXEL : 0;\n}\n\nexport function buildImageUrl(image: WorksheetImage): string {\n if (\n typeof Blob !== 'undefined' &&\n typeof URL !== 'undefined' &&\n typeof URL.createObjectURL === 'function'\n ) {\n const view = image.data;\n const buffer =\n view.byteOffset === 0 && view.byteLength === view.buffer.byteLength\n ? (view.buffer as ArrayBuffer)\n : (view.buffer.slice(view.byteOffset, view.byteOffset + view.byteLength) as ArrayBuffer);\n const blob = new Blob([buffer], { type: image.mimeType });\n return URL.createObjectURL(blob);\n }\n return `data:${image.mimeType};base64,${encodeBase64(image.data)}`;\n}\n\nfunction encodeBase64(data: Uint8Array): string {\n if (typeof btoa === 'function') {\n let binary = '';\n for (let i = 0; i < data.length; i += 1) {\n binary += String.fromCharCode(data[i]);\n }\n return btoa(binary);\n }\n throw new Error('Base64 encoding is not supported in this environment.');\n}\n","const LOCAL_FILE_HEADER_SIGNATURE = 0x04034b50;\nconst CENTRAL_DIRECTORY_SIGNATURE = 0x02014b50;\nconst END_OF_CENTRAL_DIR_SIGNATURE = 0x06054b50;\n\nconst textEncoder = typeof TextEncoder !== 'undefined' ? new TextEncoder() : null;\n\nconst CRC32_TABLE = (() => {\n const table = new Uint32Array(256);\n for (let i = 0; i < 256; i += 1) {\n let value = i;\n for (let bit = 0; bit < 8; bit += 1) {\n value = (value & 1) === 1 ? 0xedb88320 ^ (value >>> 1) : value >>> 1;\n }\n table[i] = value >>> 0;\n }\n return table;\n})();\n\nfunction encodeUtf8(input: string): Uint8Array {\n if (textEncoder) {\n return textEncoder.encode(input);\n }\n const buffer = new Uint8Array(input.length);\n for (let i = 0; i < input.length; i += 1) {\n buffer[i] = input.charCodeAt(i);\n }\n return buffer;\n}\n\nfunction crc32(data: Uint8Array): number {\n let crc = 0xffffffff;\n for (let i = 0; i < data.length; i += 1) {\n crc = CRC32_TABLE[(crc ^ data[i]) & 0xff] ^ (crc >>> 8);\n }\n return (crc ^ 0xffffffff) >>> 0;\n}\n\nexport function createZip(entries: Array<{ name: string; data: Uint8Array }>): Uint8Array {\n const fileChunks: Uint8Array[] = [];\n const centralChunks: Uint8Array[] = [];\n let offset = 0;\n\n for (const entry of entries) {\n const nameBytes = encodeUtf8(entry.name);\n const entryCrc = crc32(entry.data);\n const localHeader = new Uint8Array(30 + nameBytes.length);\n const localView = new DataView(localHeader.buffer);\n localView.setUint32(0, LOCAL_FILE_HEADER_SIGNATURE, true);\n localView.setUint16(4, 20, true); // version needed to extract\n localView.setUint16(6, 0, true); // general purpose bit flag\n localView.setUint16(8, 0, true); // compression (0 = store)\n localView.setUint16(10, 0, true); // mod time\n localView.setUint16(12, 0, true); // mod date\n localView.setUint32(14, entryCrc, true);\n localView.setUint32(18, entry.data.length, true);\n localView.setUint32(22, entry.data.length, true);\n localView.setUint16(26, nameBytes.length, true);\n localView.setUint16(28, 0, true); // extra field length\n localHeader.set(nameBytes, 30);\n\n fileChunks.push(localHeader);\n fileChunks.push(entry.data);\n\n const centralHeader = new Uint8Array(46 + nameBytes.length);\n const centralView = new DataView(centralHeader.buffer);\n centralView.setUint32(0, CENTRAL_DIRECTORY_SIGNATURE, true);\n centralView.setUint16(4, 20, true); // version made by\n centralView.setUint16(6, 20, true); // version needed to extract\n centralView.setUint16(8, 0, true); // general purpose bit flag\n centralView.setUint16(10, 0, true); // compression\n centralView.setUint16(12, 0, true); // mod time\n centralView.setUint16(14, 0, true); // mod date\n centralView.setUint32(16, entryCrc, true);\n centralView.setUint32(20, entry.data.length, true);\n centralView.setUint32(24, entry.data.length, true);\n centralView.setUint16(28, nameBytes.length, true);\n centralView.setUint16(30, 0, true); // extra field length\n centralView.setUint16(32, 0, true); // file comment length\n centralView.setUint16(34, 0, true); // disk number start\n centralView.setUint16(36, 0, true); // internal file attributes\n centralView.setUint32(40, 0, true); // external file attributes\n centralView.setUint32(42, offset, true);\n centralHeader.set(nameBytes, 46);\n\n centralChunks.push(centralHeader);\n\n offset += localHeader.length + entry.data.length;\n }\n\n const centralDirOffset = offset;\n const centralDirSize = centralChunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const eocd = new Uint8Array(22);\n const eocdView = new DataView(eocd.buffer);\n eocdView.setUint32(0, END_OF_CENTRAL_DIR_SIGNATURE, true);\n eocdView.setUint16(4, 0, true); // number of this disk\n eocdView.setUint16(6, 0, true); // disk where central directory starts\n eocdView.setUint16(8, entries.length, true); // number of central dir records on this disk\n eocdView.setUint16(10, entries.length, true); // total central dir records\n eocdView.setUint32(12, centralDirSize, true);\n eocdView.setUint32(16, centralDirOffset, true);\n eocdView.setUint16(20, 0, true); // comment length\n\n const totalLength =\n fileChunks.reduce((sum, chunk) => sum + chunk.length, 0) + centralDirSize + eocd.length;\n const output = new Uint8Array(totalLength);\n let position = 0;\n for (const chunk of fileChunks) {\n output.set(chunk, position);\n position += chunk.length;\n }\n for (const chunk of centralChunks) {\n output.set(chunk, position);\n position += chunk.length;\n }\n output.set(eocd, position);\n return output;\n}\n","import { DEFAULT_COLUMN_WIDTH, DEFAULT_ROW_HEIGHT } from '../core/worksheet/gridDefaults';\nimport { DEFAULT_CELL_STYLE, type CellStyle } from '../core/style/cellStyle';\nimport type { WorksheetExportSnapshot } from '../core/worksheet/worksheet';\nimport { utils } from './xlsx';\nimport { createZip } from './zipWriter';\n\nconst WORKBOOK_NAMESPACE = 'http://schemas.openxmlformats.org/spreadsheetml/2006/main';\nconst RELS_NAMESPACE = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships';\n\nconst textEncoder = typeof TextEncoder !== 'undefined' ? new TextEncoder() : null;\nconst COLUMN_PADDING = 5;\nconst COLUMN_CHARACTER_WIDTH = 7;\n\ntype FontDefinition = {\n name?: string;\n sz?: number;\n bold?: true;\n italic?: true;\n underline?: string;\n color?: { rgb: string };\n};\n\ntype FillDefinition =\n | { patternType: 'none' }\n | { patternType: 'gray125' }\n | { patternType: 'solid'; fgColor: { rgb: string }; bgColor: { indexed: string } };\n\ntype AlignmentDefinition = { horizontal?: string; vertical?: string; wrapText?: '1' };\n\ntype CellXfDefinition = {\n fontId: number;\n fillId: number;\n alignment?: AlignmentDefinition;\n applyFont?: boolean;\n applyFill?: boolean;\n applyAlignment?: boolean;\n};\n\nfunction encodeUtf8(value: string): Uint8Array {\n if (textEncoder) {\n return textEncoder.encode(value);\n }\n const output = new Uint8Array(value.length);\n for (let i = 0; i < value.length; i += 1) {\n output[i] = value.charCodeAt(i);\n }\n return output;\n}\n\nexport function buildXlsxFromSnapshot(\n snapshot: WorksheetExportSnapshot,\n sheetName: string,\n): ArrayBuffer {\n const styleManager = new StyleManager();\n const sharedStrings = new SharedStringTable();\n const sheetXml = buildSheetXml(snapshot, styleManager, sharedStrings);\n const stylesXml = styleManager.buildStylesXml();\n const workbookXml = buildWorkbookXml(sheetName);\n const workbookRelsXml = buildWorkbookRelationshipsXml();\n const contentTypesXml = buildContentTypesXml();\n const sharedStringsXml = buildSharedStringsXml(sharedStrings);\n const themeXml = buildThemeXml();\n const timestamp = formatIsoDate(new Date());\n const corePropertiesXml = buildCorePropertiesXml(timestamp);\n const appPropertiesXml = buildAppPropertiesXml();\n const rootRelsXml = buildRootRelationshipsXml();\n\n const entries = [\n { name: '[Content_Types].xml', data: encodeUtf8(contentTypesXml) },\n { name: '_rels/.rels', data: encodeUtf8(rootRelsXml) },\n { name: 'xl/workbook.xml', data: encodeUtf8(workbookXml) },\n { name: 'xl/_rels/workbook.xml.rels', data: encodeUtf8(workbookRelsXml) },\n { name: 'xl/styles.xml', data: encodeUtf8(stylesXml) },\n { name: 'xl/sharedStrings.xml', data: encodeUtf8(sharedStringsXml) },\n { name: 'xl/theme/theme1.xml', data: encodeUtf8(themeXml) },\n { name: 'docProps/core.xml', data: encodeUtf8(corePropertiesXml) },\n { name: 'docProps/app.xml', data: encodeUtf8(appPropertiesXml) },\n { name: 'xl/worksheets/sheet1.xml', data: encodeUtf8(sheetXml) },\n ];\n const zip = createZip(entries);\n return zip.buffer.slice(zip.byteOffset, zip.byteOffset + zip.byteLength) as ArrayBuffer;\n}\n\nfunction buildSheetXml(\n snapshot: WorksheetExportSnapshot,\n styleManager: StyleManager,\n strings: SharedStringTable,\n): string {\n const cellGroups = new Map<number, WorksheetExportSnapshot['cells']>();\n let maxRow = Math.max(snapshot.rows - 1, 0);\n let maxCol = Math.max(snapshot.columns - 1, 0);\n\n for (const cell of snapshot.cells) {\n if (!cellGroups.has(cell.row)) {\n cellGroups.set(cell.row, []);\n }\n cellGroups.get(cell.row)!.push(cell);\n maxRow = Math.max(maxRow, cell.row);\n maxCol = Math.max(maxCol, cell.column);\n }\n\n for (const merge of snapshot.merges) {\n maxRow = Math.max(maxRow, merge.bottomRow);\n maxCol = Math.max(maxCol, merge.rightColumn);\n }\n\n const dimensionRef = `${utils.encode_cell({ r: 0, c: 0 })}:${utils.encode_cell({\n r: Math.max(maxRow, 0),\n c: Math.max(maxCol, 0),\n })}`;\n\n const columns = buildColumnsSection(Math.max(snapshot.columnWidths.length, maxCol + 1), snapshot);\n const rows = buildRowsSection(cellGroups, snapshot, styleManager, strings);\n const merges = buildMergeCellsSection(snapshot.merges);\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<worksheet xmlns:r=\"${RELS_NAMESPACE}\" xmlns=\"${WORKBOOK_NAMESPACE}\">\n <dimension ref=\"${dimensionRef}\"/>\n <sheetViews>\n <sheetView workbookViewId=\"0\" showGridLines=\"1\"/>\n </sheetViews>\n <sheetFormatPr defaultColWidth=\"${columnWidthToExcel(DEFAULT_COLUMN_WIDTH)}\" defaultRowHeight=\"${DEFAULT_ROW_HEIGHT}\"/>\n ${columns}\n <sheetData>${rows}</sheetData>\n ${merges}\n</worksheet>`;\n}\n\nfunction buildColumnsSection(columnCount: number, snapshot: WorksheetExportSnapshot): string {\n const parts: string[] = [];\n for (let index = 0; index < Math.max(columnCount, 1); index += 1) {\n const widthPx = snapshot.columnWidths[index] ?? DEFAULT_COLUMN_WIDTH;\n const width = columnWidthToExcel(widthPx);\n const customWidth = widthPx !== DEFAULT_COLUMN_WIDTH ? ' customWidth=\"1\"' : '';\n parts.push(`<col min=\"${index + 1}\" max=\"${index + 1}\" width=\"${width}\"${customWidth}/>`);\n }\n return `<cols>${parts.join('')}</cols>`;\n}\n\nfunction columnWidthToExcel(px: number): string {\n const width = Math.max(0.1, (px - COLUMN_PADDING) / COLUMN_CHARACTER_WIDTH);\n return width.toFixed(4);\n}\n\nfunction buildRowsSection(\n cellGroups: Map<number, WorksheetExportSnapshot['cells']>,\n snapshot: WorksheetExportSnapshot,\n styleManager: StyleManager,\n strings: SharedStringTable,\n): string {\n const rowHeights = snapshot.rowHeights;\n const rowsToRender = new Set<number>();\n for (const rowIndex of cellGroups.keys()) {\n rowsToRender.add(rowIndex);\n }\n for (let index = 0; index < rowHeights.length; index += 1) {\n const height = rowHeights[index];\n if (height !== DEFAULT_ROW_HEIGHT) {\n rowsToRender.add(index);\n }\n }\n const sortedRows = Array.from(rowsToRender).sort((a, b) => a - b);\n const parts: string[] = [];\n for (const rowIndex of sortedRows) {\n const height = snapshot.rowHeights[rowIndex] ?? DEFAULT_ROW_HEIGHT;\n const attributes = [`r=\"${rowIndex + 1}\"`];\n if (height !== DEFAULT_ROW_HEIGHT) {\n attributes.push(`ht=\"${height.toFixed(2)}\"`);\n attributes.push('customHeight=\"1\"');\n }\n const cells = (cellGroups.get(rowIndex) ?? []).slice().sort((a, b) => a.column - b.column);\n const cellXml = cells.map((cell) => buildCellXml(cell, styleManager, strings)).join('');\n if (cellXml) {\n parts.push(`<row ${attributes.join(' ')}>${cellXml}</row>`);\n } else {\n parts.push(`<row ${attributes.join(' ')}/>`);\n }\n }\n return parts.join('');\n}\n\nfunction buildCellXml(\n cell: WorksheetExportSnapshot['cells'][number],\n styleManager: StyleManager,\n strings: SharedStringTable,\n): string {\n const address = utils.encode_cell({ r: cell.row, c: cell.column });\n const styleIndex = styleManager.getStyleIndex(cell.style);\n const styleAttribute = typeof styleIndex === 'number' ? ` s=\"${styleIndex}\"` : '';\n const value = cell.value ?? '';\n if (typeof value === 'string') {\n const index = strings.register(value);\n return `<c r=\"${address}\" t=\"s\"${styleAttribute}><v>${index}</v></c>`;\n }\n if (typeof value === 'number') {\n return `<c r=\"${address}\" t=\"n\"${styleAttribute}><v>${value}</v></c>`;\n }\n if (typeof value === 'boolean') {\n return `<c r=\"${address}\" t=\"b\"${styleAttribute}><v>${value ? 1 : 0}</v></c>`;\n }\n return `<c r=\"${address}\" t=\"n\"${styleAttribute}><v>0</v></c>`;\n}\n\nfunction buildMergeCellsSection(merges: WorksheetExportSnapshot['merges']): string {\n if (!merges.length) {\n return '';\n }\n const cells = merges.map((merge) => {\n const start = utils.encode_cell({ r: merge.topRow, c: merge.leftColumn });\n const end = utils.encode_cell({ r: merge.bottomRow, c: merge.rightColumn });\n return `<mergeCell ref=\"${start}:${end}\"/>`;\n });\n return `<mergeCells count=\"${cells.length}\">${cells.join('')}</mergeCells>`;\n}\n\nfunction escapeXml(input: string): string {\n return input\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&apos;');\n}\n\nfunction buildWorkbookXml(name: string): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<workbook xmlns:r=\"${RELS_NAMESPACE}\" xmlns=\"${WORKBOOK_NAMESPACE}\">\n <sheets>\n <sheet name=\"${escapeXml(name)}\" sheetId=\"1\" r:id=\"rId1\"/>\n </sheets>\n</workbook>`;\n}\n\nfunction buildWorkbookRelationshipsXml(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"${RELS_NAMESPACE}\">\n <Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet\" Target=\"worksheets/sheet1.xml\"/>\n <Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/>\n <Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings\" Target=\"sharedStrings.xml\"/>\n <Relationship Id=\"rId4\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme\" Target=\"theme/theme1.xml\"/>\n</Relationships>`;\n}\n\nfunction buildContentTypesXml(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">\n <Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/>\n <Default Extension=\"xml\" ContentType=\"application/xml\"/>\n <Override PartName=\"/xl/workbook.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml\"/>\n <Override PartName=\"/xl/worksheets/sheet1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml\"/>\n <Override PartName=\"/xl/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml\"/>\n <Override PartName=\"/xl/sharedStrings.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml\"/>\n <Override PartName=\"/xl/theme/theme1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.theme+xml\"/>\n <Override PartName=\"/docProps/core.xml\" ContentType=\"application/vnd.openxmlformats-package.core-properties+xml\"/>\n <Override PartName=\"/docProps/app.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.extended-properties+xml\"/>\n</Types>`;\n}\n\nfunction buildRootRelationshipsXml(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n <Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\" Target=\"xl/workbook.xml\"/>\n <Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/metadata/core-properties\" Target=\"docProps/core.xml\"/>\n <Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties\" Target=\"docProps/app.xml\"/>\n</Relationships>`;\n}\n\nfunction buildSharedStringsXml(table: SharedStringTable): string {\n const entriesXml = table.entries\n .map(\n (entry) =>\n `<si><t${entry.preserve ? ' xml:space=\"preserve\"' : ''}>${escapeXml(entry.text)}</t></si>`,\n )\n .join('');\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<sst xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" count=\"${table.count}\" uniqueCount=\"${table.entries.length}\">\n ${entriesXml}\n</sst>`;\n}\n\nclass SharedStringTable {\n public entries: Array<{ text: string; preserve: boolean }> = [];\n public count = 0;\n\n private readonly map: Map<string, number> = new Map();\n\n register(value: string): number {\n this.count += 1;\n const existing = this.map.get(value);\n if (existing !== undefined) {\n return existing;\n }\n const preserve = /^\\s|\\s$/.test(value);\n const index = this.entries.length;\n this.entries.push({ text: value, preserve });\n this.map.set(value, index);\n return index;\n }\n}\n\nfunction buildThemeXml(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<a:theme xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" name=\"Office Theme\">\n <a:themeElements>\n <a:clrScheme name=\"Office\">\n <a:dk1><a:sysClr val=\"windowText\" lastClr=\"000000\"/></a:dk1>\n <a:lt1><a:sysClr val=\"window\" lastClr=\"FFFFFF\"/></a:lt1>\n <a:dk2><a:srgbClr val=\"1F497D\"/></a:dk2>\n <a:lt2><a:srgbClr val=\"EEECE1\"/></a:lt2>\n <a:accent1><a:srgbClr val=\"4F81BC\"/></a:accent1>\n <a:accent2><a:srgbClr val=\"C0504D\"/></a:accent2>\n <a:accent3><a:srgbClr val=\"9BBB59\"/></a:accent3>\n <a:accent4><a:srgbClr val=\"8064A2\"/></a:accent4>\n <a:accent5><a:srgbClr val=\"4BACC6\"/></a:accent5>\n <a:accent6><a:srgbClr val=\"F79646\"/></a:accent6>\n <a:hlink><a:srgbClr val=\"0000FF\"/></a:hlink>\n <a:folHlink><a:srgbClr val=\"800080\"/></a:folHlink>\n </a:clrScheme>\n <a:fontScheme name=\"Office\">\n <a:majorFont>\n <a:latin typeface=\"Calibri\"/>\n </a:majorFont>\n <a:minorFont>\n <a:latin typeface=\"Calibri\"/>\n </a:minorFont>\n </a:fontScheme>\n <a:fmtScheme name=\"Office\">\n <a:fillStyleLst>\n <a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill>\n <a:gradFill rotWithShape=\"1\">\n <a:gsLst>\n <a:gs pos=\"0\"><a:schemeClr val=\"phClr\"><a:lumMod val=\"110000\"/><a:lumOff val=\"100000\"/></a:schemeClr></a:gs>\n <a:gs pos=\"50000\"><a:schemeClr val=\"phClr\"><a:lumMod val=\"105000\"/><a:lumOff val=\"100000\"/></a:schemeClr></a:gs>\n <a:gs pos=\"100000\"><a:schemeClr val=\"phClr\"><a:lumMod val=\"105000\"/><a:lumOff val=\"100000\"/></a:schemeClr></a:gs>\n </a:gsLst>\n <a:lin ang=\"16200000\" scaled=\"1\"/>\n </a:gradFill>\n <a:gradFill rotWithShape=\"1\">\n <a:gsLst>\n <a:gs pos=\"0\"><a:schemeClr val=\"phClr\"><a:lumMod val=\"110000\"/><a:lumOff val=\"100000\"/></a:schemeClr></a:gs>\n <a:gs pos=\"100000\"><a:schemeClr val=\"phClr\"><a:lumMod val=\"105000\"/><a:lumOff val=\"100000\"/></a:schemeClr></a:gs>\n </a:gsLst>\n <a:lin ang=\"16200000\" scaled=\"0\"/>\n </a:gradFill>\n </a:fillStyleLst>\n <a:lnStyleLst>\n <a:ln w=\"9525\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\">\n <a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill>\n <a:prstDash val=\"solid\"/>\n </a:ln>\n </a:lnStyleLst>\n <a:effectStyleLst>\n <a:effectStyle><a:effectLst/></a:effectStyle>\n <a:effectStyle><a:effectLst/></a:effectStyle>\n <a:effectStyle><a:effectLst/></a:effectStyle>\n </a:effectStyleLst>\n <a:bgFillStyleLst>\n <a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill>\n <a:solidFill><a:schemeClr val=\"phClr\"><a:lumMod val=\"95000\"/><a:satMod val=\"105000\"/></a:schemeClr></a:solidFill>\n </a:bgFillStyleLst>\n </a:fmtScheme>\n </a:themeElements>\n </a:theme>`;\n}\n\nfunction formatIsoDate(date: Date): string {\n return date.toISOString();\n}\n\nfunction buildCorePropertiesXml(timestamp: string): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<cp:coreProperties xmlns:cp=\"http://schemas.openxmlformats.org/package/2006/metadata/core-properties\"\n xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n xmlns:dcterms=\"http://purl.org/dc/terms/\"\n xmlns:dcmitype=\"http://purl.org/dc/dcmitype/\"\n xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n <dc:creator>ReoGrid</dc:creator>\n <cp:lastModifiedBy>ReoGrid</cp:lastModifiedBy>\n <dcterms:created xsi:type=\"dcterms:W3CDTF\">${timestamp}</dcterms:created>\n <dcterms:modified xsi:type=\"dcterms:W3CDTF\">${timestamp}</dcterms:modified>\n</cp:coreProperties>`;\n}\n\nfunction buildAppPropertiesXml(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Properties xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties\"\n xmlns:vt=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\">\n <Application>ReoGrid</Application>\n <DocSecurity>0</DocSecurity>\n <ScaleCrop>false</ScaleCrop>\n <HeadingPairs>\n <vt:vector size=\"2\" baseType=\"variant\">\n <vt:variant><vt:lpstr>Worksheets</vt:lpstr></vt:variant>\n <vt:variant><vt:i4>1</vt:i4></vt:variant>\n </vt:vector>\n </HeadingPairs>\n <TitlesOfParts>\n <vt:vector size=\"1\" baseType=\"lpstr\">\n <vt:lpstr>Sheet1</vt:lpstr>\n </vt:vector>\n </TitlesOfParts>\n <Company/>\n <LinksUpToDate>false</LinksUpToDate>\n <SharedDoc>false</SharedDoc>\n</Properties>`;\n}\n\nclass StyleManager {\n private readonly fonts: FontDefinition[] = [\n { name: DEFAULT_CELL_STYLE.fontFamily, sz: DEFAULT_CELL_STYLE.fontSize },\n ];\n private readonly fontKeyMap = new Map<string, number>();\n private readonly fills: FillDefinition[] = [\n { patternType: 'none' },\n { patternType: 'gray125' },\n ];\n private readonly fillKeyMap = new Map<string, number>();\n private readonly cellXfs: CellXfDefinition[] = [{ fontId: 0, fillId: 0 }];\n private readonly styleKeyMap = new Map<string, number>();\n\n public getStyleIndex(style?: CellStyle): number | undefined {\n if (!style) {\n return undefined;\n }\n const fontId = this.resolveFont(style);\n const fillId = this.resolveFill(style);\n const alignment = this.resolveAlignment(style);\n const key = `${fontId}:${fillId}:${alignment?.horizontal ?? ''}:${alignment?.vertical ?? ''}:${alignment?.wrapText ?? ''}`;\n const existing = this.styleKeyMap.get(key);\n if (existing !== undefined) {\n return existing;\n }\n const index = this.cellXfs.length;\n this.cellXfs.push({\n fontId,\n fillId,\n alignment,\n applyFont: fontId !== 0,\n applyFill: fillId !== 0,\n applyAlignment: Boolean(\n alignment && (alignment.horizontal || alignment.vertical || alignment.wrapText),\n ),\n });\n this.styleKeyMap.set(key, index);\n return index;\n }\n\n public buildStylesXml(): string {\n const fontsXml = this.fonts.map((font) => {\n const parts: string[] = [];\n if (font.sz) {\n parts.push(`<sz val=\"${font.sz}\"/>`);\n }\n if (font.name) {\n parts.push(`<name val=\"${escapeXml(font.name)}\"/>`);\n }\n if (font.bold) {\n parts.push('<b/>');\n }\n if (font.italic) {\n parts.push('<i/>');\n }\n if (font.underline) {\n parts.push(`<u val=\"${font.underline}\"/>`);\n }\n if (font.color) {\n parts.push(`<color rgb=\"${font.color.rgb}\"/>`);\n }\n return `<font>${parts.join('')}</font>`;\n });\n\n const fillsXml = this.fills.map((fill) => {\n if (fill.patternType === 'none') {\n return '<fill><patternFill patternType=\"none\"/></fill>';\n }\n if (fill.patternType === 'gray125') {\n return '<fill><patternFill patternType=\"gray125\"/></fill>';\n }\n if (fill.patternType === 'solid') {\n return `<fill><patternFill patternType=\"solid\"><fgColor rgb=\"${fill.fgColor.rgb}\"/><bgColor indexed=\"${fill.bgColor.indexed}\"/></patternFill></fill>`;\n }\n return '<fill><patternFill patternType=\"none\"/></fill>';\n });\n\n const cellXfsXml = this.cellXfs.map((xf) => {\n const attributes = [\n `numFmtId=\"0\"`,\n `fontId=\"${xf.fontId}\"`,\n `fillId=\"${xf.fillId}\"`,\n `borderId=\"0\"`,\n `xfId=\"0\"`,\n ];\n if (xf.applyFont) {\n attributes.push('applyFont=\"1\"');\n }\n if (xf.applyFill) {\n attributes.push('applyFill=\"1\"');\n }\n if (xf.applyAlignment) {\n attributes.push('applyAlignment=\"1\"');\n }\n const alignmentXml = xf.alignment\n ? `<alignment${xf.alignment.horizontal ? ` horizontal=\"${xf.alignment.horizontal}\"` : ''}${\n xf.alignment.vertical ? ` vertical=\"${xf.alignment.vertical}\"` : ''\n }${xf.alignment.wrapText ? ' wrapText=\"1\"' : ''}/>`\n : '';\n return `<xf ${attributes.join(' ')}>${alignmentXml}</xf>`;\n });\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<styleSheet xmlns=\"${WORKBOOK_NAMESPACE}\" xmlns:x14ac=\"http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" mc:Ignorable=\"x14ac\">\n <numFmts count=\"0\"/>\n <fonts count=\"${this.fonts.length}\">${fontsXml.join('')}</fonts>\n <fills count=\"${this.fills.length}\">${fillsXml.join('')}</fills>\n <borders count=\"1\">\n <border>\n <left/>\n <right/>\n <top/>\n <bottom/>\n <diagonal/>\n </border>\n </borders>\n <cellStyleXfs count=\"1\">\n <xf numFmtId=\"0\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\"/>\n </cellStyleXfs>\n <cellXfs count=\"${this.cellXfs.length}\">${cellXfsXml.join('')}</cellXfs>\n <cellStyles count=\"1\">\n <cellStyle name=\"Normal\" xfId=\"0\" builtinId=\"0\"/>\n </cellStyles>\n</styleSheet>`;\n }\n\n private resolveFont(style: CellStyle): number {\n const defaultColor = normalizeColor(DEFAULT_CELL_STYLE.color);\n const styleColor = normalizeColor(style.color);\n const hasFontOverrides =\n style.fontFamily !== DEFAULT_CELL_STYLE.fontFamily ||\n style.fontSize !== DEFAULT_CELL_STYLE.fontSize ||\n style.bold ||\n style.italic ||\n style.underline ||\n (styleColor && styleColor !== defaultColor);\n if (!hasFontOverrides) {\n return 0;\n }\n const key = `font:${\n style.fontFamily || ''\n }:${style.fontSize}:${style.bold ? '1' : '0'}:${style.italic ? '1' : '0'}:${style.underline ? '1' : '0'}:${styleColor ?? ''}`;\n const cached = this.fontKeyMap.get(key);\n if (cached !== undefined) {\n return cached;\n }\n const entry: FontDefinition = {};\n if (style.fontFamily && style.fontFamily !== DEFAULT_CELL_STYLE.fontFamily) {\n entry.name = style.fontFamily;\n }\n if (style.fontSize && style.fontSize !== DEFAULT_CELL_STYLE.fontSize) {\n entry.sz = style.fontSize;\n }\n if (style.bold) {\n entry.bold = true;\n }\n if (style.italic) {\n entry.italic = true;\n }\n if (style.underline) {\n entry.underline = 'single';\n }\n if (styleColor && styleColor !== defaultColor) {\n entry.color = { rgb: styleColor };\n }\n this.fonts.push(entry);\n const index = this.fonts.length - 1;\n this.fontKeyMap.set(key, index);\n return index;\n }\n\n private resolveFill(style: CellStyle): number {\n const color = normalizeColor(style.backgroundColor);\n const defaultBackground = normalizeColor(DEFAULT_CELL_STYLE.backgroundColor);\n if (!color || color === defaultBackground) {\n return 0;\n }\n const key = `fill:${color}`;\n const cached = this.fillKeyMap.get(key);\n if (cached !== undefined) {\n return cached;\n }\n const entry: FillDefinition = {\n patternType: 'solid',\n fgColor: { rgb: color },\n bgColor: { indexed: '64' },\n };\n this.fills.push(entry);\n const index = this.fills.length - 1;\n this.fillKeyMap.set(key, index);\n return index;\n }\n\n private resolveAlignment(style: CellStyle): AlignmentDefinition | undefined {\n const horizontal = style.textAlign !== DEFAULT_CELL_STYLE.textAlign ? style.textAlign : undefined;\n const verticalValue =\n style.verticalAlign !== DEFAULT_CELL_STYLE.verticalAlign\n ? style.verticalAlign === 'middle'\n ? 'center'\n : style.verticalAlign\n : undefined;\n const wrapText =\n style.textWrapMode !== DEFAULT_CELL_STYLE.textWrapMode ? '1' : undefined;\n if (!horizontal && !verticalValue && !wrapText) {\n return undefined;\n }\n return {\n horizontal,\n vertical: verticalValue,\n wrapText,\n };\n }\n}\n\nfunction normalizeColor(color: string): string | undefined {\n if (!color || typeof color !== 'string') {\n return undefined;\n }\n let normalized = color.trim();\n if (!normalized) {\n return undefined;\n }\n if (normalized.startsWith('#')) {\n normalized = normalized.slice(1);\n }\n const rgbMatch = normalized.match(/^rgba?\\((\\d{1,3}),\\s*(\\d{1,3}),\\s*(\\d{1,3})/i);\n if (rgbMatch) {\n const [r, g, b] = rgbMatch.slice(1).map((value) =>\n Math.max(0, Math.min(255, Number(value) || 0)),\n );\n return `FF${[r, g, b].map((segment) => segment.toString(16).padStart(2, '0')).join('')}`.toUpperCase();\n }\n if (normalized.length === 3) {\n normalized = normalized\n .split('')\n .map((char) => char + char)\n .join('');\n }\n if (normalized.length === 6 || normalized.length === 8) {\n const hex = normalized.toUpperCase();\n return hex.length === 6 ? `FF${hex}` : hex;\n }\n return undefined;\n}\n","import type { Worksheet } from './worksheet';\nimport type { CellStyle } from '../style/cellStyle';\nimport type { BorderLineOptions, RangeBorderSide } from '../border/types';\n\nexport type CellStyleInput = Partial<CellStyle>;\n\n// ---------------------------------------------------------------------------\n// CellHandle\n// ---------------------------------------------------------------------------\n\nexport class CellHandle {\n private readonly ws: Worksheet;\n\n private readonly r: number;\n\n private readonly c: number;\n\n constructor(ws: Worksheet, row: number, col: number) {\n this.ws = ws;\n this.r = row;\n this.c = col;\n }\n\n get value(): string {\n return this.ws.getCellInput(this.r, this.c) ?? '';\n }\n\n set value(v: string) {\n this.ws.setCellInput(this.r, this.c, v);\n }\n\n get style(): Partial<CellStyle> {\n return this.ws.getComputedCellStyle(this.r, this.c);\n }\n\n set style(s: CellStyleInput) {\n this.ws.setCellStyle(this.r, this.c, s);\n }\n\n getValue(): string {\n return this.value;\n }\n\n setValue(v: string): this {\n this.value = v;\n return this;\n }\n\n getStyle(): CellStyle {\n return this.ws.getComputedCellStyle(this.r, this.c);\n }\n\n setStyle(s: CellStyleInput): this {\n this.ws.setCellStyle(this.r, this.c, s);\n return this;\n }\n}\n\n/** No-op handle returned when a cell address is outside the allowed constraint bounds. */\nexport class NullCellHandle {\n get value(): string {\n return '';\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n set value(_v: string) {}\n\n get style(): Partial<CellStyle> {\n return {};\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n set style(_s: CellStyleInput) {}\n\n getValue(): string {\n return '';\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n setValue(_v: string): this {\n return this;\n }\n\n getStyle(): CellStyle {\n return {} as CellStyle;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n setStyle(_s: CellStyleInput): this {\n return this;\n }\n}\n\n// ---------------------------------------------------------------------------\n// RangeHandle\n// ---------------------------------------------------------------------------\n\nexport class RangeHandle {\n private readonly ws: Worksheet;\n\n private readonly topRow: number;\n\n private readonly leftColumn: number;\n\n private readonly bottomRow: number;\n\n private readonly rightColumn: number;\n\n constructor(\n ws: Worksheet,\n topRow: number,\n leftColumn: number,\n bottomRow: number,\n rightColumn: number,\n ) {\n this.ws = ws;\n this.topRow = topRow;\n this.leftColumn = leftColumn;\n this.bottomRow = bottomRow;\n this.rightColumn = rightColumn;\n }\n\n setStyle(style: CellStyleInput): this {\n for (let row = this.topRow; row <= this.bottomRow; row += 1) {\n for (let col = this.leftColumn; col <= this.rightColumn; col += 1) {\n this.ws.setCellStyle(row, col, style);\n }\n }\n return this;\n }\n\n setBackgroundColor(color: string): this {\n this.ws.setRangeBackgroundColor(\n this.topRow,\n this.leftColumn,\n this.bottomRow,\n this.rightColumn,\n color,\n );\n return this;\n }\n\n merge(): this {\n this.ws.mergeCells(this.topRow, this.leftColumn, this.bottomRow, this.rightColumn);\n return this;\n }\n\n unmerge(): this {\n this.ws.unmergeCells(this.topRow, this.leftColumn, this.bottomRow, this.rightColumn);\n return this;\n }\n\n border(options: BorderLineOptions, sides?: RangeBorderSide[]): this {\n this.ws.setRangeBorder(\n this.topRow,\n this.leftColumn,\n this.bottomRow,\n this.rightColumn,\n options,\n sides,\n );\n return this;\n }\n}\n\n/** No-op handle returned when a range is outside the allowed constraint bounds. */\nexport class NullRangeHandle {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n setStyle(_s: CellStyleInput): this {\n return this;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n setBackgroundColor(_c: string): this {\n return this;\n }\n\n merge(): this {\n return this;\n }\n\n unmerge(): this {\n return this;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n border(_o: BorderLineOptions, _s?: RangeBorderSide[]): this {\n return this;\n }\n}\n\n// ---------------------------------------------------------------------------\n// ColumnHandle\n// ---------------------------------------------------------------------------\n\nexport class ColumnHandle {\n private readonly ws: Worksheet;\n\n private readonly col: number;\n\n constructor(ws: Worksheet, col: number) {\n this.ws = ws;\n this.col = col;\n }\n\n get width(): number {\n return this.ws.columnWidths[this.col] ?? 0;\n }\n\n set width(w: number) {\n this.ws.setColumnWidth(this.col, w);\n }\n}\n\n// ---------------------------------------------------------------------------\n// RowHandle\n// ---------------------------------------------------------------------------\n\nexport class RowHandle {\n private readonly ws: Worksheet;\n\n private readonly row: number;\n\n constructor(ws: Worksheet, row: number) {\n this.ws = ws;\n this.row = row;\n }\n\n get height(): number {\n return this.ws.rowHeights[this.row] ?? 0;\n }\n\n set height(h: number) {\n this.ws.setRowHeight(this.row, h);\n }\n}\n","import { Worksheet, MIN_COLUMN_WIDTH, MIN_ROW_HEIGHT, CELL_TEXT_PADDING } from './worksheet';\nimport type { CellStyle } from '../style/cellStyle';\nimport { SheetRenderer, type SheetRendererContext } from '../../render/sheetRenderer';\nimport { ViewportController } from '../../render/viewports';\nimport { utils, type WorksheetImage } from '../../io/xlsx';\nimport {\n XlsxImporter,\n convertImageInfo,\n buildImageUrl,\n type LoadXlsxOptions,\n type WorksheetImageInfo,\n type WorksheetImageAnchorPosition,\n type WorksheetImagePlacement,\n} from '../../io/xlsxImporter';\nimport { buildXlsxFromSnapshot } from '../../io/xlsxWriter';\nimport {\n CellHandle,\n NullCellHandle,\n RangeHandle,\n NullRangeHandle,\n ColumnHandle,\n RowHandle,\n type CellStyleInput,\n} from './handles';\nimport type { MergedCellRange } from '../cell/types';\n\nexport type SaveXlsxOptions = { filename?: string; sheetName?: string };\n\nexport type {\n LoadXlsxOptions,\n WorksheetImageInfo,\n WorksheetImageAnchorPosition,\n WorksheetImagePlacement,\n};\n\nexport interface WorksheetConstraints {\n maxRows?: number;\n maxCols?: number;\n}\n\nexport class CanvasWorksheet extends Worksheet {\n public readonly canvas: HTMLCanvasElement;\n\n private readonly ctx: CanvasRenderingContext2D;\n\n private readonly sheetRenderer: SheetRenderer;\n\n private readonly viewportController: ViewportController;\n\n // ── Constraints (Lite edition limits) ─────────────────────────────────────\n\n private readonly constraints: WorksheetConstraints;\n\n // ── Image management ───────────────────────────────────────────────────────\n\n private worksheetImages: WorksheetImage[] = [];\n\n private readonly imageUrlCache: Map<string, string> = new Map();\n\n private readonly imageListeners: Set<(images: WorksheetImageInfo[]) => void> = new Set();\n\n constructor(canvas: HTMLCanvasElement, constraints: WorksheetConstraints = {}) {\n super();\n this.canvas = canvas;\n this.constraints = constraints;\n const context = canvas.getContext('2d');\n if (!context) {\n throw new Error('Canvas 2D context is not available.');\n }\n this.ctx = context;\n this.sheetRenderer = new SheetRenderer(this.createSheetRendererContext());\n this.viewportController = new ViewportController(this);\n this.resize();\n }\n\n // ── Grid lines property ────────────────────────────────────────────────────\n\n get showGridLines(): boolean {\n return this.getShowGridLines();\n }\n\n set showGridLines(visible: boolean) {\n this.setShowGridLines(visible);\n }\n\n // ── OO cell/range/column/row factory methods ───────────────────────────────\n\n cell(a1: string): CellHandle | NullCellHandle {\n const pos = this.decodeA1Cell(a1);\n if (this.isOutOfBounds(pos.row, pos.column)) {\n return new NullCellHandle();\n }\n return new CellHandle(this, pos.row, pos.column);\n }\n\n range(a1Range: string): RangeHandle | NullRangeHandle {\n const r = this.decodeA1Range(a1Range);\n if (this.isRangeOutOfBounds(r.topRow, r.leftColumn, r.bottomRow, r.rightColumn)) {\n return new NullRangeHandle();\n }\n return new RangeHandle(this, r.topRow, r.leftColumn, r.bottomRow, r.rightColumn);\n }\n\n column(index: number): ColumnHandle {\n return new ColumnHandle(this, index);\n }\n\n row(index: number): RowHandle {\n return new RowHandle(this, index);\n }\n\n // ── xlsx import / export ───────────────────────────────────────────────────\n\n async loadFromUrl(url: string | URL, options?: LoadXlsxOptions): Promise<void> {\n const response = await fetch(url.toString());\n if (!response.ok) {\n throw new Error(`Failed to fetch XLSX from ${url}: ${response.status} ${response.statusText}`);\n }\n const buffer = await response.arrayBuffer();\n await this.loadFromXlsx(buffer, options);\n }\n\n async loadFromFile(file: File, options?: LoadXlsxOptions): Promise<void> {\n const buffer = await file.arrayBuffer();\n await this.loadFromXlsx(buffer, options);\n }\n\n async loadFromXlsx(\n data: ArrayBuffer | Uint8Array | string,\n options?: LoadXlsxOptions,\n ): Promise<void> {\n this.resetImageCache();\n const importer = new XlsxImporter(this);\n const result = importer.load(data, options);\n this.worksheetImages = result.images;\n this.notifyImagesChanged();\n }\n\n saveAsXlsx(options?: SaveXlsxOptions): void {\n const snapshot = this.getExportSnapshot();\n const sheetName = this.normalizeSheetName(options?.sheetName ?? 'Sheet1');\n const buffer = buildXlsxFromSnapshot(snapshot, sheetName);\n const filename = options?.filename ?? 'reogrid.xlsx';\n this.downloadWorkbook(buffer, filename);\n }\n\n // ── Image management ───────────────────────────────────────────────────────\n\n getImages(): WorksheetImageInfo[] {\n return this.worksheetImages.map((image) => convertImageInfo(image));\n }\n\n createImageUrl(imageId: string): string {\n const cached = this.imageUrlCache.get(imageId);\n if (cached) {\n return cached;\n }\n const image = this.findImage(imageId);\n if (!image) {\n throw new Error(`Image \"${imageId}\" not found.`);\n }\n const url = buildImageUrl(image);\n this.imageUrlCache.set(imageId, url);\n return url;\n }\n\n revokeImageUrl(imageId: string): void {\n const url = this.imageUrlCache.get(imageId);\n if (!url) {\n return;\n }\n if (typeof URL !== 'undefined' && typeof URL.revokeObjectURL === 'function') {\n URL.revokeObjectURL(url);\n }\n this.imageUrlCache.delete(imageId);\n }\n\n onImagesChange(listener: (images: WorksheetImageInfo[]) => void): () => void {\n this.imageListeners.add(listener);\n listener(this.getImages());\n return () => {\n this.imageListeners.delete(listener);\n };\n }\n\n // ── Canvas rendering ───────────────────────────────────────────────────────\n\n resize(width?: number, height?: number): void {\n const targetRect =\n this.canvas.parentElement?.getBoundingClientRect() ?? this.canvas.getBoundingClientRect();\n const rootWindow = typeof window === 'undefined' ? null : window;\n const fallbackWidth = rootWindow?.innerWidth ?? this.canvas.width;\n const fallbackHeight = rootWindow?.innerHeight ?? this.canvas.height;\n const resolvedWidth = width ?? (targetRect.width || fallbackWidth);\n const resolvedHeight = height ?? (targetRect.height || fallbackHeight);\n\n this.viewportWidth = resolvedWidth;\n this.viewportHeight = resolvedHeight;\n\n const devicePixelRatio = rootWindow?.devicePixelRatio ?? 1;\n this.pixelRatio = devicePixelRatio;\n const displayWidth = Math.max(1, Math.round(resolvedWidth * devicePixelRatio));\n const displayHeight = Math.max(1, Math.round(resolvedHeight * devicePixelRatio));\n\n this.canvas.style.width = `${resolvedWidth}px`;\n this.canvas.style.height = `${resolvedHeight}px`;\n if (this.canvas.width !== displayWidth) {\n this.canvas.width = displayWidth;\n }\n if (this.canvas.height !== displayHeight) {\n this.canvas.height = displayHeight;\n }\n\n this.ctx.setTransform(devicePixelRatio, 0, 0, devicePixelRatio, 0, 0);\n this.ctx.imageSmoothingEnabled = false;\n this.clampScrollOffsetInPlace();\n this.render();\n }\n\n public override render(): void {\n this.updateBoundaries();\n const viewports = this.viewportController.update();\n this.clear();\n this.sheetRenderer.drawHeaders(viewports);\n this.sheetRenderer.drawCells(viewports.cells);\n this.sheetRenderer.drawCustomBorders(viewports.cells);\n this.withBodyClip(() => this.selection.draw(this.ctx));\n this.withBodyClip(() => this.drawResizeGuide());\n }\n\n // ── Private helpers ────────────────────────────────────────────────────────\n\n private isOutOfBounds(row: number, col: number): boolean {\n const { maxRows, maxCols } = this.constraints;\n return (maxRows !== undefined && row >= maxRows) || (maxCols !== undefined && col >= maxCols);\n }\n\n private isRangeOutOfBounds(\n topRow: number,\n leftCol: number,\n bottomRow: number,\n rightCol: number,\n ): boolean {\n return this.isOutOfBounds(topRow, leftCol) || this.isOutOfBounds(bottomRow, rightCol);\n }\n\n private decodeA1Cell(a1Ref: string): { row: number; column: number } {\n let decoded: { r: number; c: number };\n try {\n decoded = utils.decode_cell(a1Ref);\n } catch (error) {\n throw new Error(`Invalid cell reference \"${a1Ref}\": ${(error as Error).message}`);\n }\n return { row: decoded.r, column: decoded.c };\n }\n\n private decodeA1Range(a1Range: string): MergedCellRange {\n let decoded: { s: { r: number; c: number }; e: { r: number; c: number } };\n try {\n decoded = utils.decode_range(a1Range);\n } catch (error) {\n throw new Error(`Invalid range reference \"${a1Range}\": ${(error as Error).message}`);\n }\n return {\n topRow: Math.min(decoded.s.r, decoded.e.r),\n bottomRow: Math.max(decoded.s.r, decoded.e.r),\n leftColumn: Math.min(decoded.s.c, decoded.e.c),\n rightColumn: Math.max(decoded.s.c, decoded.e.c),\n };\n }\n\n private findImage(imageId: string): WorksheetImage | undefined {\n return this.worksheetImages.find((image) => image.id === imageId);\n }\n\n private resetImageCache(): void {\n this.clearImageUrlCache();\n this.worksheetImages = [];\n this.notifyImagesChanged();\n }\n\n private clearImageUrlCache(): void {\n if (typeof URL !== 'undefined' && typeof URL.revokeObjectURL === 'function') {\n for (const url of this.imageUrlCache.values()) {\n URL.revokeObjectURL(url);\n }\n }\n this.imageUrlCache.clear();\n }\n\n private notifyImagesChanged(): void {\n const snapshot = this.getImages();\n for (const listener of this.imageListeners) {\n listener(snapshot);\n }\n }\n\n private normalizeSheetName(name: string): string {\n const cleaned = name.replace(/[:\\\\\\/\\?\\*\\[\\]]/g, '').trim();\n if (!cleaned.length) {\n return 'Sheet1';\n }\n return cleaned.slice(0, 31);\n }\n\n private downloadWorkbook(buffer: ArrayBuffer, filename: string): void {\n const blob = new Blob([buffer], {\n type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n });\n this.triggerDownload(blob, filename);\n }\n\n private triggerDownload(blob: Blob, filename: string): void {\n if (\n typeof document === 'undefined' ||\n typeof URL === 'undefined' ||\n typeof URL.createObjectURL !== 'function'\n ) {\n throw new Error('Saving XLSX requires a browser environment.');\n }\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.download = filename;\n anchor.style.display = 'none';\n const container = document.body;\n if (!container) {\n throw new Error('Saving XLSX requires a mounted document body.');\n }\n container.appendChild(anchor);\n anchor.click();\n container.removeChild(anchor);\n URL.revokeObjectURL(url);\n }\n\n private clear(): void {\n const ctx = this.ctx;\n ctx.save();\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n ctx.restore();\n }\n\n private withBodyClip(callback: () => void): void {\n const bodyWidth = this.getBodyViewportWidth();\n const bodyHeight = this.getBodyViewportHeight();\n if (bodyWidth <= 0 || bodyHeight <= 0) {\n return;\n }\n const ctx = this.ctx;\n ctx.save();\n ctx.beginPath();\n ctx.rect(this.headerColumnWidth, this.headerRowHeight, bodyWidth, bodyHeight);\n ctx.clip();\n try {\n callback();\n } finally {\n ctx.restore();\n }\n }\n\n private drawResizeGuide(): void {\n const guide = this.resizeGuide;\n if (!guide) {\n return;\n }\n const ctx = this.ctx;\n ctx.save();\n ctx.strokeStyle = '#1f2933';\n ctx.lineWidth = 1 / this.pixelRatio;\n ctx.setLineDash([4 / this.pixelRatio, 4 / this.pixelRatio]);\n ctx.beginPath();\n if (guide.type === 'column') {\n const bodyHeight = this.getBodyViewportHeight();\n ctx.moveTo(guide.position, this.headerRowHeight);\n ctx.lineTo(guide.position, this.headerRowHeight + bodyHeight);\n } else {\n const bodyWidth = this.getBodyViewportWidth();\n ctx.moveTo(this.headerColumnWidth, guide.position);\n ctx.lineTo(this.headerColumnWidth + bodyWidth, guide.position);\n }\n ctx.stroke();\n ctx.restore();\n }\n\n protected override measureColumnWidth(column: number): number {\n let maxWidth = MIN_COLUMN_WIDTH;\n for (let row = 0; row < this.rows; row += 1) {\n const style = this.getComputedCellStyle(row, column);\n const width = this.measureCellContentWidth(row, column, style);\n if (width > maxWidth) {\n maxWidth = width;\n }\n }\n return Math.max(maxWidth, MIN_COLUMN_WIDTH);\n }\n\n protected override measureRowHeight(row: number): number {\n let maxHeight = 0;\n for (let column = 0; column < this.columns; column += 1) {\n const style = this.getComputedCellStyle(row, column);\n const height = this.measureCellContentHeight(row, column, style);\n if (height > maxHeight) {\n maxHeight = height;\n }\n }\n return Math.max(maxHeight, MIN_ROW_HEIGHT);\n }\n\n protected override measureCellContentHeight(row: number, column: number, style: CellStyle): number {\n const richText = this.getRichTextRuns(row, column);\n if (richText && richText.length > 0) {\n const lines = this.sheetRenderer.layoutRichText(richText, style);\n if (!lines.length) {\n return 0;\n }\n const contentHeight = lines.reduce((sum, line) => sum + line.lineHeight, 0);\n return contentHeight + CELL_TEXT_PADDING * 2;\n }\n const text = this.getCellText(row, column);\n if (!text) {\n return 0;\n }\n const fontSizePx = this.pointsToPixels(style.fontSize);\n const lineHeight = fontSizePx + CELL_TEXT_PADDING;\n const lines = text.split(/\\r\\n|\\r|\\n/);\n return lines.length * lineHeight + CELL_TEXT_PADDING * 2;\n }\n\n protected override measureCellContentWidth(row: number, column: number, style: CellStyle): number {\n const padding = CELL_TEXT_PADDING * 2;\n const richText = this.getRichTextRuns(row, column);\n if (richText && richText.length > 0) {\n const lines = this.sheetRenderer.layoutRichText(richText, style);\n if (!lines.length) {\n return MIN_COLUMN_WIDTH;\n }\n const maxWidth = lines.reduce((max, line) => Math.max(max, line.width), 0);\n return maxWidth + padding;\n }\n const text = this.getCellText(row, column);\n if (!text) {\n return MIN_COLUMN_WIDTH;\n }\n const fontFamily = style.fontFamily.includes(' ') ? `\"${style.fontFamily}\"` : style.fontFamily;\n const fontSizePx = this.pointsToPixels(style.fontSize);\n const previousFont = this.ctx.font;\n this.ctx.font = `${fontSizePx}px ${fontFamily}`;\n const lines = text.split(/\\r\\n|\\r|\\n/);\n let maxWidth = 0;\n for (const line of lines) {\n const width = this.ctx.measureText(line).width;\n if (width > maxWidth) {\n maxWidth = width;\n }\n }\n this.ctx.font = previousFont;\n return maxWidth + padding;\n }\n\n private createSheetRendererContext(): SheetRendererContext {\n return {\n getContext: () => this.ctx,\n getPixelRatio: () => this.pixelRatio,\n getBodyViewportWidth: () => this.getBodyViewportWidth(),\n getBodyViewportHeight: () => this.getBodyViewportHeight(),\n getHeaderColumnWidth: () => this.headerColumnWidth,\n getHeaderRowHeight: () => this.headerRowHeight,\n getScrollOffset: () => ({ x: this.scrollX, y: this.scrollY }),\n getColumnBoundaries: () => this.getColumnBoundaries(),\n getRowBoundaries: () => this.getRowBoundaries(),\n getColumnWidths: () => this.getColumnWidths(),\n getRowHeights: () => this.getRowHeights(),\n getVisibleColumnRange: (padding) => this.getVisibleColumnRange(padding),\n getVisibleRowRange: (padding) => this.getVisibleRowRange(padding),\n getVisibleRowIndices: () => this.getVisibleRowIndices(),\n getVisibleColumnIndices: () => this.getVisibleColumnIndices(),\n getDefaultCellStyle: () => this.getDefaultCellStyle(),\n getComputedCellStyle: (row, column) => this.getComputedCellStyle(row, column),\n getMergedRange: (row, column) => this.getMergedRange(row, column),\n getRangeRect: (topRow, leftColumn, bottomRow, rightColumn) =>\n this.getRangeRect(topRow, leftColumn, bottomRow, rightColumn),\n getRichTextRuns: (row, column) => this.getRichTextRuns(row, column),\n getCellText: (row, column) => this.getCellText(row, column),\n pointsToPixels: (points) => this.pointsToPixels(points),\n withBodyClip: (callback) => this.withBodyClip(callback),\n getMergedLineGaps: () => this.getMergedLineGaps(),\n hasCellBorders: () => this.borders.size > 0,\n getCellBorders: () => this.getCellBorders(),\n parseCellKey: (key) => this.parseCellKey(key),\n getCellMergeBounds: (row, column) => this.getCellMergeBounds(row, column),\n getCellTextPadding: () => CELL_TEXT_PADDING,\n ensureBoundaries: () => this.ensureBoundaries(),\n shouldRenderGridLines: () => this.shouldRenderGridLines(),\n };\n }\n}\n\nexport type { CellStyleInput };\n","import type { CanvasWorksheet, HitTestResult } from '../../core/worksheet';\nimport type { CellEditor } from '../editor/cellEditor';\n\ntype DragContext =\n | { type: 'cell' }\n | { type: 'row-header'; anchorRow: number }\n | { type: 'column-header'; anchorColumn: number }\n | { type: 'corner' };\n\ntype ResizeContext =\n | { type: 'column'; column: number; origin: number; originalSize: number }\n | { type: 'row'; row: number; origin: number; originalSize: number };\n\ninterface CanvasPoint {\n x: number;\n y: number;\n}\n\nexport class PointerController {\n private readonly worksheet: CanvasWorksheet;\n\n private readonly canvas: HTMLCanvasElement;\n\n private readonly eventTarget: HTMLElement;\n\n private readonly cellEditor: CellEditor;\n\n private isDragging = false;\n\n private dragContext: DragContext | null = null;\n\n private isResizing = false;\n\n private resizeContext: ResizeContext | null = null;\n\n constructor(worksheet: CanvasWorksheet, cellEditor: CellEditor, eventTarget?: HTMLElement) {\n this.worksheet = worksheet;\n this.canvas = worksheet.canvas;\n this.eventTarget = eventTarget ?? this.canvas;\n this.cellEditor = cellEditor;\n\n this.eventTarget.addEventListener('mousedown', this.handleMouseDown);\n this.eventTarget.addEventListener('dblclick', this.handleDoubleClick);\n window.addEventListener('mousemove', this.handleMouseMove);\n window.addEventListener('mouseup', this.handleMouseUp);\n }\n\n destroy(): void {\n this.eventTarget.removeEventListener('mousedown', this.handleMouseDown);\n this.eventTarget.removeEventListener('dblclick', this.handleDoubleClick);\n window.removeEventListener('mousemove', this.handleMouseMove);\n window.removeEventListener('mouseup', this.handleMouseUp);\n }\n\n private handleMouseDown = (event: MouseEvent): void => {\n if (this.cellEditor.isEditing()) {\n this.cellEditor.commit();\n }\n\n const point = this.getCanvasPoint(event);\n if (!point) {\n return;\n }\n\n if (this.tryBeginResize(point)) {\n event.preventDefault();\n return;\n }\n\n const hit = this.worksheet.hitTest(point.x, point.y);\n if (!hit) {\n return;\n }\n\n event.preventDefault();\n this.isDragging = true;\n\n const { selection } = this.worksheet;\n switch (hit.type) {\n case 'cell':\n this.dragContext = { type: 'cell' };\n selection.begin(hit.row, hit.column);\n break;\n case 'row-header':\n this.dragContext = { type: 'row-header', anchorRow: hit.row };\n selection.selectRows(hit.row);\n break;\n case 'column-header':\n this.dragContext = { type: 'column-header', anchorColumn: hit.column };\n selection.selectColumns(hit.column);\n break;\n case 'corner':\n this.dragContext = { type: 'corner' };\n selection.selectAll();\n break;\n default:\n this.isDragging = false;\n this.dragContext = null;\n return;\n }\n\n this.worksheet.render();\n this.worksheet.notifySelectionChanged();\n };\n\n private handleMouseMove = (event: MouseEvent): void => {\n const point = this.getCanvasPoint(event);\n if (this.isResizing && this.resizeContext) {\n if (point) {\n event.preventDefault();\n this.handleResizeDrag(point);\n }\n return;\n }\n\n if (!this.isDragging || !this.dragContext) {\n this.updateHoverCursor(point);\n return;\n }\n\n if (!point) {\n return;\n }\n\n const hit = this.worksheet.hitTest(point.x, point.y);\n if (!hit) {\n return;\n }\n\n let updated = false;\n const { selection } = this.worksheet;\n\n switch (this.dragContext.type) {\n case 'cell':\n if (hit.type === 'cell') {\n selection.update(hit.row, hit.column);\n updated = true;\n }\n break;\n case 'row-header': {\n const row = this.resolveRowFromHit(hit);\n if (row !== null) {\n selection.selectRows(this.dragContext.anchorRow, row);\n updated = true;\n }\n break;\n }\n case 'column-header': {\n const column = this.resolveColumnFromHit(hit);\n if (column !== null) {\n selection.selectColumns(this.dragContext.anchorColumn, column);\n updated = true;\n }\n break;\n }\n case 'corner':\n default:\n break;\n }\n\n if (updated) {\n event.preventDefault();\n this.worksheet.render();\n this.worksheet.notifySelectionChanged();\n }\n };\n\n private handleMouseUp = (): void => {\n if (this.isResizing) {\n this.isResizing = false;\n this.resizeContext = null;\n this.setCursor('default');\n this.worksheet.setResizeGuide(null);\n return;\n }\n\n if (!this.isDragging) {\n return;\n }\n\n this.isDragging = false;\n this.dragContext = null;\n };\n\n private handleDoubleClick = (event: MouseEvent): void => {\n const point = this.getCanvasPoint(event);\n if (!point) {\n return;\n }\n\n const columnHandle = this.worksheet.getColumnResizeHandle(point.x, point.y);\n if (columnHandle !== null) {\n event.preventDefault();\n this.worksheet.autoFitColumns({ columns: [columnHandle], respectCustomWidth: false });\n return;\n }\n\n const rowHandle = this.worksheet.getRowResizeHandle(point.x, point.y);\n if (rowHandle !== null) {\n event.preventDefault();\n this.worksheet.autoFitRows({ rows: [rowHandle], respectCustomHeight: false });\n return;\n }\n\n const hit = this.worksheet.hitTest(point.x, point.y);\n if (!hit || hit.type !== 'cell') {\n return;\n }\n\n event.preventDefault();\n this.cellEditor.beginEdit(hit.row, hit.column);\n };\n\n private getCanvasPoint(event: MouseEvent): CanvasPoint | null {\n const rect = this.canvas.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0) {\n return null;\n }\n\n return {\n x: event.clientX - rect.left,\n y: event.clientY - rect.top,\n };\n }\n\n private resolveRowFromHit(hit: HitTestResult): number | null {\n if (hit.type === 'row-header' || hit.type === 'cell') {\n return hit.row;\n }\n return null;\n }\n\n private resolveColumnFromHit(hit: HitTestResult): number | null {\n if (hit.type === 'column-header' || hit.type === 'cell') {\n return hit.column;\n }\n return null;\n }\n\n private tryBeginResize(point: CanvasPoint): boolean {\n const columnHandle = this.worksheet.getColumnResizeHandle(point.x, point.y);\n if (columnHandle !== null) {\n this.isResizing = true;\n this.resizeContext = {\n type: 'column',\n column: columnHandle,\n origin: point.x,\n originalSize: this.worksheet.getColumnWidth(columnHandle),\n };\n this.setCursor('col-resize');\n this.worksheet.setResizeGuide({ type: 'column', position: point.x });\n return true;\n }\n\n const rowHandle = this.worksheet.getRowResizeHandle(point.x, point.y);\n if (rowHandle !== null) {\n this.isResizing = true;\n this.resizeContext = {\n type: 'row',\n row: rowHandle,\n origin: point.y,\n originalSize: this.worksheet.getRowHeight(rowHandle),\n };\n this.setCursor('row-resize');\n this.worksheet.setResizeGuide({ type: 'row', position: point.y });\n return true;\n }\n\n return false;\n }\n\n private handleResizeDrag(point: CanvasPoint): void {\n if (!this.resizeContext) {\n return;\n }\n\n if (this.resizeContext.type === 'column') {\n const delta = point.x - this.resizeContext.origin;\n this.worksheet.setResizeGuide({ type: 'column', position: point.x }, false);\n const nextWidth = this.resizeContext.originalSize + delta;\n this.worksheet.setColumnWidth(this.resizeContext.column, nextWidth);\n } else if (this.resizeContext.type === 'row') {\n const delta = point.y - this.resizeContext.origin;\n this.worksheet.setResizeGuide({ type: 'row', position: point.y }, false);\n const nextHeight = this.resizeContext.originalSize + delta;\n this.worksheet.setRowHeight(this.resizeContext.row, nextHeight);\n }\n }\n\n private updateHoverCursor(point: CanvasPoint | null): void {\n if (this.isResizing || this.isDragging) {\n return;\n }\n if (!point) {\n this.setCursor('default');\n return;\n }\n\n if (this.worksheet.getColumnResizeHandle(point.x, point.y) !== null) {\n this.setCursor('col-resize');\n } else if (this.worksheet.getRowResizeHandle(point.x, point.y) !== null) {\n this.setCursor('row-resize');\n } else {\n this.setCursor('default');\n }\n }\n\n private setCursor(cursor: string): void {\n if (this.canvas.style.cursor !== cursor) {\n this.canvas.style.cursor = cursor;\n }\n }\n}\n","import type { CanvasWorksheet } from '../../core/worksheet';\n\ninterface EditingCell {\n row: number;\n column: number;\n}\n\ninterface BeginEditOptions {\n presetValue?: string;\n selectAll?: boolean;\n}\n\nexport class CellEditor {\n private readonly worksheet: CanvasWorksheet;\n\n private readonly input: HTMLTextAreaElement;\n\n private editingCell: EditingCell | null = null;\n\n constructor(worksheet: CanvasWorksheet) {\n this.worksheet = worksheet;\n this.input = this.createInput();\n window.addEventListener('resize', this.refreshPosition);\n }\n\n beginEdit(row: number, column: number, options: BeginEditOptions = {}): void {\n const { presetValue, selectAll = true } = options;\n this.editingCell = { row, column };\n if (presetValue !== undefined) {\n this.input.value = presetValue;\n } else {\n this.input.value = this.worksheet.getCellInput(row, column) ?? '';\n }\n const style = this.worksheet.getComputedCellStyle(row, column);\n this.input.style.textAlign = style.textAlign;\n const fontSizePx = this.worksheet.pointsToPixels(style.fontSize);\n this.input.style.fontSize = `${fontSizePx}px`;\n this.input.style.color = style.color;\n this.input.style.whiteSpace = style.textWrapMode === 'none' ? 'pre' : 'pre-wrap';\n this.input.style.wordBreak = style.textWrapMode === 'break-word' ? 'break-word' : 'normal';\n this.input.style.overflowWrap = style.textWrapMode === 'break-word' ? 'break-word' : 'normal';\n this.updateInputPosition();\n this.input.style.display = 'block';\n this.input.focus();\n if (selectAll) {\n this.input.select();\n } else {\n const pos = this.input.value.length;\n this.input.setSelectionRange(pos, pos);\n }\n }\n\n commit(): void {\n if (!this.editingCell) {\n return;\n }\n const { row, column } = this.editingCell;\n this.worksheet.setCellInput(row, column, this.input.value);\n this.hide();\n }\n\n cancel(): void {\n this.hide();\n }\n\n isEditing(): boolean {\n return this.editingCell !== null;\n }\n\n destroy(): void {\n window.removeEventListener('resize', this.refreshPosition);\n this.input.remove();\n }\n\n private hide(): void {\n this.editingCell = null;\n this.input.style.display = 'none';\n }\n\n private refreshPosition = (): void => {\n if (!this.editingCell) {\n return;\n }\n this.updateInputPosition();\n };\n\n private createInput(): HTMLTextAreaElement {\n const input = document.createElement('textarea');\n input.style.position = 'fixed';\n input.style.display = 'none';\n input.style.font = '14px sans-serif';\n input.style.padding = '2px 4px';\n input.style.border = '2px solid #2196f3';\n input.style.boxShadow = '0 2px 4px rgba(0, 0, 0, 0.15)';\n input.style.outline = 'none';\n input.style.background = '#fff';\n input.style.textAlign = 'left';\n input.style.zIndex = '1000';\n input.style.resize = 'none';\n input.style.whiteSpace = 'pre-wrap';\n input.style.overflow = 'hidden';\n input.addEventListener('keydown', (event) => {\n if (\n event.key === 'Enter' &&\n !event.shiftKey &&\n !event.altKey &&\n !event.ctrlKey &&\n !event.metaKey\n ) {\n event.preventDefault();\n this.commit();\n } else if (event.key === 'Escape') {\n event.preventDefault();\n this.cancel();\n } else if (\n (event.key === 'ArrowLeft' ||\n event.key === 'ArrowRight' ||\n event.key === 'ArrowUp' ||\n event.key === 'ArrowDown') &&\n !event.shiftKey &&\n !event.metaKey &&\n !event.ctrlKey &&\n !event.altKey\n ) {\n this.handleHorizontalNavigation(event);\n }\n });\n input.addEventListener('blur', () => {\n this.commit();\n });\n document.body.appendChild(input);\n return input;\n }\n\n private updateInputPosition(): void {\n if (!this.editingCell) {\n return;\n }\n\n const rect = this.worksheet.canvas.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0) {\n return;\n }\n\n const cellRect = this.worksheet.getCellRect(this.editingCell.row, this.editingCell.column);\n const left = rect.left + cellRect.x;\n const top = rect.top + cellRect.y;\n const width = cellRect.width;\n const height = cellRect.height;\n\n this.input.style.left = `${left}px`;\n this.input.style.top = `${top}px`;\n this.input.style.width = `${width}px`;\n this.input.style.height = `${height}px`;\n this.input.style.lineHeight = '1.4';\n }\n\n private handleHorizontalNavigation(event: KeyboardEvent): void {\n if (!this.editingCell) {\n return;\n }\n\n const selectionStart = this.input.selectionStart;\n const selectionEnd = this.input.selectionEnd;\n if (selectionStart === null || selectionEnd === null || selectionStart !== selectionEnd) {\n return;\n }\n\n if (event.key === 'ArrowRight' && selectionEnd === this.input.value.length) {\n event.preventDefault();\n this.commitAndMove(0, 1);\n } else if (event.key === 'ArrowLeft' && selectionStart === 0) {\n event.preventDefault();\n this.commitAndMove(0, -1);\n } else if (event.key === 'ArrowUp' && selectionStart === 0) {\n event.preventDefault();\n this.commitAndMove(-1, 0);\n } else if (event.key === 'ArrowDown' && selectionEnd === this.input.value.length) {\n event.preventDefault();\n this.commitAndMove(1, 0);\n }\n }\n\n private commitAndMove(rowDelta: number, columnDelta: number): void {\n if (!this.editingCell) {\n return;\n }\n this.commit();\n const next = this.worksheet.selection.moveActiveCell(rowDelta, columnDelta);\n this.worksheet.render();\n this.worksheet.notifySelectionChanged();\n this.beginEdit(next.row, next.column);\n }\n}\n","import type { CanvasWorksheet } from '../../core/worksheet';\nimport type { CellEditor } from '../editor/cellEditor';\n\nexport class KeyboardController {\n private readonly worksheet: CanvasWorksheet;\n\n private readonly cellEditor: CellEditor;\n\n constructor(worksheet: CanvasWorksheet, cellEditor: CellEditor) {\n this.worksheet = worksheet;\n this.cellEditor = cellEditor;\n window.addEventListener('keydown', this.handleKeyDown, { passive: false });\n }\n\n destroy(): void {\n window.removeEventListener('keydown', this.handleKeyDown);\n }\n\n private handleKeyDown = (event: KeyboardEvent): void => {\n if (event.defaultPrevented) {\n return;\n }\n\n if (this.cellEditor.isEditing()) {\n return;\n }\n\n const focused = document.activeElement;\n if (\n focused instanceof HTMLInputElement ||\n focused instanceof HTMLTextAreaElement ||\n focused instanceof HTMLSelectElement ||\n (focused instanceof HTMLElement && focused.isContentEditable)\n ) {\n return;\n }\n\n if (this.handleNavigationKeys(event)) {\n return;\n }\n\n const activeCell = this.ensureActiveCell();\n\n if (event.key === 'F2') {\n event.preventDefault();\n this.cellEditor.beginEdit(activeCell.row, activeCell.column);\n return;\n }\n\n if (event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {\n event.preventDefault();\n this.cellEditor.beginEdit(activeCell.row, activeCell.column, {\n presetValue: event.key,\n selectAll: false,\n });\n }\n };\n\n private handleNavigationKeys(event: KeyboardEvent): boolean {\n const selection = this.worksheet.selection;\n const key = event.key;\n let moved = false;\n switch (key) {\n case 'ArrowUp':\n selection.moveActiveCell(-1, 0);\n moved = true;\n break;\n case 'ArrowDown':\n selection.moveActiveCell(1, 0);\n moved = true;\n break;\n case 'ArrowLeft':\n selection.moveActiveCell(0, -1);\n moved = true;\n break;\n case 'ArrowRight':\n selection.moveActiveCell(0, 1);\n moved = true;\n break;\n default:\n break;\n }\n\n if (moved) {\n event.preventDefault();\n this.worksheet.render();\n this.worksheet.notifySelectionChanged();\n }\n return moved;\n }\n\n private ensureActiveCell(): { row: number; column: number } {\n const active = this.worksheet.selection.getActiveCell();\n if (active) {\n return active;\n }\n const fallback = this.worksheet.selection.moveActiveCell(0, 0);\n this.worksheet.notifySelectionChanged();\n return fallback;\n }\n}\n","import type { CanvasWorksheet, WorksheetImageInfo, WorksheetImagePlacement } from '../../core/worksheet/canvasWorksheet';\n\ntype ImageEntry = {\n element: HTMLImageElement;\n info: WorksheetImageInfo;\n};\n\nexport class WorksheetImageLayer {\n private readonly worksheet: CanvasWorksheet;\n\n private readonly container: HTMLDivElement;\n\n private readonly images: Map<string, ImageEntry> = new Map();\n\n private unsubscribeScroll: (() => void) | null = null;\n\n private unsubscribeStructure: (() => void) | null = null;\n\n private unsubscribeImages: (() => void) | null = null;\n\n constructor(worksheet: CanvasWorksheet, host: HTMLElement) {\n this.worksheet = worksheet;\n this.container = document.createElement('div');\n this.container.className = 'reogrid-image-layer';\n this.container.style.position = 'absolute';\n this.container.style.inset = '0';\n this.container.style.pointerEvents = 'none';\n this.container.style.zIndex = '2';\n host.appendChild(this.container);\n this.unsubscribeScroll = this.worksheet.onScrollChange((offset) => {\n this.syncScroll(offset.x, offset.y);\n });\n this.syncScroll(this.worksheet.getScrollOffset().x, this.worksheet.getScrollOffset().y);\n this.unsubscribeStructure = this.worksheet.onStructureChange(() => this.layoutAll());\n this.unsubscribeImages = this.worksheet.onImagesChange((images) => this.setImages(images));\n }\n\n destroy(): void {\n this.clearImages();\n if (this.unsubscribeScroll) {\n this.unsubscribeScroll();\n this.unsubscribeScroll = null;\n }\n if (this.unsubscribeStructure) {\n this.unsubscribeStructure();\n this.unsubscribeStructure = null;\n }\n if (this.unsubscribeImages) {\n this.unsubscribeImages();\n this.unsubscribeImages = null;\n }\n this.container.remove();\n }\n\n private setImages(images: WorksheetImageInfo[]): void {\n const nextIds = new Set(images.map((image) => image.id));\n for (const [id, entry] of this.images.entries()) {\n if (!nextIds.has(id)) {\n this.removeImageEntry(entry);\n this.images.delete(id);\n }\n }\n images.forEach((image) => {\n const existing = this.images.get(image.id);\n if (existing) {\n existing.info = image;\n this.layoutImage(existing.element, image.anchor);\n return;\n }\n const element = document.createElement('img');\n element.draggable = false;\n element.alt = '';\n element.decoding = 'async';\n element.loading = 'lazy';\n element.style.position = 'absolute';\n element.style.pointerEvents = 'none';\n element.style.userSelect = 'none';\n element.style.display = 'block';\n element.style.maxWidth = 'none';\n element.style.maxHeight = 'none';\n element.src = this.worksheet.createImageUrl(image.id);\n this.container.appendChild(element);\n this.layoutImage(element, image.anchor);\n this.images.set(image.id, { element, info: image });\n });\n }\n\n private clearImages(): void {\n for (const entry of this.images.values()) {\n this.removeImageEntry(entry);\n }\n this.images.clear();\n }\n\n private layoutAll(): void {\n for (const entry of this.images.values()) {\n this.layoutImage(entry.element, entry.info.anchor);\n }\n }\n\n private removeImageEntry(entry: ImageEntry): void {\n entry.element.remove();\n this.worksheet.revokeImageUrl(entry.info.id);\n }\n\n private layoutImage(element: HTMLImageElement, anchor: WorksheetImagePlacement): void {\n if (anchor.type === 'oneCell') {\n const point = this.getAnchorPoint(anchor.from);\n const width = Math.max(0, anchor.width);\n const height = Math.max(0, anchor.height);\n element.style.left = `${point.x}px`;\n element.style.top = `${point.y}px`;\n element.style.width = `${width}px`;\n element.style.height = `${height}px`;\n return;\n }\n const from = this.getAnchorPoint(anchor.from);\n const to = this.getAnchorPoint(anchor.to);\n const width = Math.max(0, to.x - from.x);\n const height = Math.max(0, to.y - from.y);\n element.style.left = `${from.x}px`;\n element.style.top = `${from.y}px`;\n element.style.width = `${width}px`;\n element.style.height = `${height}px`;\n }\n\n private getAnchorPoint(anchor: WorksheetImagePlacement['from']): { x: number; y: number } {\n const x = this.worksheet.getColumnStart(anchor.column) + anchor.offsetX;\n const y = this.worksheet.getRowStart(anchor.row) + anchor.offsetY;\n return { x, y };\n }\n\n private syncScroll(scrollX: number, scrollY: number): void {\n this.container.style.transform = `translate(${-scrollX}px, ${-scrollY}px)`;\n }\n}\n","import { CANVAS_ID, WORKSPACE_ID } from './app/domIds';\nimport {\n GRID_LAYER_CLASS,\n GRID_SCROLL_CLASS,\n GRID_SPACER_CLASS,\n WORKBOOK_CLASS,\n WORKSPACE_CLASS,\n WORKSHEET_CONTAINER_CLASS,\n ensureWorkspaceStyles,\n} from './app/styles';\nimport { CanvasWorksheet } from './core/worksheet';\nimport { PointerController } from './render/controllers/pointerController';\nimport { CellEditor } from './render/editor/cellEditor';\nimport { KeyboardController } from './render/controllers/keyboardController';\nimport { WorksheetImageLayer } from './render/layers/imageLayer';\n\ntype WorkspaceSurface = {\n canvas: HTMLCanvasElement;\n scrollContainer: HTMLDivElement;\n spacer: HTMLDivElement;\n worksheetContainer: HTMLDivElement;\n};\n\nexport type ReogridMountTarget = string | HTMLElement;\n\nexport interface ReogridOptions {\n workspace?: ReogridMountTarget;\n workspaceId?: string;\n canvasId?: string;\n injectStyles?: boolean;\n /** Maximum number of rows. Writes beyond this limit are silently ignored. */\n maxRows?: number;\n /** Maximum number of columns. Writes beyond this limit are silently ignored. */\n maxCols?: number;\n}\n\nexport interface ReogridInstance {\n worksheet: CanvasWorksheet;\n cellEditor: CellEditor;\n pointerController: PointerController;\n keyboardController: KeyboardController;\n destroy: () => void;\n}\n\nconst WORKSPACE_DATASET_FLAG = 'reogridMounted';\nconst WHEEL_LISTENER_OPTIONS: AddEventListenerOptions = { passive: false };\n\nexport function createReogrid(options: ReogridOptions = {}): ReogridInstance {\n if (typeof document === 'undefined') {\n throw new Error('createReogrid requires a browser environment.');\n }\n\n if (options.injectStyles !== false) {\n ensureWorkspaceStyles();\n }\n\n const workspace = resolveWorkspaceElement(options.workspace, options.workspaceId ?? WORKSPACE_ID);\n const canvasId = options.canvasId ?? CANVAS_ID;\n const surface = ensureWorkspaceSurface(workspace, canvasId);\n const { worksheet, destroy: teardownWorksheet } = initCanvasWorksheet(surface, {\n maxRows: options.maxRows,\n maxCols: options.maxCols,\n });\n\n const cellEditor = new CellEditor(worksheet);\n const pointerController = new PointerController(worksheet, cellEditor, surface.worksheetContainer);\n const keyboardController = new KeyboardController(worksheet, cellEditor);\n const imageLayer = new WorksheetImageLayer(worksheet, surface.worksheetContainer);\n const detachFontSync = attachFontRenderSync(worksheet);\n\n worksheet.notifySelectionChanged();\n\n const destroy = (): void => {\n detachFontSync();\n imageLayer.destroy();\n pointerController.destroy();\n keyboardController.destroy();\n cellEditor.destroy();\n teardownWorksheet();\n delete workspace.dataset[WORKSPACE_DATASET_FLAG];\n };\n\n return {\n worksheet,\n cellEditor,\n pointerController,\n keyboardController,\n destroy,\n };\n}\n\nfunction resolveWorkspaceElement(\n target: ReogridMountTarget | undefined,\n fallbackId: string,\n): HTMLElement {\n if (target instanceof HTMLElement) {\n return target;\n }\n\n if (typeof target === 'string') {\n const element = document.querySelector<HTMLElement>(target);\n if (element) {\n return element;\n }\n throw new Error(`Workspace element \"${target}\" was not found.`);\n }\n\n const fallback = document.getElementById(fallbackId);\n if (fallback instanceof HTMLElement) {\n return fallback;\n }\n\n throw new Error(`Workspace element \"#${fallbackId}\" was not found.`);\n}\n\nfunction ensureWorkspaceSurface(workspace: HTMLElement, canvasId: string): WorkspaceSurface {\n if (workspace.dataset[WORKSPACE_DATASET_FLAG]) {\n throw new Error('A ReoGrid instance is already mounted on this workspace.');\n }\n\n const doc = workspace.ownerDocument ?? document;\n workspace.classList.add(WORKSPACE_CLASS);\n\n let workbook = workspace.querySelector<HTMLDivElement>(`.${WORKBOOK_CLASS}`);\n if (!workbook) {\n workbook = doc.createElement('div');\n workbook.className = WORKBOOK_CLASS;\n workspace.appendChild(workbook);\n }\n\n let worksheetContainer = workbook.querySelector<HTMLDivElement>(`.${WORKSHEET_CONTAINER_CLASS}`);\n if (!worksheetContainer) {\n worksheetContainer = doc.createElement('div');\n worksheetContainer.className = WORKSHEET_CONTAINER_CLASS;\n workbook.appendChild(worksheetContainer);\n }\n\n let scrollContainer = worksheetContainer.querySelector<HTMLDivElement>(`.${GRID_SCROLL_CLASS}`);\n if (!scrollContainer) {\n scrollContainer = doc.createElement('div');\n scrollContainer.className = GRID_SCROLL_CLASS;\n worksheetContainer.appendChild(scrollContainer);\n }\n\n let spacer = scrollContainer.querySelector<HTMLDivElement>(`.${GRID_SPACER_CLASS}`);\n if (!spacer) {\n spacer = doc.createElement('div');\n spacer.className = GRID_SPACER_CLASS;\n scrollContainer.appendChild(spacer);\n }\n\n let canvas = worksheetContainer.querySelector<HTMLCanvasElement>(`#${canvasId}`);\n if (!canvas) {\n canvas = doc.createElement('canvas');\n canvas.id = canvasId;\n worksheetContainer.appendChild(canvas);\n }\n canvas.classList.add(GRID_LAYER_CLASS);\n\n workspace.dataset[WORKSPACE_DATASET_FLAG] = 'true';\n\n return { canvas, scrollContainer, spacer, worksheetContainer };\n}\n\nfunction initCanvasWorksheet(\n surface: WorkspaceSurface,\n constraints: { maxRows?: number; maxCols?: number },\n): {\n worksheet: CanvasWorksheet;\n destroy: () => void;\n} {\n const worksheet = new CanvasWorksheet(surface.canvas, constraints);\n\n const syncScrollFromWorksheet = (): void => {\n const { x, y } = worksheet.getScrollOffset();\n if (Math.abs(surface.scrollContainer.scrollLeft - x) > 0.5) {\n surface.scrollContainer.scrollLeft = x;\n }\n if (Math.abs(surface.scrollContainer.scrollTop - y) > 0.5) {\n surface.scrollContainer.scrollTop = y;\n }\n };\n\n const updateSpacerSize = (): void => {\n const size = worksheet.getScrollContentSize();\n surface.spacer.style.width = `${size.width}px`;\n surface.spacer.style.height = `${size.height}px`;\n syncScrollFromWorksheet();\n };\n\n const handleScroll = (): void => {\n worksheet.setScrollOffset(\n surface.scrollContainer.scrollLeft,\n surface.scrollContainer.scrollTop,\n );\n };\n\n const handleWheel = (event: WheelEvent): void => {\n if (event.ctrlKey || event.metaKey) {\n return;\n }\n surface.scrollContainer.scrollBy({\n left: event.deltaX,\n top: event.deltaY,\n behavior: 'auto',\n });\n event.preventDefault();\n };\n\n const handleResize = (): void => {\n worksheet.resize();\n };\n\n const positionScrollContainer = (): void => {\n surface.scrollContainer.style.top = `${worksheet.headerRowHeight}px`;\n surface.scrollContainer.style.left = `${worksheet.headerColumnWidth}px`;\n surface.scrollContainer.style.right = '0';\n surface.scrollContainer.style.bottom = '0';\n };\n\n surface.scrollContainer.addEventListener('scroll', handleScroll);\n surface.worksheetContainer.addEventListener('wheel', handleWheel, WHEEL_LISTENER_OPTIONS);\n const stopScrollbarPointerEvents = (event: MouseEvent): void => {\n if (isPointerEventOnScrollbar(event, surface.scrollContainer)) {\n event.stopPropagation();\n }\n };\n surface.scrollContainer.addEventListener('mousedown', stopScrollbarPointerEvents);\n surface.scrollContainer.addEventListener('dblclick', stopScrollbarPointerEvents);\n\n const unsubscribeViewport = worksheet.onViewportSizeChange(updateSpacerSize);\n const unsubscribeScroll = worksheet.onScrollChange(syncScrollFromWorksheet);\n const detachStructureListener = worksheet.onStructureChange(positionScrollContainer);\n const detachViewportSizeListener = worksheet.onViewportSizeChange(positionScrollContainer);\n\n if (typeof window !== 'undefined') {\n window.addEventListener('resize', handleResize);\n }\n\n updateSpacerSize();\n positionScrollContainer();\n\n return {\n worksheet,\n destroy: () => {\n surface.scrollContainer.removeEventListener('scroll', handleScroll);\n surface.scrollContainer.removeEventListener('mousedown', stopScrollbarPointerEvents);\n surface.scrollContainer.removeEventListener('dblclick', stopScrollbarPointerEvents);\n surface.worksheetContainer.removeEventListener('wheel', handleWheel, WHEEL_LISTENER_OPTIONS);\n if (typeof window !== 'undefined') {\n window.removeEventListener('resize', handleResize);\n }\n unsubscribeViewport();\n unsubscribeScroll();\n detachStructureListener();\n detachViewportSizeListener();\n },\n };\n}\n\nfunction isPointerEventOnScrollbar(event: MouseEvent, container: HTMLDivElement): boolean {\n const rect = container.getBoundingClientRect();\n const verticalScrollbarWidth = rect.width - container.clientWidth;\n const horizontalScrollbarHeight = rect.height - container.clientHeight;\n const isOverVerticalScrollbar =\n verticalScrollbarWidth > 0 && event.clientX >= rect.right - verticalScrollbarWidth;\n const isOverHorizontalScrollbar =\n horizontalScrollbarHeight > 0 && event.clientY >= rect.bottom - horizontalScrollbarHeight;\n return isOverVerticalScrollbar || isOverHorizontalScrollbar;\n}\n\nfunction attachFontRenderSync(worksheet: CanvasWorksheet): () => void {\n if (typeof document === 'undefined' || typeof document.fonts === 'undefined') {\n return () => {};\n }\n const fonts = document.fonts;\n let disposed = false;\n const rerender = (): void => {\n if (!disposed) {\n worksheet.render();\n }\n };\n if (fonts.ready && typeof fonts.ready.then === 'function') {\n fonts.ready.then(rerender).catch(() => {});\n }\n const handleLoadingDone = (): void => {\n rerender();\n };\n if (typeof fonts.addEventListener === 'function' && typeof fonts.removeEventListener === 'function') {\n fonts.addEventListener('loadingdone', handleLoadingDone);\n return () => {\n disposed = true;\n fonts.removeEventListener('loadingdone', handleLoadingDone);\n };\n }\n return () => {\n disposed = true;\n };\n}\n\nexport { CanvasWorksheet } from './core/worksheet';\nexport type { CellStyleInput } from './core/worksheet/handles';\nexport type {\n WorksheetImageInfo,\n WorksheetImagePlacement,\n WorksheetImageAnchorPosition,\n SaveXlsxOptions,\n LoadXlsxOptions,\n} from './core/worksheet/canvasWorksheet';\nexport type { TextAlign, VerticalAlign, CellStyle } from './core/style/cellStyle';\nexport { Worksheet } from './core/worksheet/worksheet';\nexport { ToolbarController } from './render/controllers/toolbarController';\nexport { CellEditor } from './render/editor/cellEditor';\nexport { PointerController } from './render/controllers/pointerController';\nexport { KeyboardController } from './render/controllers/keyboardController';\nexport * from './constants';\nexport { buildXlsxFromSnapshot } from './io/xlsxWriter';\n","import { createReogrid as createReogridCore, type ReogridInstance, type ReogridOptions } from '../index';\n\nexport type { ReogridInstance };\nexport type { ReogridOptions };\n\n// ── License validation ────────────────────────────────────────────────────────\n\ninterface LicenseCache {\n valid: boolean;\n cachedAt: number;\n plan?: string;\n expiresAt?: string | null;\n}\n\nconst CACHE_KEY = '__reogrid_pro_license__';\nconst CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000; // re-validate after 7 days\nconst GRACE_PERIOD_MS = 30 * 24 * 60 * 60 * 1000; // offline grace: 30 days\n\nfunction readCache(): LicenseCache | null {\n try {\n if (typeof localStorage !== 'undefined') {\n const raw = localStorage.getItem(CACHE_KEY);\n if (raw) return JSON.parse(raw) as LicenseCache;\n }\n } catch { /* ignore */ }\n return null;\n}\n\nfunction writeCache(data: LicenseCache): void {\n try {\n if (typeof localStorage !== 'undefined') {\n localStorage.setItem(CACHE_KEY, JSON.stringify(data));\n }\n } catch { /* ignore */ }\n}\n\nasync function validateRemote(key: string, endpoint: string): Promise<LicenseCache> {\n const res = await fetch(`${endpoint}/reogrid/license/validate`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ key }),\n });\n const data = await res.json() as { valid: boolean; plan?: string; expiresAt?: string | null };\n return {\n valid: !!data.valid,\n plan: data.plan,\n expiresAt: data.expiresAt,\n cachedAt: Date.now(),\n };\n}\n\nasync function checkLicense(key: string, endpoint: string): Promise<boolean> {\n const cached = readCache();\n const now = Date.now();\n\n // Cache still fresh — skip network call\n if (cached && now - cached.cachedAt < CACHE_TTL_MS) {\n return cached.valid;\n }\n\n try {\n const result = await validateRemote(key, endpoint);\n writeCache(result);\n if (!result.valid) {\n console.warn('[ReoGrid Pro] License validation failed. Please check your license key.');\n }\n return result.valid;\n } catch {\n // Server unreachable — fall back to cached result within grace period\n if (cached && now - cached.cachedAt < GRACE_PERIOD_MS) {\n console.warn('[ReoGrid Pro] License server unreachable. Using cached result (grace period).');\n return cached.valid;\n }\n console.warn('[ReoGrid Pro] License server unreachable and no valid cache. License unverified.');\n return false;\n }\n}\n\n// ── Public API ────────────────────────────────────────────────────────────────\n\nexport interface ReogridProOptions extends ReogridOptions {\n /**\n * Your ReoGrid Pro license key (issued from the Unvell customer portal).\n */\n licenseKey?: string;\n\n /**\n * License validation endpoint base URL.\n * Defaults to the official Unvell API server.\n */\n licenseEndpoint?: string;\n}\n\nconst DEFAULT_ENDPOINT = 'https://api.unvell.com';\n\n/**\n * Creates a ReoGrid Pro instance.\n * License validation runs in the background — the grid is immediately usable.\n * An invalid or missing key logs a console warning but does not block rendering.\n */\nexport function createReogrid(options: ReogridProOptions = {}): ReogridInstance {\n const { licenseKey, licenseEndpoint = DEFAULT_ENDPOINT, ...gridOptions } = options;\n\n const instance = createReogridCore(gridOptions);\n\n if (licenseKey) {\n checkLicense(licenseKey, licenseEndpoint).then(valid => {\n if (!valid) {\n console.warn(\n '[ReoGrid Pro] Invalid or expired license key. ' +\n 'Visit https://unvell.com/portal to manage your license.',\n );\n }\n });\n } else {\n console.warn(\n '[ReoGrid Pro] No license key provided. ' +\n 'A license key is required for production use. ' +\n 'Visit https://unvell.com/portal to obtain one.',\n );\n }\n\n return instance;\n}\n"],"mappings":"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","names":["textDecoder","valueNode","decodeUtf8","LOCAL_FILE_HEADER_SIGNATURE","textEncoder","encodeUtf8","lines","maxWidth","width","height","createReogrid","createReogrid"]}
1
+ {"version":3,"sources":["../src/pro/react/index.tsx","../src/app/domIds.ts","../src/app/styles.ts","../src/core/worksheet/gridDefaults.ts","../src/core/cell/selectionRange.ts","../src/core/formula/lexer.ts","../src/core/formula/types.ts","../src/core/formula/parser.ts","../src/core/formula/evaluator.ts","../src/core/formula/functions/registry.ts","../src/core/style/numberFormat.ts","../src/core/formula/functions/builtins.ts","../src/core/formula/dependency.ts","../src/core/formula/refUpdater.ts","../src/core/formula/serializer.ts","../src/core/formula/formulaEngine.ts","../src/core/style/cellStyle.ts","../src/core/worksheet/cellKey.ts","../src/core/worksheet/gridGeometry.ts","../src/core/border/types.ts","../src/core/border/borderManager.ts","../src/core/merge/mergeManager.ts","../src/core/cell/cellTypeRegistry.ts","../src/core/outline/outlineManager.ts","../src/core/worksheet/worksheet.ts","../src/render/sheetRenderer.ts","../src/render/viewports.ts","../src/io/unzip.ts","../src/io/xml.ts","../src/io/xlsx.ts","../src/io/xlsxImporter.ts","../src/io/zipWriter.ts","../src/io/xlsxWriter.ts","../src/core/sort/sortRows.ts","../src/core/filter/autoColumnFilter.ts","../src/core/worksheet/handles.ts","../src/core/worksheet/canvasWorksheet.ts","../src/core/action/actionManager.ts","../src/core/action/actionGroup.ts","../src/core/action/actions.ts","../src/render/controllers/pointerController.ts","../src/render/editor/cellEditor.ts","../src/render/editor/dropdownOverlay.ts","../src/render/editor/filterDropdownOverlay.ts","../src/render/controllers/keyboardController.ts","../src/core/clipboard/tsvSerializer.ts","../src/core/clipboard/tsvParser.ts","../src/core/clipboard/clipboardActions.ts","../src/core/clipboard/clipboardService.ts","../src/render/layers/imageLayer.ts","../src/core/cell/handlers/checkbox.ts","../src/core/cell/handlers/dropdown.ts","../src/core/cell/handlers/button.ts","../src/core/cell/handlers/progress.ts","../src/core/cell/handlers/rating.ts","../src/core/cell/handlers/sparkline-line.ts","../src/core/cell/handlers/sparkline-area.ts","../src/core/cell/handlers/hyperlink.ts","../src/index.ts","../src/pro/index.ts"],"sourcesContent":["import {\n forwardRef,\n useEffect,\n useRef,\n type CSSProperties,\n} from 'react';\nimport { createReogrid, type ReogridInstance, type ReogridOptions } from '../index';\n\nexport type { ReogridInstance };\n\nexport interface ReogridProps {\n className?: string;\n style?: CSSProperties;\n /**\n * Called once after the grid is initialized, with the full ReogridInstance.\n * Useful for setting initial cell values, styles, or loading an xlsx file.\n */\n onReady?: (instance: ReogridInstance) => void;\n /**\n * Options forwarded to createReogrid(). `workspace` is managed internally\n * and will be ignored if supplied.\n */\n options?: Omit<ReogridOptions, 'workspace'>;\n}\n\n/**\n * React component that mounts a ReoGrid Pro canvas spreadsheet.\n * No row/column restrictions. Full xlsx import/export support.\n *\n * The ref exposes the full `ReogridInstance` (worksheet, api, etc.).\n *\n * @example\n * ```tsx\n * const gridRef = useRef<ReogridInstance>(null);\n * <Reogrid ref={gridRef} style={{ flex: 1 }} onReady={(inst) => {\n * inst.api.setCellValue('A1', 'Hello from ReoGrid Pro!');\n * }} />\n * ```\n */\nexport const Reogrid = forwardRef<ReogridInstance, ReogridProps>(\n ({ className, style, onReady, options }, ref) => {\n const containerRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!containerRef.current) return;\n\n const instance = createReogrid({\n ...options,\n workspace: containerRef.current,\n });\n\n if (typeof ref === 'function') {\n ref(instance);\n } else if (ref) {\n ref.current = instance;\n }\n\n onReady?.(instance);\n\n return () => {\n instance.destroy();\n if (typeof ref === 'function') {\n ref(null);\n } else if (ref) {\n ref.current = null;\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return <div ref={containerRef} className={className} style={style} />;\n },\n);\n\nReogrid.displayName = 'Reogrid';\n","export const WORKSPACE_ID = 'reogrid-workspace';\nexport const CANVAS_ID = 'reogrid-canvas';\n","const DEFAULT_STYLE_ID = 'reogrid-base-styles';\nconst FONT_LINK_ID = 'reogrid-font-roboto';\nconst FONT_STYLESHEET_URL =\n 'https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap';\n\nexport const WORKSPACE_CLASS = 'reogrid-workspace';\nexport const WORKBOOK_CLASS = 'workbook';\nexport const WORKSHEET_CONTAINER_CLASS = 'worksheet-container';\nexport const GRID_SCROLL_CLASS = 'grid-scroll';\nexport const GRID_SPACER_CLASS = 'grid-spacer';\nexport const GRID_LAYER_CLASS = 'grid-layer';\n\nconst BASE_STYLES = `\n.${WORKSPACE_CLASS} {\n position: relative;\n overflow: hidden;\n background: #e2e8f0;\n display: flex;\n flex-direction: column;\n}\n\n.${WORKSPACE_CLASS} .${WORKBOOK_CLASS} {\n flex: 1;\n display: flex;\n flex-direction: column;\n position: relative;\n}\n\n.${WORKSPACE_CLASS} .${WORKSHEET_CONTAINER_CLASS} {\n flex: 1;\n position: relative;\n background: #ffffff;\n overflow: hidden;\n}\n\n.${WORKSPACE_CLASS} .${GRID_SCROLL_CLASS} {\n position: absolute;\n inset: 0;\n overflow: auto;\n overscroll-behavior: contain;\n background: transparent;\n z-index: 2;\n}\n\n.${WORKSPACE_CLASS} .${GRID_SPACER_CLASS} {\n width: 100%;\n height: 100%;\n min-width: 100%;\n min-height: 100%;\n pointer-events: none;\n}\n\n.${WORKSPACE_CLASS} canvas.${GRID_LAYER_CLASS} {\n position: absolute;\n inset: 0;\n z-index: 1;\n background: transparent;\n}\n\n\n.reogrid-dropdown-list {\n background: #ffffff;\n border: 1px solid #c0c0c0;\n border-radius: 2px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n max-height: 200px;\n overflow-y: auto;\n font: 13px sans-serif;\n}\n\n.reogrid-dropdown-item {\n padding: 4px 8px;\n cursor: pointer;\n white-space: nowrap;\n}\n\n.reogrid-dropdown-item:hover {\n background: #e8f0fe;\n}\n\n.reogrid-filter-dropdown {\n background: #ffffff;\n border: 1px solid #c0c0c0;\n border-radius: 2px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n font: 13px sans-serif;\n min-width: 160px;\n max-width: 300px;\n}\n\n.reogrid-filter-search {\n display: block;\n width: calc(100% - 16px);\n margin: 6px 8px;\n padding: 4px 6px;\n border: 1px solid #c0c0c0;\n border-radius: 2px;\n font: inherit;\n outline: none;\n box-sizing: border-box;\n}\n\n.reogrid-filter-search:focus {\n border-color: #4285f4;\n}\n\n.reogrid-filter-select-all {\n display: block;\n padding: 4px 8px;\n border-bottom: 1px solid #e0e0e0;\n cursor: pointer;\n}\n\n.reogrid-filter-items {\n max-height: 200px;\n overflow-y: auto;\n}\n\n.reogrid-filter-item {\n display: block;\n padding: 3px 8px;\n cursor: pointer;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.reogrid-filter-item:hover {\n background: #e8f0fe;\n}\n\n.reogrid-filter-actions {\n display: flex;\n justify-content: flex-end;\n gap: 6px;\n padding: 6px 8px;\n border-top: 1px solid #e0e0e0;\n}\n\n.reogrid-filter-actions button {\n padding: 4px 12px;\n border: 1px solid #c0c0c0;\n border-radius: 2px;\n background: #ffffff;\n cursor: pointer;\n font: inherit;\n}\n\n.reogrid-filter-actions button:hover {\n background: #f0f0f0;\n}\n\n.reogrid-filter-sort-buttons {\n display: flex;\n flex-direction: column;\n padding: 4px 8px;\n}\n\n.reogrid-filter-sort-btn {\n display: block;\n width: 100%;\n padding: 5px 8px;\n border: none;\n border-radius: 2px;\n background: transparent;\n cursor: pointer;\n font: inherit;\n text-align: left;\n}\n\n.reogrid-filter-sort-btn:hover {\n background: #e8f0fe;\n}\n\n.reogrid-filter-separator {\n margin: 0;\n border: none;\n border-top: 1px solid #e0e0e0;\n}\n`.trim();\n\nexport function ensureWorkspaceStyles(styleId: string = DEFAULT_STYLE_ID): void {\n if (typeof document === 'undefined') {\n return;\n }\n ensureFontStyles();\n if (document.getElementById(styleId)) {\n return;\n }\n const style = document.createElement('style');\n style.id = styleId;\n style.textContent = BASE_STYLES;\n document.head.appendChild(style);\n}\n\nfunction ensureFontStyles(): void {\n if (document.getElementById(FONT_LINK_ID)) {\n return;\n }\n const link = document.createElement('link');\n link.id = FONT_LINK_ID;\n link.rel = 'stylesheet';\n link.href = FONT_STYLESHEET_URL;\n document.head.appendChild(link);\n}\n","export const DEFAULT_ROWS = 40;\nexport const DEFAULT_COLUMNS = 26;\nexport const DEFAULT_COLUMN_WIDTH = 80;\nexport const DEFAULT_ROW_HEIGHT = 22;\nexport const HEADER_COLUMN_WIDTH = 60;\nexport const HEADER_ROW_HEIGHT = 24;\n","import type { Worksheet } from '../worksheet/worksheet';\nimport type { RangeRect } from '../worksheet/types';\n\ntype SelectionBounds = RangeRect & {\n topRow: number;\n bottomRow: number;\n leftColumn: number;\n rightColumn: number;\n};\n\nexport class SelectionRange {\nprivate readonly worksheet: Worksheet;\n\n private startRow: number | null = null;\n\n private startColumn: number | null = null;\n\n private endRow: number | null = null;\n\n private endColumn: number | null = null;\n\n private anchorBounds: { top: number; bottom: number; left: number; right: number } | null = null;\n\n constructor(worksheet: Worksheet) {\n this.worksheet = worksheet;\n this.reset();\n }\n\n reset(): void {\n this.startRow = null;\n this.startColumn = null;\n this.endRow = null;\n this.endColumn = null;\n this.anchorBounds = null;\n }\n\n begin(row: number, column: number): void {\n const clamped = this.clampCell(row, column);\n const bounds = this.worksheet.getCellMergeBounds(clamped.row, clamped.column);\n this.startRow = bounds.topRow;\n this.startColumn = bounds.leftColumn;\n this.endRow = bounds.bottomRow;\n this.endColumn = bounds.rightColumn;\n this.anchorBounds = {\n top: bounds.topRow,\n bottom: bounds.bottomRow,\n left: bounds.leftColumn,\n right: bounds.rightColumn,\n };\n }\n\n update(row: number, column: number): void {\n if (!this.isActive() || !this.anchorBounds) {\n return;\n }\n\n const clamped = this.clampCell(row, column);\n const target = this.worksheet.getCellMergeBounds(clamped.row, clamped.column);\n const union = {\n top: Math.min(this.anchorBounds.top, target.topRow),\n bottom: Math.max(this.anchorBounds.bottom, target.bottomRow),\n left: Math.min(this.anchorBounds.left, target.leftColumn),\n right: Math.max(this.anchorBounds.right, target.rightColumn),\n };\n\n const bounds = this.worksheet.expandSelectionWithMergedCells({\n top: union.top,\n bottom: union.bottom,\n left: union.left,\n right: union.right,\n });\n this.startRow = bounds.top;\n this.startColumn = bounds.left;\n this.endRow = bounds.bottom;\n this.endColumn = bounds.right;\n }\n\n isActive(): boolean {\n return this.startRow !== null && this.startColumn !== null;\n }\n\n clampCell(row: number, column: number): { row: number; column: number } {\n const clampedRow = Math.min(Math.max(row, 0), this.worksheet.rows - 1);\n const clampedColumn = Math.min(Math.max(column, 0), this.worksheet.columns - 1);\n return { row: clampedRow, column: clampedColumn };\n }\n\n setRange(startRow: number, startColumn: number, endRow: number, endColumn: number): void {\n const start = this.clampCell(startRow, startColumn);\n const end = this.clampCell(endRow, endColumn);\n this.startRow = start.row;\n this.startColumn = start.column;\n this.endRow = end.row;\n this.endColumn = end.column;\n this.anchorBounds = {\n top: start.row,\n bottom: start.row,\n left: start.column,\n right: start.column,\n };\n }\n\n selectRows(startRow: number, endRow: number = startRow): void {\n const top = Math.min(startRow, endRow);\n const bottom = Math.max(startRow, endRow);\n const expanded = this.worksheet.expandSelectionWithMergedCells({\n top,\n bottom,\n left: 0,\n right: this.worksheet.columns - 1,\n });\n this.setRange(expanded.top, expanded.left, expanded.bottom, expanded.right);\n }\n\n selectColumns(startColumn: number, endColumn: number = startColumn): void {\n const left = Math.min(startColumn, endColumn);\n const right = Math.max(startColumn, endColumn);\n const expanded = this.worksheet.expandSelectionWithMergedCells({\n top: 0,\n bottom: this.worksheet.rows - 1,\n left,\n right,\n });\n this.setRange(expanded.top, expanded.left, expanded.bottom, expanded.right);\n }\n\n selectAll(): void {\n this.setRange(0, 0, this.worksheet.rows - 1, this.worksheet.columns - 1);\n }\n\n getNormalizedBounds(): SelectionBounds | null {\n if (!this.isActive() || this.startRow === null || this.startColumn === null || this.endRow === null || this.endColumn === null) {\n return null;\n }\n\n const topRow = Math.min(this.startRow, this.endRow);\n const bottomRow = Math.max(this.startRow, this.endRow);\n const leftColumn = Math.min(this.startColumn, this.endColumn);\n const rightColumn = Math.max(this.startColumn, this.endColumn);\n\n const rect = this.worksheet.getRangeRect(topRow, leftColumn, bottomRow, rightColumn);\n return { ...rect, topRow, leftColumn, bottomRow, rightColumn };\n }\n\n /** Returns the normalized selection row/column bounds, or null if inactive. */\n getSelectionBounds(): { topRow: number; bottomRow: number; leftColumn: number; rightColumn: number } | null {\n if (!this.isActive() || this.startRow === null || this.startColumn === null || this.endRow === null || this.endColumn === null) {\n return null;\n }\n return {\n topRow: Math.min(this.startRow, this.endRow),\n bottomRow: Math.max(this.startRow, this.endRow),\n leftColumn: Math.min(this.startColumn, this.endColumn),\n rightColumn: Math.max(this.startColumn, this.endColumn),\n };\n }\n\n draw(ctx: CanvasRenderingContext2D): void {\n const bounds = this.getNormalizedBounds();\n if (!bounds) {\n return;\n }\n\n ctx.save();\n ctx.fillStyle = 'rgba(33, 150, 243, 0.2)';\n ctx.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);\n\n const pixelRatio = this.worksheet.getPixelRatio();\n const inset = 0.5 / pixelRatio;\n ctx.strokeStyle = '#2196f3';\n ctx.lineWidth = 2 / pixelRatio;\n ctx.strokeRect(\n bounds.x + inset,\n bounds.y + inset,\n Math.max(0, bounds.width - inset * 2),\n Math.max(0, bounds.height - inset * 2),\n );\n ctx.restore();\n }\n\n /** Draw the selection fill and border at the given screen-space rect. */\n drawRect(ctx: CanvasRenderingContext2D, x: number, y: number, width: number, height: number): void {\n ctx.save();\n ctx.fillStyle = 'rgba(33, 150, 243, 0.2)';\n ctx.fillRect(x, y, width, height);\n\n const pixelRatio = this.worksheet.getPixelRatio();\n const inset = 0.5 / pixelRatio;\n ctx.strokeStyle = '#2196f3';\n ctx.lineWidth = 2 / pixelRatio;\n ctx.strokeRect(\n x + inset,\n y + inset,\n Math.max(0, width - inset * 2),\n Math.max(0, height - inset * 2),\n );\n ctx.restore();\n }\n\n containsRow(row: number): boolean {\n const bounds = this.getSelectionBounds();\n if (!bounds) return false;\n return row >= bounds.topRow && row <= bounds.bottomRow;\n }\n\n containsColumn(column: number): boolean {\n const bounds = this.getSelectionBounds();\n if (!bounds) return false;\n return column >= bounds.leftColumn && column <= bounds.rightColumn;\n }\n\n getActiveCell(): { row: number; column: number } | null {\n if (this.startRow === null || this.startColumn === null) {\n return null;\n }\n return { row: this.startRow, column: this.startColumn };\n }\n\n moveActiveCell(rowDelta: number, columnDelta: number): { row: number; column: number } {\n const current = this.getActiveCell() ?? { row: 0, column: 0 };\n const currentRange = this.worksheet.getMergedRange(current.row, current.column);\n let baseRow = current.row;\n let baseColumn = current.column;\n if (currentRange) {\n if (rowDelta > 0) {\n baseRow = currentRange.bottomRow;\n } else if (rowDelta < 0) {\n baseRow = currentRange.topRow;\n }\n if (columnDelta > 0) {\n baseColumn = currentRange.rightColumn;\n } else if (columnDelta < 0) {\n baseColumn = currentRange.leftColumn;\n }\n }\n const next = this.clampCell(baseRow + rowDelta, baseColumn + columnDelta);\n const bounds = this.worksheet.expandSelectionWithMergedCells({\n top: next.row,\n bottom: next.row,\n left: next.column,\n right: next.column,\n });\n this.startRow = bounds.top;\n this.startColumn = bounds.left;\n this.endRow = bounds.bottom;\n this.endColumn = bounds.right;\n this.anchorBounds = {\n top: bounds.top,\n bottom: bounds.bottom,\n left: bounds.left,\n right: bounds.right,\n };\n return { row: this.startRow, column: this.startColumn };\n }\n}\n","// =============================================================================\n// Formula Engine — Lexer\n// =============================================================================\n\nexport type TokenType =\n | 'number'\n | 'string'\n | 'identifier'\n | 'plus'\n | 'minus'\n | 'multiply'\n | 'divide'\n | 'caret' // ^ (exponentiation)\n | 'percent' // % (postfix percent)\n | 'ampersand' // & (string concatenation)\n | 'lparen'\n | 'rparen'\n | 'comma'\n | 'colon'\n | 'eq' // =\n | 'ne' // <>\n | 'lt' // <\n | 'gt' // >\n | 'le' // <=\n | 'ge' // >=\n | 'eof';\n\nexport interface Token {\n type: TokenType;\n value?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Character helpers — char-code comparisons instead of regex for hot paths\n// ---------------------------------------------------------------------------\n\nfunction isDigit(ch: string): boolean {\n const c = ch.charCodeAt(0);\n return c >= 48 && c <= 57; // '0'–'9'\n}\n\nfunction isAlpha(ch: string): boolean {\n const c = ch.charCodeAt(0);\n return (c >= 65 && c <= 90) || (c >= 97 && c <= 122); // 'A'–'Z' | 'a'–'z'\n}\n\nfunction isWhitespace(ch: string): boolean {\n return ch === ' ' || ch === '\\t' || ch === '\\r' || ch === '\\n';\n}\n\n// ---------------------------------------------------------------------------\n// Lexer\n// ---------------------------------------------------------------------------\n\nexport class Lexer {\n private readonly input: string;\n private position = 0;\n\n constructor(input: string) {\n this.input = input;\n }\n\n nextToken(): Token {\n this.skipWhitespace();\n\n if (this.position >= this.input.length) {\n return { type: 'eof' };\n }\n\n const ch = this.input[this.position];\n\n // Number literal: digits or leading decimal point\n if (isDigit(ch) || (ch === '.' && this.position + 1 < this.input.length && isDigit(this.input[this.position + 1]))) {\n return this.readNumber();\n }\n\n // Identifier: letters or $ (handles A1, $A$1, SUM, TRUE, FALSE …)\n if (isAlpha(ch) || ch === '$') {\n return this.readIdentifier();\n }\n\n // String literal\n if (ch === '\"') {\n return this.readString();\n }\n\n this.position += 1;\n\n switch (ch) {\n case '+': return { type: 'plus' };\n case '-': return { type: 'minus' };\n case '*': return { type: 'multiply' };\n case '/': return { type: 'divide' };\n case '^': return { type: 'caret' };\n case '%': return { type: 'percent' };\n case '&': return { type: 'ampersand' };\n case '(': return { type: 'lparen' };\n case ')': return { type: 'rparen' };\n case ',': return { type: 'comma' };\n case ':': return { type: 'colon' };\n case '=': return { type: 'eq' };\n case '<':\n if (this.input[this.position] === '>') { this.position += 1; return { type: 'ne' }; }\n if (this.input[this.position] === '=') { this.position += 1; return { type: 'le' }; }\n return { type: 'lt' };\n case '>':\n if (this.input[this.position] === '=') { this.position += 1; return { type: 'ge' }; }\n return { type: 'gt' };\n default:\n throw new SyntaxError(`Unexpected character: ${ch}`);\n }\n }\n\n // -------------------------------------------------------------------------\n\n private readNumber(): Token {\n const start = this.position;\n\n while (this.position < this.input.length && isDigit(this.input[this.position])) {\n this.position += 1;\n }\n\n // Optional decimal part\n if (\n this.input[this.position] === '.' &&\n this.position + 1 < this.input.length &&\n isDigit(this.input[this.position + 1])\n ) {\n this.position += 1;\n while (this.position < this.input.length && isDigit(this.input[this.position])) {\n this.position += 1;\n }\n }\n\n // Optional scientific notation: 1e5, 1E-3, 2.5e+10\n const ec = this.input[this.position];\n if (ec === 'e' || ec === 'E') {\n const nc = this.input[this.position + 1];\n if (nc === '+' || nc === '-' || isDigit(nc)) {\n this.position += 1; // consume 'e'/'E'\n if (this.input[this.position] === '+' || this.input[this.position] === '-') {\n this.position += 1;\n }\n while (this.position < this.input.length && isDigit(this.input[this.position])) {\n this.position += 1;\n }\n }\n }\n\n return { type: 'number', value: this.input.slice(start, this.position) };\n }\n\n private readIdentifier(): Token {\n const start = this.position;\n\n // Consume $ signs and letters (handles $A, A, $)\n while (\n this.position < this.input.length &&\n (isAlpha(this.input[this.position]) || this.input[this.position] === '$')\n ) {\n this.position += 1;\n }\n\n // Consume trailing digits (row number in cell references, e.g. A1, $A$1)\n while (this.position < this.input.length && isDigit(this.input[this.position])) {\n this.position += 1;\n }\n\n return { type: 'identifier', value: this.input.slice(start, this.position) };\n }\n\n private readString(): Token {\n this.position += 1; // opening \"\n let result = '';\n\n while (this.position < this.input.length) {\n const ch = this.input[this.position];\n if (ch === '\"') {\n // Escaped double-quote: \"\" → \"\n if (this.input[this.position + 1] === '\"') {\n result += '\"';\n this.position += 2;\n } else {\n this.position += 1; // closing \"\n break;\n }\n } else {\n result += ch;\n this.position += 1;\n }\n }\n\n return { type: 'string', value: result };\n }\n\n private skipWhitespace(): void {\n while (this.position < this.input.length && isWhitespace(this.input[this.position])) {\n this.position += 1;\n }\n }\n}\n","// =============================================================================\n// Formula Engine — Core Types\n// =============================================================================\n\n// ---------------------------------------------------------------------------\n// FormulaValue — discriminated union for all values in the formula system\n// ---------------------------------------------------------------------------\n\nexport type FormulaErrorCode =\n | '#DIV/0!'\n | '#VALUE!'\n | '#REF!'\n | '#N/A'\n | '#NAME?'\n | '#NUM!'\n | '#NULL!'\n | '#CYCLE!';\n\nexport type FormulaValue =\n | { kind: 'number'; value: number }\n | { kind: 'string'; value: string }\n | { kind: 'boolean'; value: boolean }\n | { kind: 'error'; code: FormulaErrorCode }\n | { kind: 'nil' }\n | { kind: 'range'; r1: number; c1: number; r2: number; c2: number };\n\n/** Convenience constructors */\nexport const FV = {\n number: (value: number): FormulaValue => ({ kind: 'number', value }),\n string: (value: string): FormulaValue => ({ kind: 'string', value }),\n boolean: (value: boolean): FormulaValue => ({ kind: 'boolean', value }),\n error: (code: FormulaErrorCode): FormulaValue => ({ kind: 'error', code }),\n range: (r1: number, c1: number, r2: number, c2: number): FormulaValue => ({\n kind: 'range',\n r1,\n c1,\n r2,\n c2,\n }),\n nil: { kind: 'nil' } as FormulaValue,\n};\n\n// ---------------------------------------------------------------------------\n// Cell Reference — absolute/relative flags for copy behaviour\n// ---------------------------------------------------------------------------\n\nexport interface CellRef {\n row: number;\n col: number;\n /** true when $ precedes the column label, e.g. $A1 */\n colAbs: boolean;\n /** true when $ precedes the row number, e.g. A$1 */\n rowAbs: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// AST Node types\n// ---------------------------------------------------------------------------\n\nexport type BinaryOp = '+' | '-' | '*' | '/' | '^' | '=' | '<>' | '<' | '>' | '<=' | '>=';\n\nexport type ASTNode =\n | { type: 'number'; value: number }\n | { type: 'string'; value: string }\n | { type: 'boolean'; value: boolean }\n | { type: 'cell'; ref: CellRef }\n | { type: 'range'; start: CellRef; end: CellRef }\n | { type: 'name'; name: string }\n | { type: 'unary'; op: '-' | '%'; operand: ASTNode }\n | { type: 'binary'; op: BinaryOp; left: ASTNode; right: ASTNode }\n | { type: 'concat'; left: ASTNode; right: ASTNode }\n | { type: 'func'; name: string; args: ASTNode[] };\n\n// ---------------------------------------------------------------------------\n// Evaluation context — passed through the evaluator\n// ---------------------------------------------------------------------------\n\nexport interface EvalContext {\n /** Get the computed FormulaValue of a single cell (handles formulas recursively). */\n getCellValue(row: number, col: number): FormulaValue;\n /** Expand a rectangular range to an array of FormulaValues (row-major). */\n getRangeValues(r1: number, c1: number, r2: number, c2: number): FormulaValue[];\n}\n\n// ---------------------------------------------------------------------------\n// Cell key — compact string identifier used in Maps / Sets\n// ---------------------------------------------------------------------------\n\nexport type CellKey = `${number}:${number}`;\n\nexport function cellKeyOf(row: number, col: number): CellKey {\n return `${row}:${col}`;\n}\n\nexport function parseCellKey(key: CellKey): { row: number; col: number } {\n const colon = key.indexOf(':');\n return { row: Number(key.slice(0, colon)), col: Number(key.slice(colon + 1)) };\n}\n","// =============================================================================\n// Formula Engine — Parser (produces AST, does NOT evaluate)\n// =============================================================================\n\nimport { Lexer, type Token, type TokenType } from './lexer';\nimport { type ASTNode, type BinaryOp, type CellRef } from './types';\n\n// ---------------------------------------------------------------------------\n// Cell-reference parsing helpers\n// ---------------------------------------------------------------------------\n\n/** Convert a column label (A, B, …, Z, AA, AB, …) to a 0-based index. */\nfunction colLabelToIndex(label: string): number {\n let index = 0;\n for (let i = 0; i < label.length; i++) {\n index = index * 26 + (label.charCodeAt(i) - 64); // 'A' = 65\n }\n return index - 1;\n}\n\n/**\n * Try to parse an identifier string as a cell reference.\n * Handles: A1 $A1 A$1 $A$1 AA10 $AA$10 …\n * Returns null if the identifier is not a cell reference.\n */\nfunction parseCellRef(identifier: string): CellRef | null {\n // Groups: (optional $)(column letters)(optional $)(row digits)\n const match = /^(\\$?)([A-Za-z]+)(\\$?)([0-9]+)$/.exec(identifier);\n if (!match) return null;\n\n const [, dollarCol, colLabel, dollarRow, rowStr] = match;\n const col = colLabelToIndex(colLabel.toUpperCase());\n const row = parseInt(rowStr, 10) - 1;\n\n if (row < 0 || col < 0) return null;\n\n return {\n row,\n col,\n colAbs: dollarCol === '$',\n rowAbs: dollarRow === '$',\n };\n}\n\n// ---------------------------------------------------------------------------\n// Parser\n// ---------------------------------------------------------------------------\n\nexport class Parser {\n private current: Token;\n private lookahead: Token;\n private readonly lexer: Lexer;\n\n constructor(input: string) {\n this.lexer = new Lexer(input);\n this.current = this.lexer.nextToken();\n this.lookahead = this.lexer.nextToken();\n }\n\n /**\n * Parse the full expression and return the root AST node.\n * Throws SyntaxError if parsing fails or input is not fully consumed.\n */\n parse(): ASTNode {\n if (this.current.type === 'eof') {\n throw new SyntaxError('Empty formula');\n }\n const node = this.parseComparison();\n if (this.current.type !== 'eof') {\n throw new SyntaxError(`Unexpected token: ${this.current.type}`);\n }\n return node;\n }\n\n // -------------------------------------------------------------------------\n // Operator precedence (low → high)\n // comparison = <> < > <= >=\n // concat &\n // add/sub + -\n // mul/div * /\n // exponent ^\n // percent % (postfix)\n // unary - (prefix)\n // primary literal | cell | range | func | (expr)\n // -------------------------------------------------------------------------\n\n private parseComparison(): ASTNode {\n let left = this.parseConcat();\n\n const opMap: Partial<Record<TokenType, BinaryOp>> = {\n eq: '=',\n ne: '<>',\n lt: '<',\n gt: '>',\n le: '<=',\n ge: '>=',\n };\n\n const op = opMap[this.current.type];\n if (op !== undefined) {\n this.advance();\n const right = this.parseConcat();\n left = { type: 'binary', op, left, right };\n }\n\n return left;\n }\n\n private parseConcat(): ASTNode {\n let left = this.parseAddSub();\n\n while (this.current.type === 'ampersand') {\n this.advance();\n const right = this.parseAddSub();\n left = { type: 'concat', left, right };\n }\n\n return left;\n }\n\n private parseAddSub(): ASTNode {\n let left = this.parseMulDiv();\n\n while (this.current.type === 'plus' || this.current.type === 'minus') {\n const op: BinaryOp = this.current.type === 'plus' ? '+' : '-';\n this.advance();\n const right = this.parseMulDiv();\n left = { type: 'binary', op, left, right };\n }\n\n return left;\n }\n\n private parseMulDiv(): ASTNode {\n let left = this.parseExponent();\n\n while (this.current.type === 'multiply' || this.current.type === 'divide') {\n const op: BinaryOp = this.current.type === 'multiply' ? '*' : '/';\n this.advance();\n const right = this.parseExponent();\n left = { type: 'binary', op, left, right };\n }\n\n return left;\n }\n\n private parseExponent(): ASTNode {\n let base = this.parsePercent();\n\n if (this.current.type === 'caret') {\n this.advance();\n // Right-associative: 2^3^4 = 2^(3^4)\n const exponent = this.parseExponent();\n base = { type: 'binary', op: '^', left: base, right: exponent };\n }\n\n return base;\n }\n\n private parsePercent(): ASTNode {\n let operand = this.parseUnary();\n\n // Postfix % (can chain: 50%% = 0.005)\n while (this.current.type === 'percent') {\n this.advance();\n operand = { type: 'unary', op: '%', operand };\n }\n\n return operand;\n }\n\n private parseUnary(): ASTNode {\n if (this.current.type === 'minus') {\n this.advance();\n return { type: 'unary', op: '-', operand: this.parseUnary() };\n }\n if (this.current.type === 'plus') {\n this.advance();\n return this.parseUnary(); // unary + is a no-op\n }\n return this.parsePrimary();\n }\n\n private parsePrimary(): ASTNode {\n switch (this.current.type) {\n // ---- Number literal ----\n case 'number': {\n const value = parseFloat(this.current.value ?? '0');\n this.advance();\n return { type: 'number', value };\n }\n\n // ---- String literal ----\n case 'string': {\n const value = this.current.value ?? '';\n this.advance();\n return { type: 'string', value };\n }\n\n // ---- Identifier: cell ref, range, function call, TRUE/FALSE, named range ----\n case 'identifier': {\n const ident = this.current.value ?? '';\n this.advance();\n\n // Function call: IDENT(\n if (this.current.type === 'lparen') {\n this.advance(); // consume '('\n const args = this.parseArgList();\n this.eat('rparen');\n return { type: 'func', name: ident.toUpperCase(), args };\n }\n\n // Range: A1:B2 (colon immediately follows an identifier that looks like a cell ref)\n if (this.current.type === 'colon') {\n const startRef = parseCellRef(ident);\n if (startRef !== null) {\n this.advance(); // consume ':'\n if (this.current.type !== 'identifier') {\n throw new SyntaxError('Expected cell reference after \":\"');\n }\n const endIdent = this.current.value ?? '';\n const endRef = parseCellRef(endIdent);\n if (endRef === null) {\n throw new SyntaxError(`Invalid cell reference: ${endIdent}`);\n }\n this.advance();\n return { type: 'range', start: startRef, end: endRef };\n }\n }\n\n // Boolean literals\n const upper = ident.toUpperCase();\n if (upper === 'TRUE') return { type: 'boolean', value: true };\n if (upper === 'FALSE') return { type: 'boolean', value: false };\n\n // Cell reference\n const cellRef = parseCellRef(ident);\n if (cellRef !== null) return { type: 'cell', ref: cellRef };\n\n // Named range / unknown identifier\n return { type: 'name', name: upper };\n }\n\n // ---- Parenthesised expression ----\n case 'lparen': {\n this.advance();\n const expr = this.parseComparison();\n this.eat('rparen');\n return expr;\n }\n\n default:\n throw new SyntaxError(`Unexpected token in expression: ${this.current.type}`);\n }\n }\n\n /**\n * Parse comma-separated function arguments.\n * Empty argument slots are allowed (e.g. IF(,,\"default\") → some functions handle nil).\n */\n private parseArgList(): ASTNode[] {\n const args: ASTNode[] = [];\n\n if (this.current.type === 'rparen') {\n return args; // no arguments\n }\n\n // First argument\n args.push(this.parseArgument());\n\n while (this.current.type === 'comma') {\n this.advance();\n args.push(this.parseArgument());\n }\n\n return args;\n }\n\n /** Parse a single argument — may be empty (returns a nil node). */\n private parseArgument(): ASTNode {\n if (this.current.type === 'comma' || this.current.type === 'rparen') {\n // Empty argument slot → nil\n return { type: 'name', name: 'NIL' } satisfies ASTNode;\n }\n return this.parseComparison();\n }\n\n // -------------------------------------------------------------------------\n // Token helpers\n // -------------------------------------------------------------------------\n\n private advance(): void {\n this.current = this.lookahead;\n this.lookahead = this.lexer.nextToken();\n }\n\n private eat(type: TokenType): void {\n if (this.current.type !== type) {\n throw new SyntaxError(`Expected ${type}, got ${this.current.type}`);\n }\n this.advance();\n }\n}\n\n// ---------------------------------------------------------------------------\n// Public helper: parse a formula string (without leading '=') into an AST\n// ---------------------------------------------------------------------------\n\nexport function parseFormula(expression: string): ASTNode {\n return new Parser(expression).parse();\n}\n\n// ---------------------------------------------------------------------------\n// Public helper: extract all cell keys referenced by an AST (static analysis)\n// Used by the DependencyGraph to register dependencies at parse time.\n// ---------------------------------------------------------------------------\n\nimport { type CellKey, cellKeyOf } from './types';\n\nexport function extractCellRefs(node: ASTNode): Set<CellKey> {\n const refs = new Set<CellKey>();\n walkRefs(node, refs);\n return refs;\n}\n\nfunction walkRefs(node: ASTNode, refs: Set<CellKey>): void {\n switch (node.type) {\n case 'cell':\n refs.add(cellKeyOf(node.ref.row, node.ref.col));\n break;\n\n case 'range': {\n const r1 = Math.min(node.start.row, node.end.row);\n const r2 = Math.max(node.start.row, node.end.row);\n const c1 = Math.min(node.start.col, node.end.col);\n const c2 = Math.max(node.start.col, node.end.col);\n for (let r = r1; r <= r2; r++) {\n for (let c = c1; c <= c2; c++) {\n refs.add(cellKeyOf(r, c));\n }\n }\n break;\n }\n\n case 'binary':\n case 'concat':\n walkRefs(node.left, refs);\n walkRefs(node.right, refs);\n break;\n\n case 'unary':\n walkRefs(node.operand, refs);\n break;\n\n case 'func':\n for (const arg of node.args) walkRefs(arg, refs);\n break;\n\n // number, string, boolean, name → no cell refs\n }\n}\n","// =============================================================================\n// Formula Engine — Evaluator (AST walker)\n// =============================================================================\n\nimport { type ASTNode, type EvalContext, type FormulaValue, FV } from './types';\nimport type { FunctionRegistry } from './functions/registry';\n\n// ---------------------------------------------------------------------------\n// Type coercion helpers (Excel-compatible semantics)\n// ---------------------------------------------------------------------------\n\n/**\n * Coerce a FormulaValue to a number.\n * nil → 0, boolean → 0/1, string → strict parse (else #VALUE!), error → propagate.\n */\nexport function coerceToNumber(v: FormulaValue): FormulaValue {\n switch (v.kind) {\n case 'number':\n return v;\n case 'nil':\n return FV.number(0);\n case 'boolean':\n return FV.number(v.value ? 1 : 0);\n case 'string': {\n const trimmed = v.value.trim();\n if (trimmed === '') return FV.number(0);\n const n = Number(trimmed);\n if (!Number.isFinite(n)) return FV.error('#VALUE!');\n return FV.number(n);\n }\n case 'error':\n return v; // propagate errors\n case 'range':\n return FV.error('#VALUE!');\n }\n}\n\n/**\n * Coerce a FormulaValue to a boolean.\n * nil → false, 0 → false, \"\" → false, non-zero → true, non-empty string → true.\n */\nexport function coerceToBool(v: FormulaValue): boolean {\n switch (v.kind) {\n case 'boolean': return v.value;\n case 'number': return v.value !== 0;\n case 'string': return v.value !== '';\n case 'nil': return false;\n default: return false;\n }\n}\n\n/**\n * Coerce a FormulaValue to a display string.\n */\nexport function coerceToString(v: FormulaValue): string {\n switch (v.kind) {\n case 'number': return String(v.value);\n case 'string': return v.value;\n case 'boolean': return v.value ? 'TRUE' : 'FALSE';\n case 'nil': return '';\n case 'error': return v.code;\n case 'range': return '#VALUE!';\n }\n}\n\n// ---------------------------------------------------------------------------\n// Evaluator\n// ---------------------------------------------------------------------------\n\nexport class Evaluator {\n constructor(private readonly registry: FunctionRegistry) {}\n\n evaluate(node: ASTNode, ctx: EvalContext): FormulaValue {\n switch (node.type) {\n // ---- Literals ----\n case 'number': return FV.number(node.value);\n case 'string': return FV.string(node.value);\n case 'boolean': return FV.boolean(node.value);\n\n // ---- Nil placeholder (empty argument slot) ----\n case 'name':\n if (node.name === 'NIL') return FV.nil;\n // Unknown named range / identifier\n return FV.error('#NAME?');\n\n // ---- Cell reference ----\n case 'cell':\n return ctx.getCellValue(node.ref.row, node.ref.col);\n\n // ---- Range (as a value — used when passed directly to a function) ----\n case 'range': {\n const r1 = Math.min(node.start.row, node.end.row);\n const r2 = Math.max(node.start.row, node.end.row);\n const c1 = Math.min(node.start.col, node.end.col);\n const c2 = Math.max(node.start.col, node.end.col);\n return FV.range(r1, c1, r2, c2);\n }\n\n // ---- Unary operators ----\n case 'unary': {\n const operand = this.evaluate(node.operand, ctx);\n if (node.op === '-') {\n const n = coerceToNumber(operand);\n if (n.kind !== 'number') return n; // propagate error\n return FV.number(-n.value);\n }\n // '%' postfix: divide by 100\n const n = coerceToNumber(operand);\n if (n.kind !== 'number') return n;\n return FV.number(n.value / 100);\n }\n\n // ---- Binary operators ----\n case 'binary':\n return this.evalBinary(node.op, node.left, node.right, ctx);\n\n // ---- String concatenation ----\n case 'concat': {\n const left = this.evaluate(node.left, ctx);\n const right = this.evaluate(node.right, ctx);\n if (left.kind === 'error') return left;\n if (right.kind === 'error') return right;\n return FV.string(coerceToString(left) + coerceToString(right));\n }\n\n // ---- Function call ----\n case 'func':\n return this.registry.call(node.name, node.args, ctx, this);\n }\n }\n\n // -------------------------------------------------------------------------\n\n private evalBinary(\n op: ASTNode & { type: 'binary' } extends { op: infer O } ? O : never,\n leftNode: ASTNode,\n rightNode: ASTNode,\n ctx: EvalContext,\n ): FormulaValue {\n // Arithmetic operators — evaluate both sides eagerly\n if (op === '+' || op === '-' || op === '*' || op === '/' || op === '^') {\n const left = coerceToNumber(this.evaluate(leftNode, ctx));\n if (left.kind === 'error') return left;\n const right = coerceToNumber(this.evaluate(rightNode, ctx));\n if (right.kind === 'error') return right;\n\n const l = (left as Extract<FormulaValue, { kind: 'number' }>).value;\n const r = (right as Extract<FormulaValue, { kind: 'number' }>).value;\n\n let result: number;\n switch (op) {\n case '+': result = l + r; break;\n case '-': result = l - r; break;\n case '*': result = l * r; break;\n case '/':\n if (r === 0) return FV.error('#DIV/0!');\n result = l / r;\n break;\n case '^': result = Math.pow(l, r); break;\n default: result = 0;\n }\n\n if (!Number.isFinite(result)) return FV.error('#NUM!');\n return FV.number(result);\n }\n\n // Comparison operators\n const left = this.evaluate(leftNode, ctx);\n const right = this.evaluate(rightNode, ctx);\n if (left.kind === 'error') return left;\n if (right.kind === 'error') return right;\n\n return FV.boolean(this.compare(op, left, right));\n }\n\n private compare(\n op: string,\n left: FormulaValue,\n right: FormulaValue,\n ): boolean {\n // Nil vs empty string: Excel treats them as equal\n const l = left.kind === 'nil' ? '' : left.kind === 'number' ? left.value\n : left.kind === 'boolean' ? (left.value ? 1 : 0)\n : left.kind === 'string' ? left.value : null;\n const r = right.kind === 'nil' ? '' : right.kind === 'number' ? right.value\n : right.kind === 'boolean' ? (right.value ? 1 : 0)\n : right.kind === 'string' ? right.value : null;\n\n if (l === null || r === null) return op === '<>';\n\n // String equality is case-insensitive in Excel\n if (typeof l === 'string' && typeof r === 'string') {\n const lc = l.toLowerCase();\n const rc = r.toLowerCase();\n if (op === '=') return lc === rc;\n if (op === '<>') return lc !== rc;\n }\n\n if (op === '=') return l === r;\n if (op === '<>') return l !== r;\n\n // Ordering: numbers before strings before booleans (Excel type order)\n if (typeof l === 'number' && typeof r === 'number') {\n if (op === '<') return l < r;\n if (op === '>') return l > r;\n if (op === '<=') return l <= r;\n if (op === '>=') return l >= r;\n }\n if (typeof l === 'string' && typeof r === 'string') {\n const cmp = l.toLowerCase().localeCompare(r.toLowerCase());\n if (op === '<') return cmp < 0;\n if (op === '>') return cmp > 0;\n if (op === '<=') return cmp <= 0;\n if (op === '>=') return cmp >= 0;\n }\n\n return false;\n }\n}\n","// =============================================================================\n// Formula Engine — Function Registry\n// =============================================================================\n\nimport type { ASTNode, EvalContext, FormulaValue } from '../types';\nimport { FV } from '../types';\nimport type { Evaluator } from '../evaluator';\n\n// ---------------------------------------------------------------------------\n// Function definition interfaces\n// ---------------------------------------------------------------------------\n\n/**\n * An eager function receives already-evaluated argument values.\n * Use for the vast majority of functions (SUM, AVERAGE, LEN, …).\n */\nexport interface EagerFunctionDef {\n lazy?: false;\n call(args: FormulaValue[], ctx: EvalContext): FormulaValue;\n}\n\n/**\n * A lazy function receives thunks — it controls when (and whether) each\n * argument is evaluated. Required for IF, AND, OR, IFERROR, IFS, …\n */\nexport interface LazyFunctionDef {\n lazy: true;\n call(args: Array<() => FormulaValue>, ctx: EvalContext): FormulaValue;\n}\n\nexport type FunctionDef = EagerFunctionDef | LazyFunctionDef;\n\n// ---------------------------------------------------------------------------\n// Registry\n// ---------------------------------------------------------------------------\n\nexport class FunctionRegistry {\n private readonly defs = new Map<string, FunctionDef>();\n\n register(name: string, def: FunctionDef): void {\n this.defs.set(name.toUpperCase(), def);\n }\n\n /**\n * Call a registered function.\n * Handles eager vs. lazy dispatch automatically.\n */\n call(\n name: string,\n argNodes: ASTNode[],\n ctx: EvalContext,\n evaluator: Evaluator,\n ): FormulaValue {\n const def = this.defs.get(name.toUpperCase());\n if (!def) return FV.error('#NAME?');\n\n if (def.lazy) {\n const thunks = argNodes.map((node) => () => evaluator.evaluate(node, ctx));\n return def.call(thunks, ctx);\n }\n\n // Eager: evaluate all args, then call.\n // Range values are kept as-is (functions receive them and can expand via ctx).\n const args = argNodes.map((node) => evaluator.evaluate(node, ctx));\n return def.call(args, ctx);\n }\n\n has(name: string): boolean {\n return this.defs.has(name.toUpperCase());\n }\n}\n","/**\n * Excel-compatible number and date format engine.\n *\n * Supports:\n * - Multi-section formats separated by `;`\n * - Number formatting with `0`, `#`, `?` placeholders, thousands grouping, decimal places\n * - Trailing-comma scaling (`#,##0,` → ÷1000, `#,##0,,` → ÷1,000,000)\n * - Percent formats (`%` multiplies value by 100)\n * - Date/time formats (`yyyy`, `mm`, `dd`, `HH`, `mm` as minutes, `ss`, `AM/PM`)\n * - Month vs minute context resolution (`mm` after `h`/`H` = minutes, else months)\n * - Literal text in double quotes and backslash-escaped characters\n * - Color/locale bracket contents (`[Red]`, `[$USD-409]`) stripped from output\n */\n\n/**\n * Format a numeric value using an Excel-style format code.\n * Kept for backward compatibility; delegates to `formatValueWithFormat`.\n */\nexport function formatNumberWithFormat(value: number, formatCode: string): string | null {\n return formatValueWithFormat(value, formatCode);\n}\n\n/**\n * Format a value (number, Date, or date string) using an Excel-style format code.\n * Returns `null` when no formatting should be applied (e.g. \"General\" format or unsupported).\n */\nexport function formatValueWithFormat(\n value: number | Date | string,\n formatCode: string,\n): string | null {\n if (!formatCode || formatCode.toLowerCase() === 'general') {\n return null;\n }\n\n let numericValue: number | null = null;\n let dateValue: Date | null = null;\n\n if (value instanceof Date) {\n dateValue = value;\n } else if (typeof value === 'number') {\n numericValue = value;\n } else if (typeof value === 'string') {\n const asNum = Number(value);\n if (Number.isFinite(asNum)) {\n numericValue = asNum;\n } else {\n const d = new Date(value);\n if (!isNaN(d.getTime())) {\n dateValue = d;\n }\n }\n }\n\n const sections = splitFormatSections(formatCode);\n let section = sections[0] ?? formatCode;\n let workingValue = numericValue ?? 0;\n\n if (numericValue !== null) {\n if (numericValue < 0 && sections.length > 1) {\n section = sections[1] ?? section;\n workingValue = Math.abs(numericValue);\n } else if (numericValue === 0 && sections.length > 2 && sections[2]) {\n section = sections[2];\n workingValue = 0;\n }\n }\n\n if (isDateFormatSection(section)) {\n const date = dateValue ?? (numericValue !== null ? excelSerialToDate(numericValue) : null);\n if (!date) return null;\n return formatDateSection(date, section);\n }\n\n if (numericValue === null) return null;\n return applyNumberFormatSection(workingValue, section);\n}\n\n/**\n * Returns true if the given format section uses date/time tokens.\n * Exported so callers (e.g. worksheet) can pre-check before parsing string dates.\n */\nexport function isDateFormatSection(section: string): boolean {\n const stripped = stripLiterals(section).toLowerCase();\n if (!stripped) return false;\n if (stripped.includes('am/pm') || stripped.includes('a/p')) return true;\n if (/[yd]/.test(stripped)) return true;\n if (/[hs]/.test(stripped) && stripped.includes('m')) return true;\n return false;\n}\n\n// ---------------------------------------------------------------------------\n// Section splitting\n// ---------------------------------------------------------------------------\n\n/**\n * Split a format code into sections at `;` boundaries, respecting quoted strings\n * and bracket contents. Leading whitespace is trimmed from each section so that\n * the common `\"pos; neg\"` style does not inject a leading space into the output.\n */\nfunction splitFormatSections(formatCode: string): string[] {\n const sections: string[] = [];\n let current = '';\n let i = 0;\n while (i < formatCode.length) {\n const c = formatCode[i];\n if (c === '\"') {\n const end = formatCode.indexOf('\"', i + 1);\n if (end === -1) {\n current += formatCode.slice(i);\n break;\n }\n current += formatCode.slice(i, end + 1);\n i = end + 1;\n } else if (c === '[') {\n const end = formatCode.indexOf(']', i + 1);\n if (end === -1) {\n current += formatCode.slice(i);\n break;\n }\n current += formatCode.slice(i, end + 1);\n i = end + 1;\n } else if (c === ';') {\n sections.push(current.trimStart());\n current = '';\n i++;\n } else {\n current += c;\n i++;\n }\n }\n sections.push(current.trimStart());\n return sections;\n}\n\n// ---------------------------------------------------------------------------\n// Number formatting\n// ---------------------------------------------------------------------------\n\nfunction applyNumberFormatSection(value: number, section: string): string | null {\n if (!section) return null;\n if (/[eE][+-]?0+/.test(section)) return null;\n\n const { cleanedSection, scaleFactor } = extractScaleCommas(section);\n const workingValue = value / scaleFactor;\n\n // Find the range of digit placeholders (0, #, ?) outside quoted strings and brackets.\n // This prevents literal digits inside \"...\" from being treated as format placeholders.\n const range = findFormatPlaceholderRange(cleanedSection);\n\n if (!range) {\n // No digit placeholders — treat the entire section as a literal string\n // (common for the zero section, e.g. `#,##0;(#,##0);\"-\"`)\n const literal = expandLiterals(cleanedSection);\n return literal.length > 0 ? literal : null;\n }\n\n const prefixRaw = cleanedSection.slice(0, range.start);\n const coreRaw = cleanedSection.slice(range.start, range.end + 1);\n const suffixRaw = cleanedSection.slice(range.end + 1);\n\n const prefix = expandLiterals(prefixRaw);\n const suffix = expandLiterals(suffixRaw);\n\n const hasPercent = cleanedSection.includes('%');\n let numValue = workingValue;\n if (hasPercent) {\n numValue *= 100;\n }\n\n const { useGrouping, minFraction, maxFraction } = extractNumericPattern(coreRaw);\n\n try {\n const formatter = new Intl.NumberFormat('en-US', {\n useGrouping,\n minimumFractionDigits: minFraction,\n maximumFractionDigits: maxFraction,\n });\n const formattedNumber = formatter.format(numValue);\n\n // When the number is negative and there is no dedicated negative section,\n // Intl.NumberFormat places the `-` sign at the start of the number string.\n // If the format has a prefix (e.g. \"¥\"), the sign must come before the prefix.\n if (prefix && formattedNumber.startsWith('-')) {\n return `-${prefix}${formattedNumber.slice(1)}${suffix}`;\n }\n return `${prefix}${formattedNumber}${suffix}`;\n } catch {\n return null;\n }\n}\n\n/**\n * Find the character range [start, end] of the first and last digit placeholder\n * (`0`, `#`, `?`) in `section`, skipping quoted strings, brackets, and escapes.\n * Returns null if no placeholders are found.\n */\nfunction findFormatPlaceholderRange(\n section: string,\n): { start: number; end: number } | null {\n let first = -1;\n let last = -1;\n let i = 0;\n while (i < section.length) {\n const c = section[i];\n if (c === '\"') {\n const end = section.indexOf('\"', i + 1);\n i = end === -1 ? section.length : end + 1;\n } else if (c === '[') {\n const end = section.indexOf(']', i + 1);\n i = end === -1 ? section.length : end + 1;\n } else if (c === '\\\\') {\n i += 2;\n } else {\n if (/[0#?]/.test(c)) {\n if (first === -1) first = i;\n last = i;\n }\n i++;\n }\n }\n if (first === -1) return null;\n return { start: first, end: last };\n}\n\n/**\n * Expand a raw format substring into its display text by interpreting:\n * - `\"...\"` quoted literals → their content\n * - `[$symbol-locale]` → the symbol only\n * - `[...]` other brackets → empty (color/condition specs)\n * - `\\c` escape → the character `c`\n * - `_c` padding placeholder → empty\n * - `*c` fill character → empty\n * All other characters are passed through as-is.\n */\nfunction expandLiterals(section: string): string {\n let result = '';\n let i = 0;\n while (i < section.length) {\n const c = section[i];\n if (c === '\"') {\n const end = section.indexOf('\"', i + 1);\n if (end === -1) break;\n result += section.slice(i + 1, end);\n i = end + 1;\n } else if (c === '[') {\n const end = section.indexOf(']', i + 1);\n if (end === -1) break;\n const content = section.slice(i + 1, end);\n if (content.startsWith('$')) {\n const dash = content.indexOf('-');\n result += dash >= 0 ? content.slice(1, dash) : content.slice(1);\n }\n // Other brackets (color, condition) produce no output\n i = end + 1;\n } else if (c === '\\\\') {\n if (i + 1 < section.length) {\n result += section[i + 1];\n i += 2;\n } else {\n i++;\n }\n } else if (c === '_') {\n i += 2;\n } else if (c === '*') {\n i += 2;\n } else {\n result += c;\n i++;\n }\n }\n return result;\n}\n\n/**\n * Count and remove trailing scale commas from the integer part of a number format.\n * Each trailing comma (after the last digit placeholder, before the decimal) divides\n * the value by 1000. Returns the stripped section and the scale factor.\n *\n * Example: \"#,##0,,.00\" → cleanedSection=\"#,##0.00\", scaleFactor=1_000_000\n */\nfunction extractScaleCommas(section: string): { cleanedSection: string; scaleFactor: number } {\n // Build a boolean map of positions inside literals (quoted strings, brackets, escapes)\n const inLiteral: boolean[] = new Array(section.length).fill(false);\n let i = 0;\n while (i < section.length) {\n if (section[i] === '\"') {\n inLiteral[i] = true;\n i++;\n while (i < section.length) {\n inLiteral[i] = true;\n if (section[i] === '\"') {\n i++;\n break;\n }\n i++;\n }\n } else if (section[i] === '[') {\n inLiteral[i] = true;\n i++;\n while (i < section.length) {\n inLiteral[i] = true;\n if (section[i] === ']') {\n i++;\n break;\n }\n i++;\n }\n } else if (section[i] === '\\\\') {\n inLiteral[i] = true;\n if (i + 1 < section.length) {\n inLiteral[i + 1] = true;\n i += 2;\n } else {\n i++;\n }\n } else {\n i++;\n }\n }\n\n // Locate decimal point outside literals\n let dotPos = -1;\n for (let j = 0; j < section.length; j++) {\n if (!inLiteral[j] && section[j] === '.') {\n dotPos = j;\n break;\n }\n }\n\n // Search only the integer part (before decimal point)\n const searchEnd = dotPos >= 0 ? dotPos : section.length;\n\n // Find last digit placeholder in the integer part (outside literals)\n let lastDigitPos = -1;\n for (let j = searchEnd - 1; j >= 0; j--) {\n if (!inLiteral[j] && /[0#?]/.test(section[j])) {\n lastDigitPos = j;\n break;\n }\n }\n\n if (lastDigitPos === -1) return { cleanedSection: section, scaleFactor: 1 };\n\n // Count consecutive commas immediately after the last digit placeholder\n let trailingCount = 0;\n let trailingEnd = lastDigitPos + 1;\n while (trailingEnd < searchEnd && !inLiteral[trailingEnd] && section[trailingEnd] === ',') {\n trailingCount++;\n trailingEnd++;\n }\n\n if (trailingCount === 0) return { cleanedSection: section, scaleFactor: 1 };\n\n const cleanedSection = section.slice(0, lastDigitPos + 1) + section.slice(trailingEnd);\n return { cleanedSection, scaleFactor: Math.pow(1000, trailingCount) };\n}\n\n\nfunction extractNumericPattern(core: string): {\n useGrouping: boolean;\n minFraction: number;\n maxFraction: number;\n} {\n const decimalPoint = core.indexOf('.');\n let integerPart = core;\n let fractionPart = '';\n if (decimalPoint >= 0) {\n integerPart = core.slice(0, decimalPoint);\n fractionPart = core.slice(decimalPoint + 1);\n }\n const useGrouping = integerPart.includes(',');\n const normalizedFraction = fractionPart.replace(/[^0#?]/g, '');\n const minFraction = (normalizedFraction.match(/0/g) ?? []).length;\n const maxFraction = normalizedFraction.length;\n return {\n useGrouping,\n minFraction,\n maxFraction: Math.max(minFraction, maxFraction),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Date/time formatting\n// ---------------------------------------------------------------------------\n\ninterface RawDateToken {\n kind:\n | 'year'\n | 'month_or_minute'\n | 'day'\n | 'hour'\n | 'second'\n | 'ampm'\n | 'literal';\n raw?: string;\n value?: string;\n long?: boolean;\n}\n\ninterface DateToken {\n kind: 'year' | 'month' | 'minute' | 'day' | 'hour' | 'second' | 'ampm' | 'literal';\n raw?: string;\n value?: string;\n long?: boolean;\n}\n\n/**\n * Tokenize a date format section, resolving the `m`/`mm` ambiguity:\n * - Treated as **minutes** when immediately preceded by an `h`/`hh` token\n * or immediately followed by an `s`/`ss` token (ignoring literals between them).\n * - Treated as **months** otherwise.\n */\nfunction tokenizeDateFormat(section: string): DateToken[] {\n const raw: RawDateToken[] = [];\n let i = 0;\n\n while (i < section.length) {\n const c = section[i];\n\n if (c === '\"') {\n const end = section.indexOf('\"', i + 1);\n if (end === -1) break;\n raw.push({ kind: 'literal', value: section.slice(i + 1, end) });\n i = end + 1;\n continue;\n }\n\n if (c === '\\\\') {\n if (i + 1 < section.length) {\n raw.push({ kind: 'literal', value: section[i + 1] });\n i += 2;\n } else {\n i++;\n }\n continue;\n }\n\n if (c === '[') {\n const end = section.indexOf(']', i + 1);\n i = end === -1 ? section.length : end + 1;\n continue;\n }\n\n const lowerSlice = section.slice(i).toLowerCase();\n\n if (lowerSlice.startsWith('am/pm')) {\n raw.push({ kind: 'ampm', long: true });\n i += 5;\n continue;\n }\n if (lowerSlice.startsWith('a/p')) {\n raw.push({ kind: 'ampm', long: false });\n i += 3;\n continue;\n }\n\n // Try each token pattern longest-first (case-insensitive)\n const patterns: Array<[string, RawDateToken['kind']]> = [\n ['yyyy', 'year'],\n ['yyy', 'year'],\n ['yy', 'year'],\n ['y', 'year'],\n ['mmmm', 'month_or_minute'],\n ['mmm', 'month_or_minute'],\n ['mm', 'month_or_minute'],\n ['m', 'month_or_minute'],\n ['dddd', 'day'],\n ['ddd', 'day'],\n ['dd', 'day'],\n ['d', 'day'],\n ['hh', 'hour'],\n ['h', 'hour'],\n ['ss', 'second'],\n ['s', 'second'],\n ];\n\n let matched = false;\n for (const [pattern, kind] of patterns) {\n if (\n section.length - i >= pattern.length &&\n section.slice(i, i + pattern.length).toLowerCase() === pattern\n ) {\n raw.push({ kind, raw: section.slice(i, i + pattern.length) });\n i += pattern.length;\n matched = true;\n break;\n }\n }\n\n if (!matched) {\n raw.push({ kind: 'literal', value: c });\n i++;\n }\n }\n\n // Resolve month_or_minute: if preceded by an hour token or followed by a second token → minute\n const resolved: DateToken[] = [];\n for (let j = 0; j < raw.length; j++) {\n const token = raw[j];\n if (token.kind !== 'month_or_minute') {\n resolved.push(token as DateToken);\n continue;\n }\n\n let prevIsHour = false;\n for (let k = j - 1; k >= 0; k--) {\n if (raw[k].kind === 'literal') continue;\n prevIsHour = raw[k].kind === 'hour';\n break;\n }\n\n let nextIsSecond = false;\n for (let k = j + 1; k < raw.length; k++) {\n if (raw[k].kind === 'literal') continue;\n nextIsSecond = raw[k].kind === 'second';\n break;\n }\n\n resolved.push({\n ...token,\n kind: prevIsHour || nextIsSecond ? 'minute' : 'month',\n } as DateToken);\n }\n\n return resolved;\n}\n\nfunction formatDateSection(date: Date, section: string): string {\n const tokens = tokenizeDateFormat(section);\n const hasAmPm = tokens.some((t) => t.kind === 'ampm');\n let result = '';\n\n for (const token of tokens) {\n switch (token.kind) {\n case 'literal':\n result += token.value ?? '';\n break;\n\n case 'year': {\n const width = token.raw!.length;\n const y = date.getFullYear();\n if (width >= 4) result += String(y).padStart(4, '0');\n else if (width >= 2) result += String(y).slice(-2).padStart(2, '0');\n else result += String(y % 10);\n break;\n }\n\n case 'month': {\n const width = token.raw!.length;\n const m = date.getMonth();\n if (width >= 4) result += MONTH_NAMES[m];\n else if (width === 3) result += MONTH_NAMES_SHORT[m];\n else if (width >= 2) result += String(m + 1).padStart(2, '0');\n else result += String(m + 1);\n break;\n }\n\n case 'day': {\n const width = token.raw!.length;\n const d = date.getDate();\n if (width >= 4) result += DAY_NAMES[date.getDay()];\n else if (width === 3) result += DAY_NAMES_SHORT[date.getDay()];\n else if (width >= 2) result += String(d).padStart(2, '0');\n else result += String(d);\n break;\n }\n\n case 'hour': {\n const width = token.raw!.length;\n let h = date.getHours();\n if (hasAmPm) {\n h = h % 12;\n if (h === 0) h = 12;\n }\n result += width >= 2 ? String(h).padStart(2, '0') : String(h);\n break;\n }\n\n case 'minute': {\n const width = token.raw!.length;\n const min = date.getMinutes();\n result += width >= 2 ? String(min).padStart(2, '0') : String(min);\n break;\n }\n\n case 'second': {\n const width = token.raw!.length;\n const s = date.getSeconds();\n result += width >= 2 ? String(s).padStart(2, '0') : String(s);\n break;\n }\n\n case 'ampm':\n result +=\n date.getHours() >= 12 ? (token.long ? 'PM' : 'P') : (token.long ? 'AM' : 'A');\n break;\n }\n }\n\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction stripLiterals(section: string): string {\n let result = '';\n for (let i = 0; i < section.length; i++) {\n const char = section[i];\n if (char === '\"') {\n while (i + 1 < section.length && section[i + 1] !== '\"') {\n i++;\n }\n i++;\n continue;\n }\n if (char === '\\\\') {\n i++;\n continue;\n }\n if (char === '[') {\n while (i + 1 < section.length && section[i + 1] !== ']') {\n i++;\n }\n i++;\n continue;\n }\n if (char === '_') {\n i++;\n continue;\n }\n if (char === '*') {\n i++;\n continue;\n }\n result += char;\n }\n return result;\n}\n\nfunction excelSerialToDate(serial: number): Date | null {\n if (!Number.isFinite(serial)) return null;\n const millisecondsPerDay = 24 * 60 * 60 * 1000;\n const epoch = Date.UTC(1899, 11, 30);\n let wholeDays = Math.trunc(serial);\n let fractional = serial - wholeDays;\n if (serial < 0 && fractional !== 0) {\n wholeDays -= 1;\n fractional = serial - wholeDays;\n }\n if (wholeDays >= 60) wholeDays -= 1;\n const ms = epoch + wholeDays * millisecondsPerDay + Math.round(fractional * millisecondsPerDay);\n return new Date(ms);\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst MONTH_NAMES = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n];\n\nconst MONTH_NAMES_SHORT = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n];\n\nconst DAY_NAMES = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n];\n\nconst DAY_NAMES_SHORT = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];\n","// =============================================================================\n// Formula Engine — Built-in Functions\n// =============================================================================\n\nimport { type EvalContext, type FormulaValue, FV } from '../types';\nimport { coerceToBool, coerceToNumber, coerceToString } from '../evaluator';\nimport type { FunctionRegistry } from './registry';\nimport { formatNumberWithFormat } from '../../style/numberFormat';\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Flatten a mix of FormulaValues (including range values) into an array of\n * scalar FormulaValues using ctx.getRangeValues for range expansion.\n */\nfunction flatten(args: FormulaValue[], ctx: EvalContext): FormulaValue[] {\n const result: FormulaValue[] = [];\n for (const arg of args) {\n if (arg.kind === 'range') {\n result.push(...ctx.getRangeValues(arg.r1, arg.c1, arg.r2, arg.c2));\n } else {\n result.push(arg);\n }\n }\n return result;\n}\n\n/** Collect numeric values from a flattened list, ignoring nil. Returns #VALUE! on non-numeric. */\nfunction collectNumbers(values: FormulaValue[]): FormulaValue[] | FormulaValue {\n const nums: FormulaValue[] = [];\n for (const v of values) {\n if (v.kind === 'nil') continue; // empty cells are skipped\n if (v.kind === 'error') return v; // propagate errors\n const n = coerceToNumber(v);\n if (n.kind === 'error') return n;\n nums.push(n);\n }\n return nums;\n}\n\n// ---------------------------------------------------------------------------\n// Register all built-ins\n// ---------------------------------------------------------------------------\n\nexport function registerBuiltins(registry: FunctionRegistry): void {\n // ===========================================================================\n // Math & Stats\n // ===========================================================================\n\n registry.register('SUM', {\n call(args, ctx) {\n const flat = flatten(args, ctx);\n let sum = 0;\n for (const v of flat) {\n if (v.kind === 'nil') continue;\n if (v.kind === 'error') return v;\n const n = coerceToNumber(v);\n if (n.kind === 'error') return n;\n sum += (n as Extract<FormulaValue, { kind: 'number' }>).value;\n }\n return FV.number(sum);\n },\n });\n\n registry.register('AVERAGE', {\n call(args, ctx) {\n const flat = flatten(args, ctx);\n let sum = 0;\n let count = 0;\n for (const v of flat) {\n if (v.kind === 'nil') continue;\n if (v.kind === 'error') return v;\n const n = coerceToNumber(v);\n if (n.kind === 'error') return n;\n sum += (n as Extract<FormulaValue, { kind: 'number' }>).value;\n count++;\n }\n if (count === 0) return FV.error('#DIV/0!');\n return FV.number(sum / count);\n },\n });\n\n registry.register('COUNT', {\n call(args, ctx) {\n const flat = flatten(args, ctx);\n let count = 0;\n for (const v of flat) {\n if (v.kind === 'number') count++;\n else if (v.kind === 'string') {\n const n = Number(v.value.trim());\n if (Number.isFinite(n)) count++;\n }\n }\n return FV.number(count);\n },\n });\n\n registry.register('COUNTA', {\n call(args, ctx) {\n const flat = flatten(args, ctx);\n let count = 0;\n for (const v of flat) {\n if (v.kind !== 'nil') count++;\n }\n return FV.number(count);\n },\n });\n\n registry.register('COUNTBLANK', {\n call(args, ctx) {\n const flat = flatten(args, ctx);\n let count = 0;\n for (const v of flat) {\n if (v.kind === 'nil' || (v.kind === 'string' && v.value === '')) count++;\n }\n return FV.number(count);\n },\n });\n\n registry.register('MAX', {\n call(args, ctx) {\n const flat = flatten(args, ctx);\n const result = collectNumbers(flat);\n if (!Array.isArray(result)) return result; // error\n if (result.length === 0) return FV.number(0);\n return FV.number(Math.max(...result.map((v) => (v as Extract<FormulaValue, { kind: 'number' }>).value)));\n },\n });\n\n registry.register('MIN', {\n call(args, ctx) {\n const flat = flatten(args, ctx);\n const result = collectNumbers(flat);\n if (!Array.isArray(result)) return result;\n if (result.length === 0) return FV.number(0);\n return FV.number(Math.min(...result.map((v) => (v as Extract<FormulaValue, { kind: 'number' }>).value)));\n },\n });\n\n registry.register('ROUND', {\n call([num, digits]) {\n const n = coerceToNumber(num ?? FV.nil);\n if (n.kind === 'error') return n;\n const d = coerceToNumber(digits ?? FV.number(0));\n if (d.kind === 'error') return d;\n const factor = Math.pow(10, (d as Extract<FormulaValue, { kind: 'number' }>).value);\n return FV.number(Math.round((n as Extract<FormulaValue, { kind: 'number' }>).value * factor) / factor);\n },\n });\n\n registry.register('ROUNDUP', {\n call([num, digits]) {\n const n = coerceToNumber(num ?? FV.nil);\n if (n.kind === 'error') return n;\n const d = coerceToNumber(digits ?? FV.number(0));\n if (d.kind === 'error') return d;\n const factor = Math.pow(10, (d as Extract<FormulaValue, { kind: 'number' }>).value);\n const val = (n as Extract<FormulaValue, { kind: 'number' }>).value;\n return FV.number(val >= 0 ? Math.ceil(val * factor) / factor : Math.floor(val * factor) / factor);\n },\n });\n\n registry.register('ROUNDDOWN', {\n call([num, digits]) {\n const n = coerceToNumber(num ?? FV.nil);\n if (n.kind === 'error') return n;\n const d = coerceToNumber(digits ?? FV.number(0));\n if (d.kind === 'error') return d;\n const factor = Math.pow(10, (d as Extract<FormulaValue, { kind: 'number' }>).value);\n const val = (n as Extract<FormulaValue, { kind: 'number' }>).value;\n return FV.number(val >= 0 ? Math.floor(val * factor) / factor : Math.ceil(val * factor) / factor);\n },\n });\n\n registry.register('ABS', {\n call([num]) {\n const n = coerceToNumber(num ?? FV.nil);\n if (n.kind === 'error') return n;\n return FV.number(Math.abs((n as Extract<FormulaValue, { kind: 'number' }>).value));\n },\n });\n\n registry.register('MOD', {\n call([num, divisor]) {\n const n = coerceToNumber(num ?? FV.nil);\n if (n.kind === 'error') return n;\n const d = coerceToNumber(divisor ?? FV.nil);\n if (d.kind === 'error') return d;\n const dv = (d as Extract<FormulaValue, { kind: 'number' }>).value;\n if (dv === 0) return FV.error('#DIV/0!');\n const nv = (n as Extract<FormulaValue, { kind: 'number' }>).value;\n return FV.number(nv - dv * Math.floor(nv / dv));\n },\n });\n\n registry.register('POWER', {\n call([base, exp]) {\n const b = coerceToNumber(base ?? FV.nil);\n if (b.kind === 'error') return b;\n const e = coerceToNumber(exp ?? FV.nil);\n if (e.kind === 'error') return e;\n const result = Math.pow(\n (b as Extract<FormulaValue, { kind: 'number' }>).value,\n (e as Extract<FormulaValue, { kind: 'number' }>).value,\n );\n if (!Number.isFinite(result)) return FV.error('#NUM!');\n return FV.number(result);\n },\n });\n\n registry.register('SQRT', {\n call([num]) {\n const n = coerceToNumber(num ?? FV.nil);\n if (n.kind === 'error') return n;\n const v = (n as Extract<FormulaValue, { kind: 'number' }>).value;\n if (v < 0) return FV.error('#NUM!');\n return FV.number(Math.sqrt(v));\n },\n });\n\n registry.register('INT', {\n call([num]) {\n const n = coerceToNumber(num ?? FV.nil);\n if (n.kind === 'error') return n;\n return FV.number(Math.floor((n as Extract<FormulaValue, { kind: 'number' }>).value));\n },\n });\n\n registry.register('TRUNC', {\n call([num, digits]) {\n const n = coerceToNumber(num ?? FV.nil);\n if (n.kind === 'error') return n;\n const d = digits ? coerceToNumber(digits) : FV.number(0);\n if (d.kind === 'error') return d;\n const factor = Math.pow(10, (d as Extract<FormulaValue, { kind: 'number' }>).value);\n const v = (n as Extract<FormulaValue, { kind: 'number' }>).value;\n return FV.number(Math.trunc(v * factor) / factor);\n },\n });\n\n // ===========================================================================\n // Logical (lazy — short-circuit evaluation)\n // ===========================================================================\n\n registry.register('IF', {\n lazy: true,\n call([condThunk, thenThunk, elseThunk]) {\n const cond = condThunk();\n if (cond.kind === 'error') return cond;\n if (coerceToBool(cond)) {\n return thenThunk ? thenThunk() : FV.boolean(true);\n } else {\n return elseThunk ? elseThunk() : FV.boolean(false);\n }\n },\n });\n\n registry.register('IFERROR', {\n lazy: true,\n call([valueThunk, fallbackThunk]) {\n const v = valueThunk();\n if (v.kind === 'error') return fallbackThunk ? fallbackThunk() : FV.nil;\n return v;\n },\n });\n\n registry.register('IFNA', {\n lazy: true,\n call([valueThunk, fallbackThunk]) {\n const v = valueThunk();\n if (v.kind === 'error' && v.code === '#N/A') return fallbackThunk ? fallbackThunk() : FV.nil;\n return v;\n },\n });\n\n registry.register('AND', {\n lazy: true,\n call(thunks) {\n for (const thunk of thunks) {\n const v = thunk();\n if (v.kind === 'error') return v;\n if (!coerceToBool(v)) return FV.boolean(false);\n }\n return FV.boolean(true);\n },\n });\n\n registry.register('OR', {\n lazy: true,\n call(thunks) {\n for (const thunk of thunks) {\n const v = thunk();\n if (v.kind === 'error') return v;\n if (coerceToBool(v)) return FV.boolean(true);\n }\n return FV.boolean(false);\n },\n });\n\n registry.register('NOT', {\n call([v]) {\n if (!v || v.kind === 'nil') return FV.boolean(true);\n if (v.kind === 'error') return v;\n return FV.boolean(!coerceToBool(v));\n },\n });\n\n registry.register('IFS', {\n lazy: true,\n call(thunks) {\n for (let i = 0; i + 1 < thunks.length; i += 2) {\n const cond = thunks[i]();\n if (cond.kind === 'error') return cond;\n if (coerceToBool(cond)) return thunks[i + 1]();\n }\n return FV.error('#N/A');\n },\n });\n\n // ===========================================================================\n // Text\n // ===========================================================================\n\n registry.register('LEN', {\n call([v]) {\n return FV.number(coerceToString(v ?? FV.nil).length);\n },\n });\n\n registry.register('LEFT', {\n call([v, n]) {\n const s = coerceToString(v ?? FV.nil);\n const count = n ? coerceToNumber(n) : FV.number(1);\n if (count.kind === 'error') return count;\n const len = Math.max(0, Math.trunc((count as Extract<FormulaValue, { kind: 'number' }>).value));\n return FV.string(s.slice(0, len));\n },\n });\n\n registry.register('RIGHT', {\n call([v, n]) {\n const s = coerceToString(v ?? FV.nil);\n const count = n ? coerceToNumber(n) : FV.number(1);\n if (count.kind === 'error') return count;\n const len = Math.max(0, Math.trunc((count as Extract<FormulaValue, { kind: 'number' }>).value));\n return FV.string(len === 0 ? '' : s.slice(-len));\n },\n });\n\n registry.register('MID', {\n call([v, start, len]) {\n const s = coerceToString(v ?? FV.nil);\n const st = coerceToNumber(start ?? FV.nil);\n const ln = coerceToNumber(len ?? FV.nil);\n if (st.kind === 'error') return st;\n if (ln.kind === 'error') return ln;\n const from = Math.max(0, Math.trunc((st as Extract<FormulaValue, { kind: 'number' }>).value) - 1);\n const length = Math.max(0, Math.trunc((ln as Extract<FormulaValue, { kind: 'number' }>).value));\n return FV.string(s.substr(from, length));\n },\n });\n\n registry.register('UPPER', {\n call([v]) { return FV.string(coerceToString(v ?? FV.nil).toUpperCase()); },\n });\n\n registry.register('LOWER', {\n call([v]) { return FV.string(coerceToString(v ?? FV.nil).toLowerCase()); },\n });\n\n registry.register('TRIM', {\n call([v]) { return FV.string(coerceToString(v ?? FV.nil).trim().replace(/\\s+/g, ' ')); },\n });\n\n registry.register('CONCATENATE', {\n call(args) {\n return FV.string(args.map((a) => coerceToString(a ?? FV.nil)).join(''));\n },\n });\n\n registry.register('CONCAT', {\n call(args, ctx) {\n const flat = flatten(args, ctx);\n return FV.string(flat.map((a) => coerceToString(a)).join(''));\n },\n });\n\n registry.register('TEXTJOIN', {\n call(args, ctx) {\n // TEXTJOIN(delimiter, ignore_empty, text1, [text2, …])\n const [delimArg, ignoreEmptyArg, ...rest] = args;\n const delim = coerceToString(delimArg ?? FV.nil);\n const ignoreEmpty = coerceToBool(ignoreEmptyArg ?? FV.boolean(true));\n const flat = flatten(rest, ctx);\n const parts = flat\n .map((v) => coerceToString(v))\n .filter((s) => !ignoreEmpty || s !== '');\n return FV.string(parts.join(delim));\n },\n });\n\n registry.register('TEXT', {\n call([v, fmt]) {\n const n = coerceToNumber(v ?? FV.nil);\n if (n.kind === 'number' && fmt) {\n const fmtStr = coerceToString(fmt ?? FV.nil);\n const formatted = formatNumberWithFormat(n.value, fmtStr);\n if (formatted !== null) return FV.string(formatted);\n }\n return FV.string(coerceToString(v ?? FV.nil));\n },\n });\n\n registry.register('FIND', {\n call([find, within, startNum]) {\n const f = coerceToString(find ?? FV.nil);\n const w = coerceToString(within ?? FV.nil);\n const start = startNum ? coerceToNumber(startNum) : FV.number(1);\n if (start.kind === 'error') return start;\n const from = Math.max(0, (start as Extract<FormulaValue, { kind: 'number' }>).value - 1);\n const idx = w.indexOf(f, from);\n if (idx === -1) return FV.error('#VALUE!');\n return FV.number(idx + 1);\n },\n });\n\n registry.register('SUBSTITUTE', {\n call([text, oldText, newText, instanceNum]) {\n const s = coerceToString(text ?? FV.nil);\n const old = coerceToString(oldText ?? FV.nil);\n const rep = coerceToString(newText ?? FV.nil);\n\n if (instanceNum) {\n const n = coerceToNumber(instanceNum);\n if (n.kind === 'error') return n;\n let count = 0;\n const target = (n as Extract<FormulaValue, { kind: 'number' }>).value;\n return FV.string(s.replace(new RegExp(escapeRegex(old), 'g'), (match) => {\n count++;\n return count === target ? rep : match;\n }));\n }\n\n return FV.string(s.split(old).join(rep));\n },\n });\n\n registry.register('REPLACE', {\n call([oldText, startNum, numChars, newText]) {\n const s = coerceToString(oldText ?? FV.nil);\n const st = coerceToNumber(startNum ?? FV.nil);\n const nc = coerceToNumber(numChars ?? FV.nil);\n if (st.kind === 'error') return st;\n if (nc.kind === 'error') return nc;\n const from = (st as Extract<FormulaValue, { kind: 'number' }>).value - 1;\n const len = (nc as Extract<FormulaValue, { kind: 'number' }>).value;\n const rep = coerceToString(newText ?? FV.nil);\n return FV.string(s.slice(0, from) + rep + s.slice(from + len));\n },\n });\n\n registry.register('REPT', {\n call([text, times]) {\n const s = coerceToString(text ?? FV.nil);\n const n = coerceToNumber(times ?? FV.nil);\n if (n.kind === 'error') return n;\n const count = Math.max(0, Math.trunc((n as Extract<FormulaValue, { kind: 'number' }>).value));\n return FV.string(s.repeat(count));\n },\n });\n\n registry.register('VALUE', {\n call([v]) {\n const s = coerceToString(v ?? FV.nil).trim();\n const n = Number(s);\n if (!Number.isFinite(n)) return FV.error('#VALUE!');\n return FV.number(n);\n },\n });\n\n // ===========================================================================\n // Information / Error handling\n // ===========================================================================\n\n registry.register('ISBLANK', {\n call([v]) {\n return FV.boolean(!v || v.kind === 'nil' || (v.kind === 'string' && v.value === ''));\n },\n });\n\n registry.register('ISNUMBER', {\n call([v]) { return FV.boolean(!!v && v.kind === 'number'); },\n });\n\n registry.register('ISTEXT', {\n call([v]) { return FV.boolean(!!v && v.kind === 'string'); },\n });\n\n registry.register('ISLOGICAL', {\n call([v]) { return FV.boolean(!!v && v.kind === 'boolean'); },\n });\n\n registry.register('ISERROR', {\n call([v]) { return FV.boolean(!!v && v.kind === 'error'); },\n });\n\n registry.register('ISERR', {\n call([v]) { return FV.boolean(!!v && v.kind === 'error' && v.code !== '#N/A'); },\n });\n\n registry.register('ISNA', {\n call([v]) { return FV.boolean(!!v && v.kind === 'error' && v.code === '#N/A'); },\n });\n\n registry.register('NA', {\n call() { return FV.error('#N/A'); },\n });\n\n registry.register('ERROR.TYPE', {\n call([v]) {\n if (!v || v.kind !== 'error') return FV.error('#N/A');\n const map: Record<string, number> = {\n '#NULL!': 1, '#DIV/0!': 2, '#VALUE!': 3,\n '#REF!': 4, '#NAME?': 5, '#NUM!': 6, '#N/A': 7,\n };\n return FV.number(map[v.code] ?? 8);\n },\n });\n\n // ===========================================================================\n // Conditional aggregation (basic implementations)\n // ===========================================================================\n\n registry.register('SUMIF', {\n call([rangeArg, criteriaArg, sumRangeArg], ctx) {\n if (!rangeArg || rangeArg.kind !== 'range') return FV.error('#VALUE!');\n const cells = ctx.getRangeValues(rangeArg.r1, rangeArg.c1, rangeArg.r2, rangeArg.c2);\n const crit = buildCriteria(criteriaArg ?? FV.nil);\n\n const sumCells = sumRangeArg && sumRangeArg.kind === 'range'\n ? ctx.getRangeValues(sumRangeArg.r1, sumRangeArg.c1, sumRangeArg.r2, sumRangeArg.c2)\n : cells;\n\n let sum = 0;\n for (let i = 0; i < cells.length; i++) {\n if (crit(cells[i])) {\n const n = coerceToNumber(sumCells[i] ?? FV.nil);\n if (n.kind === 'number') sum += n.value;\n }\n }\n return FV.number(sum);\n },\n });\n\n registry.register('COUNTIF', {\n call([rangeArg, criteriaArg], ctx) {\n if (!rangeArg || rangeArg.kind !== 'range') return FV.error('#VALUE!');\n const cells = ctx.getRangeValues(rangeArg.r1, rangeArg.c1, rangeArg.r2, rangeArg.c2);\n const crit = buildCriteria(criteriaArg ?? FV.nil);\n return FV.number(cells.filter(crit).length);\n },\n });\n\n registry.register('AVERAGEIF', {\n call([rangeArg, criteriaArg, avgRangeArg], ctx) {\n if (!rangeArg || rangeArg.kind !== 'range') return FV.error('#VALUE!');\n const cells = ctx.getRangeValues(rangeArg.r1, rangeArg.c1, rangeArg.r2, rangeArg.c2);\n const crit = buildCriteria(criteriaArg ?? FV.nil);\n\n const avgCells = avgRangeArg && avgRangeArg.kind === 'range'\n ? ctx.getRangeValues(avgRangeArg.r1, avgRangeArg.c1, avgRangeArg.r2, avgRangeArg.c2)\n : cells;\n\n let sum = 0;\n let count = 0;\n for (let i = 0; i < cells.length; i++) {\n if (crit(cells[i])) {\n const n = coerceToNumber(avgCells[i] ?? FV.nil);\n if (n.kind === 'number') { sum += n.value; count++; }\n }\n }\n if (count === 0) return FV.error('#DIV/0!');\n return FV.number(sum / count);\n },\n });\n}\n\n// ---------------------------------------------------------------------------\n// Criteria builder for *IF functions\n// Supports: number, \"text\", \">5\", \"<>hello\", \">=10\", wildcards (* ?)\n// ---------------------------------------------------------------------------\n\nfunction buildCriteria(criterion: FormulaValue): (v: FormulaValue) => boolean {\n if (criterion.kind === 'number') {\n const target = criterion.value;\n return (v) => {\n const n = coerceToNumber(v);\n return n.kind === 'number' && n.value === target;\n };\n }\n\n if (criterion.kind === 'boolean') {\n return (v) => v.kind === 'boolean' && v.value === criterion.value;\n }\n\n const raw = criterion.kind === 'string' ? criterion.value : coerceToString(criterion);\n\n // Operator-prefixed: \">5\", \"<=10\", \"<>foo\", \"=hello\"\n const opMatch = /^(>=|<=|<>|>|<|=)(.*)$/.exec(raw);\n if (opMatch) {\n const [, op, rest] = opMatch;\n const numVal = Number(rest);\n const isNum = Number.isFinite(numVal);\n\n return (v) => {\n if (isNum) {\n const n = coerceToNumber(v);\n if (n.kind !== 'number') return op === '<>';\n const nv = n.value;\n if (op === '>') return nv > numVal;\n if (op === '>=') return nv >= numVal;\n if (op === '<') return nv < numVal;\n if (op === '<=') return nv <= numVal;\n if (op === '<>') return nv !== numVal;\n if (op === '=') return nv === numVal;\n } else {\n const sv = coerceToString(v).toLowerCase();\n const target = rest.toLowerCase();\n if (op === '<>') return sv !== target;\n if (op === '=') return sv === target;\n }\n return false;\n };\n }\n\n // Wildcard pattern: * ? — convert to regex\n if (raw.includes('*') || raw.includes('?')) {\n const pattern = raw\n .replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&')\n .replace(/\\*/g, '.*')\n .replace(/\\?/g, '.');\n const re = new RegExp(`^${pattern}$`, 'i');\n return (v) => re.test(coerceToString(v));\n }\n\n // Exact text match (case-insensitive, Excel compatible)\n const lower = raw.toLowerCase();\n return (v) => coerceToString(v).toLowerCase() === lower;\n}\n\nfunction escapeRegex(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n","// =============================================================================\n// Formula Engine — Dependency Graph\n//\n// Tracks two bidirectional maps:\n//\n// precedents[formulaCell] = Set of cells that the formula reads\n// dependents[dataCell] = Set of formula cells that read this cell\n//\n// On a value change, getRecalcOrder() returns the affected formula cells in\n// topological order (Kahn's BFS algorithm) so they can be re-evaluated\n// without visiting any cell before its own dependencies.\n// =============================================================================\n\nimport { type ASTNode } from './types';\nimport { type CellKey, cellKeyOf, parseCellKey } from './types';\nimport { extractCellRefs } from './parser';\n\nexport class DependencyGraph {\n /** formula-cell → cells it reads */\n private readonly precedents = new Map<CellKey, Set<CellKey>>();\n\n /** data-cell → formula cells that read it */\n private readonly dependents = new Map<CellKey, Set<CellKey>>();\n\n // ---------------------------------------------------------------------------\n // Mutation\n // ---------------------------------------------------------------------------\n\n /**\n * Update the dependency graph when a formula cell's AST changes.\n * Diffs the old and new dependency sets so we only update what changed.\n */\n updateFormulaDeps(formulaKey: CellKey, ast: ASTNode): void {\n const newDeps = extractCellRefs(ast);\n const oldDeps = this.precedents.get(formulaKey) ?? new Set<CellKey>();\n\n // Remove edges for refs no longer present\n for (const ref of oldDeps) {\n if (!newDeps.has(ref)) {\n this.removeDependent(ref, formulaKey);\n }\n }\n\n // Add edges for new refs\n for (const ref of newDeps) {\n if (!oldDeps.has(ref)) {\n this.addDependent(ref, formulaKey);\n }\n }\n\n if (newDeps.size > 0) {\n this.precedents.set(formulaKey, newDeps);\n } else {\n this.precedents.delete(formulaKey);\n }\n }\n\n /**\n * Remove all dependency tracking for a cell (when its formula is deleted).\n */\n removeCell(cellKey: CellKey): void {\n const oldDeps = this.precedents.get(cellKey);\n if (oldDeps) {\n for (const ref of oldDeps) {\n this.removeDependent(ref, cellKey);\n }\n this.precedents.delete(cellKey);\n }\n // Also clean up if this cell appears as a dependency source\n this.dependents.delete(cellKey);\n }\n\n // ---------------------------------------------------------------------------\n // Query\n // ---------------------------------------------------------------------------\n\n /**\n * Return all formula cells that directly or transitively depend on\n * changedKey, sorted in the correct recalculation order (leaves first).\n *\n * Uses Kahn's algorithm on the subgraph of affected cells.\n */\n getRecalcOrder(changedKey: CellKey): CellKey[] {\n // 1. BFS to find all affected formula cells\n const affected = new Set<CellKey>();\n const queue: CellKey[] = [];\n\n const direct = this.dependents.get(changedKey);\n if (!direct || direct.size === 0) return [];\n\n for (const k of direct) {\n if (!affected.has(k)) {\n affected.add(k);\n queue.push(k);\n }\n }\n\n let head = 0;\n while (head < queue.length) {\n const cell = queue[head++];\n const next = this.dependents.get(cell);\n if (next) {\n for (const k of next) {\n if (!affected.has(k)) {\n affected.add(k);\n queue.push(k);\n }\n }\n }\n }\n\n // 2. Kahn's topological sort within the affected set.\n // in-degree[F] = number of F's precedents that are ALSO in the affected set\n // (i.e., how many cells in the affected set must be computed before F).\n const inDegree = new Map<CellKey, number>();\n for (const cell of affected) {\n inDegree.set(cell, 0);\n }\n\n for (const cell of affected) {\n const precs = this.precedents.get(cell);\n if (precs) {\n for (const prec of precs) {\n if (affected.has(prec)) {\n inDegree.set(cell, (inDegree.get(cell) ?? 0) + 1);\n }\n }\n }\n }\n\n const ready: CellKey[] = [];\n for (const [cell, deg] of inDegree) {\n if (deg === 0) ready.push(cell);\n }\n\n const result: CellKey[] = [];\n let ri = 0;\n while (ri < ready.length) {\n const cell = ready[ri++];\n result.push(cell);\n\n const deps = this.dependents.get(cell);\n if (deps) {\n for (const dep of deps) {\n if (affected.has(dep)) {\n const newDeg = (inDegree.get(dep) ?? 0) - 1;\n inDegree.set(dep, newDeg);\n if (newDeg === 0) ready.push(dep);\n }\n }\n }\n }\n\n // If result.length < affected.size there is a cycle — return what we have\n // (cycle detection is handled separately via the formula engine's visited set).\n return result;\n }\n\n /**\n * Static cycle detection: does formulaKey transitively depend on itself?\n * Called after updateFormulaDeps so the graph already has the new edges.\n */\n hasCycle(startKey: CellKey): boolean {\n const visited = new Set<CellKey>();\n const stack = [startKey];\n\n while (stack.length > 0) {\n const current = stack.pop()!;\n if (visited.has(current)) continue;\n visited.add(current);\n\n const precs = this.precedents.get(current);\n if (precs) {\n for (const prec of precs) {\n if (prec === startKey) return true;\n stack.push(prec);\n }\n }\n }\n\n return false;\n }\n\n /** Return all formula cells in topological order (for full worksheet recalc). */\n getFullRecalcOrder(): CellKey[] {\n // Collect all formula cells\n const all = new Set<CellKey>(this.precedents.keys());\n\n const inDegree = new Map<CellKey, number>();\n for (const cell of all) inDegree.set(cell, 0);\n\n for (const cell of all) {\n const precs = this.precedents.get(cell)!;\n for (const prec of precs) {\n if (all.has(prec)) {\n inDegree.set(cell, (inDegree.get(cell) ?? 0) + 1);\n }\n }\n }\n\n const ready: CellKey[] = [];\n for (const [cell, deg] of inDegree) {\n if (deg === 0) ready.push(cell);\n }\n\n const result: CellKey[] = [];\n let ri = 0;\n while (ri < ready.length) {\n const cell = ready[ri++];\n result.push(cell);\n const deps = this.dependents.get(cell);\n if (deps) {\n for (const dep of deps) {\n if (all.has(dep)) {\n const newDeg = (inDegree.get(dep) ?? 0) - 1;\n inDegree.set(dep, newDeg);\n if (newDeg === 0) ready.push(dep);\n }\n }\n }\n }\n\n return result;\n }\n\n // ---------------------------------------------------------------------------\n // Internal helpers\n // ---------------------------------------------------------------------------\n\n private addDependent(ref: CellKey, formulaKey: CellKey): void {\n let set = this.dependents.get(ref);\n if (!set) {\n set = new Set();\n this.dependents.set(ref, set);\n }\n set.add(formulaKey);\n }\n\n private removeDependent(ref: CellKey, formulaKey: CellKey): void {\n const set = this.dependents.get(ref);\n if (!set) return;\n set.delete(formulaKey);\n if (set.size === 0) this.dependents.delete(ref);\n }\n\n // ---------------------------------------------------------------------------\n // Debug helpers\n // ---------------------------------------------------------------------------\n\n getPrecedents(key: CellKey): ReadonlySet<CellKey> {\n return this.precedents.get(key) ?? new Set();\n }\n\n getDependents(key: CellKey): ReadonlySet<CellKey> {\n return this.dependents.get(key) ?? new Set();\n }\n}\n\n// Re-export for convenience so callers only need to import from this file.\nexport { cellKeyOf, parseCellKey };\n","// =============================================================================\n// Formula Engine — Reference Updater\n//\n// Shifts cell references in a formula AST when rows or columns are\n// inserted or deleted. Pure functions — produces new AST nodes without\n// mutating the input.\n// =============================================================================\n\nimport type { ASTNode, CellRef } from './types';\n\nexport type ShiftAxis = 'row' | 'column';\n\nexport interface ShiftResult {\n /** The updated AST (new tree — input is not mutated). */\n ast: ASTNode;\n /** true if any reference was invalidated (pointed into a deleted range). */\n invalidated: boolean;\n}\n\n/**\n * Shift all cell/range references in an AST.\n *\n * @param ast — root node of the formula AST\n * @param axis — 'row' or 'column'\n * @param index — insertion / deletion point (0-based)\n * @param count — positive = insert, negative = delete\n *\n * Absolute ($) and relative references are shifted identically —\n * the $ prefix only affects copy/paste behaviour, not structural edits.\n */\nexport function shiftFormulaReferences(\n ast: ASTNode,\n axis: ShiftAxis,\n index: number,\n count: number,\n): ShiftResult {\n let invalidated = false;\n\n function shiftRef(ref: CellRef): CellRef | null {\n const pos = axis === 'row' ? ref.row : ref.col;\n\n if (count > 0) {\n // Insert: shift refs at >= index\n if (pos >= index) {\n return axis === 'row'\n ? { ...ref, row: ref.row + count }\n : { ...ref, col: ref.col + count };\n }\n return ref;\n }\n\n // Delete: count is negative, deleteCount is the absolute number of deleted rows/cols\n const deleteCount = -count;\n if (pos >= index && pos < index + deleteCount) {\n // Reference points into the deleted range → #REF!\n return null;\n }\n if (pos >= index + deleteCount) {\n // Reference is after the deleted range → shift back\n return axis === 'row'\n ? { ...ref, row: ref.row + count }\n : { ...ref, col: ref.col + count };\n }\n return ref;\n }\n\n function walk(node: ASTNode): ASTNode {\n switch (node.type) {\n case 'cell': {\n const updated = shiftRef(node.ref);\n if (updated === null) {\n invalidated = true;\n return { type: 'name', name: '#REF!' };\n }\n if (updated === node.ref) return node;\n return { type: 'cell', ref: updated };\n }\n\n case 'range': {\n const s = shiftRef(node.start);\n const e = shiftRef(node.end);\n if (s === null || e === null) {\n invalidated = true;\n return { type: 'name', name: '#REF!' };\n }\n if (s === node.start && e === node.end) return node;\n return { type: 'range', start: s, end: e };\n }\n\n case 'binary': {\n const left = walk(node.left);\n const right = walk(node.right);\n if (left === node.left && right === node.right) return node;\n return { ...node, left, right };\n }\n\n case 'concat': {\n const left = walk(node.left);\n const right = walk(node.right);\n if (left === node.left && right === node.right) return node;\n return { ...node, left, right };\n }\n\n case 'unary': {\n const operand = walk(node.operand);\n if (operand === node.operand) return node;\n return { ...node, operand };\n }\n\n case 'func': {\n let changed = false;\n const args = node.args.map((arg) => {\n const updated = walk(arg);\n if (updated !== arg) changed = true;\n return updated;\n });\n if (!changed) return node;\n return { ...node, args };\n }\n\n // number, string, boolean, name — no cell refs\n default:\n return node;\n }\n }\n\n const result = walk(ast);\n return { ast: result, invalidated };\n}\n\n/**\n * Shift a cell position (row, col) when rows/columns are inserted or deleted.\n * Returns null if the position falls inside a deleted range.\n */\nexport function shiftPosition(\n row: number,\n col: number,\n axis: ShiftAxis,\n index: number,\n count: number,\n): { row: number; col: number } | null {\n const pos = axis === 'row' ? row : col;\n\n if (count > 0) {\n // Insert\n if (pos >= index) {\n return axis === 'row'\n ? { row: row + count, col }\n : { row, col: col + count };\n }\n return { row, col };\n }\n\n // Delete\n const deleteCount = -count;\n if (pos >= index && pos < index + deleteCount) {\n return null; // inside deleted range\n }\n if (pos >= index + deleteCount) {\n return axis === 'row'\n ? { row: row + count, col }\n : { row, col: col + count };\n }\n return { row, col };\n}\n","// =============================================================================\n// Formula Engine — AST Serializer\n//\n// Converts an ASTNode back into a formula string (without leading '=').\n// Used to regenerate formula text after structural changes (row/column\n// insert/delete) have shifted cell references in the AST.\n// =============================================================================\n\nimport type { ASTNode, CellRef } from './types';\n\n/** Convert a 0-based column index to a column label (A, B, …, Z, AA, AB, …). */\nfunction colIndexToLabel(index: number): string {\n let label = '';\n let n = index + 1; // 1-based\n while (n > 0) {\n n -= 1;\n label = String.fromCharCode(65 + (n % 26)) + label;\n n = Math.floor(n / 26);\n }\n return label;\n}\n\n/** Serialize a CellRef to a string like \"A1\", \"$A1\", \"A$1\", \"$A$1\". */\nfunction cellRefToString(ref: CellRef): string {\n const colPart = (ref.colAbs ? '$' : '') + colIndexToLabel(ref.col);\n const rowPart = (ref.rowAbs ? '$' : '') + String(ref.row + 1);\n return colPart + rowPart;\n}\n\nconst BINARY_OP_NEEDS_PARENS: Record<string, number> = {\n '+': 1, '-': 1,\n '*': 2, '/': 2,\n '^': 3,\n '=': 0, '<>': 0, '<': 0, '>': 0, '<=': 0, '>=': 0,\n};\n\nfunction precedence(op: string): number {\n return BINARY_OP_NEEDS_PARENS[op] ?? 0;\n}\n\n/**\n * Convert an AST node back to a formula string.\n * The result does NOT include the leading '=' — the caller adds it when\n * storing as cell input.\n */\nexport function astToFormula(node: ASTNode): string {\n switch (node.type) {\n case 'number':\n return String(node.value);\n\n case 'string':\n // Excel-style: double-quote escaping\n return '\"' + node.value.replace(/\"/g, '\"\"') + '\"';\n\n case 'boolean':\n return node.value ? 'TRUE' : 'FALSE';\n\n case 'cell':\n return cellRefToString(node.ref);\n\n case 'range':\n return cellRefToString(node.start) + ':' + cellRefToString(node.end);\n\n case 'name':\n return node.name;\n\n case 'unary':\n if (node.op === '%') {\n return wrapIfComplex(node.operand) + '%';\n }\n // unary minus\n return '-' + wrapIfComplex(node.operand);\n\n case 'binary': {\n const left = maybeParen(node.left, node.op, 'left');\n const right = maybeParen(node.right, node.op, 'right');\n return left + node.op + right;\n }\n\n case 'concat': {\n const left = astToFormula(node.left);\n const right = astToFormula(node.right);\n return left + '&' + right;\n }\n\n case 'func':\n return node.name + '(' + node.args.map(astToFormula).join(',') + ')';\n }\n}\n\nfunction wrapIfComplex(node: ASTNode): string {\n const s = astToFormula(node);\n if (node.type === 'binary' || node.type === 'concat' || node.type === 'unary') {\n return '(' + s + ')';\n }\n return s;\n}\n\nfunction maybeParen(child: ASTNode, parentOp: string, side: 'left' | 'right'): string {\n const s = astToFormula(child);\n if (child.type === 'binary') {\n const childPrec = precedence(child.op);\n const parentPrec = precedence(parentOp);\n if (childPrec < parentPrec || (childPrec === parentPrec && side === 'right')) {\n return '(' + s + ')';\n }\n }\n return s;\n}\n\nexport { colIndexToLabel, cellRefToString };\n","// =============================================================================\n// Formula Engine — Coordinator\n//\n// Wires together: Parser → Evaluator → DependencyGraph → cache.\n//\n// Integration contract with Worksheet:\n// • Call onInputChanged(row, col, rawValue) whenever a cell's raw input\n// changes (both formula and plain-value cells).\n// • Call rebuildAll() after a bulk load (loadCells).\n// • Call onStructureChange(axis, index, count) when rows/columns are\n// inserted or deleted — updates formula references and cell keys.\n// • Read display strings via getDisplayValue(row, col).\n// =============================================================================\n\nimport type { Worksheet } from '../worksheet/worksheet';\nimport { parseFormula } from './parser';\nimport { Evaluator } from './evaluator';\nimport { FunctionRegistry } from './functions/registry';\nimport { registerBuiltins } from './functions/builtins';\nimport { DependencyGraph } from './dependency';\nimport { shiftFormulaReferences, shiftPosition, type ShiftAxis } from './refUpdater';\nimport { astToFormula } from './serializer';\nimport {\n type ASTNode,\n type CellKey,\n type EvalContext,\n type FormulaValue,\n FV,\n cellKeyOf,\n parseCellKey,\n} from './types';\n\n// ---------------------------------------------------------------------------\n// Per-cell formula metadata (stored in engine, not in Worksheet)\n// ---------------------------------------------------------------------------\n\ninterface CellFormula {\n ast: ASTNode;\n cached: FormulaValue;\n}\n\n// ---------------------------------------------------------------------------\n// FormulaEngine\n// ---------------------------------------------------------------------------\n\nexport interface FormulaEngineOptions {\n /**\n * When true (the default), all built-in functions (SUM, IF, …) are\n * registered. Set to false for Lite builds where only basic arithmetic\n * and cell references are supported.\n */\n registerBuiltins?: boolean;\n}\n\nexport class FormulaEngine {\n private readonly registry: FunctionRegistry;\n private readonly evaluator: Evaluator;\n private deps: DependencyGraph;\n\n /** formula cells: key → { ast, cached result } */\n private readonly formulas = new Map<CellKey, CellFormula>();\n\n constructor(\n private readonly worksheet: Worksheet,\n options?: FormulaEngineOptions,\n ) {\n this.registry = new FunctionRegistry();\n if (options?.registerBuiltins !== false) {\n registerBuiltins(this.registry);\n }\n this.evaluator = new Evaluator(this.registry);\n this.deps = new DependencyGraph();\n }\n\n // ---------------------------------------------------------------------------\n // Public API — called by Worksheet\n // ---------------------------------------------------------------------------\n\n /**\n * Notify the engine that a cell's raw input has changed.\n * Handles both formula cells (=…) and plain-value cells.\n * Returns the keys of all cells whose cached values changed\n * (for optional targeted invalidation — the caller may also just re-render all).\n */\n onInputChanged(row: number, col: number, rawValue: string): void {\n const key = cellKeyOf(row, col);\n\n if (rawValue.startsWith('=')) {\n this.setFormula(key, rawValue.slice(1));\n } else {\n this.clearFormula(key);\n // Propagate value change to dependent formula cells\n this.propagate(key);\n }\n }\n\n /**\n * Bulk rebuild after loadCells().\n * Parses every cell that has a formula and rebuilds dependency graph + cache.\n */\n rebuildAll(): void {\n // Clear existing state and rebuild from scratch\n this.formulas.clear();\n this.deps = new DependencyGraph();\n\n // First pass: parse all formulas and register dependencies\n const formulaKeys: CellKey[] = [];\n for (let row = 0; row < this.worksheet.rows; row++) {\n for (let col = 0; col < this.worksheet.columns; col++) {\n const raw = this.worksheet.getCellInput(row, col);\n if (raw && raw.startsWith('=')) {\n const key = cellKeyOf(row, col);\n const ast = this.tryParse(raw.slice(1));\n if (ast) {\n this.deps.updateFormulaDeps(key, ast);\n this.formulas.set(key, { ast, cached: FV.nil });\n formulaKeys.push(key);\n }\n }\n }\n }\n\n // Second pass: evaluate in topological order\n const order = this.deps.getFullRecalcOrder();\n\n // Cells with formulas that weren't reached by topo sort (cycles or isolated)\n const ordered = new Set(order);\n for (const key of formulaKeys) {\n if (!ordered.has(key)) order.push(key);\n }\n\n for (const key of order) {\n this.evaluateAndCache(key);\n }\n }\n\n /**\n * Get the cached formula result for export (xlsx <v> tag).\n * Returns undefined for non-formula cells.\n */\n getCachedValue(row: number, col: number): string | number | boolean | undefined {\n const key = cellKeyOf(row, col);\n const formula = this.formulas.get(key);\n if (!formula) {\n return undefined;\n }\n const v = formula.cached;\n switch (v.kind) {\n case 'number':\n return v.value;\n case 'string':\n return v.value;\n case 'boolean':\n return v.value;\n case 'error':\n return v.code;\n case 'nil':\n return undefined;\n case 'range':\n return undefined;\n }\n }\n\n /**\n * Get the display string for a cell.\n * Returns '' for empty / non-formula cells (Worksheet handles those itself).\n * For formula cells, returns the cached result formatted as a string.\n */\n getDisplayValue(row: number, col: number): string {\n const key = cellKeyOf(row, col);\n const formula = this.formulas.get(key);\n if (formula) {\n return formatForDisplay(formula.cached);\n }\n\n // Not a formula cell — return the raw input as-is (Worksheet already stores it)\n const raw = this.worksheet.getCellInput(row, col);\n return raw ?? '';\n }\n\n /**\n * Notify the engine that rows or columns were inserted or deleted.\n * Shifts formula cell positions and updates all cell references inside\n * formula ASTs. The caller (Worksheet) must have already shifted the\n * cellInputs map keys — this method updates the formula strings to match.\n *\n * @param axis — 'row' or 'column'\n * @param index — insertion/deletion point (0-based)\n * @param count — positive = insert, negative = delete\n */\n onStructureChange(axis: ShiftAxis, index: number, count: number): void {\n // 1. Build a new formulas map with shifted keys and updated ASTs.\n const updated = new Map<CellKey, CellFormula>();\n\n for (const [key, formula] of this.formulas) {\n const { row, col } = parseCellKey(key);\n\n // Shift the formula cell's own position\n const newPos = shiftPosition(row, col, axis, index, count);\n if (!newPos) {\n // Formula cell itself was in the deleted range — drop it\n continue;\n }\n\n // Shift all cell references inside the formula AST\n const result = shiftFormulaReferences(formula.ast, axis, index, count);\n\n const newKey = cellKeyOf(newPos.row, newPos.col);\n\n if (result.invalidated) {\n // At least one reference became #REF!\n updated.set(newKey, { ast: result.ast, cached: FV.error('#REF!') });\n // Update the raw cell input to reflect the broken formula\n this.worksheet.setCellInputDirect(\n newPos.row,\n newPos.col,\n '=' + astToFormula(result.ast),\n );\n } else {\n updated.set(newKey, { ast: result.ast, cached: formula.cached });\n // Update the raw cell input with the shifted formula\n this.worksheet.setCellInputDirect(\n newPos.row,\n newPos.col,\n '=' + astToFormula(result.ast),\n );\n }\n }\n\n // 2. Replace the formulas map and rebuild dependencies + recalculate.\n this.formulas.clear();\n for (const [key, formula] of updated) {\n this.formulas.set(key, formula);\n }\n this.deps = new DependencyGraph();\n for (const [key, formula] of this.formulas) {\n this.deps.updateFormulaDeps(key, formula.ast);\n }\n\n // 3. Recalculate all formulas in topological order.\n const order = this.deps.getFullRecalcOrder();\n const ordered = new Set(order);\n for (const key of this.formulas.keys()) {\n if (!ordered.has(key)) order.push(key);\n }\n for (const key of order) {\n this.evaluateAndCache(key);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Private — formula lifecycle\n // ---------------------------------------------------------------------------\n\n private setFormula(key: CellKey, expression: string): void {\n const ast = this.tryParse(expression);\n if (!ast) {\n // Syntax error: cache the error value\n this.deps.removeCell(key);\n this.formulas.set(key, { ast: { type: 'name', name: 'NIL' }, cached: FV.error('#VALUE!') });\n this.propagate(key);\n return;\n }\n\n this.deps.updateFormulaDeps(key, ast);\n\n // Detect cycles before evaluating\n if (this.deps.hasCycle(key)) {\n this.formulas.set(key, { ast, cached: FV.error('#CYCLE!') });\n this.propagate(key);\n return;\n }\n\n this.formulas.set(key, { ast, cached: FV.nil });\n this.evaluateAndCache(key);\n this.propagate(key);\n }\n\n private clearFormula(key: CellKey): void {\n if (this.formulas.has(key)) {\n this.deps.removeCell(key);\n this.formulas.delete(key);\n }\n }\n\n /** Evaluate a formula cell and update its cache. */\n private evaluateAndCache(key: CellKey): void {\n const formula = this.formulas.get(key);\n if (!formula) return;\n\n const { row, col } = parseCellKey(key);\n const ctx = this.makeContext(row, col, new Set([key]));\n\n try {\n formula.cached = this.evaluator.evaluate(formula.ast, ctx);\n } catch {\n formula.cached = FV.error('#VALUE!');\n }\n }\n\n /** Re-evaluate all formula cells that (transitively) depend on changedKey. */\n private propagate(changedKey: CellKey): void {\n const order = this.deps.getRecalcOrder(changedKey);\n for (const key of order) {\n this.evaluateAndCache(key);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Private — evaluation context\n // ---------------------------------------------------------------------------\n\n /**\n * Build the EvalContext for a formula evaluation at (row, col).\n * visited tracks the current call stack for runtime cycle detection.\n */\n private makeContext(row: number, col: number, visited: Set<CellKey>): EvalContext {\n const self = this;\n return {\n getCellValue(refRow: number, refCol: number): FormulaValue {\n const refKey = cellKeyOf(refRow, refCol);\n\n // Runtime cycle detection\n if (visited.has(refKey)) return FV.error('#CYCLE!');\n\n const refFormula = self.formulas.get(refKey);\n if (refFormula) {\n // If already cached, return cache\n return refFormula.cached;\n }\n\n // Non-formula cell: read raw input\n const raw = self.worksheet.getCellInput(refRow, refCol);\n if (!raw || raw.length === 0) return FV.nil;\n const n = Number(raw);\n if (Number.isFinite(n)) return FV.number(n);\n return FV.string(raw);\n },\n\n getRangeValues(r1: number, c1: number, r2: number, c2: number): FormulaValue[] {\n const values: FormulaValue[] = [];\n const ctx = self.makeContext(row, col, visited);\n for (let r = r1; r <= r2; r++) {\n for (let c = c1; c <= c2; c++) {\n values.push(ctx.getCellValue(r, c));\n }\n }\n return values;\n },\n };\n }\n\n // ---------------------------------------------------------------------------\n // Private — parse helper\n // ---------------------------------------------------------------------------\n\n private tryParse(expression: string): ASTNode | null {\n try {\n return parseFormula(expression);\n } catch {\n return null;\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Display formatting\n// ---------------------------------------------------------------------------\n\nfunction formatForDisplay(value: FormulaValue): string {\n switch (value.kind) {\n case 'number': {\n // Avoid ugly floating-point artifacts (e.g. 0.1 + 0.2 = 0.30000000000000004)\n const n = value.value;\n if (!Number.isFinite(n)) return '#NUM!';\n // Round to 15 significant digits (Excel-compatible precision)\n const rounded = parseFloat(n.toPrecision(15));\n return String(rounded);\n }\n case 'string': return value.value;\n case 'boolean': return value.value ? 'TRUE' : 'FALSE';\n case 'error': return value.code;\n case 'nil': return '';\n case 'range': return '#VALUE!';\n }\n}\n","export type TextAlign = 'left' | 'center' | 'right';\nexport type VerticalAlign = 'top' | 'middle' | 'bottom';\nexport type TextWrapMode = 'none' | 'wrap' | 'break-word';\n\nexport interface CellStyle {\n fontFamily: string;\n fontSize: number;\n bold: boolean;\n italic: boolean;\n underline: boolean;\n backgroundColor: string;\n color: string;\n textAlign: TextAlign;\n verticalAlign: VerticalAlign;\n textWrapMode: TextWrapMode;\n}\n\nexport const DEFAULT_CELL_STYLE: CellStyle = {\n fontFamily: 'Arial',\n fontSize: 10,\n bold: false,\n italic: false,\n underline: false,\n backgroundColor: '#ffffff',\n color: '#2c3e50',\n textAlign: 'left',\n verticalAlign: 'bottom',\n textWrapMode: 'none',\n};\n","export function cellKey(row: number, column: number): string {\n return `${row}:${column}`;\n}\n\nexport function parseCellKey(key: string): { row: number; column: number } | null {\n const [rowStr, columnStr] = key.split(':');\n const row = Number(rowStr);\n const column = Number(columnStr);\n if (!Number.isFinite(row) || !Number.isFinite(column)) {\n return null;\n }\n return { row, column };\n}\n","import type { RangeRect } from './types';\n\n/** Builds a cumulative boundary array from a list of sizes. Result has length sizes.length + 1.\n * When `hidden` is provided, hidden segments contribute 0 to the accumulator. */\nexport function buildBoundaries(sizes: number[], hidden?: boolean[]): number[] {\n const boundaries = [0];\n let acc = 0;\n for (let i = 0; i < sizes.length; i += 1) {\n acc += (hidden && hidden[i]) ? 0 : sizes[i];\n boundaries.push(acc);\n }\n return boundaries;\n}\n\n/** Returns the index (0-based) of the segment containing `offset`, or null if out of range. */\nexport function getIndexAtOffset(offset: number, boundaries: number[]): number | null {\n for (let i = 0; i < boundaries.length - 1; i += 1) {\n if (offset >= boundaries[i] && offset < boundaries[i + 1]) {\n return i;\n }\n }\n return null;\n}\n\n/**\n * Binary-searches for the segment index that contains `offset`.\n * `count` is the number of segments (boundaries.length - 1).\n * Clamps to [0, count - 1].\n */\nexport function findIndexByOffset(offset: number, count: number, boundaries: number[]): number {\n if (count === 0) {\n return 0;\n }\n const total = boundaries[boundaries.length - 1] ?? 0;\n const clamped = Math.min(Math.max(0, offset), Math.max(0, total - 1e-3));\n let low = 0;\n let high = count - 1;\n while (low <= high) {\n const mid = (low + high) >> 1;\n if (clamped < boundaries[mid]) {\n high = mid - 1;\n } else if (clamped >= boundaries[mid + 1]) {\n low = mid + 1;\n } else {\n return mid;\n }\n }\n return Math.max(0, Math.min(count - 1, low));\n}\n\n/** Computes x/y/width/height of a cell range in canvas coordinates. */\nexport function computeRangeRect(\n topRow: number,\n leftColumn: number,\n bottomRow: number,\n rightColumn: number,\n columnBoundaries: readonly number[],\n rowBoundaries: readonly number[],\n headerColumnWidth: number,\n headerRowHeight: number,\n scrollX: number,\n scrollY: number,\n frozenColumns = 0,\n frozenRows = 0,\n): RangeRect {\n const frozenWidth = frozenColumns > 0 ? (columnBoundaries[frozenColumns] ?? 0) : 0;\n const frozenHeight = frozenRows > 0 ? (rowBoundaries[frozenRows] ?? 0) : 0;\n const effectiveScrollX = leftColumn < frozenColumns ? 0 : scrollX;\n const effectiveScrollY = topRow < frozenRows ? 0 : scrollY;\n const offsetX = leftColumn < frozenColumns\n ? headerColumnWidth\n : headerColumnWidth + frozenWidth - (columnBoundaries[frozenColumns] ?? 0);\n const offsetY = topRow < frozenRows\n ? headerRowHeight\n : headerRowHeight + frozenHeight - (rowBoundaries[frozenRows] ?? 0);\n const x = offsetX - effectiveScrollX + columnBoundaries[leftColumn];\n const y = offsetY - effectiveScrollY + rowBoundaries[topRow];\n const width = columnBoundaries[rightColumn + 1] - columnBoundaries[leftColumn];\n const height = rowBoundaries[bottomRow + 1] - rowBoundaries[topRow];\n return { x, y, width, height };\n}\n","export type BorderSide = 'top' | 'right' | 'bottom' | 'left';\nexport type RangeBorderSide = BorderSide | 'outside';\n\nexport type BorderLineStyle = 'solid' | 'dashed' | 'dotted';\n\nexport interface BorderLineOptions {\n style: BorderLineStyle;\n color?: string;\n width?: number;\n}\n\nexport interface CellBorderDefinition {\n top?: BorderLine;\n right?: BorderLine;\n bottom?: BorderLine;\n left?: BorderLine;\n}\n\nexport interface BorderLine {\n style: BorderLineStyle;\n color: string;\n width: number;\n appliedAt?: number;\n}\n\nexport const ALL_BORDER_SIDES: BorderSide[] = ['top', 'right', 'bottom', 'left'];\nexport const DEFAULT_BORDER_COLOR = '#1f2933';\nexport const DEFAULT_BORDER_WIDTH = 1;\n","import type {\n BorderSide,\n RangeBorderSide,\n CellBorderDefinition,\n BorderLine,\n BorderLineOptions,\n} from './types';\nimport { ALL_BORDER_SIDES, DEFAULT_BORDER_COLOR, DEFAULT_BORDER_WIDTH } from './types';\nimport { cellKey, parseCellKey } from '../worksheet/cellKey';\n\nexport class BorderManager {\n private readonly data: Map<string, CellBorderDefinition> = new Map();\n private sequence = 0;\n\n constructor(\n private readonly getRows: () => number,\n private readonly getColumns: () => number,\n ) {}\n\n get size(): number {\n return this.data.size;\n }\n\n entries(): Iterable<[string, CellBorderDefinition]> {\n return this.data;\n }\n\n getCell(row: number, column: number): CellBorderDefinition | undefined {\n return this.data.get(cellKey(row, column));\n }\n\n applyAll(borders: Map<string, CellBorderDefinition>): void {\n this.data.clear();\n this.sequence = 0;\n for (const [key, border] of borders) {\n const cloned: CellBorderDefinition = {};\n if (border.top) {\n cloned.top = { ...border.top, appliedAt: this.nextSequence() };\n }\n if (border.right) {\n cloned.right = { ...border.right, appliedAt: this.nextSequence() };\n }\n if (border.bottom) {\n cloned.bottom = { ...border.bottom, appliedAt: this.nextSequence() };\n }\n if (border.left) {\n cloned.left = { ...border.left, appliedAt: this.nextSequence() };\n }\n this.data.set(key, cloned);\n }\n }\n\n setRange(\n topRow: number,\n leftColumn: number,\n bottomRow: number,\n rightColumn: number,\n border: BorderLineOptions,\n sides?: RangeBorderSide[],\n ): void {\n const line = this.normalizeLine(border);\n const normalizedSides = this.normalizeSides(sides ?? ALL_BORDER_SIDES);\n if (!normalizedSides.length) {\n return;\n }\n\n const bounds = this.normalizeBounds(topRow, leftColumn, bottomRow, rightColumn);\n if (!bounds) {\n return;\n }\n\n if (normalizedSides.includes('top')) {\n for (let col = bounds.left; col <= bounds.right; col += 1) {\n this.assignBorder(bounds.top, col, 'top', line);\n }\n }\n if (normalizedSides.includes('bottom')) {\n for (let col = bounds.left; col <= bounds.right; col += 1) {\n this.assignBorder(bounds.bottom, col, 'bottom', line);\n }\n }\n if (normalizedSides.includes('left')) {\n for (let row = bounds.top; row <= bounds.bottom; row += 1) {\n this.assignBorder(row, bounds.left, 'left', line);\n }\n }\n if (normalizedSides.includes('right')) {\n for (let row = bounds.top; row <= bounds.bottom; row += 1) {\n this.assignBorder(row, bounds.right, 'right', line);\n }\n }\n }\n\n /**\n * Shift all border entries when rows or columns are inserted or deleted.\n *\n * @param axis — 'row' or 'column'\n * @param index — insertion/deletion point (0-based)\n * @param count — positive = insert, negative = delete\n */\n shiftBorders(axis: 'row' | 'column', index: number, count: number): void {\n const entries = Array.from(this.data.entries());\n this.data.clear();\n\n for (const [key, border] of entries) {\n const pos = parseCellKey(key);\n if (!pos) continue;\n let { row, column } = pos;\n\n if (axis === 'row') {\n if (count < 0) {\n const deleteCount = -count;\n if (row >= index && row < index + deleteCount) continue; // deleted\n if (row >= index + deleteCount) row += count;\n } else {\n if (row >= index) row += count;\n }\n } else {\n if (count < 0) {\n const deleteCount = -count;\n if (column >= index && column < index + deleteCount) continue;\n if (column >= index + deleteCount) column += count;\n } else {\n if (column >= index) column += count;\n }\n }\n\n this.data.set(cellKey(row, column), border);\n }\n }\n\n /** Low-level access for permuteRows. */\n getData(key: string): CellBorderDefinition | undefined {\n return this.data.get(key);\n }\n setData(key: string, value: CellBorderDefinition): void {\n this.data.set(key, value);\n }\n deleteData(key: string): void {\n this.data.delete(key);\n }\n\n /** Swap border entries between two rows within a column range. */\n swapRowCells(rowA: number, rowB: number, startColumn: number, endColumn: number): void {\n for (let c = startColumn; c <= endColumn; c++) {\n const keyA = cellKey(rowA, c);\n const keyB = cellKey(rowB, c);\n const borderA = this.data.get(keyA);\n const borderB = this.data.get(keyB);\n if (borderA !== undefined) { this.data.set(keyB, borderA); } else { this.data.delete(keyB); }\n if (borderB !== undefined) { this.data.set(keyA, borderB); } else { this.data.delete(keyA); }\n }\n }\n\n pruneOutsideGrid(): void {\n for (const key of Array.from(this.data.keys())) {\n const pos = parseCellKey(key);\n if (!pos || !this.isCellInBounds(pos.row, pos.column)) {\n this.data.delete(key);\n }\n }\n }\n\n private assignBorder(row: number, column: number, side: BorderSide, line: BorderLine): void {\n if (line.width <= 0) {\n this.removeBorderSide(row, column, side);\n this.removeAdjacentBorder(row, column, side);\n return;\n }\n const border = this.getOrCreate(row, column);\n border[side] = { ...line, appliedAt: this.nextSequence() };\n }\n\n private removeBorderSide(row: number, column: number, side: BorderSide): void {\n if (!this.isCellInBounds(row, column)) {\n return;\n }\n const key = cellKey(row, column);\n const existing = this.data.get(key);\n if (!existing || existing[side] === undefined) {\n return;\n }\n delete existing[side];\n if (!existing.top && !existing.right && !existing.bottom && !existing.left) {\n this.data.delete(key);\n }\n }\n\n private removeAdjacentBorder(row: number, column: number, side: BorderSide): void {\n const adjacent = this.getAdjacentCell(row, column, side);\n if (!adjacent) {\n return;\n }\n this.removeBorderSide(adjacent.row, adjacent.column, this.oppositeSide(side));\n }\n\n private getAdjacentCell(\n row: number,\n column: number,\n side: BorderSide,\n ): { row: number; column: number } | null {\n const rows = this.getRows();\n const columns = this.getColumns();\n switch (side) {\n case 'top':\n return row > 0 ? { row: row - 1, column } : null;\n case 'bottom':\n return row < rows - 1 ? { row: row + 1, column } : null;\n case 'left':\n return column > 0 ? { row, column: column - 1 } : null;\n case 'right':\n return column < columns - 1 ? { row, column: column + 1 } : null;\n default:\n return null;\n }\n }\n\n private oppositeSide(side: BorderSide): BorderSide {\n switch (side) {\n case 'top':\n return 'bottom';\n case 'bottom':\n return 'top';\n case 'left':\n return 'right';\n case 'right':\n default:\n return 'left';\n }\n }\n\n private getOrCreate(row: number, column: number): CellBorderDefinition {\n const key = cellKey(row, column);\n const existing = this.data.get(key);\n if (existing) {\n return existing;\n }\n const created: CellBorderDefinition = {};\n this.data.set(key, created);\n return created;\n }\n\n private normalizeLine(border: BorderLineOptions): BorderLine {\n return {\n style: border.style,\n color: border.color ?? DEFAULT_BORDER_COLOR,\n width: border.width ?? DEFAULT_BORDER_WIDTH,\n };\n }\n\n private normalizeSides(sides: RangeBorderSide[]): BorderSide[] {\n if (!sides.length) {\n return [...ALL_BORDER_SIDES];\n }\n const resolved = new Set<BorderSide>();\n for (const side of sides) {\n if (side === 'outside') {\n for (const actual of ALL_BORDER_SIDES) {\n resolved.add(actual);\n }\n continue;\n }\n resolved.add(side);\n }\n return Array.from(resolved);\n }\n\n private normalizeBounds(\n topRow: number,\n leftColumn: number,\n bottomRow: number,\n rightColumn: number,\n ): { top: number; left: number; bottom: number; right: number } | null {\n const rows = this.getRows();\n const columns = this.getColumns();\n if (rows === 0 || columns === 0) {\n return null;\n }\n const clampRow = (r: number) => Math.min(Math.max(Math.floor(r), 0), rows - 1);\n const clampCol = (c: number) => Math.min(Math.max(Math.floor(c), 0), columns - 1);\n const r1 = clampRow(topRow);\n const r2 = clampRow(bottomRow);\n const c1 = clampCol(leftColumn);\n const c2 = clampCol(rightColumn);\n return { top: Math.min(r1, r2), bottom: Math.max(r1, r2), left: Math.min(c1, c2), right: Math.max(c1, c2) };\n }\n\n private isCellInBounds(row: number, column: number): boolean {\n return row >= 0 && row < this.getRows() && column >= 0 && column < this.getColumns();\n }\n\n private nextSequence(): number {\n this.sequence += 1;\n return this.sequence;\n }\n}\n","import type { MergedCellRange } from '../cell/types';\nimport { cellKey, parseCellKey } from '../worksheet/cellKey';\n\nexport class MergeManager {\n /** Maps every cell key in a merged range to that range's descriptor. */\n private readonly cells: Map<string, MergedCellRange> = new Map();\n\n /** Maps only anchor (top-left) cell keys to their merged range descriptor. */\n private readonly anchors: Map<string, MergedCellRange> = new Map();\n\n constructor(\n private readonly getRows: () => number,\n private readonly getColumns: () => number,\n ) {}\n\n get anchorCount(): number {\n return this.anchors.size;\n }\n\n iterateAnchors(): IterableIterator<MergedCellRange> {\n return this.anchors.values();\n }\n\n get(row: number, column: number): MergedCellRange | null {\n return this.cells.get(cellKey(row, column)) ?? null;\n }\n\n isAnchor(row: number, column: number): boolean {\n return this.anchors.has(cellKey(row, column));\n }\n\n getBounds(row: number, column: number): {\n topRow: number;\n bottomRow: number;\n leftColumn: number;\n rightColumn: number;\n } {\n const merged = this.get(row, column);\n if (merged) {\n return { ...merged };\n }\n const rows = this.getRows();\n const columns = this.getColumns();\n if (rows === 0 || columns === 0) {\n return { topRow: row, bottomRow: row, leftColumn: column, rightColumn: column };\n }\n const clampedRow = Math.min(Math.max(Math.floor(row), 0), rows - 1);\n const clampedCol = Math.min(Math.max(Math.floor(column), 0), columns - 1);\n return {\n topRow: clampedRow,\n bottomRow: clampedRow,\n leftColumn: clampedCol,\n rightColumn: clampedCol,\n };\n }\n\n setAll(ranges: Iterable<MergedCellRange>): void {\n this.cells.clear();\n this.anchors.clear();\n for (const range of ranges) {\n const normalized = this.normalizeRange(range);\n if (normalized) {\n this.applyRange(normalized);\n }\n }\n }\n\n add(topRow: number, leftColumn: number, bottomRow: number, rightColumn: number): void {\n const normalized = this.normalizeRange({ topRow, leftColumn, bottomRow, rightColumn });\n if (!normalized) {\n return;\n }\n this.removeOverlapping(normalized);\n this.applyRange(normalized);\n }\n\n remove(topRow: number, leftColumn: number, bottomRow: number, rightColumn: number): boolean {\n const bounds = this.normalizeBounds(topRow, leftColumn, bottomRow, rightColumn);\n if (!bounds) {\n return false;\n }\n return this.removeOverlapping({\n topRow: bounds.top,\n bottomRow: bounds.bottom,\n leftColumn: bounds.left,\n rightColumn: bounds.right,\n });\n }\n\n clear(): boolean {\n if (this.cells.size === 0 && this.anchors.size === 0) {\n return false;\n }\n this.cells.clear();\n this.anchors.clear();\n return true;\n }\n\n expandSelection(bounds: {\n top: number;\n bottom: number;\n left: number;\n right: number;\n }): { top: number; bottom: number; left: number; right: number } {\n if (!this.anchors.size) {\n return { ...bounds };\n }\n let expanded = { ...bounds };\n let changed = false;\n do {\n changed = false;\n const selectionRange: MergedCellRange = {\n topRow: expanded.top,\n bottomRow: expanded.bottom,\n leftColumn: expanded.left,\n rightColumn: expanded.right,\n };\n for (const merged of this.anchors.values()) {\n if (!this.rangesOverlap(merged, selectionRange)) {\n continue;\n }\n const nextTop = Math.min(expanded.top, merged.topRow);\n const nextBottom = Math.max(expanded.bottom, merged.bottomRow);\n const nextLeft = Math.min(expanded.left, merged.leftColumn);\n const nextRight = Math.max(expanded.right, merged.rightColumn);\n if (\n nextTop !== expanded.top ||\n nextBottom !== expanded.bottom ||\n nextLeft !== expanded.left ||\n nextRight !== expanded.right\n ) {\n expanded = { top: nextTop, bottom: nextBottom, left: nextLeft, right: nextRight };\n changed = true;\n }\n }\n } while (changed);\n return expanded;\n }\n\n getMergedLineGaps(): {\n horizontal: Map<number, Array<{ startColumnBoundary: number; endColumnBoundary: number }>>;\n vertical: Map<number, Array<{ startRowBoundary: number; endRowBoundary: number }>>;\n } {\n const horizontal = new Map<\n number,\n Array<{ startColumnBoundary: number; endColumnBoundary: number }>\n >();\n const vertical = new Map<\n number,\n Array<{ startRowBoundary: number; endRowBoundary: number }>\n >();\n\n if (!this.anchors.size) {\n return { horizontal, vertical };\n }\n\n for (const range of this.anchors.values()) {\n if (range.bottomRow > range.topRow) {\n for (let row = range.topRow + 1; row <= range.bottomRow; row += 1) {\n let list = horizontal.get(row);\n if (!list) {\n list = [];\n horizontal.set(row, list);\n }\n list.push({\n startColumnBoundary: range.leftColumn,\n endColumnBoundary: range.rightColumn + 1,\n });\n }\n }\n if (range.rightColumn > range.leftColumn) {\n for (let column = range.leftColumn + 1; column <= range.rightColumn; column += 1) {\n let list = vertical.get(column);\n if (!list) {\n list = [];\n vertical.set(column, list);\n }\n list.push({\n startRowBoundary: range.topRow,\n endRowBoundary: range.bottomRow + 1,\n });\n }\n }\n }\n\n return { horizontal, vertical };\n }\n\n /**\n * Shift all merged ranges when rows or columns are inserted or deleted.\n *\n * @param axis — 'row' or 'column'\n * @param index — insertion/deletion point (0-based)\n * @param count — positive = insert, negative = delete\n */\n shiftRanges(axis: 'row' | 'column', index: number, count: number): void {\n const anchors = this.allAnchors();\n this.cells.clear();\n this.anchors.clear();\n\n for (const range of anchors) {\n const shifted = shiftMergedRange(range, axis, index, count);\n if (shifted) {\n this.applyRange(shifted);\n }\n }\n }\n\n pruneOutsideGrid(): void {\n if (!this.anchors.size) {\n return;\n }\n const rows = this.getRows();\n const columns = this.getColumns();\n const toRemove: MergedCellRange[] = [];\n for (const range of this.anchors.values()) {\n if (\n range.topRow < 0 ||\n range.leftColumn < 0 ||\n range.bottomRow >= rows ||\n range.rightColumn >= columns\n ) {\n toRemove.push(range);\n }\n }\n for (const range of toRemove) {\n this.removeRange(range);\n }\n }\n\n allAnchors(): MergedCellRange[] {\n return Array.from(this.anchors.values());\n }\n\n private applyRange(range: MergedCellRange): void {\n const stored: MergedCellRange = { ...range };\n this.anchors.set(cellKey(stored.topRow, stored.leftColumn), stored);\n for (let r = stored.topRow; r <= stored.bottomRow; r += 1) {\n for (let c = stored.leftColumn; c <= stored.rightColumn; c += 1) {\n this.cells.set(cellKey(r, c), stored);\n }\n }\n }\n\n private removeRange(range: MergedCellRange): void {\n this.anchors.delete(cellKey(range.topRow, range.leftColumn));\n for (let r = range.topRow; r <= range.bottomRow; r += 1) {\n for (let c = range.leftColumn; c <= range.rightColumn; c += 1) {\n this.cells.delete(cellKey(r, c));\n }\n }\n }\n\n private removeOverlapping(range: MergedCellRange): boolean {\n const toRemove: MergedCellRange[] = [];\n for (const existing of this.anchors.values()) {\n if (this.rangesOverlap(existing, range)) {\n toRemove.push(existing);\n }\n }\n if (!toRemove.length) {\n return false;\n }\n for (const merged of toRemove) {\n this.removeRange(merged);\n }\n return true;\n }\n\n private rangesOverlap(a: MergedCellRange, b: MergedCellRange): boolean {\n return !(\n a.bottomRow < b.topRow ||\n a.topRow > b.bottomRow ||\n a.rightColumn < b.leftColumn ||\n a.leftColumn > b.rightColumn\n );\n }\n\n private normalizeRange(range: MergedCellRange): MergedCellRange | null {\n const bounds = this.normalizeBounds(\n range.topRow,\n range.leftColumn,\n range.bottomRow,\n range.rightColumn,\n );\n if (!bounds) {\n return null;\n }\n if (bounds.top === bounds.bottom && bounds.left === bounds.right) {\n return null;\n }\n return {\n topRow: bounds.top,\n bottomRow: bounds.bottom,\n leftColumn: bounds.left,\n rightColumn: bounds.right,\n };\n }\n\n private normalizeBounds(\n topRow: number,\n leftColumn: number,\n bottomRow: number,\n rightColumn: number,\n ): { top: number; left: number; bottom: number; right: number } | null {\n const rows = this.getRows();\n const columns = this.getColumns();\n if (rows === 0 || columns === 0) {\n return null;\n }\n const clampRow = (r: number) => Math.min(Math.max(Math.floor(r), 0), rows - 1);\n const clampCol = (c: number) => Math.min(Math.max(Math.floor(c), 0), columns - 1);\n const r1 = clampRow(topRow);\n const r2 = clampRow(bottomRow);\n const c1 = clampCol(leftColumn);\n const c2 = clampCol(rightColumn);\n return { top: Math.min(r1, r2), bottom: Math.max(r1, r2), left: Math.min(c1, c2), right: Math.max(c1, c2) };\n }\n}\n\n/**\n * Shift a single merged range for a row/column insert or delete.\n * Returns null if the range is entirely consumed by the deletion.\n */\nfunction shiftMergedRange(\n range: MergedCellRange,\n axis: 'row' | 'column',\n index: number,\n count: number,\n): MergedCellRange | null {\n let { topRow, bottomRow, leftColumn, rightColumn } = range;\n\n if (axis === 'row') {\n if (count > 0) {\n // Insert rows at `index`\n if (topRow >= index) {\n topRow += count;\n bottomRow += count;\n } else if (bottomRow >= index) {\n // Insertion point is inside the merged range — expand\n bottomRow += count;\n }\n } else {\n // Delete rows: count is negative\n const deleteCount = -count;\n const delEnd = index + deleteCount; // exclusive end\n\n if (topRow >= delEnd) {\n // Entirely below the deleted range — shift up\n topRow += count;\n bottomRow += count;\n } else if (bottomRow < index) {\n // Entirely above the deleted range — no change\n } else {\n // Overlaps the deleted range\n const newTop = Math.max(topRow, index);\n const newBottom = Math.min(bottomRow, delEnd - 1);\n const deletedInRange = newBottom - newTop + 1;\n bottomRow -= deletedInRange;\n if (topRow >= index) {\n topRow = index;\n bottomRow = index + (range.bottomRow - range.topRow - deletedInRange);\n }\n if (bottomRow < topRow) return null; // fully consumed\n }\n }\n } else {\n if (count > 0) {\n if (leftColumn >= index) {\n leftColumn += count;\n rightColumn += count;\n } else if (rightColumn >= index) {\n rightColumn += count;\n }\n } else {\n const deleteCount = -count;\n const delEnd = index + deleteCount;\n\n if (leftColumn >= delEnd) {\n leftColumn += count;\n rightColumn += count;\n } else if (rightColumn < index) {\n // no change\n } else {\n const newLeft = Math.max(leftColumn, index);\n const newRight = Math.min(rightColumn, delEnd - 1);\n const deletedInRange = newRight - newLeft + 1;\n rightColumn -= deletedInRange;\n if (leftColumn >= index) {\n leftColumn = index;\n rightColumn = index + (range.rightColumn - range.leftColumn - deletedInRange);\n }\n if (rightColumn < leftColumn) return null;\n }\n }\n }\n\n // Single-cell result is no longer a merge\n if (topRow === bottomRow && leftColumn === rightColumn) {\n return null;\n }\n\n return { topRow, bottomRow, leftColumn, rightColumn };\n}\n\n/** Prunes map entries whose keys are not valid cell positions within the given grid bounds. */\nexport function pruneMapOutsideGrid(\n map: Map<string, unknown>,\n rows: number,\n columns: number,\n): void {\n for (const key of Array.from(map.keys())) {\n const pos = parseCellKey(key);\n if (!pos || pos.row < 0 || pos.row >= rows || pos.column < 0 || pos.column >= columns) {\n map.delete(key);\n }\n }\n}\n","import { cellKey } from '../worksheet/cellKey';\nimport type { CellTypeHandler } from './cellTypeHandler';\n\n// ---------------------------------------------------------------------------\n// Cell type config — open type system\n// ---------------------------------------------------------------------------\n\n/** Base config accepted by any cell type. */\nexport interface CellTypeConfigBase {\n type: string;\n [key: string]: unknown;\n}\n\n// Built-in configs (backward compatible named interfaces)\n\nexport interface CheckboxConfig {\n type: 'checkbox';\n}\n\nexport interface DropdownClickContext {\n row?: number;\n column: number;\n isHeader: boolean;\n}\n\nexport interface DropdownConfig {\n type: 'dropdown';\n options?: string[];\n onclick?: (context: DropdownClickContext) => void;\n}\n\nexport interface ButtonConfig {\n type: 'button';\n label?: string;\n onClick?: () => void;\n}\n\nexport interface ProgressConfig {\n type: 'progress';\n max?: number;\n color?: string;\n /** When true, negative values render left (red) and positive render right (green). */\n bidirectional?: boolean;\n}\n\nexport interface RatingConfig {\n type: 'rating';\n maxStars?: number;\n}\n\nexport interface SparklineLineConfig {\n type: 'sparkline-line';\n color?: string;\n}\n\nexport interface SparklineAreaConfig {\n type: 'sparkline-area';\n color?: string;\n fillColor?: string;\n}\n\nexport interface HyperlinkConfig {\n type: 'hyperlink';\n url?: string;\n}\n\n/** Open union — any `{ type: string }` config is accepted. */\nexport type CellTypeConfig = CellTypeConfigBase;\n\n// ---------------------------------------------------------------------------\n// Per-cell config registry (instance per worksheet)\n// ---------------------------------------------------------------------------\n\nexport class CellTypeRegistry {\n private readonly configs = new Map<string, CellTypeConfig>();\n\n set(row: number, col: number, config: CellTypeConfig): void {\n this.configs.set(cellKey(row, col), config);\n }\n\n get(row: number, col: number): CellTypeConfig | undefined {\n return this.configs.get(cellKey(row, col));\n }\n\n clear(row: number, col: number): void {\n this.configs.delete(cellKey(row, col));\n }\n\n clearAll(): void {\n this.configs.clear();\n }\n}\n\n// ---------------------------------------------------------------------------\n// Handler registry (module-level singleton, shared across worksheets)\n// ---------------------------------------------------------------------------\n\nconst handlers = new Map<string, CellTypeHandler>();\n\n/** Register a cell type handler. Called at module load time by each handler file. */\nexport function registerCellTypeHandler(name: string, handler: CellTypeHandler): void {\n handlers.set(name, handler);\n}\n\n/** Look up a handler by type name. */\nexport function getCellTypeHandler(name: string): CellTypeHandler | undefined {\n return handlers.get(name);\n}\n","import type { OutlineGroup, RowOrColumn } from './types';\n\nconst MAX_OUTLINE_LEVELS = 9;\n\nexport class OutlineManager {\n readonly direction: RowOrColumn;\n\n /** levels[0] = outermost groups, levels[n] = most nested */\n private levels: OutlineGroup[][] = [];\n\n constructor(direction: RowOrColumn) {\n this.direction = direction;\n }\n\n /** Returns the deepest level index, or -1 if no outlines exist */\n getMaxLevel(): number {\n return this.levels.length - 1;\n }\n\n /** Total number of levels (0 if no outlines) */\n getLevelCount(): number {\n return this.levels.length;\n }\n\n hasOutlines(): boolean {\n return this.levels.length > 0;\n }\n\n getGroupsAtLevel(level: number): readonly OutlineGroup[] {\n return this.levels[level] ?? [];\n }\n\n getAllGroups(): readonly (readonly OutlineGroup[])[] {\n return this.levels;\n }\n\n /**\n * Add a group spanning [start, start+count).\n * Automatically assigns the correct level based on containment:\n * larger (enclosing) groups are placed at lower levels (outermost).\n * Returns the assigned level index.\n */\n addGroup(start: number, count: number): number {\n if (count <= 0) throw new Error('Outline group count must be positive');\n\n // Check for exact duplicate\n for (let lvl = 0; lvl < this.levels.length; lvl++) {\n if (this.levels[lvl].some((g) => g.start === start && g.count === count)) {\n return lvl;\n }\n }\n\n const newGroup: OutlineGroup = { start, count, collapsed: false };\n\n // Collect all existing groups (preserving references for collapsed state etc.)\n const allGroups: OutlineGroup[] = [];\n for (const level of this.levels) {\n allGroups.push(...level);\n }\n allGroups.push(newGroup);\n\n // Sort by range size descending (larger = outermost = level 0),\n // then by start ascending for stable ordering within same size\n allGroups.sort((a, b) => b.count - a.count || a.start - b.start);\n\n // Rebuild levels: assign each group to the lowest level with no overlap\n this.levels = [];\n for (const g of allGroups) {\n const gEnd = g.start + g.count;\n let targetLevel = 0;\n for (let lvl = 0; lvl < this.levels.length; lvl++) {\n for (const existing of this.levels[lvl]) {\n const eEnd = existing.start + existing.count;\n if (g.start < eEnd && gEnd > existing.start) {\n targetLevel = Math.max(targetLevel, lvl + 1);\n break;\n }\n }\n }\n if (targetLevel >= MAX_OUTLINE_LEVELS) {\n throw new Error(`Maximum outline level (${MAX_OUTLINE_LEVELS}) exceeded`);\n }\n while (this.levels.length <= targetLevel) {\n this.levels.push([]);\n }\n const levelGroups = this.levels[targetLevel];\n const insertIdx = levelGroups.findIndex((x) => x.start > g.start);\n if (insertIdx === -1) {\n levelGroups.push(g);\n } else {\n levelGroups.splice(insertIdx, 0, g);\n }\n }\n this.trimEmptyLevels();\n\n // Return the level of the newly added group\n for (let lvl = 0; lvl < this.levels.length; lvl++) {\n if (this.levels[lvl].includes(newGroup)) return lvl;\n }\n return 0;\n }\n\n /**\n * Remove a group matching [start, start+count).\n * Returns true if a group was found and removed.\n */\n removeGroup(start: number, count: number): boolean {\n for (let lvl = 0; lvl < this.levels.length; lvl++) {\n const groups = this.levels[lvl];\n const idx = groups.findIndex((g) => g.start === start && g.count === count);\n if (idx !== -1) {\n groups.splice(idx, 1);\n this.trimEmptyLevels();\n return true;\n }\n }\n return false;\n }\n\n /**\n * Find the group at a specific level and start index.\n */\n findGroup(level: number, start: number): OutlineGroup | null {\n const groups = this.levels[level];\n if (!groups) return null;\n return groups.find((g) => g.start === start) ?? null;\n }\n\n /**\n * Collapse a group. Returns the set of indices that should be hidden.\n */\n collapseGroup(level: number, start: number): Set<number> {\n const group = this.findGroup(level, start);\n if (!group || group.collapsed) return new Set();\n\n group.collapsed = true;\n return this.getGroupHiddenIndices(group);\n }\n\n /**\n * Expand a group. Returns the set of indices that should be shown.\n */\n expandGroup(level: number, start: number): Set<number> {\n const group = this.findGroup(level, start);\n if (!group || !group.collapsed) return new Set();\n\n group.collapsed = false;\n // Return indices that should be visible, but exclude those still hidden by other collapsed groups\n return this.getGroupHiddenIndices(group);\n }\n\n /**\n * Collapse all groups at the given level and deeper.\n * Expand all groups at levels shallower than the given level.\n * Returns the complete set of hidden indices after the operation.\n */\n collapseToLevel(level: number): void {\n for (let lvl = 0; lvl < this.levels.length; lvl++) {\n for (const g of this.levels[lvl]) {\n g.collapsed = lvl >= level;\n }\n }\n }\n\n /**\n * Get all indices hidden by collapsed outline groups.\n */\n getHiddenIndices(): Set<number> {\n const hidden = new Set<number>();\n for (const groups of this.levels) {\n for (const g of groups) {\n if (g.collapsed) {\n // Hide all indices in the group except the last row (where the toggle button is)\n for (let i = g.start; i < g.start + g.count - 1; i++) {\n hidden.add(i);\n }\n }\n }\n }\n return hidden;\n }\n\n /**\n * Get hidden indices for a specific group (excluding indices hidden by inner collapsed groups).\n */\n private getGroupHiddenIndices(group: OutlineGroup): Set<number> {\n const indices = new Set<number>();\n for (let i = group.start; i < group.start + group.count - 1; i++) {\n indices.add(i);\n }\n return indices;\n }\n\n /**\n * Shift all groups when rows/columns are inserted or deleted.\n * @param index - The insert/delete position\n * @param delta - Positive for insert, negative for delete\n */\n shiftGroups(index: number, delta: number): void {\n for (const groups of this.levels) {\n for (let i = groups.length - 1; i >= 0; i--) {\n const g = groups[i];\n const end = g.start + g.count;\n\n if (delta > 0) {\n // Insert\n if (index <= g.start) {\n g.start += delta;\n } else if (index < end) {\n g.count += delta;\n }\n } else {\n // Delete\n const deleteStart = index;\n const deleteEnd = index - delta; // delta is negative, so -delta is the count\n if (deleteEnd <= g.start) {\n // Delete is entirely before this group\n g.start += delta;\n } else if (deleteStart >= end) {\n // Delete is entirely after this group - no change\n } else if (deleteStart <= g.start && deleteEnd >= end) {\n // Delete covers entire group - remove it\n groups.splice(i, 1);\n } else if (deleteStart <= g.start) {\n // Delete overlaps start of group\n const removed = deleteEnd - g.start;\n g.start = index;\n g.count -= removed;\n } else if (deleteEnd >= end) {\n // Delete overlaps end of group\n g.count = deleteStart - g.start;\n } else {\n // Delete is entirely within group\n g.count += delta;\n }\n\n // Remove degenerate groups\n if (g.count <= 0) {\n groups.splice(i, 1);\n }\n }\n }\n }\n this.trimEmptyLevels();\n }\n\n /** Remove trailing empty levels */\n private trimEmptyLevels(): void {\n while (this.levels.length > 0 && this.levels[this.levels.length - 1].length === 0) {\n this.levels.pop();\n }\n }\n\n /** Clear all outline groups */\n clear(): void {\n this.levels = [];\n }\n\n /**\n * Get a snapshot for serialization/undo.\n */\n getSnapshot(): OutlineGroup[][] {\n return this.levels.map((level) => level.map((g) => ({ ...g })));\n }\n\n /**\n * Restore from a snapshot.\n */\n restoreSnapshot(snapshot: OutlineGroup[][]): void {\n this.levels = snapshot.map((level) => level.map((g) => ({ ...g })));\n }\n}\n","import {\n DEFAULT_COLUMNS,\n DEFAULT_ROWS,\n DEFAULT_COLUMN_WIDTH,\n DEFAULT_ROW_HEIGHT,\n HEADER_COLUMN_WIDTH,\n HEADER_ROW_HEIGHT,\n} from './gridDefaults';\nimport { SelectionRange } from '../cell/selectionRange';\nimport { FormulaEngine, type FormulaEngineOptions } from '../formula/formulaEngine';\nimport type { RangeRect, HitTestResult, ContextMenuEvent } from './types';\nimport {\n DEFAULT_CELL_STYLE,\n type CellStyle,\n type TextAlign,\n type TextWrapMode,\n type VerticalAlign,\n} from '../style/cellStyle';\nimport { formatValueWithFormat, isDateFormatSection } from '../style/numberFormat';\nimport type { CellInputValue, MergedCellRange } from '../cell/types';\nimport type { BorderLineOptions, RangeBorderSide, CellBorderDefinition } from '../border/types';\nimport type { RichTextRun } from '../../types/richText';\nimport { cellKey, parseCellKey } from './cellKey';\nimport { buildBoundaries, getIndexAtOffset, findIndexByOffset, computeRangeRect } from './gridGeometry';\nimport { BorderManager } from '../border/borderManager';\nimport { MergeManager, pruneMapOutsideGrid } from '../merge/mergeManager';\nimport { CellTypeRegistry, type CellTypeConfig, type DropdownConfig } from '../cell/cellTypeRegistry';\nimport { OutlineManager, type OutlineGroup } from '../outline';\n\nexport type AlternateRowColors = { evenColor: string; oddColor: string };\n\nexport const MIN_COLUMN_WIDTH = 24;\nexport const MIN_ROW_HEIGHT = 18;\nexport const HEADER_RESIZE_TOLERANCE = 4;\nexport const CELL_TEXT_PADDING = 4;\nexport const DROPDOWN_BUTTON_WIDTH = 20;\nexport const HEADER_DROPDOWN_BUTTON_WIDTH = 16;\n\ntype SelectionChangeListener = (cell: { row: number; column: number } | null) => void;\ntype CellValueChangeListener = (payload: { row: number; column: number; value: string }) => void;\ntype ViewportSizeListener = (size: { width: number; height: number }) => void;\ntype ScrollChangeListener = (offset: { x: number; y: number }) => void;\ntype ContextMenuListener = (event: ContextMenuEvent) => void;\ntype ProtectedCellEditListener = (payload: { row: number; column: number }) => void;\n\nexport type WorksheetExportCell = {\n row: number;\n column: number;\n value?: string;\n style?: CellStyle;\n /** For formula cells: the cached computed value for the xlsx <v> tag */\n cachedValue?: string | number | boolean;\n};\n\nexport interface WorksheetExportSnapshot {\n cells: WorksheetExportCell[];\n merges: MergedCellRange[];\n borders: Map<string, CellBorderDefinition>;\n columnWidths: number[];\n rowHeights: number[];\n rows: number;\n columns: number;\n frozenRows: number;\n frozenColumns: number;\n}\n\nexport interface WorksheetOptions {\n /** Options forwarded to the FormulaEngine (e.g. disable built-in functions for Lite). */\n formula?: FormulaEngineOptions;\n}\n\nexport class Worksheet {\n protected pixelRatio = 1;\n\n private readonly pointToPixelRatio = 96 / 72;\n\n protected viewportWidth = 0;\n\n protected viewportHeight = 0;\n\n public rows: number;\n\n public columns: number;\n\n public readonly columnWidths: number[];\n\n private readonly columnCustomWidths: boolean[];\n\n public readonly rowHeights: number[];\n\n private readonly rowCustomHeights: boolean[];\n\n private readonly rowHidden: boolean[];\n\n private readonly columnHidden: boolean[];\n\n private columnBoundaries: number[];\n\n private rowBoundaries: number[];\n\n public headerColumnWidth: number;\n\n public headerRowHeight: number;\n\n public readonly selection: SelectionRange;\n\n private readonly cellInputs: Map<string, string>;\n\n private readonly cellRichText: Map<string, RichTextRun[]>;\n\n private readonly cellDisplayOverrides: Map<string, string>;\n\n private readonly cellNumberFormats: Map<string, string>;\n\n private readonly cellFormatting: Map<string, Partial<CellStyle>>;\n\n protected readonly borders: BorderManager;\n\n protected readonly merges: MergeManager;\n\n private readonly selectionChangeListeners: Set<SelectionChangeListener> = new Set();\n\n private readonly cellValueListeners: Set<CellValueChangeListener> = new Set();\n\n private readonly viewportSizeListeners: Set<ViewportSizeListener> = new Set();\n\n private readonly scrollListeners: Set<ScrollChangeListener> = new Set();\n\n private readonly structureListeners: Set<() => void> = new Set();\n\n private readonly contextMenuListeners: Set<ContextMenuListener> = new Set();\n\n private readonly defaultStyle: CellStyle = { ...DEFAULT_CELL_STYLE };\n\n private _showGridLines = true;\n\n private _alternateRowColors: AlternateRowColors | null = null;\n\n protected resizeGuide: { type: 'column' | 'row'; position: number } | null = null;\n\n private readonly formulaEngine: FormulaEngine;\n\n protected readonly cellTypeRegistry: CellTypeRegistry = new CellTypeRegistry();\n\n protected readonly rowOutlines: OutlineManager = new OutlineManager('row');\n\n protected readonly columnOutlines: OutlineManager = new OutlineManager('column');\n\n private readonly headerDropdowns: Map<number, DropdownConfig> = new Map();\n\n private _protected = false;\n\n private readonly cellLockStates: Map<string, 'locked' | 'unlocked'> = new Map();\n\n private readonly protectedCellEditListeners: Set<ProtectedCellEditListener> = new Set();\n\n protected scrollX = 0;\n\n protected scrollY = 0;\n\n protected frozenRows = 0;\n\n protected frozenColumns = 0;\n\n private contentWidth = 0;\n\n private contentHeight = 0;\n\n private _renderSuspended = false;\n private _renderPending = false;\n\n constructor(options?: WorksheetOptions) {\n this.rows = DEFAULT_ROWS;\n this.columns = DEFAULT_COLUMNS;\n this.columnWidths = new Array(this.columns).fill(DEFAULT_COLUMN_WIDTH);\n this.columnCustomWidths = new Array(this.columns).fill(false);\n this.rowHeights = new Array(this.rows).fill(DEFAULT_ROW_HEIGHT);\n this.rowCustomHeights = new Array(this.rows).fill(false);\n this.rowHidden = new Array(this.rows).fill(false);\n this.columnHidden = new Array(this.columns).fill(false);\n this.columnBoundaries = [];\n this.rowBoundaries = [];\n\n this.headerColumnWidth = HEADER_COLUMN_WIDTH;\n this.headerRowHeight = HEADER_ROW_HEIGHT;\n\n this.selection = new SelectionRange(this);\n\n this.cellInputs = new Map();\n this.cellRichText = new Map();\n this.cellDisplayOverrides = new Map();\n this.cellNumberFormats = new Map();\n this.cellFormatting = new Map();\n\n this.borders = new BorderManager(() => this.rows, () => this.columns);\n this.merges = new MergeManager(() => this.rows, () => this.columns);\n\n this.formulaEngine = new FormulaEngine(this, options?.formula);\n }\n\n public render(): void {\n if (this._renderSuspended) {\n this._renderPending = true;\n return;\n }\n this.renderImpl();\n }\n\n /** Override in rendering subclasses to perform actual drawing. */\n protected renderImpl(): void {\n // No-op in base Worksheet (no canvas).\n }\n\n /**\n * Suspend rendering. All render() calls become no-ops until resumeRender().\n * Use for batch operations that would otherwise trigger thousands of redraws.\n */\n suspendRender(): void {\n this._renderSuspended = true;\n this._renderPending = false;\n }\n\n /**\n * Resume rendering and flush a single render if any were requested while suspended.\n */\n resumeRender(): void {\n this._renderSuspended = false;\n if (this._renderPending) {\n this._renderPending = false;\n this.render();\n }\n }\n\n /** Rebuild formula dependency graph and re-evaluate all formulas. */\n rebuildFormulas(): void {\n this.formulaEngine.rebuildAll();\n }\n\n // ---------------------------------------------------------------------------\n // Scroll & viewport\n // ---------------------------------------------------------------------------\n\n getScrollContentSize(): { width: number; height: number } {\n this.ensureBoundaries();\n return {\n width: this.headerColumnWidth + this.contentWidth,\n height: this.headerRowHeight + this.contentHeight,\n };\n }\n\n getScrollOffset(): { x: number; y: number } {\n return { x: this.scrollX, y: this.scrollY };\n }\n\n setScrollOffset(x: number, y: number): void {\n const clamped = this.clampScrollOffset(x, y);\n if (clamped.x === this.scrollX && clamped.y === this.scrollY) {\n return;\n }\n this.scrollX = clamped.x;\n this.scrollY = clamped.y;\n this.emitScrollChange();\n this.render();\n }\n\n onViewportSizeChange(listener: ViewportSizeListener): () => void {\n this.viewportSizeListeners.add(listener);\n return () => {\n this.viewportSizeListeners.delete(listener);\n };\n }\n\n onScrollChange(listener: ScrollChangeListener): () => void {\n this.scrollListeners.add(listener);\n return () => {\n this.scrollListeners.delete(listener);\n };\n }\n\n onStructureChange(listener: () => void): () => void {\n this.structureListeners.add(listener);\n return () => {\n this.structureListeners.delete(listener);\n };\n }\n\n // ---------------------------------------------------------------------------\n // Freeze panes\n // ---------------------------------------------------------------------------\n\n getFrozenRows(): number {\n return this.frozenRows;\n }\n\n getFrozenColumns(): number {\n return this.frozenColumns;\n }\n\n setFrozenRows(count: number): void {\n const clamped = Math.max(0, Math.min(count, this.rows - 1));\n if (clamped === this.frozenRows) {\n return;\n }\n this.frozenRows = clamped;\n this.emitStructureChange();\n this.render();\n }\n\n setFrozenColumns(count: number): void {\n const clamped = Math.max(0, Math.min(count, this.columns - 1));\n if (clamped === this.frozenColumns) {\n return;\n }\n this.frozenColumns = clamped;\n this.emitStructureChange();\n this.render();\n }\n\n getFrozenWidth(): number {\n if (this.frozenColumns <= 0) {\n return 0;\n }\n this.ensureBoundaries();\n return this.columnBoundaries[this.frozenColumns] ?? 0;\n }\n\n getFrozenHeight(): number {\n if (this.frozenRows <= 0) {\n return 0;\n }\n this.ensureBoundaries();\n return this.rowBoundaries[this.frozenRows] ?? 0;\n }\n\n // ---------------------------------------------------------------------------\n // Hit testing & geometry\n // ---------------------------------------------------------------------------\n\n getCellFromPoint(x: number, y: number): { row: number; column: number } | null {\n const hit = this.hitTest(x, y);\n if (hit && hit.type === 'cell') {\n return { row: hit.row, column: hit.column };\n }\n return null;\n }\n\n hitTest(x: number, y: number): HitTestResult | null {\n if (x < 0 || y < 0) {\n return null;\n }\n\n this.ensureBoundaries();\n\n // --- Outline panel hit testing ---\n const outlinePanelWidth = this.getOutlinePanelWidth();\n const outlinePanelHeight = this.getOutlinePanelHeight();\n const LEVEL_SIZE = 16;\n const BUTTON_SIZE = 11;\n const BUTTON_HALF = Math.floor(BUTTON_SIZE / 2);\n\n // Row outline level buttons (in top-left corner)\n if (outlinePanelWidth > 0 && x < outlinePanelWidth && y < this.headerRowHeight) {\n const maxLevel = this.rowOutlines.getMaxLevel();\n for (let lvl = 0; lvl <= maxLevel; lvl++) {\n const btnX = lvl * LEVEL_SIZE + LEVEL_SIZE / 2;\n const btnY = this.headerRowHeight / 2;\n if (Math.abs(x - btnX) <= BUTTON_HALF && Math.abs(y - btnY) <= BUTTON_HALF) {\n return { type: 'outline-level-button', direction: 'row', level: lvl };\n }\n }\n }\n\n // Column outline level buttons (in top-left corner)\n if (outlinePanelHeight > 0 && y < outlinePanelHeight && x < this.headerColumnWidth) {\n const maxLevel = this.columnOutlines.getMaxLevel();\n for (let lvl = 0; lvl <= maxLevel; lvl++) {\n const btnY = lvl * LEVEL_SIZE + LEVEL_SIZE / 2;\n const btnX = this.headerColumnWidth / 2;\n if (Math.abs(x - btnX) <= BUTTON_HALF && Math.abs(y - btnY) <= BUTTON_HALF) {\n return { type: 'outline-level-button', direction: 'column', level: lvl };\n }\n }\n }\n\n // Row outline toggle buttons (in outline panel area, left of row headers)\n if (outlinePanelWidth > 0 && x < outlinePanelWidth && y >= this.headerRowHeight) {\n const gridY = this.screenToGridY(y);\n const row = getIndexAtOffset(gridY, this.rowBoundaries);\n if (row !== null) {\n const maxLevel = this.rowOutlines.getMaxLevel();\n for (let lvl = 0; lvl <= maxLevel; lvl++) {\n const groups = this.rowOutlines.getGroupsAtLevel(lvl);\n const levelCenterX = lvl * LEVEL_SIZE + LEVEL_SIZE / 2;\n for (const g of groups) {\n const groupEnd = g.start + g.count - 1;\n if (row === groupEnd && Math.abs(x - levelCenterX) <= BUTTON_HALF) {\n return { type: 'outline-toggle', direction: 'row', level: lvl, start: g.start };\n }\n }\n }\n }\n }\n\n // Column outline toggle buttons (in outline panel area, above column headers)\n if (outlinePanelHeight > 0 && y < outlinePanelHeight && x >= this.headerColumnWidth) {\n const gridX = this.screenToGridX(x);\n const col = getIndexAtOffset(gridX, this.columnBoundaries);\n if (col !== null) {\n const maxLevel = this.columnOutlines.getMaxLevel();\n for (let lvl = 0; lvl <= maxLevel; lvl++) {\n const groups = this.columnOutlines.getGroupsAtLevel(lvl);\n const levelCenterY = lvl * LEVEL_SIZE + LEVEL_SIZE / 2;\n for (const g of groups) {\n const groupEnd = g.start + g.count - 1;\n if (col === groupEnd && Math.abs(y - levelCenterY) <= BUTTON_HALF) {\n return { type: 'outline-toggle', direction: 'column', level: lvl, start: g.start };\n }\n }\n }\n }\n }\n\n const bodyLeft = this.headerColumnWidth;\n const bodyTop = this.headerRowHeight;\n const bodyRight = bodyLeft + this.getBodyViewportWidth();\n const bodyBottom = bodyTop + this.getBodyViewportHeight();\n\n const withinBodyX = x >= bodyLeft && x < bodyRight;\n const withinBodyY = y >= bodyTop && y < bodyBottom;\n\n if (withinBodyX && withinBodyY) {\n const gridX = this.screenToGridX(x);\n const gridY = this.screenToGridY(y);\n const column = getIndexAtOffset(gridX, this.columnBoundaries);\n const row = getIndexAtOffset(gridY, this.rowBoundaries);\n if (column !== null && row !== null) {\n const merged = this.getMergedRange(row, column);\n if (merged) {\n return { type: 'cell', row: merged.topRow, column: merged.leftColumn };\n }\n return { type: 'cell', row, column };\n }\n return null;\n }\n\n const withinColumnHeaders =\n y >= 0 && y < this.headerRowHeight && x >= bodyLeft && x < bodyRight;\n if (withinColumnHeaders) {\n const gridX = this.screenToGridX(x);\n const column = getIndexAtOffset(gridX, this.columnBoundaries);\n if (column !== null) {\n if (this.hasHeaderDropdown(column)) {\n const colLeft = this.columnBoundaries[column] ?? 0;\n const colWidth = this.columnWidths[column] ?? 0;\n const colRight = colLeft + colWidth;\n if (gridX >= colRight - HEADER_DROPDOWN_BUTTON_WIDTH) {\n return { type: 'column-header-dropdown', column };\n }\n }\n return { type: 'column-header', column };\n }\n }\n\n const withinRowHeaders =\n x >= 0 && x < this.headerColumnWidth && y >= bodyTop && y < bodyBottom;\n if (withinRowHeaders) {\n const gridY = this.screenToGridY(y);\n const row = getIndexAtOffset(gridY, this.rowBoundaries);\n if (row !== null) {\n return { type: 'row-header', row };\n }\n }\n\n const withinCorner =\n x >= 0 && x < this.headerColumnWidth && y >= 0 && y < this.headerRowHeight;\n if (withinCorner) {\n return { type: 'corner' };\n }\n\n return null;\n }\n\n /** Converts a screen X coordinate to grid content X, accounting for frozen columns. */\n protected screenToGridX(screenX: number): number {\n const bodyLeft = this.headerColumnWidth;\n const frozenWidth = this.getFrozenWidth();\n if (this.frozenColumns > 0 && screenX < bodyLeft + frozenWidth) {\n return screenX - bodyLeft;\n }\n return screenX - bodyLeft - frozenWidth + (this.columnBoundaries[this.frozenColumns] ?? 0) + this.scrollX;\n }\n\n /** Converts a screen Y coordinate to grid content Y, accounting for frozen rows. */\n protected screenToGridY(screenY: number): number {\n const bodyTop = this.headerRowHeight;\n const frozenHeight = this.getFrozenHeight();\n if (this.frozenRows > 0 && screenY < bodyTop + frozenHeight) {\n return screenY - bodyTop;\n }\n return screenY - bodyTop - frozenHeight + (this.rowBoundaries[this.frozenRows] ?? 0) + this.scrollY;\n }\n\n updateBoundaries(): void {\n const previousWidth = this.contentWidth;\n const previousHeight = this.contentHeight;\n this.columnBoundaries = buildBoundaries(this.columnWidths, this.columnHidden);\n this.rowBoundaries = buildBoundaries(this.rowHeights, this.rowHidden);\n this.contentWidth =\n this.columnBoundaries.length > 0\n ? this.columnBoundaries[this.columnBoundaries.length - 1]\n : 0;\n this.contentHeight =\n this.rowBoundaries.length > 0 ? this.rowBoundaries[this.rowBoundaries.length - 1] : 0;\n if (this.contentWidth !== previousWidth || this.contentHeight !== previousHeight) {\n this.emitViewportSizeChange();\n this.clampScrollOffsetInPlace();\n }\n }\n\n ensureBoundaries(): void {\n if (!this.columnBoundaries.length || !this.rowBoundaries.length) {\n this.updateBoundaries();\n }\n }\n\n public getColumnBoundaries(): readonly number[] {\n return this.columnBoundaries;\n }\n\n public getRowBoundaries(): readonly number[] {\n return this.rowBoundaries;\n }\n\n protected getColumnWidths(): readonly number[] {\n return this.columnWidths;\n }\n\n protected getRowHeights(): readonly number[] {\n return this.rowHeights;\n }\n\n protected getCellBorders(): Iterable<[string, CellBorderDefinition]> {\n return this.borders.entries();\n }\n\n public getBodyViewportWidth(): number {\n return Math.max(0, this.viewportWidth - this.headerColumnWidth);\n }\n\n public getBodyViewportHeight(): number {\n return Math.max(0, this.viewportHeight - this.headerRowHeight);\n }\n\n private clampScrollOffset(x: number, y: number): { x: number; y: number } {\n const maxX = Math.max(0, this.contentWidth - this.getBodyViewportWidth());\n const maxY = Math.max(0, this.contentHeight - this.getBodyViewportHeight());\n return {\n x: Math.min(Math.max(0, x), maxX),\n y: Math.min(Math.max(0, y), maxY),\n };\n }\n\n protected clampScrollOffsetInPlace(): void {\n const clamped = this.clampScrollOffset(this.scrollX, this.scrollY);\n if (clamped.x !== this.scrollX || clamped.y !== this.scrollY) {\n this.scrollX = clamped.x;\n this.scrollY = clamped.y;\n this.emitScrollChange();\n }\n }\n\n getRangeRect(topRow: number, leftColumn: number, bottomRow: number, rightColumn: number): RangeRect {\n this.ensureBoundaries();\n return computeRangeRect(\n topRow,\n leftColumn,\n bottomRow,\n rightColumn,\n this.columnBoundaries,\n this.rowBoundaries,\n this.headerColumnWidth,\n this.headerRowHeight,\n this.scrollX,\n this.scrollY,\n this.frozenColumns,\n this.frozenRows,\n );\n }\n\n getCellRect(row: number, column: number): RangeRect {\n const bounds = this.getCellMergeBounds(row, column);\n return this.getRangeRect(bounds.topRow, bounds.leftColumn, bounds.bottomRow, bounds.rightColumn);\n }\n\n public getVisibleRowRange(padding = 1): { start: number; end: number } {\n if (this.rows === 0) {\n return { start: 0, end: -1 };\n }\n const bodyHeight = this.getBodyViewportHeight();\n const start = findIndexByOffset(this.scrollY, this.rows, this.rowBoundaries);\n const end = findIndexByOffset(this.scrollY + bodyHeight, this.rows, this.rowBoundaries);\n return {\n start: Math.max(0, start - padding),\n end: Math.min(this.rows - 1, end + padding),\n };\n }\n\n public getVisibleColumnRange(padding = 1): { start: number; end: number } {\n if (this.columns === 0) {\n return { start: 0, end: -1 };\n }\n const bodyWidth = this.getBodyViewportWidth();\n const start = findIndexByOffset(this.scrollX, this.columns, this.columnBoundaries);\n const end = findIndexByOffset(this.scrollX + bodyWidth, this.columns, this.columnBoundaries);\n return {\n start: Math.max(0, start - padding),\n end: Math.min(this.columns - 1, end + padding),\n };\n }\n\n public getVisibleRowIndices(): number[] {\n const padded = this.getVisibleRowRange();\n const viewportRows = this.getVisibleRowRange(0);\n const viewportCols = this.getVisibleColumnRange(0);\n const rows = new Set<number>();\n for (let r = padded.start; r <= padded.end; r += 1) {\n if (!this.rowHidden[r]) {\n rows.add(r);\n }\n }\n if (this.merges.anchorCount > 0) {\n for (const merged of this.merges.iterateAnchors()) {\n const overlapsViewport =\n merged.bottomRow >= viewportRows.start &&\n merged.topRow <= viewportRows.end &&\n merged.rightColumn >= viewportCols.start &&\n merged.leftColumn <= viewportCols.end;\n const anchorOutsidePadded = merged.topRow < padded.start || merged.topRow > padded.end;\n if (overlapsViewport && anchorOutsidePadded && !this.rowHidden[merged.topRow]) {\n rows.add(merged.topRow);\n }\n }\n }\n return Array.from(rows).sort((a, b) => a - b);\n }\n\n public getVisibleColumnIndices(): number[] {\n const padded = this.getVisibleColumnRange();\n const viewportCols = this.getVisibleColumnRange(0);\n const viewportRows = this.getVisibleRowRange(0);\n const columns = new Set<number>();\n for (let c = padded.start; c <= padded.end; c += 1) {\n columns.add(c);\n }\n if (this.merges.anchorCount > 0) {\n for (const merged of this.merges.iterateAnchors()) {\n const overlapsViewport =\n merged.bottomRow >= viewportRows.start &&\n merged.topRow <= viewportRows.end &&\n merged.rightColumn >= viewportCols.start &&\n merged.leftColumn <= viewportCols.end;\n const anchorOutsidePadded =\n merged.leftColumn < padded.start || merged.leftColumn > padded.end;\n if (overlapsViewport && anchorOutsidePadded) {\n columns.add(merged.leftColumn);\n }\n }\n }\n return Array.from(columns).sort((a, b) => a - b);\n }\n\n getColumnResizeHandle(x: number, y: number, tolerance = HEADER_RESIZE_TOLERANCE): number | null {\n if (y < 0 || y > this.headerRowHeight) {\n return null;\n }\n if (x < this.headerColumnWidth) {\n return null;\n }\n this.ensureBoundaries();\n const frozenWidth = this.getFrozenWidth();\n for (let i = 1; i < this.columnBoundaries.length; i += 1) {\n let boundaryX: number;\n if (i <= this.frozenColumns) {\n boundaryX = this.headerColumnWidth + this.columnBoundaries[i];\n } else {\n boundaryX = this.headerColumnWidth + frozenWidth + (this.columnBoundaries[i] - (this.columnBoundaries[this.frozenColumns] ?? 0)) - this.scrollX;\n }\n if (Math.abs(boundaryX - x) <= tolerance) {\n return Math.min(i - 1, this.columns - 1);\n }\n }\n return null;\n }\n\n getRowResizeHandle(x: number, y: number, tolerance = HEADER_RESIZE_TOLERANCE): number | null {\n if (x < 0 || x > this.headerColumnWidth) {\n return null;\n }\n if (y < this.headerRowHeight) {\n return null;\n }\n this.ensureBoundaries();\n const frozenHeight = this.getFrozenHeight();\n for (let i = 1; i < this.rowBoundaries.length; i += 1) {\n let boundaryY: number;\n if (i <= this.frozenRows) {\n boundaryY = this.headerRowHeight + this.rowBoundaries[i];\n } else {\n boundaryY = this.headerRowHeight + frozenHeight + (this.rowBoundaries[i] - (this.rowBoundaries[this.frozenRows] ?? 0)) - this.scrollY;\n }\n if (Math.abs(boundaryY - y) <= tolerance) {\n return Math.min(i - 1, this.rows - 1);\n }\n }\n return null;\n }\n\n getColumnStart(column: number): number {\n this.ensureBoundaries();\n const clamped = Math.max(0, Math.min(column, this.columnBoundaries.length - 1));\n return this.headerColumnWidth + this.columnBoundaries[clamped];\n }\n\n getRowStart(row: number): number {\n this.ensureBoundaries();\n const clamped = Math.max(0, Math.min(row, this.rowBoundaries.length - 1));\n return this.headerRowHeight + this.rowBoundaries[clamped];\n }\n\n // ---------------------------------------------------------------------------\n // Cell data\n // ---------------------------------------------------------------------------\n\n getCellInput(row: number, column: number): string | undefined {\n return this.cellInputs.get(cellKey(row, column));\n }\n\n protected getRichTextRuns(row: number, column: number): RichTextRun[] | undefined {\n return this.cellRichText.get(cellKey(row, column));\n }\n\n setCellInput(row: number, column: number, value: string): void {\n const merged = this.getMergedRange(row, column);\n const targetRow = merged ? merged.topRow : row;\n const targetColumn = merged ? merged.leftColumn : column;\n const key = cellKey(targetRow, targetColumn);\n this.cellRichText.delete(key);\n if (value.length === 0) {\n this.cellInputs.delete(key);\n } else {\n this.cellInputs.set(key, value);\n }\n this.formulaEngine.onInputChanged(targetRow, targetColumn, value);\n this.updateCellDisplayValue(targetRow, targetColumn);\n this.render();\n this.emitCellValueChange(targetRow, targetColumn);\n }\n\n // ---------------------------------------------------------------------------\n // Number formats\n // ---------------------------------------------------------------------------\n\n setCellNumberFormat(row: number, column: number, formatCode: string): void {\n const key = cellKey(row, column);\n this.cellNumberFormats.set(key, formatCode);\n this.updateCellDisplayValue(row, column);\n this.render();\n }\n\n getCellNumberFormat(row: number, column: number): string | undefined {\n return this.cellNumberFormats.get(cellKey(row, column));\n }\n\n clearCellNumberFormat(row: number, column: number): void {\n const key = cellKey(row, column);\n this.cellNumberFormats.delete(key);\n this.cellDisplayOverrides.delete(key);\n this.render();\n }\n\n // ---------------------------------------------------------------------------\n // Cell types\n // ---------------------------------------------------------------------------\n\n setCellType(row: number, col: number, config: CellTypeConfig): void {\n this.cellTypeRegistry.set(row, col, config);\n this.render();\n }\n\n getCellType(row: number, col: number): CellTypeConfig | undefined {\n return this.cellTypeRegistry.get(row, col);\n }\n\n clearCellType(row: number, col: number): void {\n this.cellTypeRegistry.clear(row, col);\n this.render();\n }\n\n // ---------------------------------------------------------------------------\n // Header dropdowns\n // ---------------------------------------------------------------------------\n\n setHeaderDropdown(column: number, config: DropdownConfig | null): void {\n if (config) {\n this.headerDropdowns.set(column, config);\n } else {\n this.headerDropdowns.delete(column);\n }\n this.render();\n }\n\n getHeaderDropdown(column: number): DropdownConfig | undefined {\n return this.headerDropdowns.get(column);\n }\n\n hasHeaderDropdown(column: number): boolean {\n return this.headerDropdowns.has(column);\n }\n\n /** Check if a screen X coordinate hits the dropdown button area of a cell. */\n isDropdownButtonHit(row: number, column: number, screenX: number): boolean {\n const cellRect = this.getCellRect(row, column);\n return screenX >= cellRect.x + cellRect.width - DROPDOWN_BUTTON_WIDTH;\n }\n\n loadCells(cells: Iterable<CellInputValue>): void {\n this.cellInputs.clear();\n this.cellRichText.clear();\n this.cellDisplayOverrides.clear();\n this.cellNumberFormats.clear();\n this.cellFormatting.clear();\n const changedCells: CellInputValue[] = [];\n for (const cell of cells) {\n if (!this.isCellInBounds(cell.row, cell.column)) {\n continue;\n }\n const normalized = cell.value ?? '';\n const hasValue = normalized.length > 0;\n const hasFormatting =\n !!cell.style || !!cell.displayValue || !!cell.richText?.length || !!cell.numberFormat;\n if (!hasValue && !hasFormatting) {\n continue;\n }\n const key = cellKey(cell.row, cell.column);\n if (hasValue) {\n this.cellInputs.set(key, normalized);\n }\n if (cell.richText && cell.richText.length > 0) {\n this.cellRichText.set(\n key,\n cell.richText.map((run) => ({ ...run })),\n );\n }\n if (cell.numberFormat) {\n this.cellNumberFormats.set(key, cell.numberFormat);\n }\n this.updateCellDisplayValue(cell.row, cell.column, cell.displayValue);\n if (cell.style) {\n this.setCellFormatting(cell.row, cell.column, cell.style);\n }\n if (hasValue) {\n changedCells.push({ row: cell.row, column: cell.column, value: normalized });\n }\n }\n this.formulaEngine.rebuildAll();\n this.render();\n for (const cell of changedCells) {\n this.emitCellValueChange(cell.row, cell.column);\n }\n const active = this.selection.getActiveCell();\n if (active) {\n this.emitCellValueChange(active.row, active.column);\n }\n }\n\n private updateCellDisplayValue(row: number, column: number, fallback?: string): void {\n const key = cellKey(row, column);\n const raw = this.cellInputs.get(key);\n const formatCode = this.cellNumberFormats.get(key);\n let display: string | null | undefined;\n if (formatCode && raw !== undefined) {\n const numeric = Number(raw);\n if (Number.isFinite(numeric)) {\n display = formatValueWithFormat(numeric, formatCode);\n } else if (isDateFormatSection(formatCode)) {\n const d = new Date(raw);\n if (!isNaN(d.getTime())) {\n display = formatValueWithFormat(d, formatCode);\n }\n }\n }\n if ((display === null || display === undefined) && fallback !== undefined) {\n display = fallback;\n }\n if (display && display.length > 0) {\n this.cellDisplayOverrides.set(key, display);\n } else {\n this.cellDisplayOverrides.delete(key);\n }\n }\n\n protected getCellText(row: number, column: number): string | null {\n const key = cellKey(row, column);\n if (this.cellDisplayOverrides.has(key)) {\n const display = this.cellDisplayOverrides.get(key) ?? '';\n return display.length ? display : null;\n }\n const value = this.formulaEngine.getDisplayValue(row, column);\n return value && value.length > 0 ? value : null;\n }\n\n // ---------------------------------------------------------------------------\n // Cell style\n // ---------------------------------------------------------------------------\n\n getCellRawStyle(row: number, column: number): Partial<CellStyle> | undefined {\n const key = cellKey(row, column);\n const style = this.cellFormatting.get(key);\n return style ? { ...style } : undefined;\n }\n\n replaceCellStyle(row: number, column: number, style: Partial<CellStyle> | undefined): void {\n const key = cellKey(row, column);\n if (style === undefined || Object.keys(style).length === 0) {\n this.cellFormatting.delete(key);\n } else {\n this.cellFormatting.set(key, { ...style });\n }\n this.render();\n }\n\n clearCellStyle(row: number, column: number): void {\n const key = cellKey(row, column);\n this.cellFormatting.delete(key);\n this.render();\n }\n\n getComputedCellStyle(row: number, column: number): CellStyle {\n const key = cellKey(row, column);\n const formatting = this.cellFormatting.get(key);\n return {\n fontFamily: formatting?.fontFamily ?? this.defaultStyle.fontFamily,\n fontSize: formatting?.fontSize ?? this.defaultStyle.fontSize,\n bold: formatting?.bold ?? this.defaultStyle.bold,\n italic: formatting?.italic ?? this.defaultStyle.italic,\n underline: formatting?.underline ?? this.defaultStyle.underline,\n backgroundColor: formatting?.backgroundColor ?? this.defaultStyle.backgroundColor,\n color: formatting?.color ?? this.defaultStyle.color,\n textAlign: formatting?.textAlign ?? this.defaultStyle.textAlign,\n verticalAlign: formatting?.verticalAlign ?? this.defaultStyle.verticalAlign,\n textWrapMode: formatting?.textWrapMode ?? this.defaultStyle.textWrapMode,\n };\n }\n\n getActiveCellStyle(): CellStyle {\n const active = this.selection.getActiveCell();\n if (!active) {\n return { ...this.defaultStyle };\n }\n return this.getComputedCellStyle(active.row, active.column);\n }\n\n getDefaultCellStyle(): CellStyle {\n return { ...this.defaultStyle };\n }\n\n setCellStyle(row: number, column: number, style: Partial<CellStyle>): void {\n if (!this.isCellInBounds(row, column)) {\n throw new Error(`Cell (${row}, ${column}) is outside of the worksheet bounds.`);\n }\n this.setCellFormatting(row, column, style);\n this.render();\n }\n\n private setCellFormatting(row: number, column: number, style: Partial<CellStyle>): void {\n const key = cellKey(row, column);\n const existing = this.cellFormatting.get(key) ?? {};\n const next: Partial<CellStyle> = { ...existing, ...style };\n const cleaned: Partial<CellStyle> = {};\n if (next.fontFamily !== undefined) { cleaned.fontFamily = next.fontFamily; }\n if (next.fontSize !== undefined) { cleaned.fontSize = next.fontSize; }\n if (next.bold !== undefined) { cleaned.bold = next.bold; }\n if (next.italic !== undefined) { cleaned.italic = next.italic; }\n if (next.underline !== undefined) { cleaned.underline = next.underline; }\n if (next.backgroundColor !== undefined) { cleaned.backgroundColor = next.backgroundColor; }\n if (next.color !== undefined) { cleaned.color = next.color; }\n if (next.textAlign !== undefined) { cleaned.textAlign = next.textAlign; }\n if (next.verticalAlign !== undefined) { cleaned.verticalAlign = next.verticalAlign; }\n if (next.textWrapMode !== undefined) { cleaned.textWrapMode = next.textWrapMode; }\n const hasFormatting = Object.keys(cleaned).length > 0;\n if (!hasFormatting) {\n this.cellFormatting.delete(key);\n } else {\n this.cellFormatting.set(key, cleaned);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Selection style operations\n // ---------------------------------------------------------------------------\n\n setSelectionFontFamily(fontFamily: string): void {\n this.applyToSelection((row, column) => { this.setCellFormatting(row, column, { fontFamily }); });\n this.render();\n }\n\n setSelectionFontSize(fontSize: number): void {\n this.applyToSelection((row, column) => { this.setCellFormatting(row, column, { fontSize }); });\n this.render();\n }\n\n setSelectionFontBold(enabled: boolean): void {\n this.applyToSelection((row, column) => { this.setCellFormatting(row, column, { bold: enabled }); });\n this.render();\n }\n\n setSelectionFontItalic(enabled: boolean): void {\n this.applyToSelection((row, column) => { this.setCellFormatting(row, column, { italic: enabled }); });\n this.render();\n }\n\n setSelectionUnderline(enabled: boolean): void {\n this.applyToSelection((row, column) => { this.setCellFormatting(row, column, { underline: enabled }); });\n this.render();\n }\n\n setSelectionBackgroundColor(color: string): void {\n this.applyToSelection((row, column) => { this.setCellFormatting(row, column, { backgroundColor: color }); });\n this.render();\n }\n\n setSelectionHorizontalAlignment(alignment: TextAlign): void {\n this.applyToSelection((row, column) => { this.setCellFormatting(row, column, { textAlign: alignment }); });\n this.render();\n }\n\n setSelectionVerticalAlignment(alignment: VerticalAlign): void {\n this.applyToSelection((row, column) => { this.setCellFormatting(row, column, { verticalAlign: alignment }); });\n this.render();\n }\n\n setSelectionTextWrapMode(mode: TextWrapMode): void {\n this.applyToSelection((row, column) => { this.setCellFormatting(row, column, { textWrapMode: mode }); });\n this.render();\n }\n\n setRangeBackgroundColor(\n topRow: number,\n leftColumn: number,\n bottomRow: number,\n rightColumn: number,\n color: string,\n ): void {\n const bounds = this.normalizeRangeBounds(topRow, leftColumn, bottomRow, rightColumn);\n if (!bounds) {\n return;\n }\n for (let r = bounds.top; r <= bounds.bottom; r += 1) {\n for (let c = bounds.left; c <= bounds.right; c += 1) {\n this.setCellFormatting(r, c, { backgroundColor: color });\n }\n }\n this.render();\n }\n\n // ---------------------------------------------------------------------------\n // Selection\n // ---------------------------------------------------------------------------\n\n setSelectionRange(topRow: number, leftColumn: number, bottomRow: number, rightColumn: number): void {\n const bounds = this.normalizeRangeBounds(topRow, leftColumn, bottomRow, rightColumn);\n if (!bounds) {\n return;\n }\n const expanded = this.merges.expandSelection(bounds);\n this.selection.setRange(expanded.top, expanded.left, expanded.bottom, expanded.right);\n this.render();\n this.notifySelectionChanged();\n }\n\n onSelectionChange(listener: SelectionChangeListener): () => void {\n this.selectionChangeListeners.add(listener);\n return () => {\n this.selectionChangeListeners.delete(listener);\n };\n }\n\n onCellValueChange(listener: CellValueChangeListener): () => void {\n this.cellValueListeners.add(listener);\n return () => {\n this.cellValueListeners.delete(listener);\n };\n }\n\n onContextMenu(listener: ContextMenuListener): () => void {\n this.contextMenuListeners.add(listener);\n return () => {\n this.contextMenuListeners.delete(listener);\n };\n }\n\n emitContextMenu(event: ContextMenuEvent): void {\n for (const listener of this.contextMenuListeners) {\n listener(event);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Cell protection\n // ---------------------------------------------------------------------------\n\n /** Whether the worksheet is in protected mode (all cells locked by default). */\n get protected(): boolean {\n return this._protected;\n }\n\n set protected(value: boolean) {\n this._protected = value;\n }\n\n /** Set an explicit lock state on a cell, overriding the worksheet default. */\n setCellLock(row: number, column: number, state: 'locked' | 'unlocked'): void {\n this.cellLockStates.set(cellKey(row, column), state);\n }\n\n /** Remove the explicit lock state from a cell, reverting to worksheet default. */\n clearCellLock(row: number, column: number): void {\n this.cellLockStates.delete(cellKey(row, column));\n }\n\n /** Get the explicit lock state of a cell, or `undefined` if inheriting from worksheet. */\n getCellLock(row: number, column: number): 'locked' | 'unlocked' | undefined {\n return this.cellLockStates.get(cellKey(row, column));\n }\n\n /** Set an explicit lock state on all cells in a range. */\n setRangeLock(\n topRow: number, leftColumn: number,\n bottomRow: number, rightColumn: number,\n state: 'locked' | 'unlocked',\n ): void {\n for (let r = topRow; r <= bottomRow; r++) {\n for (let c = leftColumn; c <= rightColumn; c++) {\n this.cellLockStates.set(cellKey(r, c), state);\n }\n }\n }\n\n /** Remove explicit lock states from all cells in a range. */\n clearRangeLock(\n topRow: number, leftColumn: number,\n bottomRow: number, rightColumn: number,\n ): void {\n for (let r = topRow; r <= bottomRow; r++) {\n for (let c = leftColumn; c <= rightColumn; c++) {\n this.cellLockStates.delete(cellKey(r, c));\n }\n }\n }\n\n /**\n * Resolve the effective protection state of a cell.\n * Explicit lock state takes precedence; otherwise inherits from `worksheet.protected`.\n */\n isCellProtected(row: number, column: number): boolean {\n const explicit = this.cellLockStates.get(cellKey(row, column));\n if (explicit === 'locked') return true;\n if (explicit === 'unlocked') return false;\n return this._protected;\n }\n\n /** Returns `true` if any cell in the range is protected. */\n isRangeProtected(\n topRow: number, leftColumn: number,\n bottomRow: number, rightColumn: number,\n ): boolean {\n for (let r = topRow; r <= bottomRow; r++) {\n for (let c = leftColumn; c <= rightColumn; c++) {\n if (this.isCellProtected(r, c)) return true;\n }\n }\n return false;\n }\n\n onProtectedCellEdit(listener: ProtectedCellEditListener): () => void {\n this.protectedCellEditListeners.add(listener);\n return () => {\n this.protectedCellEditListeners.delete(listener);\n };\n }\n\n emitProtectedCellEdit(row: number, column: number): void {\n for (const listener of this.protectedCellEditListeners) {\n listener({ row, column });\n }\n }\n\n notifySelectionChanged(): void {\n this.emitSelectionChange();\n }\n\n isActiveCell(row: number, column: number): boolean {\n const active = this.selection.getActiveCell();\n return !!active && active.row === row && active.column === column;\n }\n\n private applyToSelection(callback: (row: number, column: number) => void): void {\n const bounds = this.selection.getNormalizedBounds();\n if (!bounds) {\n const active = this.selection.getActiveCell();\n if (active) {\n callback(active.row, active.column);\n return;\n }\n this.selection.begin(0, 0);\n this.emitSelectionChange();\n callback(0, 0);\n return;\n }\n for (let r = bounds.topRow; r <= bounds.bottomRow; r += 1) {\n for (let c = bounds.leftColumn; c <= bounds.rightColumn; c += 1) {\n callback(r, c);\n }\n }\n }\n\n // ---------------------------------------------------------------------------\n // Merge management (delegates to MergeManager)\n // ---------------------------------------------------------------------------\n\n setMergedRanges(ranges: Iterable<MergedCellRange>): void {\n this.merges.setAll(ranges);\n this.render();\n }\n\n mergeCells(topRow: number, leftColumn: number, bottomRow: number, rightColumn: number): void {\n this.merges.add(topRow, leftColumn, bottomRow, rightColumn);\n this.render();\n }\n\n unmergeCells(topRow: number, leftColumn: number, bottomRow: number, rightColumn: number): void {\n if (this.merges.remove(topRow, leftColumn, bottomRow, rightColumn)) {\n this.render();\n }\n }\n\n clearMergedRanges(): void {\n if (this.merges.clear()) {\n this.render();\n }\n }\n\n getMergedRange(row: number, column: number): MergedCellRange | null {\n return this.merges.get(row, column);\n }\n\n isMergedCellAnchor(row: number, column: number): boolean {\n return this.merges.isAnchor(row, column);\n }\n\n getCellMergeBounds(row: number, column: number): {\n topRow: number;\n bottomRow: number;\n leftColumn: number;\n rightColumn: number;\n } {\n return this.merges.getBounds(row, column);\n }\n\n expandSelectionWithMergedCells(bounds: {\n top: number;\n bottom: number;\n left: number;\n right: number;\n }): { top: number; bottom: number; left: number; right: number } {\n return this.merges.expandSelection(bounds);\n }\n\n protected getMergedLineGaps(): {\n horizontal: Map<number, Array<{ startColumnBoundary: number; endColumnBoundary: number }>>;\n vertical: Map<number, Array<{ startRowBoundary: number; endRowBoundary: number }>>;\n } {\n return this.merges.getMergedLineGaps();\n }\n\n // ---------------------------------------------------------------------------\n // Border management (delegates to BorderManager)\n // ---------------------------------------------------------------------------\n\n getCellBorder(row: number, column: number): CellBorderDefinition | undefined {\n return this.borders.getCell(row, column);\n }\n\n applyCellBorders(borders: Map<string, CellBorderDefinition>): void {\n this.borders.applyAll(borders);\n this.render();\n }\n\n setRangeBorder(\n topRow: number,\n leftColumn: number,\n bottomRow: number,\n rightColumn: number,\n border: BorderLineOptions,\n sides?: RangeBorderSide[],\n ): void {\n this.borders.setRange(topRow, leftColumn, bottomRow, rightColumn, border, sides);\n this.render();\n }\n\n // ---------------------------------------------------------------------------\n // Column/row sizing\n // ---------------------------------------------------------------------------\n\n getColumnWidth(column: number): number {\n if (column < 0 || column >= this.columns) {\n return DEFAULT_COLUMN_WIDTH;\n }\n return this.columnWidths[column];\n }\n\n setColumnWidth(column: number, width: number): void {\n if (column < 0 || column >= this.columns) {\n return;\n }\n const normalizedWidth = Math.max(MIN_COLUMN_WIDTH, width);\n if (this.columnWidths[column] === normalizedWidth) {\n return;\n }\n this.columnWidths[column] = normalizedWidth;\n this.columnCustomWidths[column] = true;\n this.render();\n this.emitStructureChange();\n }\n\n getRowHeight(row: number): number {\n if (row < 0 || row >= this.rows) {\n return DEFAULT_ROW_HEIGHT;\n }\n return this.rowHeights[row];\n }\n\n setRowHeight(row: number, height: number): void {\n if (row < 0 || row >= this.rows) {\n return;\n }\n const normalizedHeight = Math.max(MIN_ROW_HEIGHT, height);\n if (this.rowHeights[row] === normalizedHeight) {\n return;\n }\n this.rowHeights[row] = normalizedHeight;\n this.rowCustomHeights[row] = true;\n this.render();\n this.emitStructureChange();\n }\n\n applyColumnWidths(\n widths: Map<number, number>,\n options?: { customColumns?: Set<number>; enforceMinColumnWidth?: boolean },\n ): void {\n let changed = false;\n for (let column = 0; column < this.columns; column += 1) {\n const width = widths.get(column);\n const minWidth = options?.enforceMinColumnWidth ?? true ? MIN_COLUMN_WIDTH : 0;\n const normalized = Math.max(minWidth, width ?? DEFAULT_COLUMN_WIDTH);\n if (this.columnWidths[column] !== normalized) {\n this.columnWidths[column] = normalized;\n changed = true;\n }\n if (options?.customColumns) {\n this.columnCustomWidths[column] = options.customColumns.has(column);\n }\n }\n if (changed) {\n this.updateBoundaries();\n this.emitStructureChange();\n }\n }\n\n applyRowHeights(heights: Map<number, number>, options?: { customRows?: Set<number> }): void {\n let changed = false;\n for (let row = 0; row < this.rows; row += 1) {\n const height = heights.get(row);\n const normalized = Math.max(MIN_ROW_HEIGHT, height ?? DEFAULT_ROW_HEIGHT);\n if (this.rowHeights[row] !== normalized) {\n this.rowHeights[row] = normalized;\n if (options?.customRows?.has(row)) {\n this.rowCustomHeights[row] = true;\n }\n changed = true;\n } else if (options?.customRows?.has(row)) {\n this.rowCustomHeights[row] = true;\n }\n }\n if (changed) {\n this.updateBoundaries();\n this.emitStructureChange();\n }\n }\n\n autoFitColumns(options: { columns?: number[]; respectCustomWidth?: boolean } = {}): void {\n const respectCustom = options.respectCustomWidth ?? true;\n const targetColumns =\n options.columns ?? Array.from({ length: this.columns }, (_, index) => index);\n let changed = false;\n for (const column of targetColumns) {\n if (column < 0 || column >= this.columns) {\n continue;\n }\n if (respectCustom && this.columnCustomWidths[column]) {\n continue;\n }\n const measured = this.measureColumnWidth(column);\n const normalized = Math.max(MIN_COLUMN_WIDTH, measured);\n if (Math.abs(normalized - this.columnWidths[column]) > 0.5) {\n this.columnWidths[column] = normalized;\n this.columnCustomWidths[column] = true;\n changed = true;\n }\n }\n if (changed) {\n this.updateBoundaries();\n this.emitStructureChange();\n this.render();\n }\n }\n\n autoFitRows(options: { rows?: number[]; respectCustomHeight?: boolean } = {}): void {\n const respectCustom = options.respectCustomHeight ?? true;\n const targetRows =\n options.rows ?? Array.from({ length: this.rows }, (_, index) => index);\n let changed = false;\n for (const row of targetRows) {\n if (row < 0 || row >= this.rows) {\n continue;\n }\n if (respectCustom && this.rowCustomHeights[row]) {\n continue;\n }\n const measured = this.measureRowHeight(row);\n const normalized = Math.max(DEFAULT_ROW_HEIGHT, measured);\n if (Math.abs(normalized - this.rowHeights[row]) > 0.5) {\n this.rowHeights[row] = normalized;\n changed = true;\n }\n }\n if (changed) {\n this.updateBoundaries();\n this.emitStructureChange();\n this.render();\n }\n }\n\n protected measureColumnWidth(_column: number): number {\n return MIN_COLUMN_WIDTH;\n }\n\n protected measureRowHeight(_row: number): number {\n return DEFAULT_ROW_HEIGHT;\n }\n\n protected measureCellContentHeight(_row: number, _column: number, _style: CellStyle): number {\n return 0;\n }\n\n protected measureCellContentWidth(_row: number, _column: number, _style: CellStyle): number {\n return MIN_COLUMN_WIDTH;\n }\n\n // ---------------------------------------------------------------------------\n // Row visibility\n // ---------------------------------------------------------------------------\n\n isRowHidden(row: number): boolean {\n if (row < 0 || row >= this.rows) {\n return false;\n }\n return this.rowHidden[row];\n }\n\n setRowHidden(row: number, hidden: boolean): void {\n if (row < 0 || row >= this.rows) {\n return;\n }\n if (this.rowHidden[row] === hidden) {\n return;\n }\n this.rowHidden[row] = hidden;\n this.updateBoundaries();\n this.render();\n this.emitStructureChange();\n }\n\n setRowsHidden(rows: number[], hidden: boolean): void {\n let changed = false;\n for (const row of rows) {\n if (row >= 0 && row < this.rows && this.rowHidden[row] !== hidden) {\n this.rowHidden[row] = hidden;\n changed = true;\n }\n }\n if (changed) {\n this.updateBoundaries();\n this.render();\n this.emitStructureChange();\n }\n }\n\n // ---------------------------------------------------------------------------\n // Column visibility\n // ---------------------------------------------------------------------------\n\n isColumnHidden(column: number): boolean {\n if (column < 0 || column >= this.columns) {\n return false;\n }\n return this.columnHidden[column];\n }\n\n setColumnHidden(column: number, hidden: boolean): void {\n if (column < 0 || column >= this.columns) {\n return;\n }\n if (this.columnHidden[column] === hidden) {\n return;\n }\n this.columnHidden[column] = hidden;\n this.updateBoundaries();\n this.render();\n this.emitStructureChange();\n }\n\n setColumnsHidden(columns: number[], hidden: boolean): void {\n let changed = false;\n for (const col of columns) {\n if (col >= 0 && col < this.columns && this.columnHidden[col] !== hidden) {\n this.columnHidden[col] = hidden;\n changed = true;\n }\n }\n if (changed) {\n this.updateBoundaries();\n this.render();\n this.emitStructureChange();\n }\n }\n\n // ---------------------------------------------------------------------------\n // Outline (Group/Ungroup)\n // ---------------------------------------------------------------------------\n\n private static readonly OUTLINE_LEVEL_SIZE = 16;\n private static readonly OUTLINE_PANEL_PADDING = 8;\n\n getRowOutlines(): OutlineManager {\n return this.rowOutlines;\n }\n\n getColumnOutlines(): OutlineManager {\n return this.columnOutlines;\n }\n\n /** Width of the row outline panel (left of row headers). 0 if no row outlines. */\n getOutlinePanelWidth(): number {\n const levels = this.rowOutlines.getLevelCount();\n if (levels === 0) return 0;\n return levels * Worksheet.OUTLINE_LEVEL_SIZE + Worksheet.OUTLINE_PANEL_PADDING;\n }\n\n /** Height of the column outline panel (above column headers). 0 if no column outlines. */\n getOutlinePanelHeight(): number {\n const levels = this.columnOutlines.getLevelCount();\n if (levels === 0) return 0;\n return levels * Worksheet.OUTLINE_LEVEL_SIZE + Worksheet.OUTLINE_PANEL_PADDING;\n }\n\n /** Recalculate header sizes based on outline levels */\n private updateHeaderSizes(): void {\n this.headerColumnWidth = HEADER_COLUMN_WIDTH + this.getOutlinePanelWidth();\n this.headerRowHeight = HEADER_ROW_HEIGHT + this.getOutlinePanelHeight();\n }\n\n /** Apply outline hidden state to row/column hidden arrays */\n private syncOutlineHidden(): void {\n // Sync row outline hidden state\n const rowHidden = this.rowOutlines.getHiddenIndices();\n for (let r = 0; r < this.rows; r++) {\n this.rowHidden[r] = rowHidden.has(r);\n }\n // Sync column outline hidden state\n const colHidden = this.columnOutlines.getHiddenIndices();\n for (let c = 0; c < this.columns; c++) {\n this.columnHidden[c] = colHidden.has(c);\n }\n }\n\n groupRows(startRow: number, endRow: number): void {\n const count = endRow - startRow + 1;\n if (count <= 0) return;\n this.rowOutlines.addGroup(startRow, count);\n this.updateHeaderSizes();\n this.updateBoundaries();\n this.emitStructureChange();\n this.render();\n }\n\n ungroupRows(startRow: number, endRow: number): void {\n const count = endRow - startRow + 1;\n if (count <= 0) return;\n this.rowOutlines.removeGroup(startRow, count);\n this.updateHeaderSizes();\n this.updateBoundaries();\n this.emitStructureChange();\n this.render();\n }\n\n groupColumns(startColumn: number, endColumn: number): void {\n const count = endColumn - startColumn + 1;\n if (count <= 0) return;\n this.columnOutlines.addGroup(startColumn, count);\n this.updateHeaderSizes();\n this.updateBoundaries();\n this.emitStructureChange();\n this.render();\n }\n\n ungroupColumns(startColumn: number, endColumn: number): void {\n const count = endColumn - startColumn + 1;\n if (count <= 0) return;\n this.columnOutlines.removeGroup(startColumn, count);\n this.updateHeaderSizes();\n this.updateBoundaries();\n this.emitStructureChange();\n this.render();\n }\n\n collapseRowOutline(level: number, start: number): void {\n this.rowOutlines.collapseGroup(level, start);\n this.syncOutlineHidden();\n this.updateBoundaries();\n this.emitStructureChange();\n this.render();\n }\n\n expandRowOutline(level: number, start: number): void {\n this.rowOutlines.expandGroup(level, start);\n this.syncOutlineHidden();\n this.updateBoundaries();\n this.emitStructureChange();\n this.render();\n }\n\n collapseColumnOutline(level: number, start: number): void {\n this.columnOutlines.collapseGroup(level, start);\n this.syncOutlineHidden();\n this.updateBoundaries();\n this.emitStructureChange();\n this.render();\n }\n\n expandColumnOutline(level: number, start: number): void {\n this.columnOutlines.expandGroup(level, start);\n this.syncOutlineHidden();\n this.updateBoundaries();\n this.emitStructureChange();\n this.render();\n }\n\n collapseRowsToLevel(level: number): void {\n this.rowOutlines.collapseToLevel(level);\n this.syncOutlineHidden();\n this.updateBoundaries();\n this.emitStructureChange();\n this.render();\n }\n\n collapseColumnsToLevel(level: number): void {\n this.columnOutlines.collapseToLevel(level);\n this.syncOutlineHidden();\n this.updateBoundaries();\n this.emitStructureChange();\n this.render();\n }\n\n // ---------------------------------------------------------------------------\n // Row/column insert & delete\n // ---------------------------------------------------------------------------\n\n insertRows(index: number, count: number): void {\n if (count <= 0 || index < 0 || index > this.rows) return;\n\n // 1. Shift cell data maps\n this.shiftCellDataMaps('row', index, count);\n\n // 2. Splice row arrays\n this.rowHeights.splice(index, 0, ...new Array(count).fill(DEFAULT_ROW_HEIGHT));\n this.rowCustomHeights.splice(index, 0, ...new Array(count).fill(false));\n this.rowHidden.splice(index, 0, ...new Array(count).fill(false));\n this.rows += count;\n\n // 3. Shift merges and borders\n this.merges.shiftRanges('row', index, count);\n this.borders.shiftBorders('row', index, count);\n\n // 4. Update formula references (must happen after cellInputs are shifted)\n this.formulaEngine.onStructureChange('row', index, count);\n this.rowOutlines.shiftGroups(index, count);\n\n // 5. Adjust frozen panes\n if (this.frozenRows > 0 && index <= this.frozenRows) {\n this.frozenRows = Math.min(this.frozenRows + count, this.rows - 1);\n }\n\n this.updateBoundaries();\n this.emitStructureChange();\n this.render();\n }\n\n insertColumns(index: number, count: number): void {\n if (count <= 0 || index < 0 || index > this.columns) return;\n\n this.shiftCellDataMaps('column', index, count);\n\n this.columnWidths.splice(index, 0, ...new Array(count).fill(DEFAULT_COLUMN_WIDTH));\n this.columnCustomWidths.splice(index, 0, ...new Array(count).fill(false));\n this.columnHidden.splice(index, 0, ...new Array(count).fill(false));\n this.columns += count;\n\n this.merges.shiftRanges('column', index, count);\n this.borders.shiftBorders('column', index, count);\n this.formulaEngine.onStructureChange('column', index, count);\n this.columnOutlines.shiftGroups(index, count);\n\n if (this.frozenColumns > 0 && index <= this.frozenColumns) {\n this.frozenColumns = Math.min(this.frozenColumns + count, this.columns - 1);\n }\n\n this.updateBoundaries();\n this.emitStructureChange();\n this.render();\n }\n\n deleteRows(index: number, count: number): void {\n if (count <= 0 || index < 0 || index >= this.rows) return;\n count = Math.min(count, this.rows - index);\n if (this.rows - count < 1) return; // must keep at least 1 row\n\n // 1. Shift cell data maps (removes entries in deleted range, shifts the rest)\n this.shiftCellDataMaps('row', index, -count);\n\n // 2. Splice row arrays\n this.rowHeights.splice(index, count);\n this.rowCustomHeights.splice(index, count);\n this.rowHidden.splice(index, count);\n this.rows -= count;\n\n // 3. Shift merges and borders\n this.merges.shiftRanges('row', index, -count);\n this.borders.shiftBorders('row', index, -count);\n\n // 4. Update formula references\n this.formulaEngine.onStructureChange('row', index, -count);\n this.rowOutlines.shiftGroups(index, -count);\n\n // 5. Adjust frozen panes\n if (this.frozenRows > 0) {\n if (index < this.frozenRows) {\n const frozenDeleted = Math.min(count, this.frozenRows - index);\n this.frozenRows = Math.max(0, this.frozenRows - frozenDeleted);\n }\n }\n\n this.clampSelectionToBounds();\n this.updateBoundaries();\n this.emitStructureChange();\n this.render();\n }\n\n deleteColumns(index: number, count: number): void {\n if (count <= 0 || index < 0 || index >= this.columns) return;\n count = Math.min(count, this.columns - index);\n if (this.columns - count < 1) return;\n\n this.shiftCellDataMaps('column', index, -count);\n\n this.columnWidths.splice(index, count);\n this.columnCustomWidths.splice(index, count);\n this.columnHidden.splice(index, count);\n this.columns -= count;\n\n this.merges.shiftRanges('column', index, -count);\n this.borders.shiftBorders('column', index, -count);\n this.formulaEngine.onStructureChange('column', index, -count);\n this.columnOutlines.shiftGroups(index, -count);\n\n if (this.frozenColumns > 0) {\n if (index < this.frozenColumns) {\n const frozenDeleted = Math.min(count, this.frozenColumns - index);\n this.frozenColumns = Math.max(0, this.frozenColumns - frozenDeleted);\n }\n }\n\n this.clampSelectionToBounds();\n this.updateBoundaries();\n this.emitStructureChange();\n this.render();\n }\n\n /**\n * Write to cellInputs without triggering the formula engine.\n * Used by FormulaEngine.onStructureChange() to update formula strings\n * after reference shifting — avoids infinite recursion.\n */\n setCellInputDirect(row: number, column: number, value: string): void {\n const key = cellKey(row, column);\n if (value.length === 0) {\n this.cellInputs.delete(key);\n } else {\n this.cellInputs.set(key, value);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Row swap / permute (for sorting)\n // ---------------------------------------------------------------------------\n\n /**\n * Swap cell data between two rows within [startColumn, endColumn].\n * Swaps: cellInputs, cellRichText, cellDisplayOverrides, cellNumberFormats,\n * cellFormatting, borders. Does NOT swap rowHeight or rowHidden.\n * Does NOT trigger render — caller is responsible.\n */\n swapRows(rowA: number, rowB: number, startColumn: number, endColumn: number): void {\n if (rowA === rowB) return;\n for (let c = startColumn; c <= endColumn; c++) {\n const keyA = cellKey(rowA, c);\n const keyB = cellKey(rowB, c);\n this.swapMapEntries(this.cellInputs, keyA, keyB);\n this.swapMapEntries(this.cellRichText, keyA, keyB);\n this.swapMapEntries(this.cellDisplayOverrides, keyA, keyB);\n this.swapMapEntries(this.cellNumberFormats, keyA, keyB);\n this.swapMapEntries(this.cellFormatting, keyA, keyB);\n }\n this.borders.swapRowCells(rowA, rowB, startColumn, endColumn);\n }\n\n /**\n * Apply a row permutation within [startColumn, endColumn].\n * `targetRows[i]` receives the data currently at `sourceRows[i]`.\n * Both arrays must have the same length and targetRows must equal the\n * set of participating row positions (a permutation of sourceRows is NOT\n * required — sourceRows may list the same rows in a different order).\n *\n * Operates directly on internal Maps for performance — no per-cell\n * render(), formulaEngine, or event callbacks are triggered.\n * Caller must call formulaEngine.rebuildAll() and render() afterwards.\n */\n permuteRows(\n sourceRows: number[],\n targetRows: number[],\n startColumn: number,\n endColumn: number,\n ): void {\n const maps = [\n this.cellInputs,\n this.cellRichText,\n this.cellDisplayOverrides,\n this.cellNumberFormats,\n this.cellFormatting,\n ] as Map<string, unknown>[];\n\n // Phase 1: Extract all source row data from every map\n const savedData: Map<string, unknown>[][] = [];\n for (let i = 0; i < sourceRows.length; i++) {\n const row = sourceRows[i];\n const perMap: Map<string, unknown>[] = [];\n for (const map of maps) {\n const entries = new Map<string, unknown>();\n for (let c = startColumn; c <= endColumn; c++) {\n const key = cellKey(row, c);\n const val = map.get(key);\n if (val !== undefined) entries.set(String(c), val);\n }\n perMap.push(entries);\n }\n savedData.push(perMap);\n }\n // Borders\n const savedBorders: Map<string, unknown>[] = [];\n for (let i = 0; i < sourceRows.length; i++) {\n const row = sourceRows[i];\n const entries = new Map<string, unknown>();\n for (let c = startColumn; c <= endColumn; c++) {\n const key = cellKey(row, c);\n const val = this.borders.getData(key);\n if (val !== undefined) entries.set(String(c), val);\n }\n savedBorders.push(entries);\n }\n\n // Phase 2: Clear all target row cells\n for (const targetRow of targetRows) {\n for (let c = startColumn; c <= endColumn; c++) {\n const key = cellKey(targetRow, c);\n for (const map of maps) map.delete(key);\n this.borders.deleteData(key);\n }\n }\n\n // Phase 3: Write saved data into target positions\n for (let i = 0; i < targetRows.length; i++) {\n const targetRow = targetRows[i];\n for (let m = 0; m < maps.length; m++) {\n for (const [colStr, val] of savedData[i][m]) {\n maps[m].set(cellKey(targetRow, Number(colStr)), val);\n }\n }\n // Borders\n for (const [colStr, val] of savedBorders[i]) {\n this.borders.setData(cellKey(targetRow, Number(colStr)), val as any);\n }\n }\n }\n\n private swapMapEntries<V>(map: Map<string, V>, keyA: string, keyB: string): void {\n const valA = map.get(keyA);\n const valB = map.get(keyB);\n if (valA !== undefined) { map.set(keyB, valA); } else { map.delete(keyB); }\n if (valB !== undefined) { map.set(keyA, valB); } else { map.delete(keyA); }\n }\n\n /** Get all cell data in a range (for backup before deletion). */\n getRangeData(\n topRow: number, leftColumn: number, bottomRow: number, rightColumn: number,\n ): Map<string, {\n input?: string;\n richText?: RichTextRun[];\n displayOverride?: string;\n numberFormat?: string;\n formatting?: Partial<CellStyle>;\n }> {\n const data = new Map<string, {\n input?: string;\n richText?: RichTextRun[];\n displayOverride?: string;\n numberFormat?: string;\n formatting?: Partial<CellStyle>;\n }>();\n for (let r = topRow; r <= bottomRow; r++) {\n for (let c = leftColumn; c <= rightColumn; c++) {\n const key = cellKey(r, c);\n const entry: {\n input?: string;\n richText?: RichTextRun[];\n displayOverride?: string;\n numberFormat?: string;\n formatting?: Partial<CellStyle>;\n } = {};\n const input = this.cellInputs.get(key);\n if (input !== undefined) entry.input = input;\n const richText = this.cellRichText.get(key);\n if (richText !== undefined) entry.richText = richText.map(r => ({ ...r }));\n const display = this.cellDisplayOverrides.get(key);\n if (display !== undefined) entry.displayOverride = display;\n const numFmt = this.cellNumberFormats.get(key);\n if (numFmt !== undefined) entry.numberFormat = numFmt;\n const fmt = this.cellFormatting.get(key);\n if (fmt !== undefined) entry.formatting = { ...fmt };\n if (Object.keys(entry).length > 0) {\n data.set(key, entry);\n }\n }\n }\n return data;\n }\n\n /** Restore cell data from a backup (used by undo of delete operations). */\n restoreRangeData(data: Map<string, {\n input?: string;\n richText?: RichTextRun[];\n displayOverride?: string;\n numberFormat?: string;\n formatting?: Partial<CellStyle>;\n }>): void {\n for (const [key, entry] of data) {\n if (entry.input !== undefined) this.cellInputs.set(key, entry.input);\n if (entry.richText !== undefined) this.cellRichText.set(key, entry.richText);\n if (entry.displayOverride !== undefined) this.cellDisplayOverrides.set(key, entry.displayOverride);\n if (entry.numberFormat !== undefined) this.cellNumberFormats.set(key, entry.numberFormat);\n if (entry.formatting !== undefined) this.cellFormatting.set(key, entry.formatting);\n }\n this.formulaEngine.rebuildAll();\n }\n\n // ---------------------------------------------------------------------------\n // Grid size\n // ---------------------------------------------------------------------------\n\n setGridSize(rows: number, columns: number): void {\n const normalizedRows = Math.max(1, Math.floor(rows));\n const normalizedColumns = Math.max(1, Math.floor(columns));\n if (normalizedRows === this.rows && normalizedColumns === this.columns) {\n return;\n }\n this.rows = normalizedRows;\n this.columns = normalizedColumns;\n\n this.ensureArrayLength(this.columnWidths, normalizedColumns, DEFAULT_COLUMN_WIDTH);\n this.ensureArrayLength(this.columnCustomWidths, normalizedColumns, false);\n this.ensureArrayLength(this.rowHeights, normalizedRows, DEFAULT_ROW_HEIGHT);\n this.ensureArrayLength(this.rowCustomHeights, normalizedRows, false);\n this.ensureArrayLength(this.rowHidden, normalizedRows, false);\n this.ensureArrayLength(this.columnHidden, normalizedColumns, false);\n\n this.updateBoundaries();\n this.pruneCellDataOutsideGrid();\n this.merges.pruneOutsideGrid();\n this.clampSelectionToBounds();\n\n this.render();\n this.emitStructureChange();\n }\n\n // ---------------------------------------------------------------------------\n // Grid lines & resize guide\n // ---------------------------------------------------------------------------\n\n setShowGridLines(visible: boolean): void {\n if (this._showGridLines === visible) {\n return;\n }\n this._showGridLines = visible;\n this.render();\n }\n\n getShowGridLines(): boolean {\n return this._showGridLines;\n }\n\n protected shouldRenderGridLines(): boolean {\n return this._showGridLines;\n }\n\n // ---------------------------------------------------------------------------\n // Alternate row colors\n // ---------------------------------------------------------------------------\n\n setAlternateRowColors(colors: AlternateRowColors | null): void {\n this._alternateRowColors = colors;\n this.render();\n }\n\n getAlternateRowColors(): AlternateRowColors | null {\n return this._alternateRowColors;\n }\n\n setResizeGuide(\n guide: { type: 'column' | 'row'; position: number } | null,\n shouldRender = true,\n ): void {\n const existing = this.resizeGuide;\n const guidesMatch =\n existing !== null &&\n guide !== null &&\n existing.type === guide.type &&\n Math.abs(existing.position - guide.position) <= 1e-3;\n const shouldUpdate = !guidesMatch && guide !== existing;\n if (shouldUpdate) {\n this.resizeGuide = guide;\n } else if (guide === null && existing !== null) {\n this.resizeGuide = null;\n }\n if (shouldRender && (shouldUpdate || (guide === null && existing !== null))) {\n this.render();\n }\n }\n\n // ---------------------------------------------------------------------------\n // Unit conversion\n // ---------------------------------------------------------------------------\n\n getPixelRatio(): number {\n return this.pixelRatio;\n }\n\n pointsToPixels(points: number): number {\n if (!Number.isFinite(points)) {\n return this.pointToPixelRatio;\n }\n return Math.max(1, points * this.pointToPixelRatio);\n }\n\n // ---------------------------------------------------------------------------\n // Export\n // ---------------------------------------------------------------------------\n\n public getExportSnapshot(): WorksheetExportSnapshot {\n const cells = new Map<string, WorksheetExportCell>();\n const defaultStyle = this.getDefaultCellStyle();\n\n const getCellEntry = (row: number, column: number): WorksheetExportCell => {\n const key = cellKey(row, column);\n let entry = cells.get(key);\n if (!entry) {\n entry = { row, column };\n cells.set(key, entry);\n }\n return entry;\n };\n\n const styleMatchesDefault = (style: CellStyle): boolean =>\n style.fontFamily === defaultStyle.fontFamily &&\n style.fontSize === defaultStyle.fontSize &&\n style.bold === defaultStyle.bold &&\n style.italic === defaultStyle.italic &&\n style.underline === defaultStyle.underline &&\n style.backgroundColor === defaultStyle.backgroundColor &&\n style.color === defaultStyle.color &&\n style.textAlign === defaultStyle.textAlign &&\n style.verticalAlign === defaultStyle.verticalAlign &&\n style.textWrapMode === defaultStyle.textWrapMode;\n\n for (const [key, value] of this.cellInputs) {\n const position = parseCellKey(key);\n if (!position || !this.isCellInBounds(position.row, position.column)) {\n continue;\n }\n const entry = getCellEntry(position.row, position.column);\n entry.value = value;\n if (value.startsWith('=')) {\n const cached = this.formulaEngine.getCachedValue(position.row, position.column);\n if (cached !== undefined) {\n entry.cachedValue = cached;\n }\n }\n }\n\n for (const key of this.cellFormatting.keys()) {\n const position = parseCellKey(key);\n if (!position || !this.isCellInBounds(position.row, position.column)) {\n continue;\n }\n const computedStyle = this.getComputedCellStyle(position.row, position.column);\n if (styleMatchesDefault(computedStyle)) {\n continue;\n }\n getCellEntry(position.row, position.column).style = computedStyle;\n }\n\n const bordersCopy = new Map<string, CellBorderDefinition>();\n for (const [key, border] of this.borders.entries()) {\n bordersCopy.set(key, { ...border });\n }\n\n return {\n cells: Array.from(cells.values()),\n merges: this.merges.allAnchors().map((range) => ({ ...range })),\n borders: bordersCopy,\n columnWidths: [...this.columnWidths],\n rowHeights: [...this.rowHeights],\n rows: this.rows,\n columns: this.columns,\n frozenRows: this.frozenRows,\n frozenColumns: this.frozenColumns,\n };\n }\n\n // ---------------------------------------------------------------------------\n // Protected helpers (used by subclasses and SheetRendererContext)\n // ---------------------------------------------------------------------------\n\n protected parseCellKey(key: string): { row: number; column: number } | null {\n return parseCellKey(key);\n }\n\n // ---------------------------------------------------------------------------\n // Private helpers\n // ---------------------------------------------------------------------------\n\n private isCellInBounds(row: number, column: number): boolean {\n return row >= 0 && row < this.rows && column >= 0 && column < this.columns;\n }\n\n private clampRow(row: number): number {\n return Math.min(Math.max(Math.floor(row), 0), this.rows - 1);\n }\n\n private clampColumn(column: number): number {\n return Math.min(Math.max(Math.floor(column), 0), this.columns - 1);\n }\n\n normalizeRangeBounds(\n topRow: number,\n leftColumn: number,\n bottomRow: number,\n rightColumn: number,\n ): { top: number; left: number; bottom: number; right: number } | null {\n if (this.rows === 0 || this.columns === 0) {\n return null;\n }\n const r1 = this.clampRow(topRow);\n const r2 = this.clampRow(bottomRow);\n const c1 = this.clampColumn(leftColumn);\n const c2 = this.clampColumn(rightColumn);\n return {\n top: Math.min(r1, r2),\n bottom: Math.max(r1, r2),\n left: Math.min(c1, c2),\n right: Math.max(c1, c2),\n };\n }\n\n private clampSelectionToBounds(): void {\n const bounds = this.selection.getNormalizedBounds();\n if (bounds) {\n const topRow = Math.min(bounds.topRow, this.rows - 1);\n const bottomRow = Math.min(bounds.bottomRow, this.rows - 1);\n const leftColumn = Math.min(bounds.leftColumn, this.columns - 1);\n const rightColumn = Math.min(bounds.rightColumn, this.columns - 1);\n this.selection.setRange(topRow, leftColumn, bottomRow, rightColumn);\n return;\n }\n const active = this.selection.getActiveCell();\n if (active && !this.isCellInBounds(active.row, active.column)) {\n this.selection.begin(0, 0);\n }\n }\n\n /**\n * Shift keys in all cell data Maps when rows/columns are inserted or deleted.\n * count > 0 = insert, count < 0 = delete.\n */\n private shiftCellDataMaps(axis: 'row' | 'column', index: number, count: number): void {\n const maps: Map<string, unknown>[] = [\n this.cellInputs,\n this.cellRichText,\n this.cellDisplayOverrides,\n this.cellNumberFormats,\n this.cellFormatting,\n this.cellLockStates,\n ];\n for (const map of maps) {\n shiftCellDataMap(map, axis, index, count);\n }\n }\n\n private pruneCellDataOutsideGrid(): void {\n pruneMapOutsideGrid(this.cellInputs, this.rows, this.columns);\n pruneMapOutsideGrid(this.cellRichText, this.rows, this.columns);\n pruneMapOutsideGrid(this.cellDisplayOverrides, this.rows, this.columns);\n pruneMapOutsideGrid(this.cellNumberFormats, this.rows, this.columns);\n pruneMapOutsideGrid(this.cellFormatting, this.rows, this.columns);\n pruneMapOutsideGrid(this.cellLockStates, this.rows, this.columns);\n this.borders.pruneOutsideGrid();\n }\n\n private ensureArrayLength<T>(array: T[], target: number, fillValue: T): void {\n if (array.length > target) {\n array.length = target;\n return;\n }\n while (array.length < target) {\n array.push(fillValue);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Event emission\n // ---------------------------------------------------------------------------\n\n private emitSelectionChange(): void {\n const active = this.selection.getActiveCell();\n for (const listener of this.selectionChangeListeners) {\n listener(active ? { ...active } : null);\n }\n }\n\n private emitCellValueChange(row: number, column: number): void {\n const value = this.getCellInput(row, column) ?? '';\n for (const listener of this.cellValueListeners) {\n listener({ row, column, value });\n }\n }\n\n private emitViewportSizeChange(): void {\n const size = this.getScrollContentSize();\n for (const listener of this.viewportSizeListeners) {\n listener({ ...size });\n }\n }\n\n private emitScrollChange(): void {\n const offset = { x: this.scrollX, y: this.scrollY };\n for (const listener of this.scrollListeners) {\n listener({ ...offset });\n }\n }\n\n private emitStructureChange(): void {\n for (const listener of this.structureListeners) {\n listener();\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Standalone helper — shift keys in a Map<\"row:col\", V>\n// ---------------------------------------------------------------------------\n\nfunction shiftCellDataMap(\n map: Map<string, unknown>,\n axis: 'row' | 'column',\n index: number,\n count: number,\n): void {\n const entries = Array.from(map.entries());\n map.clear();\n\n for (const [key, value] of entries) {\n const pos = parseCellKey(key);\n if (!pos) continue;\n let { row, column } = pos;\n\n if (axis === 'row') {\n if (count < 0) {\n const deleteCount = -count;\n if (row >= index && row < index + deleteCount) continue; // deleted\n if (row >= index + deleteCount) row += count;\n } else {\n if (row >= index) row += count;\n }\n } else {\n if (count < 0) {\n const deleteCount = -count;\n if (column >= index && column < index + deleteCount) continue;\n if (column >= index + deleteCount) column += count;\n } else {\n if (column >= index) column += count;\n }\n }\n\n map.set(cellKey(row, column), value);\n }\n}\n","import type { RangeRect } from '../core/worksheet/types';\nimport type { AlternateRowColors } from '../core/worksheet/worksheet';\nimport type { CellStyle, TextAlign } from '../core/style/cellStyle';\nimport type { RichTextRun } from '../types/richText';\nimport type { MergedCellRange } from '../core/cell/types';\nimport type { CellBorderDefinition, BorderLine, BorderLineStyle } from '../core/border/types';\nimport type { BodyViewport, WorksheetViewports } from './viewports';\nimport type { CellTypeConfig } from '../core/cell/cellTypeRegistry';\nimport { getCellTypeHandler } from '../core/cell/cellTypeRegistry';\nimport type { OutlineGroup } from '../core/outline';\n\ntype RichTextLine = { runs: ResolvedRichRun[]; width: number; lineHeight: number; ascent: number };\ntype ResolvedRichRun = {\n text: string;\n fontFamily: string;\n fontSize: number;\n bold: boolean;\n italic: boolean;\n color: string;\n underline: boolean;\n};\n\ntype PendingHorizontalEdge = {\n boundaryIndex: number;\n fromColumn: number;\n toColumn: number;\n line: BorderLine;\n};\n\ntype PendingVerticalEdge = {\n boundaryIndex: number;\n fromRow: number;\n toRow: number;\n line: BorderLine;\n};\n\ntype MergedLineGaps = {\n horizontal: Map<number, Array<{ startColumnBoundary: number; endColumnBoundary: number }>>;\n vertical: Map<number, Array<{ startRowBoundary: number; endRowBoundary: number }>>;\n};\n\nexport interface SheetRendererContext {\n getContext(): CanvasRenderingContext2D;\n getPixelRatio(): number;\n getBodyViewportWidth(): number;\n getBodyViewportHeight(): number;\n getHeaderColumnWidth(): number;\n getHeaderRowHeight(): number;\n getScrollOffset(): { x: number; y: number };\n getColumnBoundaries(): readonly number[];\n getRowBoundaries(): readonly number[];\n getColumnWidths(): readonly number[];\n getRowHeights(): readonly number[];\n getVisibleColumnRange(padding: number): { start: number; end: number };\n getVisibleRowRange(padding: number): { start: number; end: number };\n getVisibleRowIndices(): number[];\n getVisibleColumnIndices(): number[];\n getDefaultCellStyle(): CellStyle;\n getComputedCellStyle(row: number, column: number): CellStyle;\n getMergedRange(row: number, column: number): MergedCellRange | null;\n getRangeRect(topRow: number, leftColumn: number, bottomRow: number, rightColumn: number): RangeRect;\n getRichTextRuns(row: number, column: number): RichTextRun[] | undefined;\n getCellText(row: number, column: number): string | null;\n pointsToPixels(points: number): number;\n withBodyClip(callback: () => void): void;\n getMergedLineGaps(): MergedLineGaps;\n isRowHidden(row: number): boolean;\n hasCellBorders(): boolean;\n getCellBorders(): Iterable<[string, CellBorderDefinition]>;\n parseCellKey(key: string): { row: number; column: number } | null;\n getCellMergeBounds(row: number, column: number): {\n topRow: number;\n bottomRow: number;\n leftColumn: number;\n rightColumn: number;\n };\n getCellTextPadding(): number;\n ensureBoundaries(): void;\n shouldRenderGridLines(): boolean;\n getCellType(row: number, column: number): CellTypeConfig | undefined;\n getFrozenRows(): number;\n getFrozenColumns(): number;\n getFrozenWidth(): number;\n getFrozenHeight(): number;\n hasHeaderDropdown(column: number): boolean;\n isColumnHidden(column: number): boolean;\n getOutlinePanelWidth(): number;\n getOutlinePanelHeight(): number;\n getRowOutlineMaxLevel(): number;\n getColumnOutlineMaxLevel(): number;\n getRowOutlineGroupsAtLevel(level: number): readonly OutlineGroup[];\n getColumnOutlineGroupsAtLevel(level: number): readonly OutlineGroup[];\n getBaseHeaderColumnWidth(): number;\n getBaseHeaderRowHeight(): number;\n getAlternateRowColors(): AlternateRowColors | null;\n getSortState(): { column: number; order: 'asc' | 'desc' } | null;\n}\n\nconst HEADER_DROPDOWN_BUTTON_WIDTH = 16;\n\nexport class SheetRenderer {\n constructor(private readonly context: SheetRendererContext) {}\n\n drawHeaders(viewports?: WorksheetViewports): void {\n const ctx = this.context.getContext();\n const bodyWidth = this.context.getBodyViewportWidth();\n const bodyHeight = this.context.getBodyViewportHeight();\n const { x: scrollX, y: scrollY } = this.context.getScrollOffset();\n const headerColumnWidth = this.context.getHeaderColumnWidth();\n const headerRowHeight = this.context.getHeaderRowHeight();\n const frozenCols = this.context.getFrozenColumns();\n const frozenRows = this.context.getFrozenRows();\n const frozenWidth = this.context.getFrozenWidth();\n const frozenHeight = this.context.getFrozenHeight();\n const viewportRight = headerColumnWidth + bodyWidth;\n const viewportBottom = headerRowHeight + bodyHeight;\n const outlinePanelWidth = this.context.getOutlinePanelWidth();\n const outlinePanelHeight = this.context.getOutlinePanelHeight();\n const baseHeaderColumnWidth = this.context.getBaseHeaderColumnWidth();\n const baseHeaderRowHeight = this.context.getBaseHeaderRowHeight();\n\n ctx.save();\n ctx.fillStyle = '#f5f5f5';\n // Column header background (only the base header area, not the outline panel)\n ctx.fillRect(headerColumnWidth, outlinePanelHeight, bodyWidth, baseHeaderRowHeight);\n // Row header background (only the base header area, not the outline panel)\n ctx.fillRect(outlinePanelWidth, headerRowHeight, baseHeaderColumnWidth, bodyHeight);\n\n ctx.fillStyle = '#e0e0e0';\n // Corner background (base header area only)\n ctx.fillRect(outlinePanelWidth, outlinePanelHeight, baseHeaderColumnWidth, baseHeaderRowHeight);\n\n const pixelRatio = this.context.getPixelRatio();\n const pixelAdjust = 0.5 / pixelRatio;\n ctx.strokeStyle = '#c0c0c0';\n ctx.lineWidth = 1 / pixelRatio;\n ctx.beginPath();\n ctx.moveTo(headerColumnWidth + pixelAdjust, 0);\n ctx.lineTo(headerColumnWidth + pixelAdjust, headerRowHeight + bodyHeight);\n ctx.moveTo(0, headerRowHeight + pixelAdjust);\n ctx.lineTo(headerColumnWidth + bodyWidth, headerRowHeight + pixelAdjust);\n ctx.stroke();\n\n ctx.font = '12px sans-serif';\n ctx.fillStyle = '#1f2933';\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n\n const columnRange = viewports?.columnHeader.columns ?? this.context.getVisibleColumnRange(0);\n const columnBoundaries = this.context.getColumnBoundaries();\n const columnWidths = this.context.getColumnWidths();\n\n const sortState = this.context.getSortState();\n\n // Helper: draw a single column header label (clipped to its cell bounds)\n const drawColumnLabel = (c: number, columnLeft: number): void => {\n const columnWidth = columnWidths[c];\n const centerX = columnLeft + columnWidth / 2;\n const centerY = outlinePanelHeight + baseHeaderRowHeight / 2;\n ctx.save();\n ctx.beginPath();\n ctx.rect(columnLeft, outlinePanelHeight, columnWidth, baseHeaderRowHeight);\n ctx.clip();\n ctx.fillText(columnIndexToName(c), centerX, centerY);\n if (this.context.hasHeaderDropdown(c)) {\n this.drawHeaderDropdownArrow(ctx, columnLeft, columnWidth, headerRowHeight);\n }\n if (sortState && sortState.column === c) {\n this.drawSortIndicator(ctx, columnLeft, columnWidth, baseHeaderRowHeight, outlinePanelHeight, sortState.order);\n }\n ctx.restore();\n };\n\n if (frozenCols > 0) {\n // Draw frozen column headers clipped to the frozen region\n ctx.save();\n ctx.beginPath();\n ctx.rect(headerColumnWidth, 0, frozenWidth, headerRowHeight);\n ctx.clip();\n for (let c = columnRange.start; c < frozenCols && c <= columnRange.end; c += 1) {\n const columnLeft = headerColumnWidth + columnBoundaries[c];\n drawColumnLabel(c, columnLeft);\n }\n ctx.restore();\n\n // Draw scrollable column headers clipped to the scrollable region\n ctx.save();\n ctx.beginPath();\n ctx.rect(headerColumnWidth + frozenWidth, 0, bodyWidth - frozenWidth, headerRowHeight);\n ctx.clip();\n for (let c = Math.max(columnRange.start, frozenCols); c <= columnRange.end; c += 1) {\n const columnLeft = headerColumnWidth + frozenWidth + (columnBoundaries[c] - (columnBoundaries[frozenCols] ?? 0)) - scrollX;\n const columnRight = columnLeft + columnWidths[c];\n if (columnRight < headerColumnWidth + frozenWidth || columnLeft > viewportRight) {\n continue;\n }\n drawColumnLabel(c, columnLeft);\n }\n ctx.restore();\n } else {\n // No freeze — single clip for all column headers\n const columnHeaderClip = viewports?.columnHeader.rect;\n if (columnHeaderClip) {\n ctx.save();\n ctx.beginPath();\n ctx.rect(columnHeaderClip.x, columnHeaderClip.y, columnHeaderClip.width, columnHeaderClip.height);\n ctx.clip();\n }\n for (let c = columnRange.start; c <= columnRange.end; c += 1) {\n const columnLeft = headerColumnWidth + columnBoundaries[c] - scrollX;\n const columnRight = columnLeft + columnWidths[c];\n if (columnRight < headerColumnWidth || columnLeft > viewportRight) {\n continue;\n }\n drawColumnLabel(c, columnLeft);\n }\n if (columnHeaderClip) {\n ctx.restore();\n }\n }\n\n const rowRange = viewports?.rowHeader.rows ?? this.context.getVisibleRowRange(0);\n const rowBoundaries = this.context.getRowBoundaries();\n const rowHeights = this.context.getRowHeights();\n\n // Helper: draw a single row header label\n const drawRowLabel = (r: number, rowTop: number): void => {\n if (this.context.isRowHidden(r)) return; // skip hidden rows\n const rowHeight = rowHeights[r];\n const centerX = outlinePanelWidth + baseHeaderColumnWidth / 2;\n const centerY = rowTop + rowHeight / 2;\n ctx.save();\n ctx.beginPath();\n ctx.rect(outlinePanelWidth, rowTop, baseHeaderColumnWidth, rowHeight);\n ctx.clip();\n ctx.fillText(String(r + 1), centerX, centerY);\n ctx.restore();\n };\n\n if (frozenRows > 0) {\n // Draw frozen row headers clipped to the frozen region\n ctx.save();\n ctx.beginPath();\n ctx.rect(0, headerRowHeight, headerColumnWidth, frozenHeight);\n ctx.clip();\n for (let r = rowRange.start; r < frozenRows && r <= rowRange.end; r += 1) {\n const rowTop = headerRowHeight + rowBoundaries[r];\n drawRowLabel(r, rowTop);\n }\n ctx.restore();\n\n // Draw scrollable row headers clipped to the scrollable region\n ctx.save();\n ctx.beginPath();\n ctx.rect(0, headerRowHeight + frozenHeight, headerColumnWidth, bodyHeight - frozenHeight);\n ctx.clip();\n for (let r = Math.max(rowRange.start, frozenRows); r <= rowRange.end; r += 1) {\n const rowTop = headerRowHeight + frozenHeight + (rowBoundaries[r] - (rowBoundaries[frozenRows] ?? 0)) - scrollY;\n const rowBottom = rowTop + rowHeights[r];\n if (rowBottom < headerRowHeight + frozenHeight || rowTop > viewportBottom) {\n continue;\n }\n drawRowLabel(r, rowTop);\n }\n ctx.restore();\n } else {\n // No freeze — single clip for all row headers\n const rowHeaderClip = viewports?.rowHeader.rect;\n if (rowHeaderClip) {\n ctx.save();\n ctx.beginPath();\n ctx.rect(rowHeaderClip.x, rowHeaderClip.y, rowHeaderClip.width, rowHeaderClip.height);\n ctx.clip();\n }\n for (let r = rowRange.start; r <= rowRange.end; r += 1) {\n const rowTop = headerRowHeight + rowBoundaries[r] - scrollY;\n const rowBottom = rowTop + rowHeights[r];\n if (rowBottom < headerRowHeight || rowTop > viewportBottom) {\n continue;\n }\n drawRowLabel(r, rowTop);\n }\n if (rowHeaderClip) {\n ctx.restore();\n }\n }\n\n // Draw freeze boundary lines in header area\n if (frozenCols > 0) {\n const freezeX = headerColumnWidth + frozenWidth + pixelAdjust;\n ctx.strokeStyle = '#808080';\n ctx.lineWidth = 2 / pixelRatio;\n ctx.beginPath();\n ctx.moveTo(freezeX, 0);\n ctx.lineTo(freezeX, headerRowHeight);\n ctx.stroke();\n }\n if (frozenRows > 0) {\n const freezeY = headerRowHeight + frozenHeight + pixelAdjust;\n ctx.strokeStyle = '#808080';\n ctx.lineWidth = 2 / pixelRatio;\n ctx.beginPath();\n ctx.moveTo(0, freezeY);\n ctx.lineTo(headerColumnWidth, freezeY);\n ctx.stroke();\n }\n\n ctx.restore();\n }\n\n drawOutlinePanel(viewports?: WorksheetViewports): void {\n const outlinePanelWidth = this.context.getOutlinePanelWidth();\n const outlinePanelHeight = this.context.getOutlinePanelHeight();\n if (outlinePanelWidth === 0 && outlinePanelHeight === 0) return;\n\n const ctx = this.context.getContext();\n const pixelRatio = this.context.getPixelRatio();\n const pixelAdjust = 0.5 / pixelRatio;\n const headerColumnWidth = this.context.getHeaderColumnWidth();\n const headerRowHeight = this.context.getHeaderRowHeight();\n const baseHeaderColumnWidth = this.context.getBaseHeaderColumnWidth();\n const baseHeaderRowHeight = this.context.getBaseHeaderRowHeight();\n const bodyWidth = this.context.getBodyViewportWidth();\n const bodyHeight = this.context.getBodyViewportHeight();\n const { x: scrollX, y: scrollY } = this.context.getScrollOffset();\n const rowBoundaries = this.context.getRowBoundaries();\n const columnBoundaries = this.context.getColumnBoundaries();\n const rowHeights = this.context.getRowHeights();\n const columnWidths = this.context.getColumnWidths();\n const frozenRows = this.context.getFrozenRows();\n const frozenCols = this.context.getFrozenColumns();\n const frozenWidth = this.context.getFrozenWidth();\n const frozenHeight = this.context.getFrozenHeight();\n\n const LEVEL_SIZE = 16;\n const BUTTON_SIZE = 11;\n const BUTTON_HALF = Math.floor(BUTTON_SIZE / 2);\n\n ctx.save();\n\n // --- Row outline panel (left of row headers) ---\n if (outlinePanelWidth > 0) {\n const maxLevel = this.context.getRowOutlineMaxLevel();\n\n // Draw outline panel background\n ctx.fillStyle = '#f0f0f0';\n ctx.fillRect(0, headerRowHeight, outlinePanelWidth, bodyHeight);\n\n // Draw level number buttons in the corner area\n ctx.fillStyle = '#e8e8e8';\n ctx.fillRect(0, 0, outlinePanelWidth, headerRowHeight);\n\n ctx.font = '10px sans-serif';\n ctx.fillStyle = '#555';\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n for (let lvl = 0; lvl <= maxLevel; lvl++) {\n const btnX = lvl * LEVEL_SIZE + LEVEL_SIZE / 2;\n const btnY = outlinePanelHeight + baseHeaderRowHeight / 2;\n // Draw level button background\n ctx.save();\n ctx.strokeStyle = '#b0b0b0';\n ctx.lineWidth = 1 / pixelRatio;\n const r = BUTTON_HALF;\n ctx.strokeRect(\n Math.floor(btnX - r) + pixelAdjust,\n Math.floor(btnY - r) + pixelAdjust,\n BUTTON_SIZE, BUTTON_SIZE,\n );\n ctx.fillStyle = '#555';\n ctx.fillText(String(lvl + 1), btnX + 1, btnY + 1);\n ctx.restore();\n }\n\n // Draw separator line between outline panel and row headers\n ctx.strokeStyle = '#c0c0c0';\n ctx.lineWidth = 1 / pixelRatio;\n ctx.beginPath();\n ctx.moveTo(outlinePanelWidth + pixelAdjust, headerRowHeight);\n ctx.lineTo(outlinePanelWidth + pixelAdjust, headerRowHeight + bodyHeight);\n ctx.stroke();\n\n // Draw outline groups and toggle buttons for each level\n const drawRowOutlineGroups = (r: number, rowTop: number, rowBottom: number) => {\n for (let lvl = 0; lvl <= maxLevel; lvl++) {\n const groups = this.context.getRowOutlineGroupsAtLevel(lvl);\n const levelCenterX = lvl * LEVEL_SIZE + LEVEL_SIZE / 2;\n for (const g of groups) {\n const groupEnd = g.start + g.count - 1;\n // Check if this row is the last row of the group (toggle button row)\n if (r === groupEnd) {\n // Draw toggle button\n const btnY = Math.floor(rowTop + (rowBottom - rowTop) / 2);\n ctx.save();\n ctx.strokeStyle = '#888';\n ctx.lineWidth = 1 / pixelRatio;\n ctx.strokeRect(\n Math.floor(levelCenterX - BUTTON_HALF) + pixelAdjust,\n Math.floor(btnY - BUTTON_HALF) + pixelAdjust,\n BUTTON_SIZE, BUTTON_SIZE,\n );\n // Draw + or -\n ctx.beginPath();\n ctx.moveTo(levelCenterX - 3, btnY);\n ctx.lineTo(levelCenterX + 3, btnY);\n if (g.collapsed) {\n ctx.moveTo(levelCenterX, btnY - 3);\n ctx.lineTo(levelCenterX, btnY + 3);\n }\n ctx.stroke();\n ctx.restore();\n }\n }\n }\n };\n\n // Draw connecting lines for groups\n const drawRowOutlineLines = (rowStart: number, rowEnd: number, getRowTop: (r: number) => number) => {\n for (let lvl = 0; lvl <= maxLevel; lvl++) {\n const groups = this.context.getRowOutlineGroupsAtLevel(lvl);\n const levelCenterX = lvl * LEVEL_SIZE + LEVEL_SIZE / 2;\n for (const g of groups) {\n if (g.collapsed) continue;\n const groupEndRow = g.start + g.count - 1;\n // Only draw if group overlaps visible range\n if (g.start > rowEnd || groupEndRow < rowStart) continue;\n const lineStartRow = Math.max(g.start, rowStart);\n const lineEndRow = Math.min(groupEndRow, rowEnd);\n const lineTop = getRowTop(lineStartRow);\n const rowCenter = getRowTop(lineEndRow) + rowHeights[lineEndRow] / 2;\n // Stop the vertical line at the top edge of the toggle button\n const lineBottom = lineEndRow === groupEndRow ? rowCenter - BUTTON_HALF : rowCenter;\n\n ctx.save();\n ctx.strokeStyle = '#aaa';\n ctx.lineWidth = 1 / pixelRatio;\n ctx.beginPath();\n // Vertical line\n if (lineStartRow === g.start) {\n const startY = lineTop + rowHeights[lineStartRow] / 2;\n ctx.moveTo(levelCenterX + pixelAdjust, startY);\n } else {\n ctx.moveTo(levelCenterX + pixelAdjust, lineTop);\n }\n ctx.lineTo(levelCenterX + pixelAdjust, lineBottom);\n // Horizontal tick to toggle button\n if (lineEndRow === groupEndRow) {\n ctx.moveTo(levelCenterX, lineBottom);\n ctx.lineTo(levelCenterX + BUTTON_HALF + 1, lineBottom);\n }\n ctx.stroke();\n ctx.restore();\n }\n }\n };\n\n // Render based on frozen rows\n const rowRange = viewports?.rowHeader.rows ?? this.context.getVisibleRowRange(0);\n if (frozenRows > 0) {\n // Frozen region\n ctx.save();\n ctx.beginPath();\n ctx.rect(0, headerRowHeight, outlinePanelWidth, frozenHeight);\n ctx.clip();\n for (let r = rowRange.start; r < frozenRows && r <= rowRange.end; r++) {\n const rowTop = headerRowHeight + rowBoundaries[r];\n const rowBottom = rowTop + rowHeights[r];\n drawRowOutlineGroups(r, rowTop, rowBottom);\n }\n drawRowOutlineLines(rowRange.start, Math.min(frozenRows - 1, rowRange.end),\n (r) => headerRowHeight + rowBoundaries[r]);\n ctx.restore();\n\n // Scrollable region\n ctx.save();\n ctx.beginPath();\n ctx.rect(0, headerRowHeight + frozenHeight, outlinePanelWidth, bodyHeight - frozenHeight);\n ctx.clip();\n const scrollRowStart = Math.max(rowRange.start, frozenRows);\n for (let r = scrollRowStart; r <= rowRange.end; r++) {\n const rowTop = headerRowHeight + frozenHeight + (rowBoundaries[r] - (rowBoundaries[frozenRows] ?? 0)) - scrollY;\n const rowBottom = rowTop + rowHeights[r];\n drawRowOutlineGroups(r, rowTop, rowBottom);\n }\n drawRowOutlineLines(scrollRowStart, rowRange.end,\n (r) => headerRowHeight + frozenHeight + (rowBoundaries[r] - (rowBoundaries[frozenRows] ?? 0)) - scrollY);\n ctx.restore();\n } else {\n ctx.save();\n ctx.beginPath();\n ctx.rect(0, headerRowHeight, outlinePanelWidth, bodyHeight);\n ctx.clip();\n for (let r = rowRange.start; r <= rowRange.end; r++) {\n const rowTop = headerRowHeight + rowBoundaries[r] - scrollY;\n const rowBottom = rowTop + rowHeights[r];\n drawRowOutlineGroups(r, rowTop, rowBottom);\n }\n drawRowOutlineLines(rowRange.start, rowRange.end,\n (r) => headerRowHeight + rowBoundaries[r] - scrollY);\n ctx.restore();\n }\n }\n\n // --- Column outline panel (above column headers) ---\n if (outlinePanelHeight > 0) {\n const maxLevel = this.context.getColumnOutlineMaxLevel();\n\n // Draw outline panel background\n ctx.fillStyle = '#f0f0f0';\n ctx.fillRect(headerColumnWidth, 0, bodyWidth, outlinePanelHeight);\n\n // Draw level number buttons in the corner area\n ctx.fillStyle = '#e8e8e8';\n ctx.fillRect(0, 0, headerColumnWidth, outlinePanelHeight);\n\n ctx.font = '10px sans-serif';\n ctx.fillStyle = '#555';\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n for (let lvl = 0; lvl <= maxLevel; lvl++) {\n const btnY = lvl * LEVEL_SIZE + LEVEL_SIZE / 2;\n const btnX = outlinePanelWidth + baseHeaderColumnWidth / 2;\n ctx.save();\n ctx.strokeStyle = '#b0b0b0';\n ctx.lineWidth = 1 / pixelRatio;\n const r = BUTTON_HALF;\n ctx.strokeRect(\n Math.floor(btnX - r) + pixelAdjust,\n Math.floor(btnY - r) + pixelAdjust,\n BUTTON_SIZE, BUTTON_SIZE,\n );\n ctx.fillStyle = '#555';\n ctx.fillText(String(lvl + 1), btnX + 1, btnY + 1);\n ctx.restore();\n }\n\n // Draw separator line\n ctx.strokeStyle = '#c0c0c0';\n ctx.lineWidth = 1 / pixelRatio;\n ctx.beginPath();\n ctx.moveTo(headerColumnWidth, outlinePanelHeight + pixelAdjust);\n ctx.lineTo(headerColumnWidth + bodyWidth, outlinePanelHeight + pixelAdjust);\n ctx.stroke();\n\n // Draw column outline groups and toggle buttons\n const columnRange = viewports?.columnHeader.columns ?? this.context.getVisibleColumnRange(0);\n\n const drawColumnOutlineGroups = (c: number, colLeft: number, colRight: number) => {\n for (let lvl = 0; lvl <= maxLevel; lvl++) {\n const groups = this.context.getColumnOutlineGroupsAtLevel(lvl);\n const levelCenterY = lvl * LEVEL_SIZE + LEVEL_SIZE / 2;\n for (const g of groups) {\n const groupEnd = g.start + g.count - 1;\n if (c === groupEnd) {\n const btnX = Math.floor(colLeft + (colRight - colLeft) / 2);\n ctx.save();\n ctx.strokeStyle = '#888';\n ctx.lineWidth = 1 / pixelRatio;\n ctx.strokeRect(\n Math.floor(btnX - BUTTON_HALF) + pixelAdjust,\n Math.floor(levelCenterY - BUTTON_HALF) + pixelAdjust,\n BUTTON_SIZE, BUTTON_SIZE,\n );\n ctx.beginPath();\n ctx.moveTo(btnX - 3, levelCenterY);\n ctx.lineTo(btnX + 3, levelCenterY);\n if (g.collapsed) {\n ctx.moveTo(btnX, levelCenterY - 3);\n ctx.lineTo(btnX, levelCenterY + 3);\n }\n ctx.stroke();\n ctx.restore();\n }\n }\n }\n };\n\n const drawColumnOutlineLines = (colStart: number, colEnd: number, getColLeft: (c: number) => number) => {\n for (let lvl = 0; lvl <= maxLevel; lvl++) {\n const groups = this.context.getColumnOutlineGroupsAtLevel(lvl);\n const levelCenterY = lvl * LEVEL_SIZE + LEVEL_SIZE / 2;\n for (const g of groups) {\n if (g.collapsed) continue;\n const groupEndCol = g.start + g.count - 1;\n if (g.start > colEnd || groupEndCol < colStart) continue;\n const lineStartCol = Math.max(g.start, colStart);\n const lineEndCol = Math.min(groupEndCol, colEnd);\n const lineLeft = getColLeft(lineStartCol);\n const colCenter = getColLeft(lineEndCol) + columnWidths[lineEndCol] / 2;\n // Stop the horizontal line at the left edge of the toggle button\n const lineRight = lineEndCol === groupEndCol ? colCenter - BUTTON_HALF : colCenter;\n\n ctx.save();\n ctx.strokeStyle = '#aaa';\n ctx.lineWidth = 1 / pixelRatio;\n ctx.beginPath();\n if (lineStartCol === g.start) {\n const startX = lineLeft + columnWidths[lineStartCol] / 2;\n ctx.moveTo(startX, levelCenterY + pixelAdjust);\n } else {\n ctx.moveTo(lineLeft, levelCenterY + pixelAdjust);\n }\n ctx.lineTo(lineRight, levelCenterY + pixelAdjust);\n if (lineEndCol === groupEndCol) {\n ctx.moveTo(lineRight, levelCenterY);\n ctx.lineTo(lineRight, levelCenterY + BUTTON_HALF + 1);\n }\n ctx.stroke();\n ctx.restore();\n }\n }\n };\n\n if (frozenCols > 0) {\n ctx.save();\n ctx.beginPath();\n ctx.rect(headerColumnWidth, 0, frozenWidth, outlinePanelHeight);\n ctx.clip();\n for (let c = columnRange.start; c < frozenCols && c <= columnRange.end; c++) {\n const colLeft = headerColumnWidth + columnBoundaries[c];\n const colRight = colLeft + columnWidths[c];\n drawColumnOutlineGroups(c, colLeft, colRight);\n }\n drawColumnOutlineLines(columnRange.start, Math.min(frozenCols - 1, columnRange.end),\n (c) => headerColumnWidth + columnBoundaries[c]);\n ctx.restore();\n\n ctx.save();\n ctx.beginPath();\n ctx.rect(headerColumnWidth + frozenWidth, 0, bodyWidth - frozenWidth, outlinePanelHeight);\n ctx.clip();\n const scrollColStart = Math.max(columnRange.start, frozenCols);\n for (let c = scrollColStart; c <= columnRange.end; c++) {\n const colLeft = headerColumnWidth + frozenWidth + (columnBoundaries[c] - (columnBoundaries[frozenCols] ?? 0)) - scrollX;\n const colRight = colLeft + columnWidths[c];\n drawColumnOutlineGroups(c, colLeft, colRight);\n }\n drawColumnOutlineLines(scrollColStart, columnRange.end,\n (c) => headerColumnWidth + frozenWidth + (columnBoundaries[c] - (columnBoundaries[frozenCols] ?? 0)) - scrollX);\n ctx.restore();\n } else {\n ctx.save();\n ctx.beginPath();\n ctx.rect(headerColumnWidth, 0, bodyWidth, outlinePanelHeight);\n ctx.clip();\n for (let c = columnRange.start; c <= columnRange.end; c++) {\n const colLeft = headerColumnWidth + columnBoundaries[c] - scrollX;\n const colRight = colLeft + columnWidths[c];\n drawColumnOutlineGroups(c, colLeft, colRight);\n }\n drawColumnOutlineLines(columnRange.start, columnRange.end,\n (c) => headerColumnWidth + columnBoundaries[c] - scrollX);\n ctx.restore();\n }\n }\n\n ctx.restore();\n }\n\n drawBodyViewport(viewport: BodyViewport): void {\n const { rect, rowIndices, columnIndices, scrollOffsetX, scrollOffsetY } = viewport;\n if (rect.width <= 0 || rect.height <= 0) {\n return;\n }\n if (!rowIndices.length || !columnIndices.length) {\n return;\n }\n\n const ctx = this.context.getContext();\n const headerColumnWidth = this.context.getHeaderColumnWidth();\n const headerRowHeight = this.context.getHeaderRowHeight();\n const frozenCols = this.context.getFrozenColumns();\n const frozenRows = this.context.getFrozenRows();\n const frozenWidth = this.context.getFrozenWidth();\n const frozenHeight = this.context.getFrozenHeight();\n\n // Compute the offset to map grid content to screen coordinates for this viewport.\n // For frozen viewports (scrollOffset = 0), cells map directly without scroll.\n // For scrollable viewports, scroll offset is applied.\n const isFrozenX = scrollOffsetX === 0 && frozenCols > 0 && columnIndices[0] < frozenCols;\n const isFrozenY = scrollOffsetY === 0 && frozenRows > 0 && rowIndices[0] < frozenRows;\n const offsetX = isFrozenX\n ? headerColumnWidth\n : headerColumnWidth + frozenWidth - (this.context.getColumnBoundaries()[frozenCols] ?? 0) - scrollOffsetX;\n const offsetY = isFrozenY\n ? headerRowHeight\n : headerRowHeight + frozenHeight - (this.context.getRowBoundaries()[frozenRows] ?? 0) - scrollOffsetY;\n\n const viewportRight = rect.x + rect.width;\n const viewportBottom = rect.y + rect.height;\n\n const rowBoundaries = this.context.getRowBoundaries();\n const rowHeights = this.context.getRowHeights();\n const columnBoundaries = this.context.getColumnBoundaries();\n const columnWidths = this.context.getColumnWidths();\n const defaultStyle = this.context.getDefaultCellStyle();\n const cellPadding = this.context.getCellTextPadding();\n const pixelRatio = this.context.getPixelRatio();\n\n ctx.save();\n ctx.beginPath();\n ctx.rect(rect.x, rect.y, rect.width, rect.height);\n ctx.clip();\n\n // Pass 0: alternate row backgrounds\n const altColors = this.context.getAlternateRowColors();\n if (altColors) {\n const lastColBoundary = columnIndices.length > 0\n ? columnBoundaries[Math.min(columnBoundaries.length - 1, columnIndices[columnIndices.length - 1] + 1)]\n : 0;\n const altWidth = lastColBoundary > 0 ? offsetX + lastColBoundary - rect.x : 0;\n for (const r of rowIndices) {\n const color = r % 2 === 0 ? altColors.evenColor : altColors.oddColor;\n if (color === defaultStyle.backgroundColor) continue;\n const rowTop = rowBoundaries[r];\n const rowHeight = rowHeights[r];\n const rowY = offsetY + rowTop;\n if (rowY > viewportBottom) break;\n ctx.fillStyle = color;\n ctx.fillRect(rect.x, rowY, altWidth, rowHeight);\n }\n }\n\n // Pass 1: backgrounds\n for (const r of rowIndices) {\n const rowTop = rowBoundaries[r];\n const rowHeight = rowHeights[r];\n const rowY = offsetY + rowTop;\n if (rowY > viewportBottom) break;\n for (const c of columnIndices) {\n const columnLeft = columnBoundaries[c];\n const columnWidth = columnWidths[c];\n const columnX = offsetX + columnLeft;\n if (columnX > viewportRight) break;\n const style = this.context.getComputedCellStyle(r, c);\n const merged = this.context.getMergedRange(r, c);\n const isAnchor = !merged || (merged.topRow === r && merged.leftColumn === c);\n const cellRect = { x: columnX, y: rowY, width: columnWidth, height: rowHeight };\n const drawRect = merged\n ? this.computeMergedDrawRect(merged, offsetX, offsetY)\n : cellRect;\n const hasCustomBackground = style.backgroundColor !== defaultStyle.backgroundColor;\n if ((!merged || isAnchor) && hasCustomBackground) {\n this.fillCellBackground(ctx, drawRect.x, drawRect.y, drawRect.width, drawRect.height, style.backgroundColor);\n }\n }\n }\n\n // Pass 2: text content\n const previousBaseline = ctx.textBaseline;\n ctx.textBaseline = 'alphabetic';\n\n for (const r of rowIndices) {\n const rowTop = rowBoundaries[r];\n const rowHeight = rowHeights[r];\n const rowY = offsetY + rowTop;\n if (rowY > viewportBottom) break;\n for (const c of columnIndices) {\n const columnLeft = columnBoundaries[c];\n const columnWidth = columnWidths[c];\n const columnX = offsetX + columnLeft;\n if (columnX > viewportRight) break;\n const style = this.context.getComputedCellStyle(r, c);\n const merged = this.context.getMergedRange(r, c);\n const isAnchor = !merged || (merged.topRow === r && merged.leftColumn === c);\n const cellRect = { x: columnX, y: rowY, width: columnWidth, height: rowHeight };\n const drawRect = merged\n ? this.computeMergedDrawRect(merged, offsetX, offsetY)\n : cellRect;\n\n if (!isAnchor) continue;\n\n // Pluggable cell type handler dispatch\n const cellType = this.context.getCellType(r, c);\n if (cellType) {\n const handler = getCellTypeHandler(cellType.type);\n if (handler) {\n const rawValue = this.context.getCellText(r, c);\n handler.render({\n ctx, rect: drawRect, value: rawValue, style,\n pixelRatio: this.context.getPixelRatio(),\n cellPadding,\n }, cellType as Record<string, unknown>);\n if (handler.replacesText !== false) continue;\n }\n }\n\n const richTextRuns = this.context.getRichTextRuns(r, c);\n if (richTextRuns && richTextRuns.length > 0) {\n this.drawRichText(drawRect, style, richTextRuns);\n continue;\n }\n\n const text = this.context.getCellText(r, c);\n if (text === null) continue;\n const fontFamily = style.fontFamily.includes(' ') ? `\"${style.fontFamily}\"` : style.fontFamily;\n const fontSizePx = this.context.pointsToPixels(style.fontSize);\n const composedFont = this.composeFont({\n text: '',\n fontFamily,\n fontSize: fontSizePx,\n bold: style.bold,\n italic: style.italic,\n color: style.color ?? defaultStyle.color,\n underline: false,\n });\n ctx.font = composedFont;\n const lineHeight = fontSizePx + cellPadding;\n const lines = this.layoutPlainTextLines(text, style, drawRect);\n ctx.fillStyle = style.color ?? defaultStyle.color;\n const contentHeight = lineHeight * lines.length;\n let firstLineY = drawRect.y + cellPadding;\n if (style.verticalAlign === 'middle') {\n firstLineY = drawRect.y + (drawRect.height - contentHeight) / 2;\n } else if (style.verticalAlign === 'bottom') {\n firstLineY = drawRect.y + drawRect.height - contentHeight - cellPadding;\n }\n const minY = drawRect.y + cellPadding;\n const maxY = drawRect.y + drawRect.height - cellPadding - contentHeight;\n firstLineY = Math.min(firstLineY, maxY);\n firstLineY = Math.max(firstLineY, minY);\n const baselineOffset = fontSizePx;\n for (let i = 0; i < lines.length; i += 1) {\n const lineTop = firstLineY + i * lineHeight;\n if (lineTop > drawRect.y + drawRect.height - cellPadding) break;\n const lineMetrics = ctx.measureText(lines[i]);\n const lineWidth = lineMetrics.width;\n const textX = this.computeAlignedX(drawRect, lineWidth, style.textAlign);\n const baseline = lineTop + baselineOffset;\n ctx.fillText(lines[i], textX, baseline);\n if (style.underline) {\n this.drawUnderline(ctx, textX, lineWidth, baseline, fontSizePx);\n }\n }\n }\n }\n ctx.textBaseline = previousBaseline;\n\n // Pass 3: gridlines\n if (this.context.shouldRenderGridLines()) {\n const pixelAdjust = 0.5 / pixelRatio;\n const mergedLineGaps = this.context.getMergedLineGaps();\n ctx.strokeStyle = '#d0d0d0';\n ctx.lineWidth = 1 / pixelRatio;\n ctx.beginPath();\n\n const rowLineStart = Math.max(0, rowIndices[0]);\n const rowLineEnd = Math.min(rowBoundaries.length - 1, rowIndices[rowIndices.length - 1] + 1);\n const lastRowBoundary = Math.min(rowBoundaries.length - 1, rowIndices[rowIndices.length - 1] + 1);\n const maxBodyY = offsetY + rowBoundaries[lastRowBoundary];\n const maxColumnBoundary = Math.min(columnBoundaries.length - 1, columnIndices[columnIndices.length - 1] + 1);\n const maxBodyX = offsetX + columnBoundaries[maxColumnBoundary];\n for (let r = rowLineStart; r <= rowLineEnd; r += 1) {\n const absolute = rowBoundaries[r];\n const y = offsetY + absolute + pixelAdjust;\n if (y < rect.y || y > viewportBottom + pixelAdjust) continue;\n const gaps = mergedLineGaps.horizontal.get(r);\n if (!gaps || gaps.length === 0) {\n ctx.moveTo(rect.x, y);\n ctx.lineTo(Math.min(maxBodyX, viewportRight), y);\n continue;\n }\n const segments = this.buildVisibleLineSegments(\n gaps.map((gap) => ({\n start: offsetX + columnBoundaries[gap.startColumnBoundary],\n end: offsetX + columnBoundaries[gap.endColumnBoundary],\n })),\n rect.x,\n Math.min(maxBodyX, viewportRight),\n );\n for (const segment of segments) {\n ctx.moveTo(segment.start, y);\n ctx.lineTo(segment.end, y);\n }\n }\n\n const columnLineStart = Math.max(0, columnIndices[0]);\n const columnLineEnd = Math.min(columnBoundaries.length - 1, columnIndices[columnIndices.length - 1] + 1);\n for (let c = columnLineStart; c <= columnLineEnd; c += 1) {\n const absolute = columnBoundaries[c];\n const x = offsetX + absolute + pixelAdjust;\n if (x < rect.x || x > Math.min(maxBodyX, viewportRight) + pixelAdjust) continue;\n const gaps = mergedLineGaps.vertical.get(c);\n if (!gaps || gaps.length === 0) {\n ctx.moveTo(x, rect.y);\n ctx.lineTo(x, Math.min(viewportBottom, maxBodyY));\n continue;\n }\n const segments = this.buildVisibleLineSegments(\n gaps.map((gap) => ({\n start: offsetY + rowBoundaries[gap.startRowBoundary],\n end: offsetY + rowBoundaries[gap.endRowBoundary],\n })),\n rect.y,\n Math.min(viewportBottom, maxBodyY),\n );\n for (const segment of segments) {\n ctx.moveTo(x, segment.start);\n ctx.lineTo(x, segment.end);\n }\n }\n\n ctx.stroke();\n }\n\n ctx.restore();\n }\n\n /** Computes the draw rect for a merged range given viewport-local offsets. */\n private computeMergedDrawRect(\n merged: { topRow: number; leftColumn: number; bottomRow: number; rightColumn: number },\n offsetX: number,\n offsetY: number,\n ): RangeRect {\n const columnBoundaries = this.context.getColumnBoundaries();\n const rowBoundaries = this.context.getRowBoundaries();\n return {\n x: offsetX + columnBoundaries[merged.leftColumn],\n y: offsetY + rowBoundaries[merged.topRow],\n width: columnBoundaries[merged.rightColumn + 1] - columnBoundaries[merged.leftColumn],\n height: rowBoundaries[merged.bottomRow + 1] - rowBoundaries[merged.topRow],\n };\n }\n\n drawBodyViewportBorders(viewport: BodyViewport): void {\n if (!this.context.hasCellBorders()) {\n return;\n }\n const { rect, rows: viewportRows, columns: viewportCols, scrollOffsetX, scrollOffsetY } = viewport;\n if (rect.width <= 0 || rect.height <= 0) {\n return;\n }\n this.context.ensureBoundaries();\n const ctx = this.context.getContext();\n const horizontalEdges = new Map<string, PendingHorizontalEdge>();\n const verticalEdges = new Map<string, PendingVerticalEdge>();\n\n for (const [key, borders] of this.context.getCellBorders()) {\n const coords = this.context.parseCellKey(key);\n if (!coords) {\n continue;\n }\n const bounds = this.context.getCellMergeBounds(coords.row, coords.column);\n const overlapsViewport =\n bounds.bottomRow >= viewportRows.start &&\n bounds.topRow <= viewportRows.end &&\n bounds.rightColumn >= viewportCols.start &&\n bounds.leftColumn <= viewportCols.end;\n if (!overlapsViewport) {\n continue;\n }\n this.addHorizontalEdge(horizontalEdges, bounds.topRow, bounds.leftColumn, bounds.rightColumn, borders.top);\n this.addHorizontalEdge(\n horizontalEdges,\n bounds.bottomRow + 1,\n bounds.leftColumn,\n bounds.rightColumn,\n borders.bottom,\n );\n this.addVerticalEdge(verticalEdges, bounds.leftColumn, bounds.topRow, bounds.bottomRow, borders.left);\n this.addVerticalEdge(\n verticalEdges,\n bounds.rightColumn + 1,\n bounds.topRow,\n bounds.bottomRow,\n borders.right,\n );\n }\n\n if (!horizontalEdges.size && !verticalEdges.size) {\n return;\n }\n\n const frozenCols = this.context.getFrozenColumns();\n const frozenRows = this.context.getFrozenRows();\n const frozenWidth = this.context.getFrozenWidth();\n const frozenHeight = this.context.getFrozenHeight();\n const headerColumnWidth = this.context.getHeaderColumnWidth();\n const headerRowHeight = this.context.getHeaderRowHeight();\n const isFrozenX = scrollOffsetX === 0 && frozenCols > 0 && viewportCols.start < frozenCols;\n const isFrozenY = scrollOffsetY === 0 && frozenRows > 0 && viewportRows.start < frozenRows;\n const borderScrollX = isFrozenX ? 0 : scrollOffsetX;\n const borderScrollY = isFrozenY ? 0 : scrollOffsetY;\n const borderOffsetX = isFrozenX\n ? headerColumnWidth\n : headerColumnWidth + frozenWidth - (this.context.getColumnBoundaries()[frozenCols] ?? 0);\n const borderOffsetY = isFrozenY\n ? headerRowHeight\n : headerRowHeight + frozenHeight - (this.context.getRowBoundaries()[frozenRows] ?? 0);\n\n ctx.save();\n ctx.beginPath();\n ctx.rect(rect.x, rect.y, rect.width, rect.height);\n ctx.clip();\n ctx.lineCap = 'butt';\n ctx.lineJoin = 'miter';\n for (const edge of horizontalEdges.values()) {\n this.drawHorizontalBorderEdgeWithOffset(ctx, edge, borderOffsetX, borderOffsetY, borderScrollX, borderScrollY);\n }\n for (const edge of verticalEdges.values()) {\n this.drawVerticalBorderEdgeWithOffset(ctx, edge, borderOffsetX, borderOffsetY, borderScrollX, borderScrollY);\n }\n ctx.restore();\n }\n\n drawFreezeLines(): void {\n const frozenRows = this.context.getFrozenRows();\n const frozenCols = this.context.getFrozenColumns();\n if (!frozenRows && !frozenCols) return;\n\n const ctx = this.context.getContext();\n const headerColumnWidth = this.context.getHeaderColumnWidth();\n const headerRowHeight = this.context.getHeaderRowHeight();\n const bodyWidth = this.context.getBodyViewportWidth();\n const bodyHeight = this.context.getBodyViewportHeight();\n const frozenWidth = this.context.getFrozenWidth();\n const frozenHeight = this.context.getFrozenHeight();\n const pixelRatio = this.context.getPixelRatio();\n\n ctx.save();\n ctx.strokeStyle = '#808080';\n ctx.lineWidth = 2 / pixelRatio;\n\n if (frozenCols > 0) {\n const x = headerColumnWidth + frozenWidth;\n ctx.beginPath();\n ctx.moveTo(x, headerRowHeight);\n ctx.lineTo(x, headerRowHeight + bodyHeight);\n ctx.stroke();\n }\n if (frozenRows > 0) {\n const y = headerRowHeight + frozenHeight;\n ctx.beginPath();\n ctx.moveTo(headerColumnWidth, y);\n ctx.lineTo(headerColumnWidth + bodyWidth, y);\n ctx.stroke();\n }\n ctx.restore();\n }\n\n layoutRichText(runs: RichTextRun[], baseStyle: CellStyle): RichTextLine[] {\n const baseFontPx = this.context.pointsToPixels(baseStyle.fontSize);\n const resolvedRuns = runs.map((run) => this.resolveRichTextRun(run, baseStyle));\n const lines: RichTextLine[] = [];\n let currentRuns: ResolvedRichRun[] = [];\n for (const run of resolvedRuns) {\n const text = run.text.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n');\n const segments = text.split('\\n');\n segments.forEach((segment, index) => {\n if (segment.length > 0) {\n currentRuns.push({ ...run, text: segment });\n }\n if (index < segments.length - 1) {\n lines.push(this.measureRichTextLine(currentRuns, baseFontPx));\n currentRuns = [];\n }\n });\n }\n if (currentRuns.length > 0 || lines.length === 0) {\n lines.push(this.measureRichTextLine(currentRuns, baseFontPx));\n }\n return lines;\n }\n\n private layoutPlainTextLines(text: string, style: CellStyle, rect: RangeRect): string[] {\n const padding = this.context.getCellTextPadding();\n const availableWidth = Math.max(0, rect.width - padding * 2);\n const wrapMode = style.textWrapMode ?? 'none';\n const shouldWrap = wrapMode !== 'none' && availableWidth > 0;\n const rawLines = text.split(/\\r\\n|\\r|\\n/);\n const lines: string[] = [];\n for (const rawLine of rawLines) {\n if (!shouldWrap) {\n lines.push(rawLine);\n continue;\n }\n const segments = this.wrapPlainLine(rawLine, availableWidth, wrapMode === 'break-word');\n if (segments.length === 0) {\n lines.push('');\n } else {\n lines.push(...segments);\n }\n }\n return lines;\n }\n\n private wrapPlainLine(line: string, maxWidth: number, breakAnywhere: boolean): string[] {\n if (!line) {\n return [''];\n }\n if (maxWidth <= 0) {\n return [line];\n }\n const ctx = this.context.getContext();\n const tokens = breakAnywhere ? Array.from(line) : line.split(/(\\s+)/);\n const lines: string[] = [];\n let current = '';\n for (const token of tokens) {\n if (!token) {\n continue;\n }\n const candidate = current ? current + token : token;\n if (this.measureTextWidth(candidate, ctx) <= maxWidth) {\n current = candidate;\n continue;\n }\n if (current) {\n lines.push(current);\n current = '';\n }\n if (this.measureTextWidth(token, ctx) <= maxWidth) {\n current = token;\n continue;\n }\n const broken = this.breakSegment(token, maxWidth, ctx);\n if (broken.length) {\n lines.push(...broken);\n }\n }\n if (current) {\n lines.push(current);\n }\n if (!lines.length) {\n lines.push('');\n }\n return lines;\n }\n\n private breakSegment(value: string, maxWidth: number, ctx: CanvasRenderingContext2D): string[] {\n const segments: string[] = [];\n let buffer = '';\n for (const char of value) {\n const candidate = buffer ? buffer + char : char;\n if (this.measureTextWidth(candidate, ctx) <= maxWidth) {\n buffer = candidate;\n continue;\n }\n if (buffer) {\n segments.push(buffer);\n }\n buffer = char;\n if (this.measureTextWidth(buffer, ctx) > maxWidth) {\n segments.push(buffer);\n buffer = '';\n }\n }\n if (buffer) {\n segments.push(buffer);\n }\n return segments;\n }\n\n private measureTextWidth(value: string, ctx: CanvasRenderingContext2D): number {\n return ctx.measureText(value).width;\n }\n\n private drawRichText(rect: RangeRect, style: CellStyle, runs: RichTextRun[]): void {\n const lines = this.layoutRichText(runs, style);\n if (!lines.length) {\n return;\n }\n const ctx = this.context.getContext();\n const previousAlign = ctx.textAlign;\n ctx.textAlign = 'left';\n const padding = this.context.getCellTextPadding();\n const contentHeight = lines.reduce((sum, line) => sum + line.lineHeight, 0);\n let firstLineY = rect.y + padding;\n if (style.verticalAlign === 'middle') {\n firstLineY = rect.y + (rect.height - contentHeight) / 2;\n } else if (style.verticalAlign === 'bottom') {\n firstLineY = rect.y + rect.height - contentHeight - padding;\n }\n const minY = rect.y + padding;\n const maxY = rect.y + rect.height - padding - contentHeight;\n firstLineY = Math.min(firstLineY, maxY);\n firstLineY = Math.max(firstLineY, minY);\n let lineTop = firstLineY;\n for (const line of lines) {\n const textX = this.computeAlignedX(rect, line.width, style.textAlign);\n let cursorX = textX;\n const baseline = lineTop + line.ascent;\n for (const run of line.runs) {\n const ctxFont = this.composeFont(run);\n ctx.font = ctxFont;\n ctx.fillStyle = run.color;\n const metrics = ctx.measureText(run.text);\n ctx.fillText(run.text, cursorX, baseline);\n if (run.underline) {\n this.drawUnderline(ctx, cursorX, metrics.width, baseline, run.fontSize);\n }\n cursorX += metrics.width;\n }\n lineTop += line.lineHeight;\n }\n ctx.textAlign = previousAlign;\n }\n\n private resolveRichTextRun(run: RichTextRun, baseStyle: CellStyle): ResolvedRichRun {\n const fontFamily = run.fontFamily ?? baseStyle.fontFamily;\n const fontSize = this.context.pointsToPixels(run.fontSize ?? baseStyle.fontSize);\n const fallbackColor = baseStyle.color ?? this.context.getDefaultCellStyle().color ?? '#000000';\n return {\n text: run.text,\n fontFamily,\n fontSize,\n bold: !!run.bold,\n italic: !!run.italic,\n color: run.color ?? fallbackColor,\n underline: !!run.underline,\n };\n }\n\n private measureRichTextLine(runs: ResolvedRichRun[], baseFontPx: number): RichTextLine {\n const ctx = this.context.getContext();\n const padding = this.context.getCellTextPadding();\n const lineRuns = runs.map((run) => ({ ...run }));\n let width = 0;\n let maxFont = baseFontPx;\n if (lineRuns.length === 0) {\n return {\n runs: [],\n width: 0,\n lineHeight: baseFontPx + padding,\n ascent: baseFontPx,\n };\n }\n for (const run of lineRuns) {\n maxFont = Math.max(maxFont, run.fontSize);\n ctx.font = this.composeFont(run);\n width += ctx.measureText(run.text).width;\n }\n return {\n runs: lineRuns,\n width,\n lineHeight: maxFont + padding,\n ascent: maxFont,\n };\n }\n\n private composeFont(run: ResolvedRichRun): string {\n const parts: string[] = [];\n if (run.italic) {\n parts.push('italic');\n }\n if (run.bold) {\n parts.push('bold');\n }\n parts.push(`${run.fontSize}px`);\n const family = run.fontFamily.includes(' ') ? `\"${run.fontFamily}\"` : run.fontFamily;\n parts.push(family);\n return parts.join(' ');\n }\n\n private drawUnderline(\n ctx: CanvasRenderingContext2D,\n x: number,\n width: number,\n baseline: number,\n fontSize: number,\n ): void {\n if (width <= 0) {\n return;\n }\n const thickness = Math.max(1, Math.round(fontSize / 15));\n const offset = Math.max(thickness, fontSize * 0.05);\n ctx.fillRect(x, baseline + offset, width, thickness);\n }\n\n private computeAlignedX(rect: RangeRect, contentWidth: number, alignment: TextAlign): number {\n const padding = this.context.getCellTextPadding();\n if (alignment === 'center') {\n return rect.x + rect.width / 2 - contentWidth / 2;\n }\n if (alignment === 'right') {\n return rect.x + rect.width - padding - contentWidth;\n }\n return rect.x + padding;\n }\n\n // ---------------------------------------------------------------------------\n // Cell type renderers\n // ---------------------------------------------------------------------------\n\n private drawHeaderDropdownArrow(\n ctx: CanvasRenderingContext2D,\n columnLeft: number,\n columnWidth: number,\n headerHeight: number,\n ): void {\n const btnX = columnLeft + columnWidth - HEADER_DROPDOWN_BUTTON_WIDTH;\n const arrowW = 7;\n const arrowH = 4;\n const cx = btnX + HEADER_DROPDOWN_BUTTON_WIDTH / 2;\n const cy = headerHeight / 2;\n\n ctx.save();\n ctx.fillStyle = '#888888';\n ctx.beginPath();\n ctx.moveTo(cx - arrowW / 2, cy - arrowH / 2);\n ctx.lineTo(cx + arrowW / 2, cy - arrowH / 2);\n ctx.lineTo(cx, cy + arrowH / 2);\n ctx.closePath();\n ctx.fill();\n ctx.restore();\n }\n\n private drawSortIndicator(\n ctx: CanvasRenderingContext2D,\n columnLeft: number,\n columnWidth: number,\n headerHeight: number,\n outlinePanelHeight: number,\n order: 'asc' | 'desc',\n ): void {\n // Draw a small triangle to the left of the dropdown button area\n const arrowW = 6;\n const arrowH = 4;\n const cx = columnLeft + columnWidth - HEADER_DROPDOWN_BUTTON_WIDTH - arrowW;\n const cy = outlinePanelHeight + headerHeight / 2;\n\n ctx.save();\n ctx.fillStyle = '#3b82f6';\n ctx.beginPath();\n if (order === 'asc') {\n // Upward triangle ▲\n ctx.moveTo(cx - arrowW / 2, cy + arrowH / 2);\n ctx.lineTo(cx + arrowW / 2, cy + arrowH / 2);\n ctx.lineTo(cx, cy - arrowH / 2);\n } else {\n // Downward triangle ▼\n ctx.moveTo(cx - arrowW / 2, cy - arrowH / 2);\n ctx.lineTo(cx + arrowW / 2, cy - arrowH / 2);\n ctx.lineTo(cx, cy + arrowH / 2);\n }\n ctx.closePath();\n ctx.fill();\n ctx.restore();\n }\n\n private fillCellBackground(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n width: number,\n height: number,\n color: string,\n ): void {\n ctx.save();\n ctx.fillStyle = color;\n ctx.fillRect(x, y, Math.max(0, width), Math.max(0, height));\n ctx.restore();\n }\n\n private buildVisibleLineSegments(\n gaps: Array<{ start: number; end: number }>,\n lineStart: number,\n lineEnd: number,\n ): Array<{ start: number; end: number }> {\n if (gaps.length === 0) {\n return [{ start: lineStart, end: lineEnd }];\n }\n const normalizedGaps = gaps\n .map((gap) => ({\n start: Math.max(lineStart, Math.min(gap.start, gap.end)),\n end: Math.min(lineEnd, Math.max(gap.start, gap.end)),\n }))\n .filter((gap) => gap.start < gap.end)\n .sort((a, b) => a.start - b.start);\n\n const segments: Array<{ start: number; end: number }> = [];\n let cursor = lineStart;\n for (const gap of normalizedGaps) {\n if (gap.start > cursor) {\n segments.push({ start: cursor, end: gap.start });\n }\n cursor = Math.max(cursor, gap.end);\n if (cursor >= lineEnd) {\n break;\n }\n }\n if (cursor < lineEnd) {\n segments.push({ start: cursor, end: lineEnd });\n }\n return segments.length > 0 ? segments : [];\n }\n\n private addHorizontalEdge(\n edges: Map<string, PendingHorizontalEdge>,\n boundaryIndex: number,\n fromColumn: number,\n toColumn: number,\n line?: BorderLine,\n ): void {\n if (!line || line.width <= 0) {\n return;\n }\n const key = this.buildHorizontalEdgeKey(boundaryIndex, fromColumn, toColumn);\n const existing = edges.get(key);\n if (!existing) {\n edges.set(key, { boundaryIndex, fromColumn, toColumn, line });\n return;\n }\n const winner = this.pickDominantBorderLine(existing.line, line);\n if (winner === existing.line) {\n return;\n }\n edges.set(key, { boundaryIndex, fromColumn, toColumn, line: winner });\n }\n\n private addVerticalEdge(\n edges: Map<string, PendingVerticalEdge>,\n boundaryIndex: number,\n fromRow: number,\n toRow: number,\n line?: BorderLine,\n ): void {\n if (!line || line.width <= 0) {\n return;\n }\n const key = this.buildVerticalEdgeKey(boundaryIndex, fromRow, toRow);\n const existing = edges.get(key);\n if (!existing) {\n edges.set(key, { boundaryIndex, fromRow, toRow, line });\n return;\n }\n const winner = this.pickDominantBorderLine(existing.line, line);\n if (winner === existing.line) {\n return;\n }\n edges.set(key, { boundaryIndex, fromRow, toRow, line: winner });\n }\n\n private buildHorizontalEdgeKey(boundaryIndex: number, fromColumn: number, toColumn: number): string {\n return `h:${boundaryIndex}:${fromColumn}:${toColumn}`;\n }\n\n private buildVerticalEdgeKey(boundaryIndex: number, fromRow: number, toRow: number): string {\n return `v:${boundaryIndex}:${fromRow}:${toRow}`;\n }\n\n private pickDominantBorderLine(existing: BorderLine, candidate: BorderLine): BorderLine {\n if (candidate.width > existing.width) {\n return candidate;\n }\n if (candidate.width < existing.width) {\n return existing;\n }\n const existingPriority = this.getBorderStylePriority(existing.style);\n const candidatePriority = this.getBorderStylePriority(candidate.style);\n if (candidatePriority > existingPriority) {\n return candidate;\n }\n if (candidatePriority < existingPriority) {\n return existing;\n }\n const existingOrder = existing.appliedAt ?? 0;\n const candidateOrder = candidate.appliedAt ?? 0;\n return candidateOrder >= existingOrder ? candidate : existing;\n }\n\n private getBorderStylePriority(style: BorderLineStyle): number {\n switch (style) {\n case 'solid':\n return 3;\n case 'dashed':\n return 2;\n case 'dotted':\n default:\n return 1;\n }\n }\n\n private drawHorizontalBorderEdge(ctx: CanvasRenderingContext2D, edge: PendingHorizontalEdge): void {\n const dash = this.getDashPattern(edge.line.style, edge.line.width);\n ctx.setLineDash(dash);\n ctx.strokeStyle = edge.line.color;\n ctx.lineWidth = edge.line.width / this.context.getPixelRatio();\n const columnBoundaries = this.context.getColumnBoundaries();\n const rowBoundaries = this.context.getRowBoundaries();\n const { x: scrollX, y: scrollY } = this.context.getScrollOffset();\n const headerColumnWidth = this.context.getHeaderColumnWidth();\n const headerRowHeight = this.context.getHeaderRowHeight();\n const pixelAdjust = 0.5 / this.context.getPixelRatio();\n const xStart = headerColumnWidth - scrollX + columnBoundaries[edge.fromColumn];\n const xEnd = headerColumnWidth - scrollX + columnBoundaries[edge.toColumn + 1];\n const y = headerRowHeight - scrollY + rowBoundaries[edge.boundaryIndex] + pixelAdjust;\n\n ctx.beginPath();\n ctx.moveTo(xStart, y);\n ctx.lineTo(xEnd, y);\n ctx.stroke();\n ctx.setLineDash([]);\n }\n\n private drawVerticalBorderEdge(ctx: CanvasRenderingContext2D, edge: PendingVerticalEdge): void {\n const dash = this.getDashPattern(edge.line.style, edge.line.width);\n ctx.setLineDash(dash);\n ctx.strokeStyle = edge.line.color;\n ctx.lineWidth = edge.line.width / this.context.getPixelRatio();\n const columnBoundaries = this.context.getColumnBoundaries();\n const rowBoundaries = this.context.getRowBoundaries();\n const { x: scrollX, y: scrollY } = this.context.getScrollOffset();\n const headerColumnWidth = this.context.getHeaderColumnWidth();\n const headerRowHeight = this.context.getHeaderRowHeight();\n const pixelAdjust = 0.5 / this.context.getPixelRatio();\n const x = headerColumnWidth - scrollX + columnBoundaries[edge.boundaryIndex] + pixelAdjust;\n const yStart = headerRowHeight - scrollY + rowBoundaries[edge.fromRow];\n const yEnd = headerRowHeight - scrollY + rowBoundaries[edge.toRow + 1];\n\n ctx.beginPath();\n ctx.moveTo(x, yStart);\n ctx.lineTo(x, yEnd);\n ctx.stroke();\n ctx.setLineDash([]);\n }\n\n private drawHorizontalBorderEdgeWithOffset(\n ctx: CanvasRenderingContext2D,\n edge: PendingHorizontalEdge,\n baseOffsetX: number,\n baseOffsetY: number,\n scrollX: number,\n scrollY: number,\n ): void {\n const dash = this.getDashPattern(edge.line.style, edge.line.width);\n ctx.setLineDash(dash);\n ctx.strokeStyle = edge.line.color;\n ctx.lineWidth = edge.line.width / this.context.getPixelRatio();\n const columnBoundaries = this.context.getColumnBoundaries();\n const rowBoundaries = this.context.getRowBoundaries();\n const pixelAdjust = 0.5 / this.context.getPixelRatio();\n const xStart = baseOffsetX - scrollX + columnBoundaries[edge.fromColumn];\n const xEnd = baseOffsetX - scrollX + columnBoundaries[edge.toColumn + 1];\n const y = baseOffsetY - scrollY + rowBoundaries[edge.boundaryIndex] + pixelAdjust;\n ctx.beginPath();\n ctx.moveTo(xStart, y);\n ctx.lineTo(xEnd, y);\n ctx.stroke();\n ctx.setLineDash([]);\n }\n\n private drawVerticalBorderEdgeWithOffset(\n ctx: CanvasRenderingContext2D,\n edge: PendingVerticalEdge,\n baseOffsetX: number,\n baseOffsetY: number,\n scrollX: number,\n scrollY: number,\n ): void {\n const dash = this.getDashPattern(edge.line.style, edge.line.width);\n ctx.setLineDash(dash);\n ctx.strokeStyle = edge.line.color;\n ctx.lineWidth = edge.line.width / this.context.getPixelRatio();\n const columnBoundaries = this.context.getColumnBoundaries();\n const rowBoundaries = this.context.getRowBoundaries();\n const pixelAdjust = 0.5 / this.context.getPixelRatio();\n const x = baseOffsetX - scrollX + columnBoundaries[edge.boundaryIndex] + pixelAdjust;\n const yStart = baseOffsetY - scrollY + rowBoundaries[edge.fromRow];\n const yEnd = baseOffsetY - scrollY + rowBoundaries[edge.toRow + 1];\n ctx.beginPath();\n ctx.moveTo(x, yStart);\n ctx.lineTo(x, yEnd);\n ctx.stroke();\n ctx.setLineDash([]);\n }\n\n private getDashPattern(style: BorderLineStyle, width: number): number[] {\n switch (style) {\n case 'dashed':\n return [4 * width, 2 * width];\n case 'dotted':\n return [width, width];\n case 'solid':\n default:\n return [];\n }\n }\n}\n\nfunction columnIndexToName(index: number): string {\n let name = '';\n let n = index;\n do {\n const remainder = n % 26;\n name = String.fromCharCode(65 + remainder) + name;\n n = Math.floor(n / 26) - 1;\n } while (n >= 0);\n return name;\n}\n","export type ViewportRange = { start: number; end: number };\n\nexport type ViewportRect = { x: number; y: number; width: number; height: number };\n\nexport interface WorksheetViewportSource {\n headerColumnWidth: number;\n headerRowHeight: number;\n getBodyViewportWidth(): number;\n getBodyViewportHeight(): number;\n getScrollOffset(): { x: number; y: number };\n getFrozenRows(): number;\n getFrozenColumns(): number;\n getFrozenWidth(): number;\n getFrozenHeight(): number;\n getVisibleRowRange(padding?: number): ViewportRange;\n getVisibleColumnRange(padding?: number): ViewportRange;\n getVisibleRowIndices(): number[];\n getVisibleColumnIndices(): number[];\n getColumnBoundaries(): readonly number[];\n getRowBoundaries(): readonly number[];\n isRowHidden(row: number): boolean;\n isColumnHidden(column: number): boolean;\n rows: number;\n columns: number;\n}\n\nclass BaseViewport {\n rect: ViewportRect = { x: 0, y: 0, width: 0, height: 0 };\n rows: ViewportRange = { start: 0, end: -1 };\n columns: ViewportRange = { start: 0, end: -1 };\n\n setRect(rect: ViewportRect): void {\n this.rect = rect;\n }\n}\n\nexport class ColumnHeaderViewport extends BaseViewport {\n setRenderRange(columns: ViewportRange): void {\n this.columns = columns;\n // Column headers render on the first row of the sheet.\n this.rows = { start: 0, end: 0 };\n }\n}\n\nexport class RowHeaderViewport extends BaseViewport {\n setRenderRange(rows: ViewportRange): void {\n this.rows = rows;\n // Row headers render on the first column of the sheet.\n this.columns = { start: 0, end: 0 };\n }\n}\n\n/** A body viewport represents a clipped drawing region for cells. */\nexport interface BodyViewport {\n rect: ViewportRect;\n rows: ViewportRange;\n columns: ViewportRange;\n rowIndices: number[];\n columnIndices: number[];\n scrollOffsetX: number;\n scrollOffsetY: number;\n}\n\nexport type WorksheetViewports = {\n columnHeader: ColumnHeaderViewport;\n rowHeader: RowHeaderViewport;\n bodyViewports: BodyViewport[];\n};\n\nexport class ViewportController {\n readonly columnHeader = new ColumnHeaderViewport();\n readonly rowHeader = new RowHeaderViewport();\n\n constructor(private readonly worksheet: WorksheetViewportSource) {}\n\n update(): WorksheetViewports {\n const bodyViewports = this.buildBodyViewports();\n this.updateHeaderRanges(bodyViewports);\n return {\n columnHeader: this.columnHeader,\n rowHeader: this.rowHeader,\n bodyViewports,\n };\n }\n\n private buildBodyViewports(): BodyViewport[] {\n const ws = this.worksheet;\n const bodyWidth = ws.getBodyViewportWidth();\n const bodyHeight = ws.getBodyViewportHeight();\n const headerColW = ws.headerColumnWidth;\n const headerRowH = ws.headerRowHeight;\n const frozenRows = ws.getFrozenRows();\n const frozenCols = ws.getFrozenColumns();\n const frozenWidth = ws.getFrozenWidth();\n const frozenHeight = ws.getFrozenHeight();\n const { x: scrollX, y: scrollY } = ws.getScrollOffset();\n\n if (frozenRows === 0 && frozenCols === 0) {\n // No freeze — single viewport (backward compatible)\n const visibleRows = ws.getVisibleRowRange(0);\n const visibleColumns = ws.getVisibleColumnRange(0);\n const rowIndices = ws.getVisibleRowIndices();\n const columnIndices = ws.getVisibleColumnIndices();\n return [{\n rect: { x: headerColW, y: headerRowH, width: bodyWidth, height: bodyHeight },\n rows: visibleRows,\n columns: visibleColumns,\n rowIndices,\n columnIndices,\n scrollOffsetX: scrollX,\n scrollOffsetY: scrollY,\n }];\n }\n\n const viewports: BodyViewport[] = [];\n const colBoundaries = ws.getColumnBoundaries();\n const rowBoundaries = ws.getRowBoundaries();\n const scrollableWidth = Math.max(0, bodyWidth - frozenWidth);\n const scrollableHeight = Math.max(0, bodyHeight - frozenHeight);\n\n // Frozen columns range: 0..frozenCols-1\n const frozenColRange: ViewportRange = { start: 0, end: frozenCols - 1 };\n const frozenColIndices = this.rangeToIndices(frozenColRange);\n // Frozen rows range: 0..frozenRows-1\n const frozenRowRange: ViewportRange = { start: 0, end: frozenRows - 1 };\n const frozenRowIndices = this.rangeToRowIndices(frozenRowRange);\n\n // Scrollable visible ranges\n const scrollableColRange = this.computeScrollableColumnRange(scrollX, scrollableWidth, colBoundaries, frozenCols);\n const scrollableColIndices = this.rangeToIndices(scrollableColRange);\n const scrollableRowRange = this.computeScrollableRowRange(scrollY, scrollableHeight, rowBoundaries, frozenRows);\n const scrollableRowIndices = this.rangeToRowIndices(scrollableRowRange);\n\n // Top-left: frozen rows + frozen columns (no scroll)\n if (frozenRows > 0 && frozenCols > 0) {\n viewports.push({\n rect: { x: headerColW, y: headerRowH, width: frozenWidth, height: frozenHeight },\n rows: frozenRowRange,\n columns: frozenColRange,\n rowIndices: frozenRowIndices,\n columnIndices: frozenColIndices,\n scrollOffsetX: 0,\n scrollOffsetY: 0,\n });\n }\n\n // Top-right: frozen rows + scrollable columns (scroll X only)\n if (frozenRows > 0 && scrollableWidth > 0) {\n viewports.push({\n rect: { x: headerColW + frozenWidth, y: headerRowH, width: scrollableWidth, height: frozenHeight },\n rows: frozenRowRange,\n columns: scrollableColRange,\n rowIndices: frozenRowIndices,\n columnIndices: scrollableColIndices,\n scrollOffsetX: scrollX,\n scrollOffsetY: 0,\n });\n }\n\n // Bottom-left: scrollable rows + frozen columns (scroll Y only)\n if (frozenCols > 0 && scrollableHeight > 0) {\n viewports.push({\n rect: { x: headerColW, y: headerRowH + frozenHeight, width: frozenWidth, height: scrollableHeight },\n rows: scrollableRowRange,\n columns: frozenColRange,\n rowIndices: scrollableRowIndices,\n columnIndices: frozenColIndices,\n scrollOffsetX: 0,\n scrollOffsetY: scrollY,\n });\n }\n\n // Bottom-right: scrollable rows + scrollable columns (scroll X + Y)\n if (scrollableWidth > 0 && scrollableHeight > 0) {\n viewports.push({\n rect: { x: headerColW + frozenWidth, y: headerRowH + frozenHeight, width: scrollableWidth, height: scrollableHeight },\n rows: scrollableRowRange,\n columns: scrollableColRange,\n rowIndices: scrollableRowIndices,\n columnIndices: scrollableColIndices,\n scrollOffsetX: scrollX,\n scrollOffsetY: scrollY,\n });\n }\n\n return viewports;\n }\n\n private computeScrollableColumnRange(\n scrollX: number,\n viewportWidth: number,\n colBoundaries: readonly number[],\n frozenCols: number,\n ): ViewportRange {\n const ws = this.worksheet;\n if (ws.columns <= frozenCols) {\n return { start: frozenCols, end: frozenCols - 1 };\n }\n const frozenOffset = colBoundaries[frozenCols] ?? 0;\n const startOffset = frozenOffset + scrollX;\n const endOffset = startOffset + viewportWidth;\n const start = this.findIndex(startOffset, colBoundaries, frozenCols, ws.columns - 1);\n const end = this.findIndex(endOffset, colBoundaries, frozenCols, ws.columns - 1);\n return { start, end: Math.min(end + 1, ws.columns - 1) };\n }\n\n private computeScrollableRowRange(\n scrollY: number,\n viewportHeight: number,\n rowBoundaries: readonly number[],\n frozenRows: number,\n ): ViewportRange {\n const ws = this.worksheet;\n if (ws.rows <= frozenRows) {\n return { start: frozenRows, end: frozenRows - 1 };\n }\n const frozenOffset = rowBoundaries[frozenRows] ?? 0;\n const startOffset = frozenOffset + scrollY;\n const endOffset = startOffset + viewportHeight;\n const start = this.findIndex(startOffset, rowBoundaries, frozenRows, ws.rows - 1);\n const end = this.findIndex(endOffset, rowBoundaries, frozenRows, ws.rows - 1);\n return { start, end: Math.min(end + 1, ws.rows - 1) };\n }\n\n private findIndex(offset: number, boundaries: readonly number[], min: number, max: number): number {\n let low = min;\n let high = max;\n while (low <= high) {\n const mid = (low + high) >> 1;\n if (offset < boundaries[mid]) {\n high = mid - 1;\n } else if (offset >= boundaries[mid + 1]) {\n low = mid + 1;\n } else {\n return mid;\n }\n }\n return Math.max(min, Math.min(max, low));\n }\n\n private rangeToIndices(range: ViewportRange): number[] {\n const indices: number[] = [];\n for (let i = range.start; i <= range.end; i += 1) {\n if (!this.worksheet.isColumnHidden(i)) {\n indices.push(i);\n }\n }\n return indices;\n }\n\n private rangeToRowIndices(range: ViewportRange): number[] {\n const indices: number[] = [];\n for (let i = range.start; i <= range.end; i += 1) {\n if (!this.worksheet.isRowHidden(i)) {\n indices.push(i);\n }\n }\n return indices;\n }\n\n private updateHeaderRanges(bodyViewports: BodyViewport[]): void {\n const ws = this.worksheet;\n const bodyWidth = ws.getBodyViewportWidth();\n const bodyHeight = ws.getBodyViewportHeight();\n\n this.columnHeader.setRect({\n x: ws.headerColumnWidth,\n y: 0,\n width: bodyWidth,\n height: ws.headerRowHeight,\n });\n this.rowHeader.setRect({\n x: 0,\n y: ws.headerRowHeight,\n width: ws.headerColumnWidth,\n height: bodyHeight,\n });\n\n // Compute the full visible column/row range from all body viewports\n if (bodyViewports.length > 0) {\n let minCol = bodyViewports[0].columns.start;\n let maxCol = bodyViewports[0].columns.end;\n let minRow = bodyViewports[0].rows.start;\n let maxRow = bodyViewports[0].rows.end;\n for (let i = 1; i < bodyViewports.length; i += 1) {\n const vp = bodyViewports[i];\n if (vp.columns.start < minCol) minCol = vp.columns.start;\n if (vp.columns.end > maxCol) maxCol = vp.columns.end;\n if (vp.rows.start < minRow) minRow = vp.rows.start;\n if (vp.rows.end > maxRow) maxRow = vp.rows.end;\n }\n this.columnHeader.setRenderRange({ start: minCol, end: maxCol });\n this.rowHeader.setRenderRange({ start: minRow, end: maxRow });\n } else {\n this.columnHeader.setRenderRange({ start: 0, end: -1 });\n this.rowHeader.setRenderRange({ start: 0, end: -1 });\n }\n }\n}\n","/* eslint-disable no-bitwise */\n/**\n * Portions of the DEFLATE implementation are adapted from SheetJS (MIT License).\n * https://github.com/SheetJS/sheetjs\n */\n\nconst EOCD_SIGNATURE = 0x06054b50;\nconst CENTRAL_DIR_SIGNATURE = 0x02014b50;\nconst LOCAL_FILE_HEADER_SIGNATURE = 0x04034b50;\n\nconst textDecoder: TextDecoder | null = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8') : null;\n\ntype ZipEntry = {\n name: string;\n compression: number;\n compressedSize: number;\n uncompressedSize: number;\n localHeaderOffset: number;\n};\n\nexport type ZipMap = Record<string, Uint8Array>;\n\nexport function unzip(data: Uint8Array): ZipMap {\n const entries = readCentralDirectory(data);\n const files: ZipMap = {};\n for (const entry of entries) {\n if (entry.name.endsWith('/')) {\n continue;\n }\n files[entry.name] = extractEntry(data, entry);\n }\n return files;\n}\n\nfunction readCentralDirectory(bytes: Uint8Array): ZipEntry[] {\n const eocdOffset = findEndOfCentralDirectory(bytes);\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n const totalEntries = view.getUint16(eocdOffset + 10, true);\n const centralDirOffset = view.getUint32(eocdOffset + 16, true);\n const entries: ZipEntry[] = [];\n let offset = centralDirOffset;\n for (let i = 0; i < totalEntries; i += 1) {\n const signature = view.getUint32(offset, true);\n if (signature !== CENTRAL_DIR_SIGNATURE) {\n throw new Error('Invalid central directory signature.');\n }\n const compression = view.getUint16(offset + 10, true);\n const compressedSize = view.getUint32(offset + 20, true);\n const uncompressedSize = view.getUint32(offset + 24, true);\n const nameLength = view.getUint16(offset + 28, true);\n const extraLength = view.getUint16(offset + 30, true);\n const commentLength = view.getUint16(offset + 32, true);\n const localHeaderOffset = view.getUint32(offset + 42, true);\n const nameBytes = bytes.subarray(offset + 46, offset + 46 + nameLength);\n const name = normalizePath(decodeUtf8(nameBytes));\n entries.push({\n name,\n compression,\n compressedSize,\n uncompressedSize,\n localHeaderOffset,\n });\n offset += 46 + nameLength + extraLength + commentLength;\n }\n return entries;\n}\n\nfunction findEndOfCentralDirectory(bytes: Uint8Array): number {\n for (let i = bytes.length - 22; i >= 0; i -= 1) {\n if (\n bytes[i] === 0x50 &&\n bytes[i + 1] === 0x4b &&\n bytes[i + 2] === 0x05 &&\n bytes[i + 3] === 0x06\n ) {\n return i;\n }\n }\n throw new Error('End of central directory record was not found.');\n}\n\nfunction extractEntry(bytes: Uint8Array, entry: ZipEntry): Uint8Array {\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n let offset = entry.localHeaderOffset;\n const signature = view.getUint32(offset, true);\n if (signature !== LOCAL_FILE_HEADER_SIGNATURE) {\n throw new Error(`Invalid local file header for ${entry.name}.`);\n }\n offset += 4; // signature\n offset += 2; // version\n const flags = view.getUint16(offset, true);\n offset += 2;\n const compression = view.getUint16(offset, true);\n offset += 2;\n offset += 8; // mod time/date + crc\n const _compressedSize = view.getUint32(offset, true);\n offset += 4;\n const _uncompressedSize = view.getUint32(offset, true);\n offset += 4;\n const nameLength = view.getUint16(offset, true);\n offset += 2;\n const extraLength = view.getUint16(offset, true);\n offset += 2;\n const dataStart = entry.localHeaderOffset + 30 + nameLength + extraLength;\n const compressedSize = flags & 0x0008 ? entry.compressedSize : _compressedSize;\n const uncompressedSize = flags & 0x0008 ? entry.uncompressedSize : _uncompressedSize;\n const compressed = bytes.subarray(dataStart, dataStart + compressedSize);\n if (compression === 0) {\n return compressed.slice();\n }\n if (compression === 8) {\n return inflateRaw(compressed, uncompressedSize);\n }\n throw new Error(`Unsupported ZIP compression method ${compression} in ${entry.name}.`);\n}\n\nfunction normalizePath(path: string): string {\n const withoutLeading = path.replace(/^[./\\\\]+/, '');\n return withoutLeading.replace(/\\\\/g, '/');\n}\n\nfunction decodeUtf8(bytes: Uint8Array): string {\n if (textDecoder) {\n return textDecoder.decode(bytes);\n }\n let result = '';\n for (let i = 0; i < bytes.length; i += 1) {\n result += String.fromCharCode(bytes[i]);\n }\n return result;\n}\n\n// -- Deflate implementation -------------------------------------------------\n\nconst CLEN_ORDER = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15];\nconst LEN_LN = [3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258];\nconst DST_LN = [1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577];\n\nconst bitswap8 = new Uint8Array(1 << 8);\nfor (let i = 0; i < bitswap8.length; i += 1) {\n bitswap8[i] = bitSwap8(i);\n}\n\nconst dynLiteralMap = new Uint16Array(32768);\nconst dynDistanceMap = new Uint16Array(32768);\nconst dynCodeMap = new Uint16Array(128);\nlet dynLiteralMax = 1;\nlet dynDistanceMax = 1;\n\nfunction inflateRaw(data: Uint8Array, expectedSize: number): Uint8Array {\n const [result] = inflate(data, expectedSize);\n return expectedSize ? result.slice(0, expectedSize) : result;\n}\n\nfunction inflate(data: Uint8Array, expectedSize: number): [Uint8Array, number] {\n if (data[0] === 3 && (data[1] & 3) === 0) {\n return [new Uint8Array(expectedSize), 2];\n }\n let bitOffset = 0;\n let header = 0;\n let outBuffer = createBuffer(expectedSize || 1 << 18);\n let writeOffset = 0;\n let maxLiteralBits = 0;\n let maxDistanceBits = 0;\n\n const literalMap = fixedLiteralMap;\n const distanceMap = fixedDistanceMap;\n\n while ((header & 1) === 0) {\n header = readBits3(data, bitOffset);\n bitOffset += 3;\n if ((header >>> 1) === 0) {\n if (bitOffset & 7) {\n bitOffset += 8 - (bitOffset & 7);\n }\n let size = data[bitOffset >>> 3] | (data[(bitOffset >>> 3) + 1] << 8);\n bitOffset += 32;\n if (size > 0) {\n if (!expectedSize && outBuffer.length < writeOffset + size) {\n outBuffer = growBuffer(outBuffer, writeOffset + size);\n }\n while (size > 0) {\n outBuffer[writeOffset++] = data[bitOffset >>> 3];\n bitOffset += 8;\n size -= 1;\n }\n }\n continue;\n }\n if ((header >> 1) === 1) {\n maxLiteralBits = 9;\n maxDistanceBits = 5;\n } else {\n bitOffset = buildDynamicTrees(data, bitOffset);\n maxLiteralBits = dynLiteralMax;\n maxDistanceBits = dynDistanceMax;\n }\n\n for (;;) {\n if (!expectedSize && outBuffer.length < writeOffset + 32767) {\n outBuffer = growBuffer(outBuffer, writeOffset + 32767);\n }\n const literalBits = readBitsN(data, bitOffset, maxLiteralBits);\n const literalCode =\n (header >>> 1) === 1 ? literalMap[literalBits] : dynLiteralMap[literalBits];\n bitOffset += literalCode & 15;\n let code = literalCode >>> 4;\n if ((code >>> 8 & 255) === 0) {\n outBuffer[writeOffset++] = code;\n continue;\n }\n if (code === 256) {\n break;\n }\n code -= 257;\n let lengthExtraBits = code < 8 ? 0 : (code - 4) >> 2;\n if (lengthExtraBits > 5) {\n lengthExtraBits = 0;\n }\n let target = writeOffset + LEN_LN[code];\n if (lengthExtraBits > 0) {\n target += readBitsN(data, bitOffset, lengthExtraBits);\n bitOffset += lengthExtraBits;\n }\n const distBits = readBitsN(data, bitOffset, maxDistanceBits);\n let distCode =\n (header >>> 1) === 1 ? distanceMap[distBits] : dynDistanceMap[distBits];\n bitOffset += distCode & 15;\n distCode >>>= 4;\n let distExtraBits = distCode < 4 ? 0 : (distCode - 2) >> 1;\n let distance = DST_LN[distCode];\n if (distExtraBits > 0) {\n distance += readBitsN(data, bitOffset, distExtraBits);\n bitOffset += distExtraBits;\n }\n if (!expectedSize && outBuffer.length < target) {\n outBuffer = growBuffer(outBuffer, target + 100);\n }\n while (writeOffset < target) {\n outBuffer[writeOffset] = outBuffer[writeOffset - distance];\n writeOffset += 1;\n }\n }\n }\n if (expectedSize) {\n return [outBuffer, (bitOffset + 7) >>> 3];\n }\n return [outBuffer.slice(0, writeOffset), (bitOffset + 7) >>> 3];\n}\n\nfunction buildDynamicTrees(data: Uint8Array, bitOffset: number): number {\n const HLIT = readBits5(data, bitOffset) + 257;\n bitOffset += 5;\n const HDIST = readBits5(data, bitOffset) + 1;\n bitOffset += 5;\n const HCLEN = readBits4(data, bitOffset) + 4;\n bitOffset += 4;\n\n const codeLengths = new Uint8Array(19);\n let maxLen = 1;\n const bitCounts = new Uint8Array(8);\n const nextCodes = new Uint8Array(8);\n for (let i = 0; i < HCLEN; i += 1) {\n const value = readBits3(data, bitOffset);\n const index = CLEN_ORDER[i];\n codeLengths[index] = value;\n if (maxLen < value) {\n maxLen = value;\n }\n bitCounts[value] += 1;\n bitOffset += 3;\n }\n let code = 0;\n bitCounts[0] = 0;\n for (let i = 1; i <= maxLen; i += 1) {\n nextCodes[i] = code = (code + bitCounts[i - 1]) << 1;\n }\n const codeTree = new Uint16Array(19);\n for (let i = 0; i < codeLengths.length; i += 1) {\n const len = codeLengths[i];\n if (len !== 0) {\n codeTree[i] = nextCodes[len]++;\n }\n }\n const codeMap = dynCodeMap;\n codeMap.fill(0);\n for (let i = 0; i < codeLengths.length; i += 1) {\n const len = codeLengths[i];\n if (len !== 0) {\n const swapped = bitswap8[codeTree[i]] >> (8 - len);\n for (let j = (1 << (7 - len)) - 1; j >= 0; --j) {\n codeMap[swapped | (j << len)] = (len & 7) | (i << 3);\n }\n }\n }\n const hCodes: number[] = [];\n maxLen = 1;\n while (hCodes.length < HLIT + HDIST) {\n let symbol = codeMap[readBits7(data, bitOffset)];\n bitOffset += symbol & 7;\n symbol >>>= 3;\n if (symbol === 16) {\n let repeat = 3 + readBits2(data, bitOffset);\n bitOffset += 2;\n const last = hCodes[hCodes.length - 1];\n while (repeat-- > 0) {\n hCodes.push(last);\n }\n } else if (symbol === 17) {\n let repeat = 3 + readBits3(data, bitOffset);\n bitOffset += 3;\n while (repeat-- > 0) {\n hCodes.push(0);\n }\n } else if (symbol === 18) {\n let repeat = 11 + readBits7(data, bitOffset);\n bitOffset += 7;\n while (repeat-- > 0) {\n hCodes.push(0);\n }\n } else {\n hCodes.push(symbol);\n if (maxLen < symbol) {\n maxLen = symbol;\n }\n }\n }\n const literalLengths = hCodes.slice(0, HLIT);\n const distanceLengths = hCodes.slice(HLIT);\n while (literalLengths.length < 286) literalLengths.push(0);\n while (distanceLengths.length < 30) distanceLengths.push(0);\n dynLiteralMax = buildTree(literalLengths, dynLiteralMap, 286);\n dynDistanceMax = buildTree(distanceLengths, dynDistanceMap, 30);\n return bitOffset;\n}\n\nfunction buildTree(codeLengths: number[], target: Uint16Array, maxSymbols: number): number {\n let maxLen = 1;\n const counts = new Uint16Array(32);\n for (let i = 0; i < codeLengths.length; i += 1) {\n const len = codeLengths[i] || 0;\n codeLengths[i] = len;\n counts[len] += 1;\n if (maxLen < len) {\n maxLen = len;\n }\n }\n counts[0] = 0;\n let code = 0;\n const nextCode = new Uint16Array(32);\n for (let i = 1; i <= maxLen; i += 1) {\n nextCode[i] = code = (code + counts[i - 1]) << 1;\n }\n for (let i = 0; i < maxSymbols; i += 1) {\n const len = codeLengths[i] || 0;\n if (len !== 0) {\n const val = bitSwapN(nextCode[len], maxLen) >> (maxLen - len);\n nextCode[len] += 1;\n for (let j = (1 << (maxLen + 4 - len)) - 1; j >= 0; --j) {\n target[val | (j << len)] = (len & 15) | (i << 4);\n }\n }\n }\n return maxLen;\n}\n\nconst fixedLiteralMap = new Uint16Array(512);\nconst fixedDistanceMap = new Uint16Array(32);\n\n(function initializeFixedTables() {\n const distLens: number[] = [];\n for (let i = 0; i < 32; i += 1) distLens.push(5);\n buildTree(distLens, fixedDistanceMap, 32);\n\n const literalLens: number[] = [];\n for (let i = 0; i <= 143; i += 1) literalLens.push(8);\n for (let i = 144; i <= 255; i += 1) literalLens.push(9);\n for (let i = 256; i <= 279; i += 1) literalLens.push(7);\n for (let i = 280; i <= 287; i += 1) literalLens.push(8);\n buildTree(literalLens, fixedLiteralMap, 288);\n})();\n\nfunction growBuffer(buffer: Uint8Array, size: number): Uint8Array {\n if (buffer.length >= size) {\n return buffer;\n }\n const next = new Uint8Array(Math.max(buffer.length * 2, size));\n next.set(buffer);\n return next;\n}\n\nfunction createBuffer(size: number): Uint8Array {\n return new Uint8Array(size);\n}\n\nfunction bitSwap8(value: number): number {\n const t =\n (((value << 1) | (value << 11)) & 139536) |\n (((value << 5) | (value << 15)) & 558144);\n return ((t >> 16) | (t >> 8) | t) & 255;\n}\n\nfunction bitSwapN(value: number, bits: number): number {\n let rev = bitswap8[value & 0xff];\n if (bits <= 8) {\n return rev >>> (8 - bits);\n }\n rev = (rev << 8) | bitswap8[(value >> 8) & 0xff];\n if (bits <= 16) {\n return rev >>> (16 - bits);\n }\n rev = (rev << 8) | bitswap8[(value >> 16) & 0xff];\n return rev >>> (24 - bits);\n}\n\nfunction readBits2(buf: Uint8Array, bitOffset: number): number {\n const w = bitOffset & 7;\n const h = bitOffset >>> 3;\n return (buf[h] | (w <= 6 ? 0 : buf[h + 1] << 8)) >>> w & 3;\n}\n\nfunction readBits3(buf: Uint8Array, bitOffset: number): number {\n const w = bitOffset & 7;\n const h = bitOffset >>> 3;\n return (buf[h] | (w <= 5 ? 0 : buf[h + 1] << 8)) >>> w & 7;\n}\n\nfunction readBits4(buf: Uint8Array, bitOffset: number): number {\n const w = bitOffset & 7;\n const h = bitOffset >>> 3;\n return (buf[h] | (w <= 4 ? 0 : buf[h + 1] << 8)) >>> w & 15;\n}\n\nfunction readBits5(buf: Uint8Array, bitOffset: number): number {\n const w = bitOffset & 7;\n const h = bitOffset >>> 3;\n return (buf[h] | (w <= 3 ? 0 : buf[h + 1] << 8)) >>> w & 31;\n}\n\nfunction readBits7(buf: Uint8Array, bitOffset: number): number {\n const w = bitOffset & 7;\n const h = bitOffset >>> 3;\n return (buf[h] | (w <= 1 ? 0 : buf[h + 1] << 8)) >>> w & 127;\n}\n\nfunction readBitsN(buf: Uint8Array, bitOffset: number, n: number): number {\n const w = bitOffset & 7;\n const h = bitOffset >>> 3;\n const mask = (1 << n) - 1;\n let value = buf[h] >>> w;\n if (n < 8 - w) {\n return value & mask;\n }\n value |= buf[h + 1] << (8 - w);\n if (n < 16 - w) {\n return value & mask;\n }\n value |= buf[h + 2] << (16 - w);\n if (n < 24 - w) {\n return value & mask;\n }\n value |= buf[h + 3] << (24 - w);\n return value & mask;\n}\n","export interface XmlNode {\n name: string;\n attributes: Record<string, string>;\n children: XmlNode[];\n text: string;\n}\n\nconst XML_ENTITY_MAP: Record<string, string> = {\n amp: '&',\n lt: '<',\n gt: '>',\n quot: '\"',\n apos: \"'\",\n};\n\n/**\n * Extremely small XML parser that is sufficient for the subset of OpenXML data\n * we need. It is not a full XML implementation but supports attributes,\n * self-closing tags, CDATA, namespaces, and nested nodes.\n */\nexport function parseXml(xml: string): XmlNode {\n const root: XmlNode = { name: '__root__', attributes: {}, children: [], text: '' };\n const stack: XmlNode[] = [root];\n const tokenRegex = /<!\\[CDATA\\[([\\s\\S]*?)\\]\\]>|<!--[\\s\\S]*?-->|<[^>]+>|[^<]+/g;\n let match: RegExpExecArray | null;\n\n while ((match = tokenRegex.exec(xml)) !== null) {\n // CDATA block\n if (match[1] !== undefined) {\n stack[stack.length - 1].text += match[1];\n continue;\n }\n\n const token = match[0];\n if (!token) {\n continue;\n }\n\n if (token.startsWith('<!--')) {\n continue;\n }\n\n if (token.startsWith('<?') || token.startsWith('<!')) {\n continue;\n }\n\n if (token.startsWith('</')) {\n stack.pop();\n continue;\n }\n\n if (token.startsWith('<')) {\n const selfClosing = token.endsWith('/>');\n const content = token.slice(1, selfClosing ? -2 : -1).trim();\n if (!content) {\n continue;\n }\n const nameMatch = /^[^\\s/>]+/.exec(content);\n if (!nameMatch) {\n continue;\n }\n const tagName = nameMatch[0];\n const attrString = content.slice(tagName.length).trim();\n const node: XmlNode = {\n name: tagName,\n attributes: parseAttributes(attrString),\n children: [],\n text: '',\n };\n stack[stack.length - 1].children.push(node);\n if (!selfClosing) {\n stack.push(node);\n }\n continue;\n }\n\n const text = decodeXmlEntities(token);\n if (!text.length) {\n continue;\n }\n const target = stack[stack.length - 1];\n if (!/\\S/.test(text) && target.attributes['xml:space'] !== 'preserve') {\n continue;\n }\n target.text += text;\n }\n\n return root;\n}\n\nexport function localName(name: string): string {\n const index = name.indexOf(':');\n return index >= 0 ? name.slice(index + 1) : name;\n}\n\nexport function findChildren(node: XmlNode, tagName: string): XmlNode[] {\n const target = localName(tagName);\n return node.children.filter((child) => localName(child.name) === target);\n}\n\nexport function findChild(node: XmlNode, tagName: string): XmlNode | undefined {\n const target = localName(tagName);\n return node.children.find((child) => localName(child.name) === target);\n}\n\nexport function getTextContent(node: XmlNode): string {\n let output = node.text ?? '';\n for (const child of node.children) {\n output += getTextContent(child);\n }\n return output;\n}\n\nfunction parseAttributes(input: string): Record<string, string> {\n if (!input) {\n return {};\n }\n const attributes: Record<string, string> = {};\n const regex = /([^\\s=]+)\\s*=\\s*(\"([^\"]*)\"|'([^']*)')/g;\n let match: RegExpExecArray | null;\n while ((match = regex.exec(input)) !== null) {\n const [, key, , doubleValue, singleValue] = match;\n attributes[key] = decodeXmlEntities(doubleValue ?? singleValue ?? '');\n }\n return attributes;\n}\n\nfunction decodeXmlEntities(text: string): string {\n return text.replace(/&(#\\d+|#x[0-9a-fA-F]+|\\w+);/g, (match, entity) => {\n if (entity[0] === '#') {\n const codePoint = entity[1] === 'x' || entity[1] === 'X' ? parseInt(entity.slice(2), 16) : parseInt(entity.slice(1), 10);\n if (!Number.isNaN(codePoint)) {\n return String.fromCodePoint(codePoint);\n }\n return '';\n }\n return XML_ENTITY_MAP[entity] ?? match;\n });\n}\n","import { unzip } from './unzip';\nimport { findChild, findChildren, getTextContent, localName, parseXml, type XmlNode } from './xml';\nimport type { RichTextRun } from '../types/richText';\n\nexport type Range = { s: { r: number; c: number }; e: { r: number; c: number } };\nexport type WorksheetMergeRange = { s: { r: number; c: number }; e: { r: number; c: number } };\n\nexport type ColumnInfo = { wpx?: number; wch?: number; width?: number; custom?: boolean };\nexport type RowInfo = { hpx?: number; hpt?: number; custom?: boolean };\nexport type SheetFormatProperties = {\n defaultRowHeight?: number;\n defaultColWidth?: number;\n customHeight?: boolean;\n};\nexport type SheetView = {\n showGridLines?: boolean;\n frozenRows?: number;\n frozenColumns?: number;\n};\n\nexport type DrawingAnchorPosition = {\n row: number;\n column: number;\n rowOffset: number;\n columnOffset: number;\n};\n\nexport type WorksheetImageAnchor =\n | { type: 'oneCell'; from: DrawingAnchorPosition; width: number; height: number }\n | { type: 'twoCell'; from: DrawingAnchorPosition; to: DrawingAnchorPosition };\n\nexport type WorksheetImage = {\n id: string;\n imagePath: string;\n format: string;\n mimeType: string;\n data: Uint8Array;\n anchor: WorksheetImageAnchor;\n};\n\nexport type ExcelFont = {\n name?: string;\n size?: number;\n color?: ExcelColor;\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n};\n\nexport type CellStyle = {\n alignment?: { horizontal?: string; vertical?: string };\n font?: ExcelFont;\n numFmtId?: number;\n formatCode?: string;\n};\n\nexport type CellObject = {\n v: string | number | boolean | null;\n value?: string | number | boolean | null;\n t: string;\n s?: CellStyle;\n richText?: RichTextRun[];\n /** Formula string (without leading '='), e.g. \"SUM(A1:A3)\" */\n f?: string;\n};\n\nexport type WorkSheet = {\n [address: string]:\n | CellObject\n | string\n | ColumnInfo[]\n | RowInfo[]\n | WorksheetMergeRange[]\n | SheetFormatProperties\n | WorksheetImage[]\n | SheetView\n | undefined;\n '!ref'?: string;\n '!cols'?: ColumnInfo[];\n '!rows'?: RowInfo[];\n '!merges'?: WorksheetMergeRange[];\n '!sheetFormat'?: SheetFormatProperties;\n '!images'?: WorksheetImage[];\n '!sheetView'?: SheetView;\n};\n\ntype SharedStringEntry = { text: string; richText?: RichTextRun[] };\n\nexport type ExcelBorderLine = { style?: string; color?: ExcelColor };\nexport type ExcelBorder = {\n left?: ExcelBorderLine;\n right?: ExcelBorderLine;\n top?: ExcelBorderLine;\n bottom?: ExcelBorderLine;\n};\nexport type ExcelColor = { rgb?: string; indexed?: number; theme?: number; tint?: number };\nexport type ExcelFill = { patternType?: string; fgColor?: ExcelColor; bgColor?: ExcelColor };\n\nexport type CellXfRecord = {\n borderId?: number;\n fillId?: number;\n fontId?: number;\n numFmtId?: number;\n alignment?: { horizontal?: string; vertical?: string; wrapText?: string };\n};\n\ntype WorkbookColors = {\n indexed?: Array<string | null>;\n};\n\nexport type WorkbookStyles = {\n CellXf?: CellXfRecord[];\n Borders?: ExcelBorder[];\n Fills?: Array<ExcelFill | undefined>;\n Fonts?: ExcelFont[];\n NumberFormats?: Map<number, string>;\n Colors?: WorkbookColors;\n};\n\nexport type WorkBook = {\n SheetNames: string[];\n Sheets: Record<string, WorkSheet>;\n Styles?: WorkbookStyles;\n Directory?: { sheets?: string[] };\n files?: Record<string, { content?: string } | string>;\n};\n\nexport type SheetToJsonOptions = {\n header?: 1;\n defval?: string | number | boolean | null;\n raw?: boolean;\n};\n\nexport type ReadOptions = {\n type?: 'binary' | 'array';\n cellStyles?: boolean;\n bookFiles?: boolean;\n};\n\nconst textDecoder: TextDecoder | null = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8') : null;\n\nexport const utils = {\n sheet_to_json,\n encode_cell: encodeCell,\n decode_cell: decodeCell,\n decode_range: decodeRange,\n};\n\nexport function read(data: ArrayBuffer | Uint8Array | string, _options?: ReadOptions): WorkBook {\n const bytes = normalizeInput(data);\n const zipEntries = unzip(bytes);\n const workbookXml = readXml(zipEntries, 'xl/workbook.xml');\n const workbookDoc = parseXml(workbookXml);\n const workbookNode = workbookDoc.children.find((child) => localName(child.name) === 'workbook') ?? workbookDoc.children[0];\n if (!workbookNode) {\n throw new Error('Workbook XML is invalid.');\n }\n const sheetsNode = findChild(workbookNode, 'sheets');\n if (!sheetsNode) {\n throw new Error('Workbook does not contain sheets metadata.');\n }\n const sheetNodes = findChildren(sheetsNode, 'sheet');\n if (!sheetNodes.length) {\n throw new Error('Workbook does not contain any sheets.');\n }\n const relationships = readWorkbookRelationships(zipEntries);\n const sharedStrings = readSharedStrings(zipEntries);\n const styles = readStyles(zipEntries);\n\n const workbook: WorkBook = {\n SheetNames: [],\n Sheets: {},\n Styles: styles,\n Directory: { sheets: [] },\n files: {},\n };\n\n sheetNodes.forEach((sheetNode) => {\n const name = sheetNode.attributes.name;\n const relId = sheetNode.attributes['r:id'];\n if (!name || !relId) {\n return;\n }\n const path = relationships.get(relId);\n if (!path) {\n throw new Error(`Unable to resolve worksheet path for ${name}.`);\n }\n const sheetXml = readXml(zipEntries, path);\n const worksheet = readWorksheet(sheetXml, sharedStrings, styles, zipEntries, path);\n workbook.SheetNames.push(name);\n workbook.Sheets[name] = worksheet;\n workbook.Directory?.sheets?.push(path);\n workbook.files![path] = sheetXml;\n });\n\n return workbook;\n}\n\nfunction readWorksheet(\n xml: string,\n sharedStrings: SharedStringEntry[],\n styles: WorkbookStyles | undefined,\n zipEntries: Record<string, Uint8Array>,\n sheetPath: string,\n): WorkSheet {\n const doc = parseXml(xml);\n const root = doc.children.find((child) => localName(child.name) === 'worksheet') ?? doc.children[0];\n if (!root) {\n throw new Error('Worksheet XML is invalid.');\n }\n const worksheet: WorkSheet = {};\n const dimensionRef = findChild(root, 'dimension')?.attributes.ref;\n const sheetFormatNode = findChild(root, 'sheetFormatPr');\n const sheetViewsNode = findChild(root, 'sheetViews');\n if (sheetViewsNode) {\n const viewNode = findChild(sheetViewsNode, 'sheetView');\n if (viewNode?.attributes) {\n const sheetView: SheetView = {};\n const showGridLinesAttr =\n viewNode.attributes.showGridLines ?? viewNode.attributes.showgridlines;\n const showGridLines = parseBooleanAttribute(showGridLinesAttr);\n if (showGridLines !== null) {\n sheetView.showGridLines = showGridLines;\n }\n const paneNode = findChild(viewNode, 'pane');\n if (paneNode?.attributes) {\n const state = paneNode.attributes.state ?? paneNode.attributes.State;\n if (state === 'frozen' || state === 'frozenSplit') {\n const ySplit = parseInt(paneNode.attributes.ySplit ?? paneNode.attributes.ysplit ?? '0', 10);\n const xSplit = parseInt(paneNode.attributes.xSplit ?? paneNode.attributes.xsplit ?? '0', 10);\n if (Number.isFinite(ySplit) && ySplit > 0) {\n sheetView.frozenRows = ySplit;\n }\n if (Number.isFinite(xSplit) && xSplit > 0) {\n sheetView.frozenColumns = xSplit;\n }\n }\n }\n if (sheetView.showGridLines !== undefined || sheetView.frozenRows || sheetView.frozenColumns) {\n worksheet['!sheetView'] = sheetView;\n }\n }\n }\n if (sheetFormatNode) {\n const format: SheetFormatProperties = {};\n const defaultRowHeight = parseFloat(sheetFormatNode.attributes.defaultRowHeight ?? '');\n if (Number.isFinite(defaultRowHeight)) {\n format.defaultRowHeight = defaultRowHeight;\n }\n const defaultColWidth = parseFloat(sheetFormatNode.attributes.defaultColWidth ?? '');\n if (Number.isFinite(defaultColWidth)) {\n format.defaultColWidth = defaultColWidth;\n }\n if (sheetFormatNode.attributes.customHeight !== undefined) {\n format.customHeight = sheetFormatNode.attributes.customHeight === '1';\n }\n if (Object.keys(format).length > 0) {\n worksheet['!sheetFormat'] = format;\n }\n }\n const colsNode = findChild(root, 'cols');\n if (colsNode) {\n worksheet['!cols'] = readColumns(colsNode);\n }\n const sheetDataNode = findChild(root, 'sheetData');\n const { minRow, minCol, maxRow, maxCol } = readSheetData(sheetDataNode, worksheet, sharedStrings, styles);\n const mergesNode = findChild(root, 'mergeCells');\n if (mergesNode) {\n worksheet['!merges'] = readMerges(mergesNode);\n }\n const rowsNode = sheetDataNode ? findChildren(sheetDataNode, 'row') : [];\n if (rowsNode.length) {\n worksheet['!rows'] = readRowsInfo(rowsNode);\n }\n const images = readWorksheetImages(root, zipEntries, sheetPath);\n if (images.length) {\n worksheet['!images'] = images;\n }\n worksheet['!ref'] =\n dimensionRef ??\n encodeRange({\n s: { r: Math.max(minRow, 0), c: Math.max(minCol, 0) },\n e: { r: Math.max(maxRow, 0), c: Math.max(maxCol, 0) },\n });\n return worksheet;\n}\n\nfunction readColumns(colsNode: XmlNode): ColumnInfo[] {\n const columns: ColumnInfo[] = [];\n const colNodes = findChildren(colsNode, 'col');\n for (const colNode of colNodes) {\n const min = Math.max(parseInt(colNode.attributes.min ?? '1', 10) - 1, 0);\n const max = Math.max(parseInt(colNode.attributes.max ?? String(min + 1), 10) - 1, min);\n const width = colNode.attributes.width ? Number(colNode.attributes.width) : undefined;\n const wpx = typeof width === 'number' ? charWidthToPixels(width) : undefined;\n const customAttr = colNode.attributes.customWidth ?? colNode.attributes.customwidth;\n const custom =\n customAttr !== undefined\n ? customAttr === '1' || customAttr.toLowerCase() === 'true'\n : undefined;\n for (let idx = min; idx <= max; idx += 1) {\n columns[idx] = {\n width,\n wch: width,\n wpx,\n custom,\n };\n }\n }\n return columns;\n}\n\nfunction readRowsInfo(rowNodes: XmlNode[]): RowInfo[] {\n const rows: RowInfo[] = [];\n for (const rowNode of rowNodes) {\n const rowIndex = Math.max(parseInt(rowNode.attributes.r ?? '1', 10) - 1, 0);\n const info: RowInfo = {};\n if (rowNode.attributes.ht) {\n const height = Number(rowNode.attributes.ht);\n if (Number.isFinite(height)) {\n info.hpt = height;\n info.hpx = height * (96 / 72);\n }\n }\n if (rowNode.attributes.customHeight !== undefined) {\n info.custom = rowNode.attributes.customHeight === '1' || rowNode.attributes.customHeight === 'true';\n }\n rows[rowIndex] = info;\n }\n return rows;\n}\n\nfunction readWorksheetImages(\n root: XmlNode,\n zipEntries: Record<string, Uint8Array>,\n sheetPath: string,\n): WorksheetImage[] {\n const drawingNodes = findChildren(root, 'drawing');\n if (!drawingNodes.length) {\n return [];\n }\n const relationships = readPartRelationships(zipEntries, sheetPath);\n if (!relationships.size) {\n return [];\n }\n const images: WorksheetImage[] = [];\n for (const drawingNode of drawingNodes) {\n const relId = drawingNode.attributes['r:id'];\n if (!relId) {\n continue;\n }\n const drawingPath = relationships.get(relId);\n if (!drawingPath) {\n continue;\n }\n images.push(...readDrawingImages(zipEntries, drawingPath));\n }\n return images;\n}\n\nfunction readDrawingImages(\n zipEntries: Record<string, Uint8Array>,\n drawingPath: string,\n): WorksheetImage[] {\n if (!zipEntries[drawingPath]) {\n return [];\n }\n const xml = readXml(zipEntries, drawingPath);\n const doc = parseXml(xml);\n const root = doc.children.find((child) => localName(child.name) === 'wsDr') ?? doc.children[0];\n if (!root) {\n return [];\n }\n const relationships = readPartRelationships(zipEntries, drawingPath);\n if (!relationships.size) {\n return [];\n }\n const anchors = root.children.filter((node) => {\n const name = localName(node.name);\n return name === 'oneCellAnchor' || name === 'twoCellAnchor';\n });\n const images: WorksheetImage[] = [];\n anchors.forEach((anchorNode, index) => {\n const picNode = findChild(anchorNode, 'pic');\n if (!picNode) {\n return;\n }\n const blipFill = findChild(picNode, 'blipFill');\n const blip = blipFill ? findChild(blipFill, 'blip') : undefined;\n const embedId =\n blip?.attributes['r:embed'] ??\n blip?.attributes['r:Embed'] ??\n blip?.attributes['r:EMBED'] ??\n blip?.attributes['r:id'];\n if (!embedId) {\n return;\n }\n const imagePath = relationships.get(embedId);\n if (!imagePath) {\n return;\n }\n const anchor = parseDrawingAnchor(anchorNode);\n if (!anchor) {\n return;\n }\n const mediaEntry = zipEntries[imagePath];\n if (!mediaEntry) {\n return;\n }\n const data = new Uint8Array(mediaEntry);\n images.push({\n id: `${drawingPath}#${embedId}#${index}`,\n imagePath,\n format: imagePath.split('.').pop()?.toLowerCase() ?? 'image',\n mimeType: guessMimeType(imagePath),\n data,\n anchor,\n });\n });\n return images;\n}\n\nfunction guessMimeType(path: string): string {\n const ext = path.split('.').pop()?.toLowerCase();\n switch (ext) {\n case 'png':\n return 'image/png';\n case 'jpg':\n case 'jpeg':\n return 'image/jpeg';\n case 'gif':\n return 'image/gif';\n case 'bmp':\n return 'image/bmp';\n case 'svg':\n return 'image/svg+xml';\n case 'tif':\n case 'tiff':\n return 'image/tiff';\n case 'webp':\n return 'image/webp';\n default:\n return 'application/octet-stream';\n }\n}\n\nfunction parseDrawingAnchor(anchorNode: XmlNode): WorksheetImageAnchor | null {\n const fromNode = findChild(anchorNode, 'from');\n const from = parseAnchorPosition(fromNode);\n if (!from) {\n return null;\n }\n const anchorType = localName(anchorNode.name);\n if (anchorType === 'oneCellAnchor') {\n const extNode = findChild(anchorNode, 'ext');\n const width = extNode?.attributes.cx ? Number(extNode.attributes.cx) : 0;\n const height = extNode?.attributes.cy ? Number(extNode.attributes.cy) : 0;\n return {\n type: 'oneCell',\n from,\n width: Number.isFinite(width) ? width : 0,\n height: Number.isFinite(height) ? height : 0,\n };\n }\n if (anchorType === 'twoCellAnchor') {\n const toNode = findChild(anchorNode, 'to');\n const to = parseAnchorPosition(toNode);\n if (!to) {\n return null;\n }\n return {\n type: 'twoCell',\n from,\n to,\n };\n }\n return null;\n}\n\nfunction parseAnchorPosition(node: XmlNode | undefined): DrawingAnchorPosition | null {\n if (!node) {\n return null;\n }\n const column = Number.parseInt(findChild(node, 'col')?.text ?? '0', 10);\n const row = Number.parseInt(findChild(node, 'row')?.text ?? '0', 10);\n const columnOffset = Number.parseInt(findChild(node, 'colOff')?.text ?? '0', 10);\n const rowOffset = Number.parseInt(findChild(node, 'rowOff')?.text ?? '0', 10);\n if (\n Number.isNaN(column) ||\n Number.isNaN(row) ||\n column < 0 ||\n row < 0 ||\n Number.isNaN(columnOffset) ||\n Number.isNaN(rowOffset)\n ) {\n return null;\n }\n return {\n row,\n column,\n rowOffset,\n columnOffset,\n };\n}\n\nfunction readRichTextRuns(node: XmlNode): RichTextRun[] {\n const runNodes = findChildren(node, 'r');\n if (!runNodes.length) {\n const textNode = findChild(node, 't');\n const text = textNode ? getTextContent(textNode) : getTextContent(node);\n return text ? [{ text }] : [];\n }\n const runs: RichTextRun[] = [];\n for (const runNode of runNodes) {\n const textNode = findChild(runNode, 't');\n const text = textNode ? getTextContent(textNode) : '';\n const run: RichTextRun = { text };\n const propsNode = findChild(runNode, 'rPr');\n if (propsNode) {\n const fontNode = findChild(propsNode, 'rFont');\n const fontFamily = fontNode?.attributes.val;\n if (fontFamily) {\n run.fontFamily = fontFamily;\n }\n const sizeNode = findChild(propsNode, 'sz');\n if (sizeNode?.attributes.val) {\n const size = Number(sizeNode.attributes.val);\n if (Number.isFinite(size) && size > 0) {\n run.fontSize = size;\n }\n }\n const boldNode = findChild(propsNode, 'b');\n if (boldNode) {\n run.bold = boldNode.attributes.val === undefined || boldNode.attributes.val !== '0';\n }\n const italicNode = findChild(propsNode, 'i');\n if (italicNode) {\n run.italic = italicNode.attributes.val === undefined || italicNode.attributes.val !== '0';\n }\n const underlineNode = findChild(propsNode, 'u');\n if (underlineNode) {\n const val = underlineNode.attributes.val ?? 'single';\n run.underline = val !== 'none' && val !== '0';\n }\n const colorNode = findChild(propsNode, 'color');\n const rgb = colorNode?.attributes.rgb;\n if (rgb) {\n run.color = convertRichTextColor(rgb);\n }\n }\n runs.push(run);\n }\n return runs;\n}\n\nfunction convertRichTextColor(rgb: string): string {\n if (rgb.length === 8) {\n return `#${rgb.slice(2)}`;\n }\n if (rgb.length === 6) {\n return `#${rgb}`;\n }\n return '#000000';\n}\n\nfunction readSheetData(\n sheetData: XmlNode | undefined,\n worksheet: WorkSheet,\n sharedStrings: SharedStringEntry[],\n styles: WorkbookStyles | undefined,\n): { minRow: number; minCol: number; maxRow: number; maxCol: number } {\n if (!sheetData) {\n return { minRow: 0, minCol: 0, maxRow: 0, maxCol: 0 };\n }\n const rows = findChildren(sheetData, 'row');\n let minRow = Number.MAX_SAFE_INTEGER;\n let minCol = Number.MAX_SAFE_INTEGER;\n let maxRow = 0;\n let maxCol = 0;\n for (const row of rows) {\n const rowIndex = Math.max(parseInt(row.attributes.r ?? '1', 10) - 1, 0);\n const cellNodes = findChildren(row, 'c');\n let fallbackColumn = 0;\n for (const cellNode of cellNodes) {\n const address = cellNode.attributes.r;\n const position = address ? decodeCell(address) : { r: rowIndex, c: fallbackColumn };\n fallbackColumn = position.c + 1;\n const cellType = cellNode.attributes.t ?? 'n';\n const styleIndex = cellNode.attributes.s ? Number(cellNode.attributes.s) : undefined;\n const decoded = readCellValue(cellNode, cellType, sharedStrings);\n const value = decoded.value;\n const formulaNode = findChild(cellNode, 'f');\n const formulaText = formulaNode ? getTextContent(formulaNode) : '';\n if ((value === null || value === undefined || value === '') && !formulaText) {\n continue;\n }\n const cell: CellObject = {\n v: value,\n value,\n t: normalizeCellType(cellType),\n };\n if (formulaText) {\n cell.f = formulaText;\n }\n if (decoded.richText && decoded.richText.length > 0) {\n cell.richText = decoded.richText;\n }\n const cellStyle = resolveCellStyle(styleIndex, styles);\n if (cellStyle) {\n cell.s = cellStyle;\n }\n const key = encodeCell(position);\n worksheet[key] = cell;\n minRow = Math.min(minRow, position.r);\n minCol = Math.min(minCol, position.c);\n maxRow = Math.max(maxRow, position.r);\n maxCol = Math.max(maxCol, position.c);\n }\n }\n if (minRow === Number.MAX_SAFE_INTEGER) {\n minRow = 0;\n minCol = 0;\n }\n return { minRow, minCol, maxRow, maxCol };\n}\n\ntype DecodedCellValue = { value: string | number | boolean | null; richText?: RichTextRun[] };\n\nfunction readCellValue(\n cellNode: XmlNode,\n cellType: string,\n sharedStrings: SharedStringEntry[],\n): DecodedCellValue {\n if (cellType === 's') {\n const valueNode = findChild(cellNode, 'v');\n if (!valueNode?.text) {\n return { value: '' };\n }\n const index = Number(valueNode.text);\n const entry = sharedStrings[index];\n return entry ? { value: entry.text, richText: entry.richText } : { value: '' };\n }\n if (cellType === 'inlineStr') {\n const inlineNode = findChild(cellNode, 'is') ?? cellNode;\n const runs = readRichTextRuns(inlineNode);\n if (runs.length > 0) {\n return { value: runs.map((run) => run.text).join(''), richText: runs };\n }\n const textNode = findChild(inlineNode, 't');\n if (textNode) {\n return { value: getTextContent(textNode) };\n }\n return { value: getTextContent(inlineNode) };\n }\n if (cellType === 'b') {\n const valueNode = findChild(cellNode, 'v');\n if (!valueNode?.text) {\n return { value: false };\n }\n return { value: valueNode.text === '1' };\n }\n const valueNode = findChild(cellNode, 'v');\n if (!valueNode) {\n return { value: null };\n }\n if (cellType === 'n' || cellType === 'd') {\n const parsed = Number(valueNode.text);\n if (Number.isFinite(parsed)) {\n return { value: parsed };\n }\n }\n return { value: valueNode.text ?? '' };\n}\n\nfunction normalizeCellType(cellType: string): string {\n if (cellType === 'inlineStr') {\n return 's';\n }\n return cellType;\n}\n\nfunction readMerges(mergeNode: XmlNode): WorksheetMergeRange[] {\n const merges: WorksheetMergeRange[] = [];\n const mergeCells = findChildren(mergeNode, 'mergeCell');\n for (const mergeCell of mergeCells) {\n const ref = mergeCell.attributes.ref;\n if (!ref) {\n continue;\n }\n const range = decodeRange(ref);\n merges.push(range);\n }\n return merges;\n}\n\nfunction readSharedStrings(zipEntries: Record<string, Uint8Array>): SharedStringEntry[] {\n const sharedStrings: SharedStringEntry[] = [];\n const path = 'xl/sharedStrings.xml';\n if (!zipEntries[path]) {\n return sharedStrings;\n }\n const xml = readXml(zipEntries, path);\n const doc = parseXml(xml);\n const root = doc.children.find((child) => localName(child.name) === 'sst');\n if (!root) {\n return sharedStrings;\n }\n const siNodes = findChildren(root, 'si');\n for (const siNode of siNodes) {\n const runs = readRichTextRuns(siNode);\n if (runs.length > 0) {\n sharedStrings.push({ text: runs.map((run) => run.text).join(''), richText: runs });\n continue;\n }\n sharedStrings.push({ text: getTextContent(siNode) });\n }\n return sharedStrings;\n}\n\nfunction readStyles(zipEntries: Record<string, Uint8Array>): WorkbookStyles | undefined {\n const path = 'xl/styles.xml';\n if (!zipEntries[path]) {\n return undefined;\n }\n const xml = readXml(zipEntries, path);\n const doc = parseXml(xml);\n const root = doc.children.find((child) => localName(child.name) === 'styleSheet');\n if (!root) {\n return undefined;\n }\n const styles: WorkbookStyles = {\n CellXf: [],\n Borders: [],\n Fills: [],\n Fonts: [],\n NumberFormats: new Map(),\n };\n const numFmtsNode = findChild(root, 'numFmts');\n if (numFmtsNode) {\n const customFormats = readNumberFormats(numFmtsNode);\n customFormats.forEach((code, id) => {\n styles.NumberFormats?.set(id, code);\n });\n }\n const bordersNode = findChild(root, 'borders');\n if (bordersNode) {\n const borderNodes = findChildren(bordersNode, 'border');\n styles.Borders = borderNodes.map(readBorder);\n }\n const fontsNode = findChild(root, 'fonts');\n if (fontsNode) {\n const fontNodes = findChildren(fontsNode, 'font');\n styles.Fonts = fontNodes.map(readFont);\n }\n const colorsNode = findChild(root, 'colors');\n if (colorsNode) {\n const colors = readColors(colorsNode);\n if (colors.indexed && colors.indexed.length > 0) {\n styles.Colors = colors;\n }\n }\n const fillsNode = findChild(root, 'fills');\n if (fillsNode) {\n const fillNodes = findChildren(fillsNode, 'fill');\n styles.Fills = fillNodes.map((fillNode) => readFill(fillNode));\n }\n const cellXfsNode = findChild(root, 'cellXfs');\n if (cellXfsNode) {\n const xfNodes = findChildren(cellXfsNode, 'xf');\n styles.CellXf = xfNodes.map((xfNode) => {\n const xf: CellXfRecord = {};\n const borderIndex = parseIndexAttribute(xfNode.attributes.borderId ?? xfNode.attributes.borderid);\n if (borderIndex !== null) {\n xf.borderId = borderIndex;\n }\n const fillIndex = parseIndexAttribute(xfNode.attributes.fillId ?? xfNode.attributes.fillid);\n if (fillIndex !== null) {\n xf.fillId = fillIndex;\n }\n const fontIndex = parseIndexAttribute(xfNode.attributes.fontId ?? xfNode.attributes.fontid);\n if (fontIndex !== null) {\n xf.fontId = fontIndex;\n }\n const numFmtId = parseIndexAttribute(xfNode.attributes.numFmtId ?? xfNode.attributes.numfmtid);\n if (numFmtId !== null) {\n xf.numFmtId = numFmtId;\n }\n const alignmentNode = findChild(xfNode, 'alignment');\n if (alignmentNode?.attributes) {\n const horizontal = alignmentNode.attributes.horizontal;\n const vertical = alignmentNode.attributes.vertical;\n const wrapText = alignmentNode.attributes.wrapText ?? alignmentNode.attributes.wraptext;\n if (horizontal || vertical || wrapText) {\n xf.alignment = {};\n if (horizontal) {\n xf.alignment.horizontal = horizontal;\n }\n if (vertical) {\n xf.alignment.vertical = vertical;\n }\n if (wrapText) {\n xf.alignment.wrapText = wrapText;\n }\n }\n }\n return xf;\n });\n }\n return styles;\n}\n\nfunction parseIndexAttribute(value: string | undefined): number | null {\n if (value === undefined) {\n return null;\n }\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : null;\n}\n\nfunction parseBooleanAttribute(value: string | undefined): boolean | null {\n if (value === undefined) {\n return null;\n }\n if (value === '1') {\n return true;\n }\n if (value === '0') {\n return false;\n }\n const normalized = value.trim().toLowerCase();\n if (normalized === 'true') {\n return true;\n }\n if (normalized === 'false') {\n return false;\n }\n return null;\n}\n\nfunction readColors(colorsNode: XmlNode): WorkbookColors {\n const colors: WorkbookColors = {};\n const indexedNode = findChild(colorsNode, 'indexedColors');\n if (indexedNode) {\n const rgbNodes = findChildren(indexedNode, 'rgbColor');\n colors.indexed = rgbNodes.map((node) => normalizeRgbAttribute(node.attributes.rgb));\n }\n return colors;\n}\n\nfunction normalizeRgbAttribute(rgb: string | undefined): string | null {\n if (!rgb) {\n return null;\n }\n const hex = rgb.replace(/^#/, '');\n if (hex.length === 8) {\n return `#${hex.slice(2)}`;\n }\n if (hex.length === 6) {\n return `#${hex}`;\n }\n return null;\n}\n\nfunction readBorder(borderNode: XmlNode): ExcelBorder {\n return {\n left: readBorderEdge(findChild(borderNode, 'left')),\n right: readBorderEdge(findChild(borderNode, 'right')),\n top: readBorderEdge(findChild(borderNode, 'top')),\n bottom: readBorderEdge(findChild(borderNode, 'bottom')),\n };\n}\n\nfunction readBorderEdge(edgeNode: XmlNode | undefined): ExcelBorderLine | undefined {\n if (!edgeNode) {\n return undefined;\n }\n const style = edgeNode.attributes.style;\n const colorNode = findChild(edgeNode, 'color');\n const color = readColor(colorNode);\n if (!style && !color) {\n return undefined;\n }\n return { style, color };\n}\n\nfunction readFill(fillNode: XmlNode): ExcelFill | undefined {\n const patternNode = findChild(fillNode, 'patternFill');\n if (!patternNode) {\n return undefined;\n }\n const patternType = patternNode.attributes.patternType ?? patternNode.attributes.patterntype;\n const fgColorNode = findChild(patternNode, 'fgColor');\n const bgColorNode = findChild(patternNode, 'bgColor');\n const fgColor = readColor(fgColorNode);\n const bgColor = readColor(bgColorNode);\n if (!patternType && !fgColor && !bgColor) {\n return undefined;\n }\n return { patternType, fgColor, bgColor };\n}\n\nfunction readColor(colorNode: XmlNode | undefined): ExcelColor | undefined {\n if (!colorNode) {\n return undefined;\n }\n const color: ExcelColor = {};\n if (colorNode.attributes.rgb) {\n color.rgb = colorNode.attributes.rgb;\n }\n const indexed = parseIndexAttribute(colorNode.attributes.indexed);\n if (indexed !== null) {\n color.indexed = indexed;\n }\n const theme = parseIndexAttribute(colorNode.attributes.theme);\n if (theme !== null) {\n color.theme = theme;\n }\n if (colorNode.attributes.tint !== undefined) {\n const tint = Number(colorNode.attributes.tint);\n if (Number.isFinite(tint)) {\n color.tint = tint;\n }\n }\n return Object.keys(color).length ? color : undefined;\n}\n\nfunction readNumberFormats(numFmtsNode: XmlNode): Map<number, string> {\n const formats = new Map<number, string>();\n const numFmtNodes = findChildren(numFmtsNode, 'numFmt');\n for (const fmtNode of numFmtNodes) {\n const id = parseIndexAttribute(fmtNode.attributes.numFmtId ?? fmtNode.attributes.numfmtid);\n const code = fmtNode.attributes.formatCode ?? fmtNode.attributes.formatcode;\n if (id === null || !code) {\n continue;\n }\n formats.set(id, code);\n }\n return formats;\n}\n\nfunction readFont(fontNode: XmlNode): ExcelFont {\n const font: ExcelFont = {};\n const nameNode = findChild(fontNode, 'name');\n if (nameNode?.attributes.val) {\n font.name = nameNode.attributes.val;\n }\n const sizeNode = findChild(fontNode, 'sz');\n if (sizeNode?.attributes.val) {\n const parsed = Number(sizeNode.attributes.val);\n if (Number.isFinite(parsed)) {\n font.size = parsed;\n }\n }\n const colorNode = findChild(fontNode, 'color');\n const color = readColor(colorNode);\n if (color) {\n font.color = color;\n }\n const boldNode = findChild(fontNode, 'b');\n if (boldNode) {\n font.bold = boldNode.attributes.val === undefined || boldNode.attributes.val !== '0';\n }\n const italicNode = findChild(fontNode, 'i');\n if (italicNode) {\n font.italic = italicNode.attributes.val === undefined || italicNode.attributes.val !== '0';\n }\n const underlineNode = findChild(fontNode, 'u');\n if (underlineNode) {\n const val = underlineNode.attributes.val ?? 'single';\n font.underline = val !== 'none' && val !== '0';\n }\n return font;\n}\n\nfunction readWorkbookRelationships(zipEntries: Record<string, Uint8Array>): Map<string, string> {\n return readPartRelationships(zipEntries, 'xl/workbook.xml');\n}\n\nfunction readPartRelationships(\n zipEntries: Record<string, Uint8Array>,\n partPath: string,\n): Map<string, string> {\n const relationships = new Map<string, string>();\n const relsPath = getRelationshipsPath(partPath);\n if (!zipEntries[relsPath]) {\n return relationships;\n }\n const xml = readXml(zipEntries, relsPath);\n const doc = parseXml(xml);\n const root = doc.children.find((child) => localName(child.name) === 'Relationships');\n if (!root) {\n return relationships;\n }\n const relationNodes = findChildren(root, 'Relationship');\n for (const rel of relationNodes) {\n const id = rel.attributes.Id;\n const target = rel.attributes.Target;\n if (!id || !target) {\n continue;\n }\n relationships.set(id, resolveRelationshipTarget(partPath, target));\n }\n return relationships;\n}\n\nfunction getRelationshipsPath(partPath: string): string {\n const lastSlash = partPath.lastIndexOf('/');\n const directory = lastSlash >= 0 ? partPath.slice(0, lastSlash + 1) : '';\n const file = lastSlash >= 0 ? partPath.slice(lastSlash + 1) : partPath;\n return `${directory}_rels/${file}.rels`.replace(/\\/+/g, '/');\n}\n\nfunction resolveRelationshipTarget(basePath: string, target: string): string {\n if (target.startsWith('/')) {\n return target.replace(/^\\//, '');\n }\n const baseParts = basePath.split('/');\n baseParts.pop();\n const segments = target.split('/');\n for (const segment of segments) {\n if (!segment || segment === '.') {\n continue;\n }\n if (segment === '..') {\n if (baseParts.length) {\n baseParts.pop();\n }\n } else {\n baseParts.push(segment);\n }\n }\n return baseParts.join('/');\n}\n\nfunction readXml(zipEntries: Record<string, Uint8Array>, path: string): string {\n const entry = zipEntries[path];\n if (!entry) {\n throw new Error(`File \"${path}\" was not found in the archive.`);\n }\n return decodeUtf8(entry);\n}\n\nfunction decodeUtf8(bytes: Uint8Array): string {\n if (textDecoder) {\n return textDecoder.decode(bytes);\n }\n let result = '';\n for (let i = 0; i < bytes.length; i += 1) {\n result += String.fromCharCode(bytes[i]);\n }\n return result;\n}\n\nfunction normalizeInput(input: ArrayBuffer | Uint8Array | string): Uint8Array {\n if (typeof input === 'string') {\n const buffer = new Uint8Array(input.length);\n for (let i = 0; i < input.length; i += 1) {\n buffer[i] = input.charCodeAt(i) & 0xff;\n }\n return buffer;\n }\n if (input instanceof Uint8Array) {\n return input;\n }\n return new Uint8Array(input);\n}\n\nfunction sheet_to_json<T = (string | number | boolean | null)[]>(sheet: WorkSheet, options?: SheetToJsonOptions): T[] {\n if (options?.header !== 1) {\n throw new Error('sheet_to_json currently supports header: 1 only.');\n }\n const defval = options?.defval ?? null;\n const raw = options?.raw ?? true;\n const rangeRef = sheet['!ref'] ?? inferSheetRange(sheet);\n const range = decodeRange(rangeRef);\n const maxRow = Math.max(range.e.r, 0);\n const maxCol = Math.max(range.e.c, 0);\n const totalRows = maxRow + 1;\n const totalCols = maxCol + 1;\n const rows: (string | number | boolean | null)[][] = new Array(totalRows);\n\n for (let r = range.s.r; r <= range.e.r; r += 1) {\n const row = ensureRow(rows, r, totalCols, defval);\n for (let c = range.s.c; c <= range.e.c; c += 1) {\n const address = encodeCell({ r, c });\n const cell = sheet[address] as CellObject | undefined;\n if (!cell) {\n continue;\n }\n row[c] = raw === false ? formatCell(cell) : (cell.v ?? defval);\n }\n }\n\n for (let r = 0; r < totalRows; r += 1) {\n ensureRow(rows, r, totalCols, defval);\n }\n\n return rows as unknown as T[];\n}\n\nfunction formatCell(cell: CellObject): string {\n if (cell.t === 'b') {\n return cell.v ? 'TRUE' : 'FALSE';\n }\n return cell.v !== null && cell.v !== undefined ? String(cell.v) : '';\n}\n\nfunction inferSheetRange(sheet: WorkSheet): string {\n let minRow = Number.MAX_SAFE_INTEGER;\n let minCol = Number.MAX_SAFE_INTEGER;\n let maxRow = 0;\n let maxCol = 0;\n Object.keys(sheet).forEach((key) => {\n if (!/^[A-Z]+[0-9]+$/.test(key)) {\n return;\n }\n const position = decodeCell(key);\n minRow = Math.min(minRow, position.r);\n minCol = Math.min(minCol, position.c);\n maxRow = Math.max(maxRow, position.r);\n maxCol = Math.max(maxCol, position.c);\n });\n if (minRow === Number.MAX_SAFE_INTEGER) {\n return 'A1:A1';\n }\n return encodeRange({\n s: { r: minRow, c: minCol },\n e: { r: maxRow, c: maxCol },\n });\n}\n\nfunction ensureRow(\n rows: (string | number | boolean | null)[][],\n index: number,\n columnCount: number,\n defval: string | number | boolean | null,\n): (string | number | boolean | null)[] {\n if (!rows[index]) {\n const row: (string | number | boolean | null)[] = new Array(columnCount);\n for (let i = 0; i < columnCount; i += 1) {\n row[i] = defval;\n }\n rows[index] = row;\n }\n return rows[index];\n}\n\nfunction resolveCellStyle(\n styleIndex: number | undefined,\n styles: WorkbookStyles | undefined,\n): CellStyle | undefined {\n if (!styles || typeof styleIndex !== 'number') {\n return undefined;\n }\n const xf = styles.CellXf?.[styleIndex];\n if (!xf) {\n return undefined;\n }\n const style: CellStyle = {};\n if (xf.alignment?.horizontal || xf.alignment?.vertical) {\n style.alignment = {};\n if (xf.alignment.horizontal) {\n style.alignment.horizontal = xf.alignment.horizontal;\n }\n if (xf.alignment.vertical) {\n style.alignment.vertical = xf.alignment.vertical;\n }\n }\n if (typeof xf.numFmtId === 'number') {\n style.numFmtId = xf.numFmtId;\n const customFormat = styles.NumberFormats?.get(xf.numFmtId);\n if (customFormat) {\n style.formatCode = customFormat;\n }\n }\n if (typeof xf.fontId === 'number' && xf.fontId >= 0) {\n const font = styles.Fonts?.[xf.fontId];\n if (font) {\n const normalizedFont: ExcelFont = {};\n if (font.name) {\n normalizedFont.name = font.name;\n }\n if (typeof font.size === 'number' && Number.isFinite(font.size)) {\n normalizedFont.size = font.size;\n }\n if (font.color) {\n normalizedFont.color = { ...font.color };\n }\n if (normalizedFont.name || normalizedFont.size || normalizedFont.color) {\n style.font = normalizedFont;\n }\n }\n }\n return style.alignment || style.font || style.numFmtId !== undefined ? style : undefined;\n}\n\nfunction encodeRange(range: Range): string {\n return `${encodeCell(range.s)}:${encodeCell(range.e)}`;\n}\n\nfunction decodeRange(ref: string): Range {\n const parts = ref.split(':');\n if (parts.length === 1) {\n const pos = decodeCell(parts[0]);\n return { s: pos, e: pos };\n }\n return { s: decodeCell(parts[0]), e: decodeCell(parts[1]) };\n}\n\nfunction encodeCell(position: { r: number; c: number }): string {\n return `${encodeCol(position.c)}${encodeRow(position.r)}`;\n}\n\nfunction decodeCell(address: string): { r: number; c: number } {\n const match = /^([A-Z]+)(\\d+)$/.exec(address.toUpperCase());\n if (!match) {\n throw new Error(`Invalid cell address \"${address}\".`);\n }\n return {\n c: decodeCol(match[1]),\n r: Number(match[2]) - 1,\n };\n}\n\nfunction encodeCol(columnIndex: number): string {\n let column = '';\n let index = columnIndex;\n while (index >= 0) {\n column = String.fromCharCode((index % 26) + 65) + column;\n index = Math.floor(index / 26) - 1;\n }\n return column;\n}\n\nfunction encodeRow(rowIndex: number): string {\n return String(rowIndex + 1);\n}\n\nfunction decodeCol(col: string): number {\n let result = 0;\n for (let i = 0; i < col.length; i += 1) {\n result = result * 26 + (col.charCodeAt(i) - 64);\n }\n return result - 1;\n}\n\nfunction charWidthToPixels(measure: number): number {\n if (!Number.isFinite(measure) || measure <= 0) {\n return 0;\n }\n const MAX_DIGIT_WIDTH = 7;\n const CELL_PADDING = 5;\n if (measure < 1) {\n return Math.floor(measure * (MAX_DIGIT_WIDTH + CELL_PADDING));\n }\n return Math.floor(measure * MAX_DIGIT_WIDTH + CELL_PADDING);\n}\n","import {\n read,\n utils,\n type WorkBook,\n type WorkSheet,\n type CellObject,\n type SheetFormatProperties,\n type DrawingAnchorPosition,\n type WorksheetImage,\n} from './xlsx';\nimport { DEFAULT_COLUMNS, DEFAULT_ROWS } from '../core/worksheet/gridDefaults';\nimport { type CellStyle, type TextAlign, type VerticalAlign } from '../core/style/cellStyle';\nimport { formatNumberWithFormat } from '../core/style/numberFormat';\nimport type { CellInputValue, MergedCellRange } from '../core/cell/types';\nimport type { BorderLineOptions, CellBorderDefinition } from '../core/border/types';\n\n// ---------------------------------------------------------------------------\n// Built-in Excel number format codes (numFmtId → format string)\n// ---------------------------------------------------------------------------\n\nconst BUILTIN_NUMBER_FORMATS: Record<number, string> = {\n 0: 'General',\n 1: '0',\n 2: '0.00',\n 3: '#,##0',\n 4: '#,##0.00',\n 5: '$#,##0_);($#,##0)',\n 6: '$#,##0_);[Red]($#,##0)',\n 7: '$#,##0.00_);($#,##0.00)',\n 8: '$#,##0.00_);[Red]($#,##0.00)',\n 9: '0%',\n 10: '0.00%',\n 11: '0.00E+00',\n 12: '# ?/?',\n 13: '# ??/??',\n 14: 'm/d/yy',\n 15: 'd-mmm-yy',\n 16: 'd-mmm',\n 17: 'mmm-yy',\n 18: 'h:mm AM/PM',\n 19: 'h:mm:ss AM/PM',\n 20: 'h:mm',\n 21: 'h:mm:ss',\n 22: 'm/d/yy h:mm',\n 37: '#,##0 ;(#,##0)',\n 38: '#,##0 ;[Red](#,##0)',\n 39: '#,##0.00;(#,##0.00)',\n 40: '#,##0.00;[Red](#,##0.00)',\n 41: '_(* #,##0_);_(* (#,##0);_(* \"-\"_);_(@_)',\n 42: '_(\"$\"* #,##0_);_(\"$\"* (#,##0);_(\"$\"* \"-\"_);_(@_)',\n 43: '_(* #,##0.00_);_(* (#,##0.00);_(* \"-\"??_);_(@_)',\n 44: '_(\"$\"* #,##0.00_);_(\"$\"* (#,##0.00);_(\"$\"* \"-\"??_);_(@_)',\n 45: 'mm:ss',\n 46: '[h]:mm:ss',\n 47: 'mm:ss.0',\n 48: '##0.0E+0',\n 49: '@',\n};\n\n// ---------------------------------------------------------------------------\n// Internal Excel type aliases\n// ---------------------------------------------------------------------------\n\ntype WorksheetMergeRange = { s: { r: number; c: number }; e: { r: number; c: number } };\ntype ColumnInfo = { wpx?: number; wch?: number; width?: number; custom?: boolean };\ntype RowInfo = { hpx?: number; hpt?: number; custom?: boolean };\ntype ExcelBorder = {\n left?: ExcelBorderLine;\n right?: ExcelBorderLine;\n top?: ExcelBorderLine;\n bottom?: ExcelBorderLine;\n};\ntype ExcelBorderLine = { style?: string; color?: ExcelColor };\ntype ExcelColor = { rgb?: string; indexed?: number; theme?: number; tint?: number };\ntype ExcelFontDefinition = {\n sz?: number;\n name?: string;\n color?: ExcelColor;\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n};\ntype ExcelFill = { patternType?: string; fgColor?: ExcelColor; bgColor?: ExcelColor };\ntype AlignmentStyle = { horizontal?: TextAlign; vertical?: VerticalAlign; wrapText?: boolean };\n\nconst CELL_ADDRESS_REGEX = /^[A-Z]+[0-9]+$/i;\nconst EMUS_PER_PIXEL = 914400 / 96;\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport type LoadXlsxOptions = { sheetName?: string };\n\n/** Shape of the return value from XlsxImporter.load(). */\nexport type LoadXlsxResult = { images: WorksheetImage[] };\n\n/**\n * Minimal interface of the worksheet object that the importer writes to.\n * Keeping this narrow makes the importer independent of the full Worksheet class.\n */\nexport interface XlsxImportTarget {\n rows: number;\n columns: number;\n setGridSize(rows: number, columns: number): void;\n setShowGridLines(visible: boolean): void;\n applyColumnWidths(\n widths: Map<number, number>,\n options?: { customColumns?: Set<number>; enforceMinColumnWidth?: boolean },\n ): void;\n applyRowHeights(heights: Map<number, number>, options?: { customRows?: Set<number> }): void;\n applyCellBorders(borders: Map<string, CellBorderDefinition>): void;\n setMergedRanges(ranges: Iterable<MergedCellRange>): void;\n loadCells(cells: Iterable<CellInputValue>): void;\n setScrollOffset(x: number, y: number): void;\n autoFitRows(options?: { rows?: number[]; respectCustomHeight?: boolean }): void;\n setFrozenRows(count: number): void;\n setFrozenColumns(count: number): void;\n}\n\n// ---------------------------------------------------------------------------\n// XlsxImporter\n// ---------------------------------------------------------------------------\n\n/**\n * Parses an xlsx file and loads its data into an XlsxImportTarget (typically a Worksheet).\n * Create a new instance per load operation.\n */\nexport class XlsxImporter {\n private readonly binaryDecoder: TextDecoder | null =\n typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8') : null;\n\n private indexedColors: Map<number, string> = new Map();\n\n constructor(private readonly worksheet: XlsxImportTarget) {}\n\n load(data: ArrayBuffer | Uint8Array | string, options?: LoadXlsxOptions): LoadXlsxResult {\n const workbook = this.readWorkbook(data);\n this.indexedColors = this.buildIndexedColorMap(workbook);\n\n const sheetName = options?.sheetName ?? workbook.SheetNames[0];\n if (!sheetName) {\n throw new Error('Workbook does not contain any sheets.');\n }\n const sheet = workbook.Sheets[sheetName];\n if (!sheet) {\n throw new Error(`Sheet \"${sheetName}\" was not found.`);\n }\n\n const { rows, columns } = this.determineSheetDimensions(sheet);\n this.worksheet.setGridSize(rows, columns);\n\n const sheetIndex = workbook.SheetNames.indexOf(sheetName);\n if (sheetIndex < 0) {\n throw new Error(`Unable to resolve sheet index for \"${sheetName}\".`);\n }\n\n const showGridLines = this.resolveSheetGridLineVisibility(sheet);\n this.worksheet.setShowGridLines(showGridLines ?? true);\n\n const frozenRows = sheet['!sheetView']?.frozenRows;\n const frozenColumns = sheet['!sheetView']?.frozenColumns;\n this.worksheet.setFrozenRows(frozenRows ?? 0);\n this.worksheet.setFrozenColumns(frozenColumns ?? 0);\n\n const { widths: columnWidths, customColumns } = this.extractColumnWidths(sheet);\n const { heights: rowHeights, customRows } = this.extractRowHeights(sheet);\n this.worksheet.applyColumnWidths(columnWidths, {\n customColumns,\n enforceMinColumnWidth: false,\n });\n this.worksheet.applyRowHeights(rowHeights, { customRows });\n\n const styleIndexes = this.extractCellStyleIndexes(workbook, sheetIndex);\n const cellBorders = this.extractCellBorders(workbook, styleIndexes);\n const numberFormats = this.buildStyleNumberFormatMap(workbook);\n const styleAlignments = this.buildStyleAlignmentMap(workbook);\n const styleFills = this.buildStyleFillMap(workbook);\n const styleFonts = this.buildStyleFontMap(workbook);\n this.worksheet.applyCellBorders(cellBorders);\n\n const sheetMerges = (sheet['!merges'] as WorksheetMergeRange[] | undefined) ?? [];\n const cells = this.extractCells(\n sheet,\n sheetMerges,\n styleIndexes,\n numberFormats,\n styleAlignments,\n styleFills,\n styleFonts,\n );\n const mergedRanges = this.extractMergedRanges(sheetMerges);\n this.worksheet.setMergedRanges(mergedRanges);\n this.worksheet.loadCells(cells);\n this.worksheet.setScrollOffset(0, 0);\n this.worksheet.autoFitRows({ respectCustomHeight: true });\n\n const sheetImages = (sheet['!images'] as WorksheetImage[] | undefined) ?? [];\n const images = sheetImages.map((image) => ({\n ...image,\n data: new Uint8Array(image.data),\n }));\n\n return { images };\n }\n\n private readWorkbook(data: ArrayBuffer | Uint8Array | string): WorkBook {\n if (typeof data === 'string') {\n return read(data, { type: 'binary', cellStyles: true, bookFiles: true });\n }\n const buffer = data instanceof Uint8Array ? data : new Uint8Array(data);\n return read(buffer, { type: 'array', cellStyles: true, bookFiles: true });\n }\n\n private determineSheetDimensions(sheet: WorkSheet): { rows: number; columns: number } {\n const ref = sheet['!ref'];\n if (typeof ref === 'string') {\n const range = utils.decode_range(ref);\n return { rows: Math.max(1, range.e.r + 1), columns: Math.max(1, range.e.c + 1) };\n }\n let maxRow = -1;\n let maxCol = -1;\n for (const address of Object.keys(sheet)) {\n if (!CELL_ADDRESS_REGEX.test(address)) {\n continue;\n }\n const position = utils.decode_cell(address);\n maxRow = Math.max(maxRow, position.r);\n maxCol = Math.max(maxCol, position.c);\n }\n if (maxRow < 0 || maxCol < 0) {\n return { rows: DEFAULT_ROWS, columns: DEFAULT_COLUMNS };\n }\n return { rows: maxRow + 1, columns: maxCol + 1 };\n }\n\n private resolveSheetGridLineVisibility(sheet: WorkSheet): boolean | null {\n const flag = sheet['!sheetView']?.showGridLines;\n return typeof flag === 'boolean' ? flag : null;\n }\n\n private extractCells(\n sheet: WorkSheet,\n merges: WorksheetMergeRange[],\n styleIndexes: Map<string, number>,\n numberFormats: Map<number, string>,\n styleAlignments: Map<number, AlignmentStyle>,\n styleFills: Map<number, string>,\n styleFonts: Map<\n number,\n {\n color?: string;\n fontFamily?: string;\n fontSize?: number;\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n }\n >,\n ): CellInputValue[] {\n const rows = utils.sheet_to_json<(string | number | boolean | null)[]>(sheet, {\n header: 1,\n raw: true,\n defval: '',\n });\n\n const maxRows = Math.min(rows.length, this.worksheet.rows);\n const cells: CellInputValue[] = [];\n for (let r = 0; r < maxRows; r += 1) {\n const row = rows[r];\n const maxColumns = Math.min(row.length, this.worksheet.columns);\n for (let c = 0; c < maxColumns; c += 1) {\n const cellValue = row[c];\n const address = utils.encode_cell({ r, c });\n const cellMeta = sheet[address] as CellObject | undefined;\n const styleIndex = styleIndexes.get(address);\n const styleAlignment =\n styleIndex !== undefined ? styleAlignments.get(styleIndex) : undefined;\n const textAlign = this.getHorizontalAlignment(\n cellMeta,\n merges,\n r,\n c,\n styleAlignment?.horizontal,\n );\n const verticalAlign = this.getVerticalAlignment(\n cellMeta,\n merges,\n r,\n c,\n styleAlignment?.vertical,\n );\n const backgroundColor = styleIndex !== undefined ? styleFills.get(styleIndex) : undefined;\n const fontOverrides = styleIndex !== undefined ? styleFonts.get(styleIndex) : undefined;\n const style = this.buildCellStyle(\n cellMeta,\n textAlign,\n verticalAlign,\n backgroundColor,\n fontOverrides,\n styleAlignment?.wrapText,\n );\n const formatCode = styleIndex !== undefined ? numberFormats.get(styleIndex) : undefined;\n const formula = cellMeta?.f;\n const rawString = formula ? `=${formula}` : this.serializeRawCellValue(cellValue ?? null);\n const formattedValue =\n typeof cellValue === 'number' && formatCode\n ? formatNumberWithFormat(cellValue, formatCode)\n : null;\n const richText = cellMeta?.richText;\n const hasValue = rawString !== null && rawString.length > 0;\n if (!hasValue && !style && !richText?.length) {\n continue;\n }\n cells.push({\n row: r,\n column: c,\n value: rawString ?? '',\n displayValue: formattedValue ?? undefined,\n numberFormat: formatCode,\n style,\n richText: richText && richText.length ? richText.map((run) => ({ ...run })) : undefined,\n });\n }\n }\n return cells;\n }\n\n private extractMergedRanges(merges: WorksheetMergeRange[]): MergedCellRange[] {\n const normalized: MergedCellRange[] = [];\n for (const merge of merges) {\n const top = Math.min(Math.max(merge.s.r, 0), this.worksheet.rows - 1);\n const bottom = Math.min(Math.max(merge.e.r, 0), this.worksheet.rows - 1);\n const left = Math.min(Math.max(merge.s.c, 0), this.worksheet.columns - 1);\n const right = Math.min(Math.max(merge.e.c, 0), this.worksheet.columns - 1);\n const normalizedTop = Math.min(top, bottom);\n const normalizedBottom = Math.max(top, bottom);\n const normalizedLeft = Math.min(left, right);\n const normalizedRight = Math.max(left, right);\n if (normalizedTop === normalizedBottom && normalizedLeft === normalizedRight) {\n continue;\n }\n normalized.push({\n topRow: normalizedTop,\n bottomRow: normalizedBottom,\n leftColumn: normalizedLeft,\n rightColumn: normalizedRight,\n });\n }\n return normalized;\n }\n\n private extractColumnWidths(sheet: WorkSheet): {\n widths: Map<number, number>;\n customColumns: Set<number>;\n } {\n const output = new Map<number, number>();\n const customColumns = new Set<number>();\n const sheetFormat = this.getSheetFormat(sheet);\n const defaultWidth = this.normalizeDefaultColumnWidth(sheetFormat?.defaultColWidth);\n if (defaultWidth !== null) {\n for (let column = 0; column < this.worksheet.columns; column += 1) {\n output.set(column, defaultWidth);\n }\n }\n const columns = sheet['!cols'] as ColumnInfo[] | undefined;\n if (!Array.isArray(columns)) {\n return { widths: output, customColumns };\n }\n for (let index = 0; index < columns.length && index < this.worksheet.columns; index += 1) {\n const col = columns[index];\n if (!col) {\n continue;\n }\n const width = this.normalizeColumnWidth(col);\n if (width !== null) {\n output.set(index, width);\n }\n if (col.custom) {\n customColumns.add(index);\n }\n }\n return { widths: output, customColumns };\n }\n\n private extractRowHeights(sheet: WorkSheet): {\n heights: Map<number, number>;\n customRows: Set<number>;\n } {\n const output = new Map<number, number>();\n const customRows = new Set<number>();\n const sheetFormat = this.getSheetFormat(sheet);\n const defaultHeight = this.normalizeDefaultRowHeight(sheetFormat?.defaultRowHeight);\n if (defaultHeight !== null) {\n for (let row = 0; row < this.worksheet.rows; row += 1) {\n output.set(row, defaultHeight);\n }\n }\n const rows = sheet['!rows'] as RowInfo[] | undefined;\n if (!Array.isArray(rows)) {\n return { heights: output, customRows };\n }\n for (let index = 0; index < rows.length && index < this.worksheet.rows; index += 1) {\n const row = rows[index];\n if (!row) {\n continue;\n }\n const height = this.normalizeRowHeight(row);\n if (height !== null) {\n output.set(index, height);\n if (row.custom) {\n customRows.add(index);\n }\n }\n }\n return { heights: output, customRows };\n }\n\n private extractCellStyleIndexes(workbook: WorkBook, sheetIndex: number): Map<string, number> {\n const xml = this.getSheetXml(workbook, sheetIndex);\n if (!xml) {\n return new Map();\n }\n const regex = /<c\\b([^>]*)>/g;\n const map = new Map<string, number>();\n let match: RegExpExecArray | null;\n while ((match = regex.exec(xml)) !== null) {\n const attrs = match[1];\n const refMatch = /r=\"([^\"]+)\"/.exec(attrs);\n const styleMatch = /s=\"([^\"]+)\"/.exec(attrs);\n if (!refMatch || !styleMatch) {\n continue;\n }\n const styleIndex = Number(styleMatch[1]);\n if (!Number.isFinite(styleIndex)) {\n continue;\n }\n map.set(refMatch[1], styleIndex);\n }\n return map;\n }\n\n private extractCellBorders(\n workbook: WorkBook,\n styleIndexes: Map<string, number>,\n ): Map<string, CellBorderDefinition> {\n if (!styleIndexes.size) {\n return new Map();\n }\n const styles = this.buildStyleBorderMap(workbook);\n if (!styles.size) {\n return new Map();\n }\n const borders = new Map<string, CellBorderDefinition>();\n for (const [address, styleIndex] of styleIndexes.entries()) {\n const border = styles.get(styleIndex);\n if (!border) {\n continue;\n }\n const decoded = utils.decode_cell(address);\n if (\n decoded.r < 0 ||\n decoded.c < 0 ||\n decoded.r >= this.worksheet.rows ||\n decoded.c >= this.worksheet.columns\n ) {\n continue;\n }\n borders.set(`${decoded.r}:${decoded.c}`, border);\n }\n return borders;\n }\n\n private buildStyleNumberFormatMap(workbook: WorkBook): Map<number, string> {\n const map = new Map<number, string>();\n const styles = workbook.Styles;\n const cellXfs = styles?.CellXf ?? [];\n cellXfs.forEach((xf, index) => {\n const numFmtId = this.parseIndex(xf.numFmtId);\n if (numFmtId === null) {\n return;\n }\n const code = styles?.NumberFormats?.get(numFmtId) ?? BUILTIN_NUMBER_FORMATS[numFmtId];\n if (code) {\n map.set(index, code);\n }\n });\n return map;\n }\n\n private buildStyleAlignmentMap(workbook: WorkBook): Map<number, AlignmentStyle> {\n const workbookAny = workbook as unknown as {\n Styles?: {\n CellXf?: Array<{\n alignment?: { horizontal?: string; vertical?: string; wrapText?: string };\n }>;\n };\n };\n const cellXfs = workbookAny.Styles?.CellXf ?? [];\n const map = new Map<number, AlignmentStyle>();\n cellXfs.forEach((xf, index) => {\n const horizontal = this.normalizeHorizontalAlignment(xf.alignment?.horizontal);\n const vertical = this.normalizeVerticalAlignment(xf.alignment?.vertical);\n const wrapText = xf.alignment?.wrapText === '1' ? true : undefined;\n if (horizontal || vertical || wrapText) {\n map.set(index, { horizontal, vertical, wrapText });\n }\n });\n return map;\n }\n\n private buildStyleFillMap(workbook: WorkBook): Map<number, string> {\n const workbookAny = workbook as unknown as {\n Styles?: {\n CellXf?: Array<{ fillId?: number | string; [key: string]: unknown }>;\n Fills?: Array<ExcelFill | undefined>;\n };\n };\n const cellXfs = workbookAny.Styles?.CellXf ?? [];\n const fills = (workbookAny.Styles?.Fills ?? []) as Array<ExcelFill | undefined>;\n const map = new Map<number, string>();\n cellXfs.forEach((xf, index) => {\n const fillIndex = this.parseIndex(xf.fillId ?? xf.fillid);\n if (fillIndex === null) {\n return;\n }\n const fill = fills[fillIndex];\n const color = this.convertExcelFill(fill);\n if (color) {\n map.set(index, color);\n }\n });\n return map;\n }\n\n private buildStyleFontMap(workbook: WorkBook): Map<\n number,\n {\n color?: string;\n fontFamily?: string;\n fontSize?: number;\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n }\n > {\n const workbookAny = workbook as unknown as {\n Styles?: {\n CellXf?: Array<{ fontId?: number | string; [key: string]: unknown }>;\n Fonts?: Array<ExcelFontDefinition | undefined>;\n };\n };\n const cellXfs = workbookAny.Styles?.CellXf ?? [];\n const fonts = (workbookAny.Styles?.Fonts ?? []) as Array<ExcelFontDefinition | undefined>;\n const map = new Map<\n number,\n {\n color?: string;\n fontFamily?: string;\n fontSize?: number;\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n }\n >();\n cellXfs.forEach((xf, index) => {\n const fontIndex = this.parseIndex(xf.fontId ?? xf.fontid);\n if (fontIndex === null) {\n return;\n }\n const font = fonts[fontIndex];\n if (!font) {\n return;\n }\n const color = this.extractFontColor(font) ?? undefined;\n const fontFamily = font?.name;\n const fontSize = typeof font?.sz === 'number' ? font.sz : undefined;\n const bold = typeof font?.bold === 'boolean' ? font.bold : undefined;\n const italic = typeof font?.italic === 'boolean' ? font.italic : undefined;\n const underline = typeof font?.underline === 'boolean' ? font.underline : undefined;\n if (color || fontFamily || fontSize || bold !== undefined || italic !== undefined || underline !== undefined) {\n map.set(index, { color, fontFamily, fontSize, bold, italic, underline });\n }\n });\n return map;\n }\n\n private buildStyleBorderMap(workbook: WorkBook): Map<number, CellBorderDefinition> {\n const workbookAny = workbook as unknown as {\n Styles?: {\n CellXf?: Array<{ borderId?: number | string; [key: string]: unknown }>;\n Borders?: ExcelBorder[];\n };\n };\n const cellXfs = (workbookAny.Styles?.CellXf ?? []) as Array<{\n borderId?: number | string;\n [key: string]: unknown;\n }>;\n const borders = (workbookAny.Styles?.Borders ?? []) as ExcelBorder[];\n const map = new Map<number, CellBorderDefinition>();\n cellXfs.forEach((xf, index) => {\n const borderIndex = this.parseIndex(xf.borderId ?? xf.borderid);\n if (borderIndex === null) {\n return;\n }\n const excelBorder = borders[borderIndex];\n const converted = this.convertExcelBorder(excelBorder);\n if (converted) {\n map.set(index, converted);\n }\n });\n return map;\n }\n\n private convertExcelFill(fill?: ExcelFill): string | null {\n if (!fill) {\n return null;\n }\n const patternType = fill.patternType?.toLowerCase();\n if (patternType && patternType !== 'solid') {\n return null;\n }\n const color = fill.fgColor ?? fill.bgColor;\n if (!color) {\n return null;\n }\n return this.convertExcelColor(color, '#ffffff');\n }\n\n private convertExcelBorder(border?: ExcelBorder): CellBorderDefinition | null {\n if (!border) {\n return null;\n }\n const result: CellBorderDefinition = {};\n const top = this.convertExcelBorderLine(border.top);\n const right = this.convertExcelBorderLine(border.right);\n const bottom = this.convertExcelBorderLine(border.bottom);\n const left = this.convertExcelBorderLine(border.left);\n if (top) {\n result.top = top;\n }\n if (right) {\n result.right = right;\n }\n if (bottom) {\n result.bottom = bottom;\n }\n if (left) {\n result.left = left;\n }\n return Object.keys(result).length ? result : null;\n }\n\n private convertExcelBorderLine(edge?: ExcelBorderLine) {\n if (!edge || !edge.style) {\n return undefined;\n }\n const { style, width } = this.mapExcelBorderStyle(edge.style);\n const color = this.convertExcelColor(edge.color);\n return { style, width, color };\n }\n\n private mapExcelBorderStyle(excelStyle: string): {\n style: BorderLineOptions['style'];\n width: number;\n } {\n switch (excelStyle) {\n case 'dotted':\n return { style: 'dotted', width: 1 };\n case 'dashDot':\n case 'dashDotDot':\n case 'dashed':\n return { style: 'dashed', width: 1 };\n case 'mediumDashDot':\n case 'mediumDashDotDot':\n case 'mediumDashed':\n return { style: 'dashed', width: 2 };\n case 'thick':\n case 'double':\n return { style: 'solid', width: 3 };\n case 'medium':\n return { style: 'solid', width: 2 };\n case 'hair':\n case 'thin':\n default:\n return { style: 'solid', width: 1 };\n }\n }\n\n private convertExcelColor(color?: ExcelColor, fallback = '#1f2933'): string {\n return this.resolveExcelColor(color) ?? fallback;\n }\n\n private resolveExcelColor(color?: ExcelColor): string | null {\n if (!color) {\n return null;\n }\n if (color.rgb) {\n const normalized = this.normalizeColorHex(color.rgb);\n if (normalized) {\n return normalized;\n }\n }\n if (color.indexed !== undefined) {\n const paletteColor = this.indexedColors.get(color.indexed);\n if (paletteColor) {\n return paletteColor;\n }\n }\n return null;\n }\n\n private normalizeColorHex(value: string | null | undefined): string | null {\n if (!value) {\n return null;\n }\n const hex = value.replace(/^#/, '');\n if (hex.length === 8) {\n return `#${hex.slice(2)}`;\n }\n if (hex.length === 6) {\n return `#${hex}`;\n }\n return null;\n }\n\n private extractFontColor(font?: ExcelFontDefinition): string | null {\n if (!font?.color) {\n return null;\n }\n return this.convertExcelColor(font.color);\n }\n\n // Standard indexed color palette defined by OOXML spec (ECMA-376 §18.8.27).\n // Used as fallback when the file has no custom <colors> element.\n private static readonly STANDARD_INDEXED_COLORS: readonly string[] = [\n '#000000', '#ffffff', '#ff0000', '#00ff00', '#0000ff', '#ffff00', '#ff00ff', '#00ffff',\n '#000000', '#ffffff', '#ff0000', '#00ff00', '#0000ff', '#ffff00', '#ff00ff', '#00ffff',\n '#800000', '#008000', '#000080', '#808000', '#800080', '#008080', '#c0c0c0', '#808080',\n '#9999ff', '#993366', '#ffffcc', '#ccffff', '#660066', '#ff8080', '#0066cc', '#ccccff',\n '#000080', '#ff00ff', '#ffff00', '#00ffff', '#800080', '#800000', '#008080', '#0000ff',\n '#00ccff', '#ccffff', '#ccffcc', '#ffff99', '#99ccff', '#ff99cc', '#cc99ff', '#ffcc99',\n '#3366ff', '#33cccc', '#99cc00', '#ffcc00', '#ff9900', '#ff6600', '#666699', '#969696',\n '#003366', '#339966', '#003300', '#333300', '#993300', '#993366', '#333399', '#333333',\n ];\n\n private buildIndexedColorMap(workbook: WorkBook): Map<number, string> {\n const map = new Map<number, string>();\n\n // Seed with the standard palette as fallback\n XlsxImporter.STANDARD_INDEXED_COLORS.forEach((color, index) => {\n map.set(index, color);\n });\n\n // Override with any custom palette embedded in the file\n const indexed = workbook.Styles?.Colors?.indexed;\n if (indexed && indexed.length > 0) {\n indexed.forEach((value, index) => {\n const normalized = this.normalizeColorHex(value);\n if (normalized) {\n map.set(index, normalized);\n }\n });\n }\n\n return map;\n }\n\n private getSheetXml(workbook: WorkBook, sheetIndex: number): string | null {\n const workbookAny = workbook as unknown as {\n Directory?: { sheets?: string[] };\n files?: Record<string, { content?: unknown } | ArrayBuffer | Uint8Array | string>;\n };\n const sheets = workbookAny.Directory?.sheets;\n if (!sheets || sheetIndex < 0 || sheetIndex >= sheets.length) {\n return null;\n }\n const path = sheets[sheetIndex]?.replace(/^\\/+/, '');\n if (!path) {\n return null;\n }\n const fileRecord = workbookAny.files?.[path];\n if (!fileRecord) {\n return null;\n }\n const raw = (fileRecord as { content?: unknown }).content ?? fileRecord;\n return this.decodeBinaryString(raw);\n }\n\n private decodeBinaryString(data: unknown): string | null {\n if (!data) {\n return null;\n }\n if (typeof data === 'string') {\n return data;\n }\n if (data instanceof ArrayBuffer) {\n return this.decodeWithTextDecoder(new Uint8Array(data));\n }\n if (ArrayBuffer.isView(data)) {\n const view = data as ArrayBufferView;\n const array = new Uint8Array(view.buffer, view.byteOffset, view.byteLength);\n return this.decodeWithTextDecoder(array);\n }\n return null;\n }\n\n private decodeWithTextDecoder(bytes: Uint8Array): string {\n if (this.binaryDecoder) {\n return this.binaryDecoder.decode(bytes);\n }\n let result = '';\n for (let i = 0; i < bytes.length; i += 1) {\n result += String.fromCharCode(bytes[i]);\n }\n return result;\n }\n\n private parseIndex(value: unknown): number | null {\n const parsed = typeof value === 'string' ? Number.parseInt(value, 10) : Number(value);\n return Number.isFinite(parsed) ? parsed : null;\n }\n\n private getSheetFormat(sheet: WorkSheet): SheetFormatProperties | undefined {\n const format = sheet['!sheetFormat'];\n if (format && typeof format === 'object') {\n return format as SheetFormatProperties;\n }\n return undefined;\n }\n\n private normalizeColumnWidth(column: ColumnInfo): number | null {\n if (typeof column.wpx === 'number' && column.wpx > 0) {\n return column.wpx;\n }\n if (typeof column.width === 'number' && column.width > 0) {\n return this.charWidthToPixels(column.width);\n }\n if (typeof column.wch === 'number' && column.wch > 0) {\n return this.charWidthToPixels(column.wch);\n }\n return null;\n }\n\n private normalizeRowHeight(row: RowInfo): number | null {\n if (typeof row.hpx === 'number' && row.hpx > 0) {\n return row.hpx;\n }\n if (typeof row.hpt === 'number' && row.hpt > 0) {\n return row.hpt * (96 / 72);\n }\n return null;\n }\n\n private normalizeDefaultColumnWidth(width?: number): number | null {\n if (typeof width !== 'number' || Number.isNaN(width) || width <= 0) {\n return null;\n }\n return this.charWidthToPixels(width);\n }\n\n private normalizeDefaultRowHeight(height?: number): number | null {\n if (typeof height !== 'number' || Number.isNaN(height) || height <= 0) {\n return null;\n }\n return height * (96 / 72);\n }\n\n private charWidthToPixels(measure: number): number {\n if (!Number.isFinite(measure) || measure <= 0) {\n return 0;\n }\n const MAX_DIGIT_WIDTH = 7; // Excel default for Calibri 11\n const CELL_PADDING = 5; // Excel adds ~5px padding to each column\n if (measure < 1) {\n return Math.floor(measure * (MAX_DIGIT_WIDTH + CELL_PADDING));\n }\n return Math.floor(measure * MAX_DIGIT_WIDTH + CELL_PADDING);\n }\n\n private getHorizontalAlignment(\n cell: CellObject | undefined,\n merges: WorksheetMergeRange[],\n row: number,\n column: number,\n styleAlignment?: TextAlign,\n ): TextAlign | undefined {\n const explicit =\n styleAlignment ??\n this.normalizeHorizontalAlignment(\n (cell?.s as { alignment?: { horizontal?: string } } | undefined)?.alignment?.horizontal,\n );\n if (explicit) {\n return explicit;\n }\n if (cell && (cell.t === 'n' || cell.t === 'd')) {\n return 'right';\n }\n return undefined;\n }\n\n private getVerticalAlignment(\n cell: CellObject | undefined,\n merges: WorksheetMergeRange[],\n row: number,\n column: number,\n styleAlignment?: VerticalAlign,\n ): VerticalAlign | undefined {\n return (\n styleAlignment ??\n this.normalizeVerticalAlignment(\n (cell?.s as { alignment?: { vertical?: string } } | undefined)?.alignment?.vertical,\n )\n );\n }\n\n private buildCellStyle(\n cell: CellObject | undefined,\n textAlign: TextAlign | undefined,\n verticalAlign: VerticalAlign | undefined,\n backgroundColor: string | undefined,\n fontOverrides?: {\n color?: string;\n fontFamily?: string;\n fontSize?: number;\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n },\n wrapText?: boolean,\n ): Partial<CellStyle> | undefined {\n const style: Partial<CellStyle> = {};\n if (textAlign) {\n style.textAlign = textAlign;\n }\n if (verticalAlign) {\n style.verticalAlign = verticalAlign;\n }\n if (wrapText) {\n style.textWrapMode = 'wrap';\n }\n if (backgroundColor) {\n style.backgroundColor = backgroundColor;\n }\n const resolvedFontColor = this.getCellFontColor(cell) ?? fontOverrides?.color;\n if (resolvedFontColor) {\n style.color = resolvedFontColor;\n }\n const fontFamily = this.getCellFontFamily(cell) ?? fontOverrides?.fontFamily;\n if (fontFamily) {\n style.fontFamily = fontFamily;\n }\n const fontSize = this.getCellFontSize(cell) ?? fontOverrides?.fontSize;\n if (fontSize) {\n style.fontSize = fontSize;\n }\n const fontBold = this.getCellFontBold(cell) ?? fontOverrides?.bold;\n if (fontBold !== undefined) {\n style.bold = fontBold;\n }\n const fontItalic = this.getCellFontItalic(cell) ?? fontOverrides?.italic;\n if (fontItalic !== undefined) {\n style.italic = fontItalic;\n }\n const fontUnderline = this.getCellFontUnderline(cell) ?? fontOverrides?.underline;\n if (fontUnderline !== undefined) {\n style.underline = fontUnderline;\n }\n return Object.keys(style).length ? style : undefined;\n }\n\n private getCellFontColor(cell: CellObject | undefined): string | undefined {\n const fontColor = (cell?.s as { font?: { color?: ExcelColor } } | undefined)?.font?.color;\n if (!fontColor) {\n return undefined;\n }\n return this.convertExcelColor(fontColor);\n }\n\n private getCellFontFamily(cell: CellObject | undefined): string | undefined {\n const fontName = (cell?.s as { font?: { name?: string } } | undefined)?.font?.name;\n if (typeof fontName === 'string' && fontName.trim().length > 0) {\n return fontName;\n }\n return undefined;\n }\n\n private getCellFontSize(cell: CellObject | undefined): number | undefined {\n const fontSize = (cell?.s as { font?: { size?: number } } | undefined)?.font?.size;\n if (typeof fontSize !== 'number' || Number.isNaN(fontSize) || fontSize <= 0) {\n return undefined;\n }\n return fontSize;\n }\n\n private getCellFontBold(cell: CellObject | undefined): boolean | undefined {\n const fontBold = (cell?.s as { font?: { bold?: boolean } } | undefined)?.font?.bold;\n return typeof fontBold === 'boolean' ? fontBold : undefined;\n }\n\n private getCellFontItalic(cell: CellObject | undefined): boolean | undefined {\n const fontItalic = (cell?.s as { font?: { italic?: boolean } } | undefined)?.font?.italic;\n return typeof fontItalic === 'boolean' ? fontItalic : undefined;\n }\n\n private getCellFontUnderline(cell: CellObject | undefined): boolean | undefined {\n const fontUnderline = (cell?.s as { font?: { underline?: boolean } } | undefined)?.font?.underline;\n return typeof fontUnderline === 'boolean' ? fontUnderline : undefined;\n }\n\n private normalizeHorizontalAlignment(value?: string): TextAlign | undefined {\n switch (value) {\n case 'center':\n case 'centerContinuous':\n case 'distributed':\n case 'justify':\n return 'center';\n case 'right':\n return 'right';\n case 'left':\n return 'left';\n default:\n return undefined;\n }\n }\n\n private normalizeVerticalAlignment(value?: string): VerticalAlign | undefined {\n switch (value) {\n case 'center':\n case 'centerContinuous':\n case 'distributed':\n case 'justify':\n case 'middle':\n return 'middle';\n case 'bottom':\n return 'bottom';\n case 'top':\n return 'top';\n default:\n return undefined;\n }\n }\n\n private serializeRawCellValue(value: string | number | boolean | null): string | null {\n if (value === null || value === undefined) {\n return null;\n }\n if (typeof value === 'string') {\n return value;\n }\n if (typeof value === 'number') {\n return Number.isFinite(value) ? value.toString() : null;\n }\n if (typeof value === 'boolean') {\n return value ? 'TRUE' : 'FALSE';\n }\n return null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Image URL helpers (used by WorksheetAPI after import)\n// ---------------------------------------------------------------------------\n\nexport type WorksheetImageAnchorPosition = {\n row: number;\n column: number;\n offsetX: number;\n offsetY: number;\n};\n\nexport type WorksheetImagePlacement =\n | { type: 'oneCell'; from: WorksheetImageAnchorPosition; width: number; height: number }\n | { type: 'twoCell'; from: WorksheetImageAnchorPosition; to: WorksheetImageAnchorPosition };\n\nexport type WorksheetImageInfo = {\n id: string;\n mimeType: string;\n data: Uint8Array;\n anchor: WorksheetImagePlacement;\n};\n\nexport function convertImageInfo(image: WorksheetImage): WorksheetImageInfo {\n return {\n id: image.id,\n mimeType: image.mimeType,\n data: image.data,\n anchor: convertAnchor(image.anchor),\n };\n}\n\nfunction convertAnchor(anchor: WorksheetImage['anchor']): WorksheetImagePlacement {\n if (anchor.type === 'oneCell') {\n return {\n type: 'oneCell',\n from: convertAnchorPosition(anchor.from),\n width: emuToPixels(anchor.width),\n height: emuToPixels(anchor.height),\n };\n }\n return {\n type: 'twoCell',\n from: convertAnchorPosition(anchor.from),\n to: convertAnchorPosition(anchor.to),\n };\n}\n\nfunction convertAnchorPosition(position: DrawingAnchorPosition): WorksheetImageAnchorPosition {\n return {\n row: position.row,\n column: position.column,\n offsetX: emuToPixels(position.columnOffset),\n offsetY: emuToPixels(position.rowOffset),\n };\n}\n\nfunction emuToPixels(value: number): number {\n return Number.isFinite(value) ? value / EMUS_PER_PIXEL : 0;\n}\n\nexport function buildImageUrl(image: WorksheetImage): string {\n if (\n typeof Blob !== 'undefined' &&\n typeof URL !== 'undefined' &&\n typeof URL.createObjectURL === 'function'\n ) {\n const view = image.data;\n const buffer =\n view.byteOffset === 0 && view.byteLength === view.buffer.byteLength\n ? (view.buffer as ArrayBuffer)\n : (view.buffer.slice(view.byteOffset, view.byteOffset + view.byteLength) as ArrayBuffer);\n const blob = new Blob([buffer], { type: image.mimeType });\n return URL.createObjectURL(blob);\n }\n return `data:${image.mimeType};base64,${encodeBase64(image.data)}`;\n}\n\nfunction encodeBase64(data: Uint8Array): string {\n if (typeof btoa === 'function') {\n let binary = '';\n for (let i = 0; i < data.length; i += 1) {\n binary += String.fromCharCode(data[i]);\n }\n return btoa(binary);\n }\n throw new Error('Base64 encoding is not supported in this environment.');\n}\n","const LOCAL_FILE_HEADER_SIGNATURE = 0x04034b50;\nconst CENTRAL_DIRECTORY_SIGNATURE = 0x02014b50;\nconst END_OF_CENTRAL_DIR_SIGNATURE = 0x06054b50;\n\nconst textEncoder = typeof TextEncoder !== 'undefined' ? new TextEncoder() : null;\n\nconst CRC32_TABLE = (() => {\n const table = new Uint32Array(256);\n for (let i = 0; i < 256; i += 1) {\n let value = i;\n for (let bit = 0; bit < 8; bit += 1) {\n value = (value & 1) === 1 ? 0xedb88320 ^ (value >>> 1) : value >>> 1;\n }\n table[i] = value >>> 0;\n }\n return table;\n})();\n\nexport function encodeUtf8(input: string): Uint8Array {\n if (textEncoder) {\n return textEncoder.encode(input);\n }\n const buffer = new Uint8Array(input.length);\n for (let i = 0; i < input.length; i += 1) {\n buffer[i] = input.charCodeAt(i);\n }\n return buffer;\n}\n\nfunction crc32(data: Uint8Array): number {\n let crc = 0xffffffff;\n for (let i = 0; i < data.length; i += 1) {\n crc = CRC32_TABLE[(crc ^ data[i]) & 0xff] ^ (crc >>> 8);\n }\n return (crc ^ 0xffffffff) >>> 0;\n}\n\nexport function createZip(entries: Array<{ name: string; data: Uint8Array }>): Uint8Array {\n const fileChunks: Uint8Array[] = [];\n const centralChunks: Uint8Array[] = [];\n let offset = 0;\n\n for (const entry of entries) {\n const nameBytes = encodeUtf8(entry.name);\n const entryCrc = crc32(entry.data);\n const localHeader = new Uint8Array(30 + nameBytes.length);\n const localView = new DataView(localHeader.buffer);\n localView.setUint32(0, LOCAL_FILE_HEADER_SIGNATURE, true);\n localView.setUint16(4, 20, true); // version needed to extract\n localView.setUint16(6, 0, true); // general purpose bit flag\n localView.setUint16(8, 0, true); // compression (0 = store)\n localView.setUint16(10, 0, true); // mod time (00:00:00)\n localView.setUint16(12, 0x0021, true); // mod date (1980-01-01)\n localView.setUint32(14, entryCrc, true);\n localView.setUint32(18, entry.data.length, true);\n localView.setUint32(22, entry.data.length, true);\n localView.setUint16(26, nameBytes.length, true);\n localView.setUint16(28, 0, true); // extra field length\n localHeader.set(nameBytes, 30);\n\n fileChunks.push(localHeader);\n fileChunks.push(entry.data);\n\n const centralHeader = new Uint8Array(46 + nameBytes.length);\n const centralView = new DataView(centralHeader.buffer);\n centralView.setUint32(0, CENTRAL_DIRECTORY_SIGNATURE, true);\n centralView.setUint16(4, 20, true); // version made by\n centralView.setUint16(6, 20, true); // version needed to extract\n centralView.setUint16(8, 0, true); // general purpose bit flag\n centralView.setUint16(10, 0, true); // compression\n centralView.setUint16(12, 0, true); // mod time (00:00:00)\n centralView.setUint16(14, 0x0021, true); // mod date (1980-01-01)\n centralView.setUint32(16, entryCrc, true);\n centralView.setUint32(20, entry.data.length, true);\n centralView.setUint32(24, entry.data.length, true);\n centralView.setUint16(28, nameBytes.length, true);\n centralView.setUint16(30, 0, true); // extra field length\n centralView.setUint16(32, 0, true); // file comment length\n centralView.setUint16(34, 0, true); // disk number start\n centralView.setUint16(36, 0, true); // internal file attributes\n centralView.setUint32(40, 0, true); // external file attributes\n centralView.setUint32(42, offset, true);\n centralHeader.set(nameBytes, 46);\n\n centralChunks.push(centralHeader);\n\n offset += localHeader.length + entry.data.length;\n }\n\n const centralDirOffset = offset;\n const centralDirSize = centralChunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const eocd = new Uint8Array(22);\n const eocdView = new DataView(eocd.buffer);\n eocdView.setUint32(0, END_OF_CENTRAL_DIR_SIGNATURE, true);\n eocdView.setUint16(4, 0, true); // number of this disk\n eocdView.setUint16(6, 0, true); // disk where central directory starts\n eocdView.setUint16(8, entries.length, true); // number of central dir records on this disk\n eocdView.setUint16(10, entries.length, true); // total central dir records\n eocdView.setUint32(12, centralDirSize, true);\n eocdView.setUint32(16, centralDirOffset, true);\n eocdView.setUint16(20, 0, true); // comment length\n\n const totalLength =\n fileChunks.reduce((sum, chunk) => sum + chunk.length, 0) + centralDirSize + eocd.length;\n const output = new Uint8Array(totalLength);\n let position = 0;\n for (const chunk of fileChunks) {\n output.set(chunk, position);\n position += chunk.length;\n }\n for (const chunk of centralChunks) {\n output.set(chunk, position);\n position += chunk.length;\n }\n output.set(eocd, position);\n return output;\n}\n","import { DEFAULT_COLUMN_WIDTH, DEFAULT_ROW_HEIGHT } from '../core/worksheet/gridDefaults';\nimport { DEFAULT_CELL_STYLE, type CellStyle } from '../core/style/cellStyle';\nimport type { CellBorderDefinition, BorderLine } from '../core/border/types';\nimport type { WorksheetExportSnapshot } from '../core/worksheet/worksheet';\nimport { parseCellKey } from '../core/worksheet/cellKey';\nimport { utils } from './xlsx';\nimport { createZip, encodeUtf8 } from './zipWriter';\n\nconst WORKBOOK_NAMESPACE = 'http://schemas.openxmlformats.org/spreadsheetml/2006/main';\n// Used as xmlns:r in content XML files (workbook.xml, sheet1.xml) and as the\n// base for relationship Type attribute values in .rels files.\nconst REL_TYPE_NS = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships';\n// Used as xmlns on the <Relationships> root element in all .rels files.\nconst PACKAGE_RELS_NS = 'http://schemas.openxmlformats.org/package/2006/relationships';\n\nconst COLUMN_PADDING = 5;\nconst COLUMN_CHARACTER_WIDTH = 7;\n\ntype FontDefinition = {\n name?: string;\n sz?: number;\n bold?: true;\n italic?: true;\n underline?: string;\n color?: { rgb: string };\n};\n\ntype FillDefinition =\n | { patternType: 'none' }\n | { patternType: 'gray125' }\n | { patternType: 'solid'; fgColor: { rgb: string }; bgColor: { indexed: string } };\n\ntype AlignmentDefinition = { horizontal?: string; vertical?: string; wrapText?: '1' };\n\ntype BorderEdgeDefinition = { style: string; color: string };\ntype XlsxBorderDefinition = {\n left?: BorderEdgeDefinition;\n right?: BorderEdgeDefinition;\n top?: BorderEdgeDefinition;\n bottom?: BorderEdgeDefinition;\n};\n\ntype CellXfDefinition = {\n fontId: number;\n fillId: number;\n borderId: number;\n alignment?: AlignmentDefinition;\n applyFont?: boolean;\n applyFill?: boolean;\n applyBorder?: boolean;\n applyAlignment?: boolean;\n};\n\nexport function buildXlsxFromSnapshot(\n snapshot: WorksheetExportSnapshot,\n sheetName: string,\n): ArrayBuffer {\n const styleManager = new StyleManager();\n const sharedStrings = new SharedStringTable();\n const sheetXml = buildSheetXml(snapshot, styleManager, sharedStrings);\n const stylesXml = styleManager.buildStylesXml();\n const workbookXml = buildWorkbookXml(sheetName);\n const workbookRelsXml = buildWorkbookRelationshipsXml();\n const contentTypesXml = buildContentTypesXml();\n const sharedStringsXml = buildSharedStringsXml(sharedStrings);\n const timestamp = formatIsoDate(new Date());\n const corePropertiesXml = buildCorePropertiesXml(timestamp);\n const appPropertiesXml = buildAppPropertiesXml(sheetName);\n const rootRelsXml = buildRootRelationshipsXml();\n\n const entries = [\n { name: '[Content_Types].xml', data: encodeUtf8(contentTypesXml) },\n { name: '_rels/.rels', data: encodeUtf8(rootRelsXml) },\n { name: 'xl/workbook.xml', data: encodeUtf8(workbookXml) },\n { name: 'xl/_rels/workbook.xml.rels', data: encodeUtf8(workbookRelsXml) },\n { name: 'xl/styles.xml', data: encodeUtf8(stylesXml) },\n { name: 'xl/sharedStrings.xml', data: encodeUtf8(sharedStringsXml) },\n { name: 'docProps/core.xml', data: encodeUtf8(corePropertiesXml) },\n { name: 'docProps/app.xml', data: encodeUtf8(appPropertiesXml) },\n { name: 'xl/worksheets/sheet1.xml', data: encodeUtf8(sheetXml) },\n ];\n const zip = createZip(entries);\n return zip.buffer.slice(zip.byteOffset, zip.byteOffset + zip.byteLength) as ArrayBuffer;\n}\n\nfunction buildSheetXml(\n snapshot: WorksheetExportSnapshot,\n styleManager: StyleManager,\n strings: SharedStringTable,\n): string {\n const cellGroups = new Map<number, WorksheetExportSnapshot['cells']>();\n let maxRow = Math.max(snapshot.rows - 1, 0);\n let maxCol = Math.max(snapshot.columns - 1, 0);\n\n for (const cell of snapshot.cells) {\n if (!cellGroups.has(cell.row)) {\n cellGroups.set(cell.row, []);\n }\n cellGroups.get(cell.row)!.push(cell);\n maxRow = Math.max(maxRow, cell.row);\n maxCol = Math.max(maxCol, cell.column);\n }\n\n for (const merge of snapshot.merges) {\n maxRow = Math.max(maxRow, merge.bottomRow);\n maxCol = Math.max(maxCol, merge.rightColumn);\n }\n\n // Ensure cells with borders (but no value/style) are included in the output\n for (const [key] of snapshot.borders) {\n const pos = parseCellKey(key);\n if (pos) {\n if (!cellGroups.has(pos.row)) {\n cellGroups.set(pos.row, []);\n }\n const existing = cellGroups.get(pos.row)!;\n if (!existing.some((c) => c.row === pos.row && c.column === pos.column)) {\n existing.push({ row: pos.row, column: pos.column });\n }\n maxRow = Math.max(maxRow, pos.row);\n maxCol = Math.max(maxCol, pos.column);\n }\n }\n\n const dimensionRef = `${utils.encode_cell({ r: 0, c: 0 })}:${utils.encode_cell({\n r: Math.max(maxRow, 0),\n c: Math.max(maxCol, 0),\n })}`;\n\n const columns = buildColumnsSection(Math.max(snapshot.columnWidths.length, maxCol + 1), snapshot);\n const rows = buildRowsSection(cellGroups, snapshot, styleManager, strings);\n const merges = buildMergeCellsSection(snapshot.merges);\n\n const parts = [\n `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>`,\n `<worksheet xmlns:r=\"${REL_TYPE_NS}\" xmlns=\"${WORKBOOK_NAMESPACE}\">`,\n ` <dimension ref=\"${dimensionRef}\"/>`,\n ` <sheetViews>${buildSheetViewXml(snapshot)}</sheetViews>`,\n ` <sheetFormatPr defaultColWidth=\"${columnWidthToExcel(DEFAULT_COLUMN_WIDTH)}\" defaultRowHeight=\"${DEFAULT_ROW_HEIGHT}\"/>`,\n ];\n if (columns) {\n parts.push(` ${columns}`);\n }\n parts.push(` <sheetData>${rows}</sheetData>`);\n if (merges) {\n parts.push(` ${merges}`);\n }\n parts.push(`</worksheet>`);\n return parts.join('\\n');\n}\n\nfunction buildSheetViewXml(snapshot: WorksheetExportSnapshot): string {\n const frozenRows = snapshot.frozenRows ?? 0;\n const frozenCols = snapshot.frozenColumns ?? 0;\n if (frozenRows === 0 && frozenCols === 0) {\n return '<sheetView workbookViewId=\"0\" showGridLines=\"1\"/>';\n }\n const paneAttrs: string[] = [];\n if (frozenCols > 0) {\n paneAttrs.push(`xSplit=\"${frozenCols}\"`);\n }\n if (frozenRows > 0) {\n paneAttrs.push(`ySplit=\"${frozenRows}\"`);\n }\n const topLeftCell = `${utils.encode_cell({ r: frozenRows, c: frozenCols })}`;\n paneAttrs.push(`topLeftCell=\"${topLeftCell}\"`);\n let activePane: string;\n if (frozenRows > 0 && frozenCols > 0) {\n activePane = 'bottomRight';\n } else if (frozenRows > 0) {\n activePane = 'bottomLeft';\n } else {\n activePane = 'topRight';\n }\n paneAttrs.push(`activePane=\"${activePane}\"`);\n paneAttrs.push('state=\"frozen\"');\n return `<sheetView workbookViewId=\"0\" showGridLines=\"1\"><pane ${paneAttrs.join(' ')}/><selection pane=\"${activePane}\" activeCell=\"${topLeftCell}\" sqref=\"${topLeftCell}\"/></sheetView>`;\n}\n\nfunction buildColumnsSection(columnCount: number, snapshot: WorksheetExportSnapshot): string {\n const parts: string[] = [];\n for (let index = 0; index < columnCount; index += 1) {\n const widthPx = snapshot.columnWidths[index] ?? DEFAULT_COLUMN_WIDTH;\n if (widthPx === DEFAULT_COLUMN_WIDTH) {\n continue;\n }\n const width = columnWidthToExcel(widthPx);\n parts.push(`<col min=\"${index + 1}\" max=\"${index + 1}\" width=\"${width}\" customWidth=\"1\"/>`);\n }\n if (parts.length === 0) {\n return '';\n }\n return `<cols>${parts.join('')}</cols>`;\n}\n\nfunction columnWidthToExcel(px: number): string {\n const width = Math.max(0.1, (px - COLUMN_PADDING) / COLUMN_CHARACTER_WIDTH);\n return width.toFixed(4);\n}\n\nfunction buildRowsSection(\n cellGroups: Map<number, WorksheetExportSnapshot['cells']>,\n snapshot: WorksheetExportSnapshot,\n styleManager: StyleManager,\n strings: SharedStringTable,\n): string {\n const rowHeights = snapshot.rowHeights;\n const rowsToRender = new Set<number>();\n for (const rowIndex of cellGroups.keys()) {\n rowsToRender.add(rowIndex);\n }\n for (let index = 0; index < rowHeights.length; index += 1) {\n const height = rowHeights[index];\n if (height !== DEFAULT_ROW_HEIGHT) {\n rowsToRender.add(index);\n }\n }\n const sortedRows = Array.from(rowsToRender).sort((a, b) => a - b);\n const parts: string[] = [];\n for (const rowIndex of sortedRows) {\n const height = snapshot.rowHeights[rowIndex] ?? DEFAULT_ROW_HEIGHT;\n const attributes = [`r=\"${rowIndex + 1}\"`];\n if (height !== DEFAULT_ROW_HEIGHT) {\n attributes.push(`ht=\"${height.toFixed(2)}\"`);\n attributes.push('customHeight=\"1\"');\n }\n const cells = (cellGroups.get(rowIndex) ?? []).slice().sort((a, b) => a.column - b.column);\n const cellXml = cells.map((cell) => buildCellXml(cell, snapshot.borders, styleManager, strings)).join('');\n if (cellXml) {\n parts.push(`<row ${attributes.join(' ')}>${cellXml}</row>`);\n } else {\n parts.push(`<row ${attributes.join(' ')}/>`);\n }\n }\n return parts.join('');\n}\n\nfunction buildCellXml(\n cell: WorksheetExportSnapshot['cells'][number],\n borders: Map<string, CellBorderDefinition>,\n styleManager: StyleManager,\n strings: SharedStringTable,\n): string {\n const address = utils.encode_cell({ r: cell.row, c: cell.column });\n const cellBorder = borders.get(`${cell.row}:${cell.column}`);\n const styleIndex = styleManager.getStyleIndex(cell.style, cellBorder);\n const styleAttribute = typeof styleIndex === 'number' ? ` s=\"${styleIndex}\"` : '';\n const value = cell.value ?? '';\n\n // Formula cell: value starts with '='\n if (typeof value === 'string' && value.startsWith('=')) {\n const formulaText = escapeXml(value.slice(1));\n const cached = cell.cachedValue;\n let cachedXml = '';\n if (typeof cached === 'number') {\n cachedXml = `<v>${cached}</v>`;\n } else if (typeof cached === 'boolean') {\n cachedXml = `<v>${cached ? 1 : 0}</v>`;\n } else if (typeof cached === 'string' && cached.length > 0) {\n // String cached values use shared strings\n const index = strings.register(cached);\n return `<c r=\"${address}\" t=\"s\"${styleAttribute}><f>${formulaText}</f><v>${index}</v></c>`;\n }\n return `<c r=\"${address}\"${styleAttribute}><f>${formulaText}</f>${cachedXml}</c>`;\n }\n\n if (typeof value === 'string') {\n const index = strings.register(value);\n return `<c r=\"${address}\" t=\"s\"${styleAttribute}><v>${index}</v></c>`;\n }\n if (typeof value === 'number') {\n return `<c r=\"${address}\" t=\"n\"${styleAttribute}><v>${value}</v></c>`;\n }\n if (typeof value === 'boolean') {\n return `<c r=\"${address}\" t=\"b\"${styleAttribute}><v>${value ? 1 : 0}</v></c>`;\n }\n return `<c r=\"${address}\" t=\"n\"${styleAttribute}><v>0</v></c>`;\n}\n\nfunction buildMergeCellsSection(merges: WorksheetExportSnapshot['merges']): string {\n if (!merges.length) {\n return '';\n }\n const cells = merges.map((merge) => {\n const start = utils.encode_cell({ r: merge.topRow, c: merge.leftColumn });\n const end = utils.encode_cell({ r: merge.bottomRow, c: merge.rightColumn });\n return `<mergeCell ref=\"${start}:${end}\"/>`;\n });\n return `<mergeCells count=\"${cells.length}\">${cells.join('')}</mergeCells>`;\n}\n\nfunction escapeXml(input: string): string {\n return input\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&apos;');\n}\n\nfunction buildWorkbookXml(name: string): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<workbook xmlns:r=\"${REL_TYPE_NS}\" xmlns=\"${WORKBOOK_NAMESPACE}\">\n <bookViews>\n <workbookView xWindow=\"0\" yWindow=\"0\" windowWidth=\"16384\" windowHeight=\"8192\"/>\n </bookViews>\n <sheets>\n <sheet name=\"${escapeXml(name)}\" sheetId=\"1\" r:id=\"rId1\"/>\n </sheets>\n</workbook>`;\n}\n\nfunction buildWorkbookRelationshipsXml(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"${PACKAGE_RELS_NS}\">\n <Relationship Id=\"rId1\" Type=\"${REL_TYPE_NS}/worksheet\" Target=\"worksheets/sheet1.xml\"/>\n <Relationship Id=\"rId2\" Type=\"${REL_TYPE_NS}/styles\" Target=\"styles.xml\"/>\n <Relationship Id=\"rId3\" Type=\"${REL_TYPE_NS}/sharedStrings\" Target=\"sharedStrings.xml\"/>\n</Relationships>`;\n}\n\nfunction buildContentTypesXml(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">\n <Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/>\n <Default Extension=\"xml\" ContentType=\"application/xml\"/>\n <Override PartName=\"/xl/workbook.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml\"/>\n <Override PartName=\"/xl/worksheets/sheet1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml\"/>\n <Override PartName=\"/xl/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml\"/>\n <Override PartName=\"/xl/sharedStrings.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml\"/>\n <Override PartName=\"/docProps/core.xml\" ContentType=\"application/vnd.openxmlformats-package.core-properties+xml\"/>\n <Override PartName=\"/docProps/app.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.extended-properties+xml\"/>\n</Types>`;\n}\n\nfunction buildRootRelationshipsXml(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"${PACKAGE_RELS_NS}\">\n <Relationship Id=\"rId1\" Type=\"${REL_TYPE_NS}/officeDocument\" Target=\"xl/workbook.xml\"/>\n <Relationship Id=\"rId2\" Type=\"${PACKAGE_RELS_NS}/metadata/core-properties\" Target=\"docProps/core.xml\"/>\n <Relationship Id=\"rId3\" Type=\"${REL_TYPE_NS}/extended-properties\" Target=\"docProps/app.xml\"/>\n</Relationships>`;\n}\n\nfunction buildSharedStringsXml(table: SharedStringTable): string {\n const entriesXml = table.entries\n .map(\n (entry) =>\n `<si><t${entry.preserve ? ' xml:space=\"preserve\"' : ''}>${escapeXml(entry.text)}</t></si>`,\n )\n .join('');\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<sst xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" count=\"${table.count}\" uniqueCount=\"${table.entries.length}\">\n ${entriesXml}\n</sst>`;\n}\n\nclass SharedStringTable {\n public entries: Array<{ text: string; preserve: boolean }> = [];\n public count = 0;\n\n private readonly map: Map<string, number> = new Map();\n\n register(value: string): number {\n this.count += 1;\n const existing = this.map.get(value);\n if (existing !== undefined) {\n return existing;\n }\n const preserve = /^\\s|\\s$/.test(value);\n const index = this.entries.length;\n this.entries.push({ text: value, preserve });\n this.map.set(value, index);\n return index;\n }\n}\n\n\nfunction formatIsoDate(date: Date): string {\n return date.toISOString();\n}\n\nfunction buildCorePropertiesXml(timestamp: string): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<cp:coreProperties xmlns:cp=\"http://schemas.openxmlformats.org/package/2006/metadata/core-properties\"\n xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n xmlns:dcterms=\"http://purl.org/dc/terms/\"\n xmlns:dcmitype=\"http://purl.org/dc/dcmitype/\"\n xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n <dc:creator>ReoGrid</dc:creator>\n <cp:lastModifiedBy>ReoGrid</cp:lastModifiedBy>\n <dcterms:created xsi:type=\"dcterms:W3CDTF\">${timestamp}</dcterms:created>\n <dcterms:modified xsi:type=\"dcterms:W3CDTF\">${timestamp}</dcterms:modified>\n</cp:coreProperties>`;\n}\n\nfunction buildAppPropertiesXml(sheetName: string): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Properties xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties\"\n xmlns:vt=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\">\n <Application>ReoGrid</Application>\n <DocSecurity>0</DocSecurity>\n <ScaleCrop>false</ScaleCrop>\n <HeadingPairs>\n <vt:vector size=\"2\" baseType=\"variant\">\n <vt:variant><vt:lpstr>Worksheets</vt:lpstr></vt:variant>\n <vt:variant><vt:i4>1</vt:i4></vt:variant>\n </vt:vector>\n </HeadingPairs>\n <TitlesOfParts>\n <vt:vector size=\"1\" baseType=\"lpstr\">\n <vt:lpstr>${escapeXml(sheetName)}</vt:lpstr>\n </vt:vector>\n </TitlesOfParts>\n <Company/>\n <LinksUpToDate>false</LinksUpToDate>\n <SharedDoc>false</SharedDoc>\n</Properties>`;\n}\n\nclass StyleManager {\n private readonly fonts: FontDefinition[] = [\n { name: DEFAULT_CELL_STYLE.fontFamily, sz: DEFAULT_CELL_STYLE.fontSize },\n ];\n private readonly fontKeyMap = new Map<string, number>();\n private readonly fills: FillDefinition[] = [\n { patternType: 'none' },\n { patternType: 'gray125' },\n ];\n private readonly fillKeyMap = new Map<string, number>();\n private readonly xlsxBorders: XlsxBorderDefinition[] = [{}]; // index 0 = empty border\n private readonly borderKeyMap = new Map<string, number>();\n private readonly cellXfs: CellXfDefinition[] = [{ fontId: 0, fillId: 0, borderId: 0 }];\n private readonly styleKeyMap = new Map<string, number>();\n\n public getStyleIndex(style?: CellStyle, border?: CellBorderDefinition): number | undefined {\n if (!style && !border) {\n return undefined;\n }\n const fontId = style ? this.resolveFont(style) : 0;\n const fillId = style ? this.resolveFill(style) : 0;\n const borderId = border ? this.resolveBorder(border) : 0;\n const alignment = style ? this.resolveAlignment(style) : undefined;\n const key = `${fontId}:${fillId}:${borderId}:${alignment?.horizontal ?? ''}:${alignment?.vertical ?? ''}:${alignment?.wrapText ?? ''}`;\n const existing = this.styleKeyMap.get(key);\n if (existing !== undefined) {\n return existing;\n }\n const index = this.cellXfs.length;\n this.cellXfs.push({\n fontId,\n fillId,\n borderId,\n alignment,\n applyFont: fontId !== 0,\n applyFill: fillId !== 0,\n applyBorder: borderId !== 0,\n applyAlignment: Boolean(\n alignment && (alignment.horizontal || alignment.vertical || alignment.wrapText),\n ),\n });\n this.styleKeyMap.set(key, index);\n return index;\n }\n\n public buildStylesXml(): string {\n const fontsXml = this.fonts.map((font) => {\n const parts: string[] = [];\n if (font.sz) {\n parts.push(`<sz val=\"${font.sz}\"/>`);\n }\n if (font.name) {\n parts.push(`<name val=\"${escapeXml(font.name)}\"/>`);\n }\n if (font.bold) {\n parts.push('<b/>');\n }\n if (font.italic) {\n parts.push('<i/>');\n }\n if (font.underline) {\n parts.push(`<u val=\"${font.underline}\"/>`);\n }\n if (font.color) {\n parts.push(`<color rgb=\"${font.color.rgb}\"/>`);\n }\n return `<font>${parts.join('')}</font>`;\n });\n\n const fillsXml = this.fills.map((fill) => {\n if (fill.patternType === 'none') {\n return '<fill><patternFill patternType=\"none\"/></fill>';\n }\n if (fill.patternType === 'gray125') {\n return '<fill><patternFill patternType=\"gray125\"/></fill>';\n }\n if (fill.patternType === 'solid') {\n return `<fill><patternFill patternType=\"solid\"><fgColor rgb=\"${fill.fgColor.rgb}\"/><bgColor indexed=\"${fill.bgColor.indexed}\"/></patternFill></fill>`;\n }\n return '<fill><patternFill patternType=\"none\"/></fill>';\n });\n\n const bordersXml = this.xlsxBorders.map((border) => {\n const edgeXml = (side: string, edge?: BorderEdgeDefinition): string => {\n if (!edge) return `<${side}/>`;\n return `<${side} style=\"${edge.style}\"><color rgb=\"${edge.color}\"/></${side}>`;\n };\n return `<border>${edgeXml('left', border.left)}${edgeXml('right', border.right)}${edgeXml('top', border.top)}${edgeXml('bottom', border.bottom)}<diagonal/></border>`;\n });\n\n const cellXfsXml = this.cellXfs.map((xf) => {\n const attributes = [\n `numFmtId=\"0\"`,\n `fontId=\"${xf.fontId}\"`,\n `fillId=\"${xf.fillId}\"`,\n `borderId=\"${xf.borderId}\"`,\n `xfId=\"0\"`,\n ];\n if (xf.applyFont) {\n attributes.push('applyFont=\"1\"');\n }\n if (xf.applyFill) {\n attributes.push('applyFill=\"1\"');\n }\n if (xf.applyBorder) {\n attributes.push('applyBorder=\"1\"');\n }\n if (xf.applyAlignment) {\n attributes.push('applyAlignment=\"1\"');\n }\n const alignmentXml = xf.alignment\n ? `<alignment${xf.alignment.horizontal ? ` horizontal=\"${xf.alignment.horizontal}\"` : ''}${\n xf.alignment.vertical ? ` vertical=\"${xf.alignment.vertical}\"` : ''\n }${xf.alignment.wrapText ? ' wrapText=\"1\"' : ''}/>`\n : '';\n return `<xf ${attributes.join(' ')}>${alignmentXml}</xf>`;\n });\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<styleSheet xmlns=\"${WORKBOOK_NAMESPACE}\" xmlns:x14ac=\"http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" mc:Ignorable=\"x14ac\">\n <numFmts count=\"0\"/>\n <fonts count=\"${this.fonts.length}\">${fontsXml.join('')}</fonts>\n <fills count=\"${this.fills.length}\">${fillsXml.join('')}</fills>\n <borders count=\"${this.xlsxBorders.length}\">${bordersXml.join('')}</borders>\n <cellStyleXfs count=\"1\">\n <xf numFmtId=\"0\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\"/>\n </cellStyleXfs>\n <cellXfs count=\"${this.cellXfs.length}\">${cellXfsXml.join('')}</cellXfs>\n <cellStyles count=\"1\">\n <cellStyle name=\"Normal\" xfId=\"0\" builtinId=\"0\"/>\n </cellStyles>\n</styleSheet>`;\n }\n\n private resolveFont(style: CellStyle): number {\n const defaultColor = normalizeColor(DEFAULT_CELL_STYLE.color);\n const styleColor = normalizeColor(style.color);\n const hasFontOverrides =\n style.fontFamily !== DEFAULT_CELL_STYLE.fontFamily ||\n style.fontSize !== DEFAULT_CELL_STYLE.fontSize ||\n style.bold ||\n style.italic ||\n style.underline ||\n (styleColor && styleColor !== defaultColor);\n if (!hasFontOverrides) {\n return 0;\n }\n const key = `font:${\n style.fontFamily || ''\n }:${style.fontSize}:${style.bold ? '1' : '0'}:${style.italic ? '1' : '0'}:${style.underline ? '1' : '0'}:${styleColor ?? ''}`;\n const cached = this.fontKeyMap.get(key);\n if (cached !== undefined) {\n return cached;\n }\n const entry: FontDefinition = {};\n if (style.fontFamily && style.fontFamily !== DEFAULT_CELL_STYLE.fontFamily) {\n entry.name = style.fontFamily;\n }\n if (style.fontSize && style.fontSize !== DEFAULT_CELL_STYLE.fontSize) {\n entry.sz = style.fontSize;\n }\n if (style.bold) {\n entry.bold = true;\n }\n if (style.italic) {\n entry.italic = true;\n }\n if (style.underline) {\n entry.underline = 'single';\n }\n if (styleColor && styleColor !== defaultColor) {\n entry.color = { rgb: styleColor };\n }\n this.fonts.push(entry);\n const index = this.fonts.length - 1;\n this.fontKeyMap.set(key, index);\n return index;\n }\n\n private resolveFill(style: CellStyle): number {\n const color = normalizeColor(style.backgroundColor);\n const defaultBackground = normalizeColor(DEFAULT_CELL_STYLE.backgroundColor);\n if (!color || color === defaultBackground) {\n return 0;\n }\n const key = `fill:${color}`;\n const cached = this.fillKeyMap.get(key);\n if (cached !== undefined) {\n return cached;\n }\n const entry: FillDefinition = {\n patternType: 'solid',\n fgColor: { rgb: color },\n bgColor: { indexed: '64' },\n };\n this.fills.push(entry);\n const index = this.fills.length - 1;\n this.fillKeyMap.set(key, index);\n return index;\n }\n\n private resolveBorder(border: CellBorderDefinition): number {\n const convertEdge = (line?: BorderLine): BorderEdgeDefinition | undefined => {\n if (!line) return undefined;\n const color = normalizeColor(line.color) ?? 'FF000000';\n const style = mapBorderLineStyleToExcel(line.style, line.width);\n return { style, color };\n };\n const left = convertEdge(border.left);\n const right = convertEdge(border.right);\n const top = convertEdge(border.top);\n const bottom = convertEdge(border.bottom);\n if (!left && !right && !top && !bottom) {\n return 0;\n }\n const key = `border:${left?.style ?? ''}:${left?.color ?? ''}:${right?.style ?? ''}:${right?.color ?? ''}:${top?.style ?? ''}:${top?.color ?? ''}:${bottom?.style ?? ''}:${bottom?.color ?? ''}`;\n const cached = this.borderKeyMap.get(key);\n if (cached !== undefined) {\n return cached;\n }\n const entry: XlsxBorderDefinition = {};\n if (left) entry.left = left;\n if (right) entry.right = right;\n if (top) entry.top = top;\n if (bottom) entry.bottom = bottom;\n this.xlsxBorders.push(entry);\n const index = this.xlsxBorders.length - 1;\n this.borderKeyMap.set(key, index);\n return index;\n }\n\n private resolveAlignment(style: CellStyle): AlignmentDefinition | undefined {\n const horizontal = style.textAlign !== DEFAULT_CELL_STYLE.textAlign ? style.textAlign : undefined;\n const verticalValue =\n style.verticalAlign !== DEFAULT_CELL_STYLE.verticalAlign\n ? style.verticalAlign === 'middle'\n ? 'center'\n : style.verticalAlign\n : undefined;\n const wrapText =\n style.textWrapMode !== DEFAULT_CELL_STYLE.textWrapMode ? '1' : undefined;\n if (!horizontal && !verticalValue && !wrapText) {\n return undefined;\n }\n return {\n horizontal,\n vertical: verticalValue,\n wrapText,\n };\n }\n}\n\nfunction mapBorderLineStyleToExcel(style: string, width: number): string {\n if (style === 'dotted') return 'dotted';\n if (style === 'dashed') return width >= 2 ? 'mediumDashed' : 'dashed';\n // solid\n if (width >= 3) return 'thick';\n if (width >= 2) return 'medium';\n return 'thin';\n}\n\nfunction normalizeColor(color: string): string | undefined {\n if (!color || typeof color !== 'string') {\n return undefined;\n }\n let normalized = color.trim();\n if (!normalized) {\n return undefined;\n }\n if (normalized.startsWith('#')) {\n normalized = normalized.slice(1);\n }\n const rgbMatch = normalized.match(/^rgba?\\((\\d{1,3}),\\s*(\\d{1,3}),\\s*(\\d{1,3})/i);\n if (rgbMatch) {\n const [r, g, b] = rgbMatch.slice(1).map((value) =>\n Math.max(0, Math.min(255, Number(value) || 0)),\n );\n return `FF${[r, g, b].map((segment) => segment.toString(16).padStart(2, '0')).join('')}`.toUpperCase();\n }\n if (normalized.length === 3) {\n normalized = normalized\n .split('')\n .map((char) => char + char)\n .join('');\n }\n if (normalized.length === 6 || normalized.length === 8) {\n const hex = normalized.toUpperCase();\n return hex.length === 6 ? `FF${hex}` : hex;\n }\n return undefined;\n}\n","import type { Worksheet } from '../worksheet/worksheet';\nimport type { SortConfig, SortResult } from './types';\n\n/**\n * Parse a string as a number if it looks numeric, otherwise return null.\n */\nfunction tryParseNumber(value: string): number | null {\n if (value === '') return null;\n const n = Number(value);\n return Number.isFinite(n) ? n : null;\n}\n\n/**\n * Compare two cell values for sorting.\n * - Empty strings sort to the end regardless of order.\n * - If both are numeric, compare numerically.\n * - Otherwise compare as strings via localeCompare.\n */\nfunction compareValues(a: string, b: string, order: 'asc' | 'desc'): number {\n if (a === '' && b === '') return 0;\n if (a === '') return 1;\n if (b === '') return -1;\n\n const numA = tryParseNumber(a);\n const numB = tryParseNumber(b);\n\n let result: number;\n if (numA !== null && numB !== null) {\n result = numA - numB;\n } else {\n result = a.localeCompare(b);\n }\n\n return order === 'desc' ? -result : result;\n}\n\n/**\n * Sort rows in the worksheet by a key column.\n *\n * Uses low-level Map permutation for performance — all cell data is\n * re-keyed in bulk, then formulaEngine.rebuildAll() and render() are\n * called once at the end.\n *\n * Returns the original row order for undo support.\n */\nexport function sortRows(worksheet: Worksheet, config: SortConfig): SortResult {\n const { column, order, startRow, endRow, startColumn, endColumn } = config;\n\n // Collect participating rows (skip hidden rows)\n const participatingRows: number[] = [];\n for (let r = startRow; r <= endRow; r++) {\n if (!worksheet.isRowHidden(r)) {\n participatingRows.push(r);\n }\n }\n\n if (participatingRows.length <= 1) {\n return { originalOrder: participatingRows.slice() };\n }\n\n // Read sort keys\n const sortKeys = new Map<number, string>();\n for (const row of participatingRows) {\n sortKeys.set(row, worksheet.getCellInput(row, column) ?? '');\n }\n\n // Compute sorted order\n const sortedSourceRows = participatingRows.slice();\n sortedSourceRows.sort((a, b) => compareValues(sortKeys.get(a)!, sortKeys.get(b)!, order));\n\n // Apply permutation: participatingRows[i] gets data from sortedSourceRows[i]\n worksheet.permuteRows(sortedSourceRows, participatingRows, startColumn, endColumn);\n\n // Rebuild formulas and render once\n worksheet.rebuildFormulas();\n worksheet.render();\n\n return { originalOrder: sortedSourceRows };\n}\n\n/**\n * Restore the original row order after sorting (for undo).\n */\nexport function applyPermutation(\n worksheet: Worksheet,\n originalOrder: number[],\n config: Pick<SortConfig, 'startRow' | 'endRow' | 'startColumn' | 'endColumn'>,\n): void {\n const { startRow, endRow, startColumn, endColumn } = config;\n\n const participatingRows: number[] = [];\n for (let r = startRow; r <= endRow; r++) {\n if (!worksheet.isRowHidden(r)) {\n participatingRows.push(r);\n }\n }\n\n if (participatingRows.length <= 1) return;\n\n // originalOrder[i] = the row whose data is currently at participatingRows[i].\n // To undo: participatingRows[i] should get back its own data.\n // That data is currently at participatingRows[j] where originalOrder[j] = participatingRows[i].\n\n // Build source array for permutation\n const posOfData = new Map<number, number>();\n for (let i = 0; i < originalOrder.length; i++) {\n posOfData.set(originalOrder[i], i);\n }\n\n const sourceRows: number[] = [];\n for (let i = 0; i < participatingRows.length; i++) {\n const sourceIdx = posOfData.get(participatingRows[i])!;\n sourceRows.push(participatingRows[sourceIdx]);\n }\n\n worksheet.permuteRows(sourceRows, participatingRows, startColumn, endColumn);\n worksheet.rebuildFormulas();\n worksheet.render();\n}\n","import type { Worksheet } from '../worksheet/worksheet';\nimport type { AutoFilterConfig, ColumnFilterState, FilterChangeEvent } from './types';\nimport { sortRows } from '../sort/sortRows';\nimport type { SortOrder, SortResult } from '../sort/types';\n\nexport class AutoColumnFilter {\n private readonly worksheet: Worksheet;\n private readonly config: AutoFilterConfig;\n private readonly columnFilters: Map<number, ColumnFilterState> = new Map();\n private readonly filterChangeListeners: Set<(event: FilterChangeEvent) => void> = new Set();\n private currentSort: { column: number; order: SortOrder } | null = null;\n\n constructor(worksheet: Worksheet, config: AutoFilterConfig) {\n this.worksheet = worksheet;\n this.config = { ...config };\n }\n\n getConfig(): Readonly<AutoFilterConfig> {\n return this.config;\n }\n\n /** Get unique cell input values in a column (below header row). Sorted alphabetically. */\n getColumnValues(column: number): string[] {\n const ws = this.worksheet;\n const values = new Set<string>();\n const startRow = this.config.headerRow + 1;\n for (let r = startRow; r < ws.rows; r += 1) {\n const input = ws.getCellInput(r, column);\n if (input != null && input !== '') {\n values.add(input);\n }\n }\n return Array.from(values).sort();\n }\n\n /** Set the filter for a column. Pass null to clear (show all). */\n setColumnFilter(column: number, selectedValues: Set<string> | null): void {\n if (selectedValues === null) {\n this.columnFilters.delete(column);\n } else {\n this.columnFilters.set(column, { column, selectedValues });\n }\n }\n\n /** Get current filter state for a column (null if no filter). */\n getColumnFilter(column: number): ColumnFilterState | null {\n return this.columnFilters.get(column) ?? null;\n }\n\n /** Returns true if any column has an active filter. */\n hasActiveFilters(): boolean {\n return this.columnFilters.size > 0;\n }\n\n /** Apply all active filters. Iterates rows once and batch-updates hidden state. */\n apply(): void {\n const ws = this.worksheet;\n const startRow = this.config.headerRow + 1;\n const activeFilters = Array.from(this.columnFilters.values());\n\n if (activeFilters.length === 0) {\n // No filters — show all rows\n const toShow: number[] = [];\n for (let r = startRow; r < ws.rows; r += 1) {\n if (ws.isRowHidden(r)) {\n toShow.push(r);\n }\n }\n if (toShow.length > 0) {\n ws.setRowsHidden(toShow, false);\n }\n this.emitFilterChange({ column: -1, selectedValues: null, hiddenRowCount: 0 });\n return;\n }\n\n const toHide: number[] = [];\n const toShow: number[] = [];\n\n for (let r = startRow; r < ws.rows; r += 1) {\n let shouldHide = false;\n\n for (const filter of activeFilters) {\n const cellValue = ws.getCellInput(r, filter.column) ?? '';\n if (!filter.selectedValues!.has(cellValue)) {\n shouldHide = true;\n break;\n }\n }\n\n if (shouldHide && !ws.isRowHidden(r)) {\n toHide.push(r);\n } else if (!shouldHide && ws.isRowHidden(r)) {\n toShow.push(r);\n }\n }\n\n // Batch update — triggers single updateBoundaries + render per call\n if (toHide.length > 0) {\n ws.setRowsHidden(toHide, true);\n }\n if (toShow.length > 0) {\n ws.setRowsHidden(toShow, false);\n }\n\n // Notify listeners\n const hiddenCount = this.getHiddenRowCount();\n for (const filter of activeFilters) {\n this.emitFilterChange({\n column: filter.column,\n selectedValues: filter.selectedValues,\n hiddenRowCount: hiddenCount,\n });\n }\n }\n\n /** Clear all column filters and unhide all data rows. */\n clearAll(): void {\n this.columnFilters.clear();\n this.apply();\n }\n\n /** Listen for filter changes. Returns unsubscribe function. */\n onFilterChange(listener: (event: FilterChangeEvent) => void): () => void {\n this.filterChangeListeners.add(listener);\n return () => {\n this.filterChangeListeners.delete(listener);\n };\n }\n\n // ── Sorting ──────────────────────────────────────────────────────────────\n\n /** Sort data rows by the given column. Returns the result for undo support. */\n sortColumn(column: number, order: SortOrder): SortResult {\n const ws = this.worksheet;\n const result = sortRows(ws, {\n column,\n order,\n startRow: this.config.headerRow + 1,\n endRow: ws.rows - 1,\n startColumn: this.config.startColumn,\n endColumn: this.config.endColumn,\n });\n this.currentSort = { column, order };\n return result;\n }\n\n /** Get the current sort state (null if not sorted). */\n getSortState(): { column: number; order: SortOrder } | null {\n return this.currentSort;\n }\n\n /** Set the sort state indicator (does not sort — use sortColumn for that). */\n setSortState(column: number, order: SortOrder): void {\n this.currentSort = { column, order };\n }\n\n /** Clear the sort state (does not revert data — use undo for that). */\n clearSortState(): void {\n this.currentSort = null;\n }\n\n /** Destroy: clear filters, remove listeners. */\n destroy(): void {\n this.clearAll();\n this.currentSort = null;\n this.filterChangeListeners.clear();\n }\n\n private getHiddenRowCount(): number {\n const ws = this.worksheet;\n let count = 0;\n const startRow = this.config.headerRow + 1;\n for (let r = startRow; r < ws.rows; r += 1) {\n if (ws.isRowHidden(r)) {\n count += 1;\n }\n }\n return count;\n }\n\n private emitFilterChange(event: FilterChangeEvent): void {\n for (const listener of this.filterChangeListeners) {\n listener(event);\n }\n }\n}\n","import type { Worksheet } from './worksheet';\nimport type { CellStyle } from '../style/cellStyle';\nimport type { BorderLineOptions, RangeBorderSide } from '../border/types';\nimport type { CellTypeConfig } from '../cell/cellTypeRegistry';\nimport type { MergedCellRange } from '../cell/types';\n\nexport type CellStyleInput = Partial<CellStyle>;\n\n// ---------------------------------------------------------------------------\n// CellHandle\n// ---------------------------------------------------------------------------\n\nexport class CellHandle {\n private readonly ws: Worksheet;\n\n private readonly r: number;\n\n private readonly c: number;\n\n constructor(ws: Worksheet, row: number, col: number) {\n this.ws = ws;\n this.r = row;\n this.c = col;\n }\n\n get value(): string {\n return this.ws.getCellInput(this.r, this.c) ?? '';\n }\n\n set value(v: string) {\n this.ws.setCellInput(this.r, this.c, v);\n }\n\n get style(): Partial<CellStyle> {\n return this.ws.getComputedCellStyle(this.r, this.c);\n }\n\n set style(s: CellStyleInput) {\n this.ws.setCellStyle(this.r, this.c, s);\n }\n\n getValue(): string {\n return this.value;\n }\n\n setValue(v: string): this {\n this.value = v;\n return this;\n }\n\n getStyle(): CellStyle {\n return this.ws.getComputedCellStyle(this.r, this.c);\n }\n\n setStyle(s: CellStyleInput): this {\n this.ws.setCellStyle(this.r, this.c, s);\n return this;\n }\n\n get format(): string | undefined {\n return this.ws.getCellNumberFormat(this.r, this.c);\n }\n\n set format(code: string | undefined) {\n if (code === undefined) {\n this.ws.clearCellNumberFormat(this.r, this.c);\n } else {\n this.ws.setCellNumberFormat(this.r, this.c, code);\n }\n }\n\n setFormat(code: string): this {\n this.ws.setCellNumberFormat(this.r, this.c, code);\n return this;\n }\n\n setType(config: CellTypeConfig): this {\n this.ws.setCellType(this.r, this.c, config);\n return this;\n }\n\n clearType(): this {\n this.ws.clearCellType(this.r, this.c);\n return this;\n }\n\n /** Returns `true` if this cell is part of a merged range. */\n get isMerged(): boolean {\n return this.ws.getMergedRange(this.r, this.c) !== null;\n }\n\n /** Returns the merged range this cell belongs to, or `null` if not merged. */\n get mergeRange(): MergedCellRange | null {\n return this.ws.getMergedRange(this.r, this.c);\n }\n\n /** Explicit lock state, or `undefined` if inheriting from worksheet. */\n get locked(): 'locked' | 'unlocked' | undefined {\n return this.ws.getCellLock(this.r, this.c);\n }\n\n set locked(state: 'locked' | 'unlocked' | undefined) {\n if (state === undefined) {\n this.ws.clearCellLock(this.r, this.c);\n } else {\n this.ws.setCellLock(this.r, this.c, state);\n }\n }\n\n /** Resolved protection state (considers worksheet.protected + explicit lock). */\n get isProtected(): boolean {\n return this.ws.isCellProtected(this.r, this.c);\n }\n}\n\n/** No-op handle returned when a cell address is outside the allowed constraint bounds. */\nexport class NullCellHandle {\n get value(): string {\n return '';\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n set value(_v: string) {}\n\n get style(): Partial<CellStyle> {\n return {};\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n set style(_s: CellStyleInput) {}\n\n getValue(): string {\n return '';\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n setValue(_v: string): this {\n return this;\n }\n\n getStyle(): CellStyle {\n return {} as CellStyle;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n setStyle(_s: CellStyleInput): this {\n return this;\n }\n\n get format(): string | undefined {\n return undefined;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n set format(_code: string | undefined) {}\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n setFormat(_code: string): this {\n return this;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n setType(_config: CellTypeConfig): this {\n return this;\n }\n\n clearType(): this {\n return this;\n }\n\n get isMerged(): boolean {\n return false;\n }\n\n get mergeRange(): MergedCellRange | null {\n return null;\n }\n\n get locked(): 'locked' | 'unlocked' | undefined {\n return undefined;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n set locked(_state: 'locked' | 'unlocked' | undefined) {}\n\n get isProtected(): boolean {\n return false;\n }\n}\n\n// ---------------------------------------------------------------------------\n// RangeHandle\n// ---------------------------------------------------------------------------\n\nexport class RangeHandle {\n private readonly ws: Worksheet;\n\n private readonly topRow: number;\n\n private readonly leftColumn: number;\n\n private readonly bottomRow: number;\n\n private readonly rightColumn: number;\n\n constructor(\n ws: Worksheet,\n topRow: number,\n leftColumn: number,\n bottomRow: number,\n rightColumn: number,\n ) {\n this.ws = ws;\n this.topRow = topRow;\n this.leftColumn = leftColumn;\n this.bottomRow = bottomRow;\n this.rightColumn = rightColumn;\n }\n\n setStyle(style: CellStyleInput): this {\n for (let row = this.topRow; row <= this.bottomRow; row += 1) {\n for (let col = this.leftColumn; col <= this.rightColumn; col += 1) {\n this.ws.setCellStyle(row, col, style);\n }\n }\n return this;\n }\n\n setBackgroundColor(color: string): this {\n this.ws.setRangeBackgroundColor(\n this.topRow,\n this.leftColumn,\n this.bottomRow,\n this.rightColumn,\n color,\n );\n return this;\n }\n\n merge(): this {\n this.ws.mergeCells(this.topRow, this.leftColumn, this.bottomRow, this.rightColumn);\n return this;\n }\n\n unmerge(): this {\n this.ws.unmergeCells(this.topRow, this.leftColumn, this.bottomRow, this.rightColumn);\n return this;\n }\n\n setFormat(code: string): this {\n for (let row = this.topRow; row <= this.bottomRow; row += 1) {\n for (let col = this.leftColumn; col <= this.rightColumn; col += 1) {\n this.ws.setCellNumberFormat(row, col, code);\n }\n }\n return this;\n }\n\n border(options: BorderLineOptions, sides?: RangeBorderSide[]): this {\n this.ws.setRangeBorder(\n this.topRow,\n this.leftColumn,\n this.bottomRow,\n this.rightColumn,\n options,\n sides,\n );\n return this;\n }\n\n setLock(state: 'locked' | 'unlocked'): this {\n this.ws.setRangeLock(this.topRow, this.leftColumn, this.bottomRow, this.rightColumn, state);\n return this;\n }\n\n clearLock(): this {\n this.ws.clearRangeLock(this.topRow, this.leftColumn, this.bottomRow, this.rightColumn);\n return this;\n }\n}\n\n/** No-op handle returned when a range is outside the allowed constraint bounds. */\nexport class NullRangeHandle {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n setStyle(_s: CellStyleInput): this {\n return this;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n setBackgroundColor(_c: string): this {\n return this;\n }\n\n merge(): this {\n return this;\n }\n\n unmerge(): this {\n return this;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n setFormat(_code: string): this {\n return this;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n border(_o: BorderLineOptions, _s?: RangeBorderSide[]): this {\n return this;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n setLock(_state: 'locked' | 'unlocked'): this {\n return this;\n }\n\n clearLock(): this {\n return this;\n }\n}\n\n// ---------------------------------------------------------------------------\n// ColumnHandle\n// ---------------------------------------------------------------------------\n\nexport class ColumnHandle {\n private readonly ws: Worksheet;\n\n private readonly col: number;\n\n constructor(ws: Worksheet, col: number) {\n this.ws = ws;\n this.col = col;\n }\n\n get width(): number {\n return this.ws.columnWidths[this.col] ?? 0;\n }\n\n set width(w: number) {\n this.ws.setColumnWidth(this.col, w);\n }\n}\n\n// ---------------------------------------------------------------------------\n// RowHandle\n// ---------------------------------------------------------------------------\n\nexport class RowHandle {\n private readonly ws: Worksheet;\n\n private readonly row: number;\n\n constructor(ws: Worksheet, row: number) {\n this.ws = ws;\n this.row = row;\n }\n\n get height(): number {\n return this.ws.rowHeights[this.row] ?? 0;\n }\n\n set height(h: number) {\n this.ws.setRowHeight(this.row, h);\n }\n}\n","import { Worksheet, MIN_COLUMN_WIDTH, MIN_ROW_HEIGHT, CELL_TEXT_PADDING, type AlternateRowColors, type WorksheetOptions } from './worksheet';\nimport { HEADER_COLUMN_WIDTH, HEADER_ROW_HEIGHT } from './gridDefaults';\nimport type { CellStyle } from '../style/cellStyle';\nimport { SheetRenderer, type SheetRendererContext } from '../../render/sheetRenderer';\nimport { ViewportController, type BodyViewport } from '../../render/viewports';\nimport { utils, type WorksheetImage } from '../../io/xlsx';\nimport {\n XlsxImporter,\n convertImageInfo,\n buildImageUrl,\n type LoadXlsxOptions,\n type WorksheetImageInfo,\n type WorksheetImageAnchorPosition,\n type WorksheetImagePlacement,\n} from '../../io/xlsxImporter';\nimport { buildXlsxFromSnapshot } from '../../io/xlsxWriter';\nimport { AutoColumnFilter } from '../filter/autoColumnFilter';\nimport type { AutoFilterConfig } from '../filter/types';\nimport { sortRows } from '../sort/sortRows';\nimport type { SortOrder, SortResult } from '../sort/types';\nimport {\n CellHandle,\n NullCellHandle,\n RangeHandle,\n NullRangeHandle,\n ColumnHandle,\n RowHandle,\n type CellStyleInput,\n} from './handles';\nimport type { MergedCellRange } from '../cell/types';\n\nexport type SaveXlsxOptions = { filename?: string; sheetName?: string };\n\nexport type {\n LoadXlsxOptions,\n WorksheetImageInfo,\n WorksheetImageAnchorPosition,\n WorksheetImagePlacement,\n};\n\nexport interface WorksheetConstraints {\n maxRows?: number;\n maxCols?: number;\n}\n\nexport class CanvasWorksheet extends Worksheet {\n public readonly canvas: HTMLCanvasElement;\n\n private readonly ctx: CanvasRenderingContext2D;\n\n private readonly sheetRenderer: SheetRenderer;\n\n private readonly viewportController: ViewportController;\n\n // ── Constraints (Lite edition limits) ─────────────────────────────────────\n\n private readonly constraints: WorksheetConstraints;\n\n // ── Image management ───────────────────────────────────────────────────────\n\n private worksheetImages: WorksheetImage[] = [];\n\n private readonly imageUrlCache: Map<string, string> = new Map();\n\n private readonly imageListeners: Set<(images: WorksheetImageInfo[]) => void> = new Set();\n\n // ── Auto-filter ──────────────────────────────────────────────────────────\n\n private autoFilter: AutoColumnFilter | null = null;\n\n constructor(canvas: HTMLCanvasElement, constraints: WorksheetConstraints = {}, worksheetOptions?: WorksheetOptions) {\n super(worksheetOptions);\n this.canvas = canvas;\n this.constraints = constraints;\n const context = canvas.getContext('2d');\n if (!context) {\n throw new Error('Canvas 2D context is not available.');\n }\n this.ctx = context;\n this.sheetRenderer = new SheetRenderer(this.createSheetRendererContext());\n this.viewportController = new ViewportController(this);\n this.resize();\n }\n\n // ── Grid lines property ────────────────────────────────────────────────────\n\n get showGridLines(): boolean {\n return this.getShowGridLines();\n }\n\n set showGridLines(visible: boolean) {\n this.setShowGridLines(visible);\n }\n\n // ── Alternate row colors property ─────────────────────────────────────────\n\n get alternateRowColors(): AlternateRowColors | null {\n return this.getAlternateRowColors();\n }\n\n set alternateRowColors(colors: AlternateRowColors | null) {\n this.setAlternateRowColors(colors);\n }\n\n // ── OO cell/range/column/row factory methods ───────────────────────────────\n\n cell(a1: string): CellHandle | NullCellHandle;\n cell(row: number, column: number): CellHandle | NullCellHandle;\n cell(a1OrRow: string | number, column?: number): CellHandle | NullCellHandle {\n let row: number;\n let col: number;\n if (typeof a1OrRow === 'number') {\n row = a1OrRow;\n col = column!;\n } else {\n const pos = this.decodeA1Cell(a1OrRow);\n row = pos.row;\n col = pos.column;\n }\n if (this.isOutOfBounds(row, col)) {\n return new NullCellHandle();\n }\n return new CellHandle(this, row, col);\n }\n\n range(a1Range: string): RangeHandle | NullRangeHandle;\n range(topRow: number, leftColumn: number, bottomRow: number, rightColumn: number): RangeHandle | NullRangeHandle;\n range(a1OrTopRow: string | number, leftColumn?: number, bottomRow?: number, rightColumn?: number): RangeHandle | NullRangeHandle {\n let tr: number, lc: number, br: number, rc: number;\n if (typeof a1OrTopRow === 'number') {\n tr = a1OrTopRow;\n lc = leftColumn!;\n br = bottomRow!;\n rc = rightColumn!;\n } else {\n const r = this.decodeA1Range(a1OrTopRow);\n tr = r.topRow;\n lc = r.leftColumn;\n br = r.bottomRow;\n rc = r.rightColumn;\n }\n if (this.isRangeOutOfBounds(tr, lc, br, rc)) {\n return new NullRangeHandle();\n }\n return new RangeHandle(this, tr, lc, br, rc);\n }\n\n column(index: number): ColumnHandle {\n return new ColumnHandle(this, index);\n }\n\n row(index: number): RowHandle {\n return new RowHandle(this, index);\n }\n\n // ── xlsx import / export ───────────────────────────────────────────────────\n\n async loadFromUrl(url: string | URL, options?: LoadXlsxOptions): Promise<void> {\n const response = await fetch(url.toString());\n if (!response.ok) {\n throw new Error(`Failed to fetch XLSX from ${url}: ${response.status} ${response.statusText}`);\n }\n const buffer = await response.arrayBuffer();\n await this.loadFromXlsx(buffer, options);\n }\n\n async loadFromFile(file: File, options?: LoadXlsxOptions): Promise<void> {\n const buffer = await file.arrayBuffer();\n await this.loadFromXlsx(buffer, options);\n }\n\n async loadFromXlsx(\n data: ArrayBuffer | Uint8Array | string,\n options?: LoadXlsxOptions,\n ): Promise<void> {\n this.resetImageCache();\n const importer = new XlsxImporter(this);\n const result = importer.load(data, options);\n this.worksheetImages = result.images;\n this.notifyImagesChanged();\n }\n\n saveAsXlsx(options?: SaveXlsxOptions): void {\n const snapshot = this.getExportSnapshot();\n const sheetName = this.normalizeSheetName(options?.sheetName ?? 'Sheet1');\n const buffer = buildXlsxFromSnapshot(snapshot, sheetName);\n const filename = options?.filename ?? 'reogrid.xlsx';\n this.downloadWorkbook(buffer, filename);\n }\n\n /** Returns the display text for a cell (formatted/computed value). */\n public getDisplayText(row: number, column: number): string | null {\n return this.getCellText(row, column);\n }\n\n // ── Image management ───────────────────────────────────────────────────────\n\n getImages(): WorksheetImageInfo[] {\n return this.worksheetImages.map((image) => convertImageInfo(image));\n }\n\n createImageUrl(imageId: string): string {\n const cached = this.imageUrlCache.get(imageId);\n if (cached) {\n return cached;\n }\n const image = this.findImage(imageId);\n if (!image) {\n throw new Error(`Image \"${imageId}\" not found.`);\n }\n const url = buildImageUrl(image);\n this.imageUrlCache.set(imageId, url);\n return url;\n }\n\n revokeImageUrl(imageId: string): void {\n const url = this.imageUrlCache.get(imageId);\n if (!url) {\n return;\n }\n if (typeof URL !== 'undefined' && typeof URL.revokeObjectURL === 'function') {\n URL.revokeObjectURL(url);\n }\n this.imageUrlCache.delete(imageId);\n }\n\n onImagesChange(listener: (images: WorksheetImageInfo[]) => void): () => void {\n this.imageListeners.add(listener);\n listener(this.getImages());\n return () => {\n this.imageListeners.delete(listener);\n };\n }\n\n // ── Canvas rendering ───────────────────────────────────────────────────────\n\n resize(width?: number, height?: number): void {\n const targetRect =\n this.canvas.parentElement?.getBoundingClientRect() ?? this.canvas.getBoundingClientRect();\n const rootWindow = typeof window === 'undefined' ? null : window;\n const fallbackWidth = rootWindow?.innerWidth ?? this.canvas.width;\n const fallbackHeight = rootWindow?.innerHeight ?? this.canvas.height;\n const resolvedWidth = width ?? (targetRect.width || fallbackWidth);\n const resolvedHeight = height ?? (targetRect.height || fallbackHeight);\n\n this.viewportWidth = resolvedWidth;\n this.viewportHeight = resolvedHeight;\n\n const devicePixelRatio = rootWindow?.devicePixelRatio ?? 1;\n this.pixelRatio = devicePixelRatio;\n const displayWidth = Math.max(1, Math.round(resolvedWidth * devicePixelRatio));\n const displayHeight = Math.max(1, Math.round(resolvedHeight * devicePixelRatio));\n\n this.canvas.style.width = `${resolvedWidth}px`;\n this.canvas.style.height = `${resolvedHeight}px`;\n if (this.canvas.width !== displayWidth) {\n this.canvas.width = displayWidth;\n }\n if (this.canvas.height !== displayHeight) {\n this.canvas.height = displayHeight;\n }\n\n this.ctx.setTransform(devicePixelRatio, 0, 0, devicePixelRatio, 0, 0);\n this.ctx.imageSmoothingEnabled = false;\n this.clampScrollOffsetInPlace();\n this.render();\n }\n\n protected override renderImpl(): void {\n this.updateBoundaries();\n const viewports = this.viewportController.update();\n this.clear();\n this.sheetRenderer.drawOutlinePanel(viewports);\n this.sheetRenderer.drawHeaders(viewports);\n for (const bodyVP of viewports.bodyViewports) {\n this.sheetRenderer.drawBodyViewport(bodyVP);\n this.sheetRenderer.drawBodyViewportBorders(bodyVP);\n }\n this.drawSelectionPerViewport(viewports.bodyViewports);\n this.withBodyClip(() => this.drawResizeGuide());\n this.sheetRenderer.drawFreezeLines();\n }\n\n // ── Private helpers ────────────────────────────────────────────────────────\n\n private isOutOfBounds(row: number, col: number): boolean {\n const { maxRows, maxCols } = this.constraints;\n return (maxRows !== undefined && row >= maxRows) || (maxCols !== undefined && col >= maxCols);\n }\n\n private isRangeOutOfBounds(\n topRow: number,\n leftCol: number,\n bottomRow: number,\n rightCol: number,\n ): boolean {\n return this.isOutOfBounds(topRow, leftCol) || this.isOutOfBounds(bottomRow, rightCol);\n }\n\n private decodeA1Cell(a1Ref: string): { row: number; column: number } {\n let decoded: { r: number; c: number };\n try {\n decoded = utils.decode_cell(a1Ref);\n } catch (error) {\n throw new Error(`Invalid cell reference \"${a1Ref}\": ${(error as Error).message}`);\n }\n return { row: decoded.r, column: decoded.c };\n }\n\n private decodeA1Range(a1Range: string): MergedCellRange {\n let decoded: { s: { r: number; c: number }; e: { r: number; c: number } };\n try {\n decoded = utils.decode_range(a1Range);\n } catch (error) {\n throw new Error(`Invalid range reference \"${a1Range}\": ${(error as Error).message}`);\n }\n return {\n topRow: Math.min(decoded.s.r, decoded.e.r),\n bottomRow: Math.max(decoded.s.r, decoded.e.r),\n leftColumn: Math.min(decoded.s.c, decoded.e.c),\n rightColumn: Math.max(decoded.s.c, decoded.e.c),\n };\n }\n\n private findImage(imageId: string): WorksheetImage | undefined {\n return this.worksheetImages.find((image) => image.id === imageId);\n }\n\n private resetImageCache(): void {\n this.clearImageUrlCache();\n this.worksheetImages = [];\n this.notifyImagesChanged();\n }\n\n private clearImageUrlCache(): void {\n if (typeof URL !== 'undefined' && typeof URL.revokeObjectURL === 'function') {\n for (const url of this.imageUrlCache.values()) {\n URL.revokeObjectURL(url);\n }\n }\n this.imageUrlCache.clear();\n }\n\n private notifyImagesChanged(): void {\n const snapshot = this.getImages();\n for (const listener of this.imageListeners) {\n listener(snapshot);\n }\n }\n\n private normalizeSheetName(name: string): string {\n const cleaned = name.replace(/[:\\\\\\/\\?\\*\\[\\]]/g, '').trim();\n if (!cleaned.length) {\n return 'Sheet1';\n }\n return cleaned.slice(0, 31);\n }\n\n private downloadWorkbook(buffer: ArrayBuffer, filename: string): void {\n const blob = new Blob([buffer], {\n type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n });\n this.triggerDownload(blob, filename);\n }\n\n private triggerDownload(blob: Blob, filename: string): void {\n if (\n typeof document === 'undefined' ||\n typeof URL === 'undefined' ||\n typeof URL.createObjectURL !== 'function'\n ) {\n throw new Error('Saving XLSX requires a browser environment.');\n }\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.download = filename;\n anchor.style.display = 'none';\n const container = document.body;\n if (!container) {\n throw new Error('Saving XLSX requires a mounted document body.');\n }\n container.appendChild(anchor);\n anchor.click();\n container.removeChild(anchor);\n URL.revokeObjectURL(url);\n }\n\n private clear(): void {\n const ctx = this.ctx;\n ctx.save();\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n ctx.restore();\n }\n\n private withBodyClip(callback: () => void): void {\n const bodyWidth = this.getBodyViewportWidth();\n const bodyHeight = this.getBodyViewportHeight();\n if (bodyWidth <= 0 || bodyHeight <= 0) {\n return;\n }\n const ctx = this.ctx;\n ctx.save();\n ctx.beginPath();\n ctx.rect(this.headerColumnWidth, this.headerRowHeight, bodyWidth, bodyHeight);\n ctx.clip();\n try {\n callback();\n } finally {\n ctx.restore();\n }\n }\n\n private drawSelectionPerViewport(bodyViewports: BodyViewport[]): void {\n const selBounds = this.selection.getSelectionBounds();\n if (!selBounds) {\n return;\n }\n\n const ctx = this.ctx;\n const frozenCols = this.getFrozenColumns();\n const frozenRows = this.getFrozenRows();\n const frozenWidth = this.getFrozenWidth();\n const frozenHeight = this.getFrozenHeight();\n const columnBoundaries = this.getColumnBoundaries();\n const rowBoundaries = this.getRowBoundaries();\n\n for (const vp of bodyViewports) {\n // Check if the selection overlaps this viewport's row/column range\n const vpRowStart = vp.rows.start;\n const vpRowEnd = vp.rows.end;\n const vpColStart = vp.columns.start;\n const vpColEnd = vp.columns.end;\n\n if (selBounds.topRow > vpRowEnd || selBounds.bottomRow < vpRowStart ||\n selBounds.leftColumn > vpColEnd || selBounds.rightColumn < vpColStart) {\n continue;\n }\n\n // Compute offset for this viewport (same logic as drawBodyViewport)\n const isFrozenX = vp.scrollOffsetX === 0 && frozenCols > 0 && vp.columnIndices[0] < frozenCols;\n const isFrozenY = vp.scrollOffsetY === 0 && frozenRows > 0 && vp.rowIndices[0] < frozenRows;\n const offsetX = isFrozenX\n ? this.headerColumnWidth\n : this.headerColumnWidth + frozenWidth - (columnBoundaries[frozenCols] ?? 0) - vp.scrollOffsetX;\n const offsetY = isFrozenY\n ? this.headerRowHeight\n : this.headerRowHeight + frozenHeight - (rowBoundaries[frozenRows] ?? 0) - vp.scrollOffsetY;\n\n // Compute selection rect in this viewport's coordinate space\n const x = offsetX + columnBoundaries[selBounds.leftColumn];\n const y = offsetY + rowBoundaries[selBounds.topRow];\n const right = offsetX + (columnBoundaries[selBounds.rightColumn + 1] ?? columnBoundaries[columnBoundaries.length - 1]);\n const bottom = offsetY + (rowBoundaries[selBounds.bottomRow + 1] ?? rowBoundaries[rowBoundaries.length - 1]);\n\n ctx.save();\n ctx.beginPath();\n ctx.rect(vp.rect.x, vp.rect.y, vp.rect.width, vp.rect.height);\n ctx.clip();\n this.selection.drawRect(ctx, x, y, right - x, bottom - y);\n ctx.restore();\n }\n }\n\n private drawResizeGuide(): void {\n const guide = this.resizeGuide;\n if (!guide) {\n return;\n }\n const ctx = this.ctx;\n ctx.save();\n ctx.strokeStyle = '#1f2933';\n ctx.lineWidth = 1 / this.pixelRatio;\n ctx.setLineDash([4 / this.pixelRatio, 4 / this.pixelRatio]);\n ctx.beginPath();\n if (guide.type === 'column') {\n const bodyHeight = this.getBodyViewportHeight();\n ctx.moveTo(guide.position, this.headerRowHeight);\n ctx.lineTo(guide.position, this.headerRowHeight + bodyHeight);\n } else {\n const bodyWidth = this.getBodyViewportWidth();\n ctx.moveTo(this.headerColumnWidth, guide.position);\n ctx.lineTo(this.headerColumnWidth + bodyWidth, guide.position);\n }\n ctx.stroke();\n ctx.restore();\n }\n\n protected override measureColumnWidth(column: number): number {\n let maxWidth = MIN_COLUMN_WIDTH;\n for (let row = 0; row < this.rows; row += 1) {\n const style = this.getComputedCellStyle(row, column);\n const width = this.measureCellContentWidth(row, column, style);\n if (width > maxWidth) {\n maxWidth = width;\n }\n }\n return Math.max(maxWidth, MIN_COLUMN_WIDTH);\n }\n\n protected override measureRowHeight(row: number): number {\n let maxHeight = 0;\n for (let column = 0; column < this.columns; column += 1) {\n const style = this.getComputedCellStyle(row, column);\n const height = this.measureCellContentHeight(row, column, style);\n if (height > maxHeight) {\n maxHeight = height;\n }\n }\n return Math.max(maxHeight, MIN_ROW_HEIGHT);\n }\n\n protected override measureCellContentHeight(row: number, column: number, style: CellStyle): number {\n const richText = this.getRichTextRuns(row, column);\n if (richText && richText.length > 0) {\n const lines = this.sheetRenderer.layoutRichText(richText, style);\n if (!lines.length) {\n return 0;\n }\n const contentHeight = lines.reduce((sum, line) => sum + line.lineHeight, 0);\n return contentHeight + CELL_TEXT_PADDING * 2;\n }\n const text = this.getCellText(row, column);\n if (!text) {\n return 0;\n }\n const fontSizePx = this.pointsToPixels(style.fontSize);\n const lineHeight = fontSizePx + CELL_TEXT_PADDING;\n const lines = text.split(/\\r\\n|\\r|\\n/);\n return lines.length * lineHeight + CELL_TEXT_PADDING * 2;\n }\n\n protected override measureCellContentWidth(row: number, column: number, style: CellStyle): number {\n const padding = CELL_TEXT_PADDING * 2;\n const richText = this.getRichTextRuns(row, column);\n if (richText && richText.length > 0) {\n const lines = this.sheetRenderer.layoutRichText(richText, style);\n if (!lines.length) {\n return MIN_COLUMN_WIDTH;\n }\n const maxWidth = lines.reduce((max, line) => Math.max(max, line.width), 0);\n return maxWidth + padding;\n }\n const text = this.getCellText(row, column);\n if (!text) {\n return MIN_COLUMN_WIDTH;\n }\n const fontFamily = style.fontFamily.includes(' ') ? `\"${style.fontFamily}\"` : style.fontFamily;\n const fontSizePx = this.pointsToPixels(style.fontSize);\n const previousFont = this.ctx.font;\n this.ctx.font = `${fontSizePx}px ${fontFamily}`;\n const lines = text.split(/\\r\\n|\\r|\\n/);\n let maxWidth = 0;\n for (const line of lines) {\n const width = this.ctx.measureText(line).width;\n if (width > maxWidth) {\n maxWidth = width;\n }\n }\n this.ctx.font = previousFont;\n return maxWidth + padding;\n }\n\n // ── Auto-filter API ────────────────────────────────────────────────────────\n\n createAutoFilter(config: AutoFilterConfig): AutoColumnFilter {\n this.removeAutoFilter();\n const filter = new AutoColumnFilter(this, config);\n this.autoFilter = filter;\n\n // Set up header dropdown buttons for each column in the filter range\n for (let c = config.startColumn; c <= config.endColumn; c += 1) {\n const column = c;\n this.setHeaderDropdown(column, {\n type: 'dropdown',\n onclick: () => {\n this.onFilterHeaderDropdownClick(column);\n },\n });\n }\n\n return filter;\n }\n\n removeAutoFilter(): void {\n if (!this.autoFilter) return;\n const config = this.autoFilter.getConfig();\n this.autoFilter.destroy();\n this.autoFilter = null;\n // Remove header dropdown buttons\n for (let c = config.startColumn; c <= config.endColumn; c += 1) {\n this.setHeaderDropdown(c, null);\n }\n this.render();\n }\n\n getAutoFilter(): AutoColumnFilter | null {\n return this.autoFilter;\n }\n\n private onFilterHeaderDropdownClick(column: number): void {\n for (const listener of this.filterDropdownListeners) {\n listener(column);\n }\n }\n\n private readonly filterDropdownListeners: Set<(column: number) => void> = new Set();\n\n onFilterDropdownClick(listener: (column: number) => void): () => void {\n this.filterDropdownListeners.add(listener);\n return () => {\n this.filterDropdownListeners.delete(listener);\n };\n }\n\n // ── Sort API ──────────────────────────────────────────────────────────────\n\n /**\n * Sort rows by the given column. If an AutoFilter is active, sorts within\n * its data range and updates its sort state. Otherwise sorts all rows.\n * Does NOT go through ActionManager — caller should wrap in SortColumnAction\n * if undo support is desired.\n */\n sortColumn(column: number, order: SortOrder): SortResult {\n const filter = this.autoFilter;\n if (filter) {\n return filter.sortColumn(column, order);\n }\n const result = sortRows(this, {\n column,\n order,\n startRow: 0,\n endRow: this.rows - 1,\n startColumn: 0,\n endColumn: this.columns - 1,\n });\n this.render();\n return result;\n }\n\n /** Get the current sort state (from the active AutoFilter, if any). */\n getSortState(): { column: number; order: SortOrder } | null {\n return this.autoFilter?.getSortState() ?? null;\n }\n\n private createSheetRendererContext(): SheetRendererContext {\n return {\n getContext: () => this.ctx,\n getPixelRatio: () => this.pixelRatio,\n getBodyViewportWidth: () => this.getBodyViewportWidth(),\n getBodyViewportHeight: () => this.getBodyViewportHeight(),\n getHeaderColumnWidth: () => this.headerColumnWidth,\n getHeaderRowHeight: () => this.headerRowHeight,\n getScrollOffset: () => ({ x: this.scrollX, y: this.scrollY }),\n getColumnBoundaries: () => this.getColumnBoundaries(),\n getRowBoundaries: () => this.getRowBoundaries(),\n getColumnWidths: () => this.getColumnWidths(),\n getRowHeights: () => this.getRowHeights(),\n getVisibleColumnRange: (padding) => this.getVisibleColumnRange(padding),\n getVisibleRowRange: (padding) => this.getVisibleRowRange(padding),\n getVisibleRowIndices: () => this.getVisibleRowIndices(),\n getVisibleColumnIndices: () => this.getVisibleColumnIndices(),\n getDefaultCellStyle: () => this.getDefaultCellStyle(),\n getComputedCellStyle: (row, column) => this.getComputedCellStyle(row, column),\n getMergedRange: (row, column) => this.getMergedRange(row, column),\n getRangeRect: (topRow, leftColumn, bottomRow, rightColumn) =>\n this.getRangeRect(topRow, leftColumn, bottomRow, rightColumn),\n getRichTextRuns: (row, column) => this.getRichTextRuns(row, column),\n getCellText: (row, column) => this.getCellText(row, column),\n pointsToPixels: (points) => this.pointsToPixels(points),\n withBodyClip: (callback) => this.withBodyClip(callback),\n getMergedLineGaps: () => this.getMergedLineGaps(),\n isRowHidden: (row) => this.isRowHidden(row),\n hasCellBorders: () => this.borders.size > 0,\n getCellBorders: () => this.getCellBorders(),\n parseCellKey: (key) => this.parseCellKey(key),\n getCellMergeBounds: (row, column) => this.getCellMergeBounds(row, column),\n getCellTextPadding: () => CELL_TEXT_PADDING,\n ensureBoundaries: () => this.ensureBoundaries(),\n shouldRenderGridLines: () => this.shouldRenderGridLines(),\n getCellType: (row, column) => this.getCellType(row, column),\n getFrozenRows: () => this.getFrozenRows(),\n getFrozenColumns: () => this.getFrozenColumns(),\n getFrozenWidth: () => this.getFrozenWidth(),\n getFrozenHeight: () => this.getFrozenHeight(),\n hasHeaderDropdown: (column) => this.hasHeaderDropdown(column),\n isColumnHidden: (column) => this.isColumnHidden(column),\n getOutlinePanelWidth: () => this.getOutlinePanelWidth(),\n getOutlinePanelHeight: () => this.getOutlinePanelHeight(),\n getRowOutlineMaxLevel: () => this.rowOutlines.getMaxLevel(),\n getColumnOutlineMaxLevel: () => this.columnOutlines.getMaxLevel(),\n getRowOutlineGroupsAtLevel: (level) => this.rowOutlines.getGroupsAtLevel(level),\n getColumnOutlineGroupsAtLevel: (level) => this.columnOutlines.getGroupsAtLevel(level),\n getBaseHeaderColumnWidth: () => HEADER_COLUMN_WIDTH,\n getBaseHeaderRowHeight: () => HEADER_ROW_HEIGHT,\n getAlternateRowColors: () => this.getAlternateRowColors(),\n getSortState: () => this.getSortState(),\n };\n }\n}\n\nexport type { CellStyleInput };\n","import type { Worksheet } from '../worksheet/worksheet';\nimport type { WorksheetAction } from './types';\n\nexport class ActionManager {\n private readonly undoStack: WorksheetAction[] = [];\n private readonly redoStack: WorksheetAction[] = [];\n private readonly capacity: number;\n private readonly worksheet: Worksheet;\n private readonly listeners = new Set<() => void>();\n\n constructor(worksheet: Worksheet, capacity = 30) {\n this.worksheet = worksheet;\n this.capacity = capacity;\n }\n\n execute(action: WorksheetAction): boolean {\n // Check cell protection for actions that modify cell data\n if (action.modifiesCellData) {\n const range = action.getTargetRange?.();\n if (range) {\n for (let r = range.topRow; r <= range.bottomRow; r++) {\n for (let c = range.leftColumn; c <= range.rightColumn; c++) {\n if (this.worksheet.isCellProtected(r, c)) {\n this.worksheet.emitProtectedCellEdit(r, c);\n return false;\n }\n }\n }\n }\n }\n\n action.do(this.worksheet);\n this.undoStack.push(action);\n if (this.undoStack.length > this.capacity) {\n this.undoStack.shift();\n }\n this.redoStack.length = 0;\n this.notifyListeners();\n return true;\n }\n\n undo(): boolean {\n const action = this.undoStack.pop();\n if (!action) return false;\n action.undo(this.worksheet);\n this.redoStack.push(action);\n this.selectActionTarget(action);\n this.notifyListeners();\n return true;\n }\n\n redo(): boolean {\n const action = this.redoStack.pop();\n if (!action) return false;\n action.do(this.worksheet);\n this.undoStack.push(action);\n this.selectActionTarget(action);\n this.notifyListeners();\n return true;\n }\n\n canUndo(): boolean {\n return this.undoStack.length > 0;\n }\n\n canRedo(): boolean {\n return this.redoStack.length > 0;\n }\n\n clear(): void {\n this.undoStack.length = 0;\n this.redoStack.length = 0;\n this.notifyListeners();\n }\n\n onUndoRedoChange(listener: () => void): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n private selectActionTarget(action: WorksheetAction): void {\n const range = action.getTargetRange?.();\n if (range) {\n this.worksheet.setSelectionRange(\n range.topRow, range.leftColumn,\n range.bottomRow, range.rightColumn,\n );\n }\n }\n\n private notifyListeners(): void {\n for (const listener of this.listeners) {\n listener();\n }\n }\n}\n","import type { Worksheet } from '../worksheet/worksheet';\nimport type { WorksheetAction, ActionTargetRange } from './types';\n\nexport class ActionGroup implements WorksheetAction {\n readonly name: string;\n private readonly actions: WorksheetAction[];\n\n constructor(name: string, actions: WorksheetAction[]) {\n this.name = name;\n this.actions = actions;\n }\n\n do(worksheet: Worksheet): void {\n for (const action of this.actions) {\n action.do(worksheet);\n }\n }\n\n undo(worksheet: Worksheet): void {\n for (let i = this.actions.length - 1; i >= 0; i--) {\n this.actions[i].undo(worksheet);\n }\n }\n\n getTargetRange(): ActionTargetRange {\n // Compute bounding box of all child actions\n let top = Infinity;\n let left = Infinity;\n let bottom = -Infinity;\n let right = -Infinity;\n for (const action of this.actions) {\n const range = action.getTargetRange?.();\n if (range) {\n top = Math.min(top, range.topRow);\n left = Math.min(left, range.leftColumn);\n bottom = Math.max(bottom, range.bottomRow);\n right = Math.max(right, range.rightColumn);\n }\n }\n if (top === Infinity) {\n return { topRow: 0, leftColumn: 0, bottomRow: 0, rightColumn: 0 };\n }\n return { topRow: top, leftColumn: left, bottomRow: bottom, rightColumn: right };\n }\n}\n","import type { CellStyle } from '../style/cellStyle';\nimport type { CellBorderDefinition, BorderLineOptions, RangeBorderSide } from '../border/types';\nimport type { MergedCellRange } from '../cell/types';\nimport type { RichTextRun } from '../../types/richText';\nimport type { Worksheet } from '../worksheet/worksheet';\nimport type { WorksheetAction, ActionTargetRange } from './types';\nimport { ActionGroup } from './actionGroup';\nimport type { SortConfig } from '../sort/types';\nimport { sortRows, applyPermutation } from '../sort/sortRows';\n\n// ---------------------------------------------------------------------------\n// Cell data\n// ---------------------------------------------------------------------------\n\nexport class SetCellInputAction implements WorksheetAction {\n readonly name = 'Set Cell Value';\n readonly modifiesCellData = true;\n private readonly row: number;\n private readonly column: number;\n private readonly newValue: string;\n private oldValue = '';\n\n constructor(row: number, column: number, value: string) {\n this.row = row;\n this.column = column;\n this.newValue = value;\n }\n\n do(worksheet: Worksheet): void {\n this.oldValue = worksheet.getCellInput(this.row, this.column) ?? '';\n worksheet.setCellInput(this.row, this.column, this.newValue);\n }\n\n undo(worksheet: Worksheet): void {\n worksheet.setCellInput(this.row, this.column, this.oldValue);\n }\n\n getTargetRange(): ActionTargetRange {\n return { topRow: this.row, leftColumn: this.column, bottomRow: this.row, rightColumn: this.column };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Cell style\n// ---------------------------------------------------------------------------\n\nexport class SetCellStyleAction implements WorksheetAction {\n readonly name = 'Set Cell Style';\n readonly modifiesCellData = true;\n private readonly row: number;\n private readonly column: number;\n private readonly newStyle: Partial<CellStyle>;\n private oldStyle: Partial<CellStyle> | undefined;\n\n constructor(row: number, column: number, style: Partial<CellStyle>) {\n this.row = row;\n this.column = column;\n this.newStyle = style;\n }\n\n do(worksheet: Worksheet): void {\n this.oldStyle = worksheet.getCellRawStyle(this.row, this.column);\n worksheet.setCellStyle(this.row, this.column, this.newStyle);\n }\n\n undo(worksheet: Worksheet): void {\n worksheet.replaceCellStyle(this.row, this.column, this.oldStyle);\n }\n\n getTargetRange(): ActionTargetRange {\n return { topRow: this.row, leftColumn: this.column, bottomRow: this.row, rightColumn: this.column };\n }\n}\n\nexport function createSetRangeStyleAction(\n name: string,\n cells: Array<{ row: number; column: number }>,\n style: Partial<CellStyle>,\n): WorksheetAction {\n const actions = cells.map(({ row, column }) => new SetCellStyleAction(row, column, style));\n if (actions.length === 1) return actions[0];\n return new ActionGroup(name, actions);\n}\n\n// ---------------------------------------------------------------------------\n// Column width / Row height\n// ---------------------------------------------------------------------------\n\nexport class SetColumnWidthAction implements WorksheetAction {\n readonly name = 'Set Column Width';\n private readonly column: number;\n private readonly newWidth: number;\n private oldWidth = 0;\n\n constructor(column: number, width: number) {\n this.column = column;\n this.newWidth = width;\n }\n\n do(worksheet: Worksheet): void {\n this.oldWidth = worksheet.getColumnWidth(this.column);\n worksheet.setColumnWidth(this.column, this.newWidth);\n }\n\n undo(worksheet: Worksheet): void {\n worksheet.setColumnWidth(this.column, this.oldWidth);\n }\n\n getTargetRange(): ActionTargetRange {\n return { topRow: 0, leftColumn: this.column, bottomRow: 0, rightColumn: this.column };\n }\n}\n\nexport class SetRowHeightAction implements WorksheetAction {\n readonly name = 'Set Row Height';\n private readonly row: number;\n private readonly newHeight: number;\n private oldHeight = 0;\n\n constructor(row: number, height: number) {\n this.row = row;\n this.newHeight = height;\n }\n\n do(worksheet: Worksheet): void {\n this.oldHeight = worksheet.getRowHeight(this.row);\n worksheet.setRowHeight(this.row, this.newHeight);\n }\n\n undo(worksheet: Worksheet): void {\n worksheet.setRowHeight(this.row, this.oldHeight);\n }\n\n getTargetRange(): ActionTargetRange {\n return { topRow: this.row, leftColumn: 0, bottomRow: this.row, rightColumn: 0 };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Borders\n// ---------------------------------------------------------------------------\n\nexport class SetRangeBorderAction implements WorksheetAction {\n readonly name = 'Set Range Border';\n private readonly topRow: number;\n private readonly leftColumn: number;\n private readonly bottomRow: number;\n private readonly rightColumn: number;\n private readonly border: BorderLineOptions;\n private readonly sides?: RangeBorderSide[];\n private oldBorders: Map<string, CellBorderDefinition | undefined> = new Map();\n\n constructor(\n topRow: number,\n leftColumn: number,\n bottomRow: number,\n rightColumn: number,\n border: BorderLineOptions,\n sides?: RangeBorderSide[],\n ) {\n this.topRow = topRow;\n this.leftColumn = leftColumn;\n this.bottomRow = bottomRow;\n this.rightColumn = rightColumn;\n this.border = border;\n this.sides = sides;\n }\n\n do(worksheet: Worksheet): void {\n // Capture old borders for all affected cells (including adjacent cells for outside borders)\n this.oldBorders.clear();\n const expandedTop = Math.max(0, this.topRow - 1);\n const expandedLeft = Math.max(0, this.leftColumn - 1);\n const expandedBottom = this.bottomRow + 1;\n const expandedRight = this.rightColumn + 1;\n for (let r = expandedTop; r <= expandedBottom; r++) {\n for (let c = expandedLeft; c <= expandedRight; c++) {\n const key = `${r}:${c}`;\n const existing = worksheet.getCellBorder(r, c);\n this.oldBorders.set(key, existing ? { ...existing } : undefined);\n }\n }\n worksheet.setRangeBorder(\n this.topRow, this.leftColumn, this.bottomRow, this.rightColumn,\n this.border, this.sides,\n );\n }\n\n undo(worksheet: Worksheet): void {\n // Restore all captured borders via applyCellBorders\n const borders = new Map<string, CellBorderDefinition>();\n for (const [key, border] of this.oldBorders) {\n if (border) {\n borders.set(key, border);\n }\n }\n worksheet.applyCellBorders(borders);\n }\n\n getTargetRange(): ActionTargetRange {\n return {\n topRow: this.topRow, leftColumn: this.leftColumn,\n bottomRow: this.bottomRow, rightColumn: this.rightColumn,\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Merge / Unmerge\n// ---------------------------------------------------------------------------\n\nexport class MergeCellsAction implements WorksheetAction {\n readonly name = 'Merge Cells';\n private readonly topRow: number;\n private readonly leftColumn: number;\n private readonly bottomRow: number;\n private readonly rightColumn: number;\n private oldValues: Array<{ row: number; column: number; value: string }> = [];\n private oldMerges: MergedCellRange[] = [];\n\n constructor(topRow: number, leftColumn: number, bottomRow: number, rightColumn: number) {\n this.topRow = topRow;\n this.leftColumn = leftColumn;\n this.bottomRow = bottomRow;\n this.rightColumn = rightColumn;\n }\n\n do(worksheet: Worksheet): void {\n // Save existing merges that overlap with this range\n this.oldMerges = [];\n for (let r = this.topRow; r <= this.bottomRow; r++) {\n for (let c = this.leftColumn; c <= this.rightColumn; c++) {\n const merge = worksheet.getMergedRange(r, c);\n if (merge && !this.oldMerges.some(m =>\n m.topRow === merge.topRow && m.leftColumn === merge.leftColumn &&\n m.bottomRow === merge.bottomRow && m.rightColumn === merge.rightColumn,\n )) {\n this.oldMerges.push({ ...merge });\n }\n }\n }\n\n // Save cell values that will be hidden by merge\n this.oldValues = [];\n for (let r = this.topRow; r <= this.bottomRow; r++) {\n for (let c = this.leftColumn; c <= this.rightColumn; c++) {\n if (r === this.topRow && c === this.leftColumn) continue;\n const value = worksheet.getCellInput(r, c);\n if (value) {\n this.oldValues.push({ row: r, column: c, value });\n }\n }\n }\n\n worksheet.mergeCells(this.topRow, this.leftColumn, this.bottomRow, this.rightColumn);\n }\n\n undo(worksheet: Worksheet): void {\n worksheet.unmergeCells(this.topRow, this.leftColumn, this.bottomRow, this.rightColumn);\n\n // Restore old cell values\n for (const { row, column, value } of this.oldValues) {\n worksheet.setCellInput(row, column, value);\n }\n\n // Restore old merges\n for (const merge of this.oldMerges) {\n worksheet.mergeCells(merge.topRow, merge.leftColumn, merge.bottomRow, merge.rightColumn);\n }\n }\n\n getTargetRange(): ActionTargetRange {\n return {\n topRow: this.topRow, leftColumn: this.leftColumn,\n bottomRow: this.bottomRow, rightColumn: this.rightColumn,\n };\n }\n}\n\nexport class UnmergeCellsAction implements WorksheetAction {\n readonly name = 'Unmerge Cells';\n private readonly topRow: number;\n private readonly leftColumn: number;\n private readonly bottomRow: number;\n private readonly rightColumn: number;\n private oldMerge: MergedCellRange | null = null;\n\n constructor(topRow: number, leftColumn: number, bottomRow: number, rightColumn: number) {\n this.topRow = topRow;\n this.leftColumn = leftColumn;\n this.bottomRow = bottomRow;\n this.rightColumn = rightColumn;\n }\n\n do(worksheet: Worksheet): void {\n this.oldMerge = worksheet.getMergedRange(this.topRow, this.leftColumn);\n worksheet.unmergeCells(this.topRow, this.leftColumn, this.bottomRow, this.rightColumn);\n }\n\n undo(worksheet: Worksheet): void {\n if (this.oldMerge) {\n worksheet.mergeCells(\n this.oldMerge.topRow, this.oldMerge.leftColumn,\n this.oldMerge.bottomRow, this.oldMerge.rightColumn,\n );\n }\n }\n\n getTargetRange(): ActionTargetRange {\n return {\n topRow: this.topRow, leftColumn: this.leftColumn,\n bottomRow: this.bottomRow, rightColumn: this.rightColumn,\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Number format\n// ---------------------------------------------------------------------------\n\nexport class SetCellNumberFormatAction implements WorksheetAction {\n readonly name = 'Set Number Format';\n readonly modifiesCellData = true;\n private readonly row: number;\n private readonly column: number;\n private readonly newFormat: string;\n private oldFormat: string | undefined;\n\n constructor(row: number, column: number, format: string) {\n this.row = row;\n this.column = column;\n this.newFormat = format;\n }\n\n do(worksheet: Worksheet): void {\n this.oldFormat = worksheet.getCellNumberFormat(this.row, this.column);\n worksheet.setCellNumberFormat(this.row, this.column, this.newFormat);\n }\n\n undo(worksheet: Worksheet): void {\n if (this.oldFormat !== undefined) {\n worksheet.setCellNumberFormat(this.row, this.column, this.oldFormat);\n } else {\n worksheet.clearCellNumberFormat(this.row, this.column);\n }\n }\n\n getTargetRange(): ActionTargetRange {\n return { topRow: this.row, leftColumn: this.column, bottomRow: this.row, rightColumn: this.column };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Row visibility\n// ---------------------------------------------------------------------------\n\nexport class SetRowHiddenAction implements WorksheetAction {\n readonly name = 'Set Row Hidden';\n private readonly rows: number[];\n private readonly hidden: boolean;\n private oldStates: boolean[] = [];\n\n constructor(rows: number[], hidden: boolean) {\n this.rows = rows;\n this.hidden = hidden;\n }\n\n do(worksheet: Worksheet): void {\n this.oldStates = this.rows.map((row) => worksheet.isRowHidden(row));\n worksheet.setRowsHidden(this.rows, this.hidden);\n }\n\n undo(worksheet: Worksheet): void {\n for (let i = 0; i < this.rows.length; i++) {\n worksheet.setRowHidden(this.rows[i], this.oldStates[i]);\n }\n }\n\n getTargetRange(): ActionTargetRange {\n const minRow = Math.min(...this.rows);\n const maxRow = Math.max(...this.rows);\n return { topRow: minRow, leftColumn: 0, bottomRow: maxRow, rightColumn: 0 };\n }\n}\n\nexport class SetColumnHiddenAction implements WorksheetAction {\n readonly name = 'Set Column Hidden';\n private readonly columns: number[];\n private readonly hidden: boolean;\n private oldStates: boolean[] = [];\n\n constructor(columns: number[], hidden: boolean) {\n this.columns = columns;\n this.hidden = hidden;\n }\n\n do(worksheet: Worksheet): void {\n this.oldStates = this.columns.map((col) => worksheet.isColumnHidden(col));\n worksheet.setColumnsHidden(this.columns, this.hidden);\n }\n\n undo(worksheet: Worksheet): void {\n for (let i = 0; i < this.columns.length; i++) {\n worksheet.setColumnHidden(this.columns[i], this.oldStates[i]);\n }\n }\n\n getTargetRange(): ActionTargetRange {\n const minCol = Math.min(...this.columns);\n const maxCol = Math.max(...this.columns);\n return { topRow: 0, leftColumn: minCol, bottomRow: 0, rightColumn: maxCol };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Row insert / delete\n// ---------------------------------------------------------------------------\n\ntype CellDataBackup = Map<string, {\n input?: string;\n richText?: RichTextRun[];\n displayOverride?: string;\n numberFormat?: string;\n formatting?: Partial<CellStyle>;\n}>;\n\nexport class InsertRowsAction implements WorksheetAction {\n readonly name = 'Insert Rows';\n private readonly index: number;\n private readonly count: number;\n\n constructor(index: number, count: number) {\n this.index = index;\n this.count = count;\n }\n\n do(worksheet: Worksheet): void {\n worksheet.insertRows(this.index, this.count);\n }\n\n undo(worksheet: Worksheet): void {\n worksheet.deleteRows(this.index, this.count);\n }\n\n getTargetRange(): ActionTargetRange {\n return {\n topRow: this.index,\n leftColumn: 0,\n bottomRow: this.index + this.count - 1,\n rightColumn: 0,\n };\n }\n}\n\nexport class DeleteRowsAction implements WorksheetAction {\n readonly name = 'Delete Rows';\n private readonly index: number;\n private readonly count: number;\n private backupData: CellDataBackup = new Map();\n private backupHeights: number[] = [];\n private backupMerges: MergedCellRange[] = [];\n private backupBorders: Map<string, CellBorderDefinition> = new Map();\n\n constructor(index: number, count: number) {\n this.index = index;\n this.count = count;\n }\n\n do(worksheet: Worksheet): void {\n // Back up data in the rows that will be deleted\n const cols = worksheet.columns;\n this.backupData = worksheet.getRangeData(\n this.index, 0, this.index + this.count - 1, cols - 1,\n );\n this.backupHeights = [];\n for (let r = this.index; r < this.index + this.count; r++) {\n this.backupHeights.push(worksheet.getRowHeight(r));\n }\n // Back up merges that touch the deleted rows\n this.backupMerges = [];\n for (let r = this.index; r < this.index + this.count; r++) {\n for (let c = 0; c < cols; c++) {\n const merge = worksheet.getMergedRange(r, c);\n if (merge && !this.backupMerges.some(m =>\n m.topRow === merge.topRow && m.leftColumn === merge.leftColumn &&\n m.bottomRow === merge.bottomRow && m.rightColumn === merge.rightColumn,\n )) {\n this.backupMerges.push({ ...merge });\n }\n }\n }\n // Back up borders\n this.backupBorders = new Map();\n for (let r = this.index; r < this.index + this.count; r++) {\n for (let c = 0; c < cols; c++) {\n const border = worksheet.getCellBorder(r, c);\n if (border) {\n this.backupBorders.set(`${r}:${c}`, { ...border });\n }\n }\n }\n\n worksheet.deleteRows(this.index, this.count);\n }\n\n undo(worksheet: Worksheet): void {\n worksheet.insertRows(this.index, this.count);\n\n // Restore row heights\n for (let i = 0; i < this.backupHeights.length; i++) {\n worksheet.setRowHeight(this.index + i, this.backupHeights[i]);\n }\n\n // Restore cell data\n worksheet.restoreRangeData(this.backupData);\n\n // Restore merges\n for (const merge of this.backupMerges) {\n worksheet.mergeCells(merge.topRow, merge.leftColumn, merge.bottomRow, merge.rightColumn);\n }\n\n // Restore borders\n if (this.backupBorders.size > 0) {\n worksheet.applyCellBorders(this.backupBorders);\n }\n }\n\n getTargetRange(): ActionTargetRange {\n return {\n topRow: this.index,\n leftColumn: 0,\n bottomRow: this.index,\n rightColumn: 0,\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Column insert / delete\n// ---------------------------------------------------------------------------\n\nexport class InsertColumnsAction implements WorksheetAction {\n readonly name = 'Insert Columns';\n private readonly index: number;\n private readonly count: number;\n\n constructor(index: number, count: number) {\n this.index = index;\n this.count = count;\n }\n\n do(worksheet: Worksheet): void {\n worksheet.insertColumns(this.index, this.count);\n }\n\n undo(worksheet: Worksheet): void {\n worksheet.deleteColumns(this.index, this.count);\n }\n\n getTargetRange(): ActionTargetRange {\n return {\n topRow: 0,\n leftColumn: this.index,\n bottomRow: 0,\n rightColumn: this.index + this.count - 1,\n };\n }\n}\n\nexport class DeleteColumnsAction implements WorksheetAction {\n readonly name = 'Delete Columns';\n private readonly index: number;\n private readonly count: number;\n private backupData: CellDataBackup = new Map();\n private backupWidths: number[] = [];\n private backupMerges: MergedCellRange[] = [];\n private backupBorders: Map<string, CellBorderDefinition> = new Map();\n\n constructor(index: number, count: number) {\n this.index = index;\n this.count = count;\n }\n\n do(worksheet: Worksheet): void {\n const rows = worksheet.rows;\n this.backupData = worksheet.getRangeData(\n 0, this.index, rows - 1, this.index + this.count - 1,\n );\n this.backupWidths = [];\n for (let c = this.index; c < this.index + this.count; c++) {\n this.backupWidths.push(worksheet.getColumnWidth(c));\n }\n this.backupMerges = [];\n for (let r = 0; r < rows; r++) {\n for (let c = this.index; c < this.index + this.count; c++) {\n const merge = worksheet.getMergedRange(r, c);\n if (merge && !this.backupMerges.some(m =>\n m.topRow === merge.topRow && m.leftColumn === merge.leftColumn &&\n m.bottomRow === merge.bottomRow && m.rightColumn === merge.rightColumn,\n )) {\n this.backupMerges.push({ ...merge });\n }\n }\n }\n this.backupBorders = new Map();\n for (let r = 0; r < rows; r++) {\n for (let c = this.index; c < this.index + this.count; c++) {\n const border = worksheet.getCellBorder(r, c);\n if (border) {\n this.backupBorders.set(`${r}:${c}`, { ...border });\n }\n }\n }\n\n worksheet.deleteColumns(this.index, this.count);\n }\n\n undo(worksheet: Worksheet): void {\n worksheet.insertColumns(this.index, this.count);\n\n for (let i = 0; i < this.backupWidths.length; i++) {\n worksheet.setColumnWidth(this.index + i, this.backupWidths[i]);\n }\n\n worksheet.restoreRangeData(this.backupData);\n\n for (const merge of this.backupMerges) {\n worksheet.mergeCells(merge.topRow, merge.leftColumn, merge.bottomRow, merge.rightColumn);\n }\n\n if (this.backupBorders.size > 0) {\n worksheet.applyCellBorders(this.backupBorders);\n }\n }\n\n getTargetRange(): ActionTargetRange {\n return {\n topRow: 0,\n leftColumn: this.index,\n bottomRow: 0,\n rightColumn: this.index,\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Sort\n// ---------------------------------------------------------------------------\n\nexport class SortColumnAction implements WorksheetAction {\n readonly name = 'Sort Column';\n private originalOrder: number[] | null = null;\n private readonly config: SortConfig;\n\n constructor(config: SortConfig) {\n this.config = config;\n }\n\n do(worksheet: Worksheet): void {\n const result = sortRows(worksheet, this.config);\n this.originalOrder = result.originalOrder;\n worksheet.render();\n }\n\n undo(worksheet: Worksheet): void {\n if (!this.originalOrder) return;\n applyPermutation(worksheet, this.originalOrder, this.config);\n worksheet.render();\n }\n\n getTargetRange(): ActionTargetRange {\n return {\n topRow: this.config.startRow,\n leftColumn: this.config.startColumn,\n bottomRow: this.config.endRow,\n rightColumn: this.config.endColumn,\n };\n }\n}\n","import type { CanvasWorksheet, HitTestResult } from '../../core/worksheet';\nimport type { ActionManager } from '../../core/action';\nimport { SetColumnWidthAction, SetRowHeightAction } from '../../core/action';\nimport type { CellEditor } from '../editor/cellEditor';\nimport type { DropdownOverlay } from '../editor/dropdownOverlay';\nimport { getCellTypeHandler } from '../../core/cell/cellTypeRegistry';\n\ntype DragContext =\n | { type: 'cell' }\n | { type: 'row-header'; anchorRow: number }\n | { type: 'column-header'; anchorColumn: number }\n | { type: 'corner' };\n\ntype ResizeContext =\n | { type: 'column'; column: number; origin: number; originalSize: number }\n | { type: 'row'; row: number; origin: number; originalSize: number };\n\ninterface CanvasPoint {\n x: number;\n y: number;\n}\n\nexport class PointerController {\n private readonly worksheet: CanvasWorksheet;\n\n private readonly canvas: HTMLCanvasElement;\n\n private readonly eventTarget: HTMLElement;\n\n private readonly cellEditor: CellEditor;\n\n private readonly dropdownOverlay: DropdownOverlay;\n\n private isDragging = false;\n\n private dragContext: DragContext | null = null;\n\n private isResizing = false;\n\n private resizeContext: ResizeContext | null = null;\n\n private readonly actionManager: ActionManager | null;\n\n constructor(worksheet: CanvasWorksheet, cellEditor: CellEditor, dropdownOverlay: DropdownOverlay, eventTarget?: HTMLElement, actionManager?: ActionManager) {\n this.worksheet = worksheet;\n this.canvas = worksheet.canvas;\n this.eventTarget = eventTarget ?? this.canvas;\n this.cellEditor = cellEditor;\n this.dropdownOverlay = dropdownOverlay;\n this.actionManager = actionManager ?? null;\n\n this.eventTarget.addEventListener('mousedown', this.handleMouseDown);\n this.eventTarget.addEventListener('dblclick', this.handleDoubleClick);\n this.eventTarget.addEventListener('contextmenu', this.handleContextMenu);\n window.addEventListener('mousemove', this.handleMouseMove);\n window.addEventListener('mouseup', this.handleMouseUp);\n }\n\n destroy(): void {\n this.eventTarget.removeEventListener('mousedown', this.handleMouseDown);\n this.eventTarget.removeEventListener('dblclick', this.handleDoubleClick);\n this.eventTarget.removeEventListener('contextmenu', this.handleContextMenu);\n window.removeEventListener('mousemove', this.handleMouseMove);\n window.removeEventListener('mouseup', this.handleMouseUp);\n }\n\n private handleMouseDown = (event: MouseEvent): void => {\n if (this.cellEditor.isEditing()) {\n this.cellEditor.commit();\n }\n\n const point = this.getCanvasPoint(event);\n if (!point) {\n return;\n }\n\n if (this.tryBeginResize(point)) {\n event.preventDefault();\n return;\n }\n\n const hit = this.worksheet.hitTest(point.x, point.y);\n if (!hit) {\n return;\n }\n\n // Close any open dropdown overlay first\n if (this.dropdownOverlay.isOpen()) {\n this.dropdownOverlay.close();\n }\n\n // Pluggable cell type interaction — handled before normal selection/drag logic\n if (hit.type === 'cell') {\n const cellType = this.worksheet.getCellType(hit.row, hit.column);\n if (cellType) {\n const handler = getCellTypeHandler(cellType.type);\n if (handler?.onClick) {\n const cellRect = this.worksheet.getCellRect(hit.row, hit.column);\n const result = handler.onClick({\n row: hit.row,\n column: hit.column,\n value: this.worksheet.getCellInput(hit.row, hit.column) ?? null,\n screenX: point.x,\n screenY: point.y,\n rect: cellRect,\n isProtected: this.worksheet.isCellProtected(hit.row, hit.column),\n }, cellType as Record<string, unknown>);\n\n if (result.handled) {\n if (this.worksheet.isCellProtected(hit.row, hit.column)) {\n this.worksheet.emitProtectedCellEdit(hit.row, hit.column);\n return;\n }\n this.worksheet.selection.begin(hit.row, hit.column);\n if (result.newValue !== undefined) {\n this.worksheet.setCellInput(hit.row, hit.column, result.newValue);\n }\n this.worksheet.render();\n this.worksheet.notifySelectionChanged();\n if (result.openDropdown) {\n this.dropdownOverlay.open(\n hit.row, hit.column,\n result.openDropdown.options,\n result.openDropdown.onSelect,\n );\n }\n return;\n }\n }\n }\n }\n\n // Header dropdown button\n if (hit.type === 'column-header-dropdown') {\n const config = this.worksheet.getHeaderDropdown(hit.column);\n if (config?.onclick) {\n config.onclick({ column: hit.column, isHeader: true });\n }\n return;\n }\n\n // Outline toggle button (+/-)\n if (hit.type === 'outline-toggle') {\n if (hit.direction === 'row') {\n const outlines = this.worksheet.getRowOutlines();\n const group = outlines.findGroup(hit.level, hit.start);\n if (group?.collapsed) {\n this.worksheet.expandRowOutline(hit.level, hit.start);\n } else {\n this.worksheet.collapseRowOutline(hit.level, hit.start);\n }\n } else {\n const outlines = this.worksheet.getColumnOutlines();\n const group = outlines.findGroup(hit.level, hit.start);\n if (group?.collapsed) {\n this.worksheet.expandColumnOutline(hit.level, hit.start);\n } else {\n this.worksheet.collapseColumnOutline(hit.level, hit.start);\n }\n }\n return;\n }\n\n // Outline level button (1, 2, 3...)\n if (hit.type === 'outline-level-button') {\n if (hit.direction === 'row') {\n this.worksheet.collapseRowsToLevel(hit.level);\n } else {\n this.worksheet.collapseColumnsToLevel(hit.level);\n }\n return;\n }\n\n event.preventDefault();\n\n const isRightClick = event.button === 2;\n const { selection } = this.worksheet;\n\n // Right-click: only update selection if target is outside current selection\n if (isRightClick) {\n let needsUpdate = false;\n switch (hit.type) {\n case 'row-header':\n if (!selection.containsRow(hit.row)) {\n selection.selectRows(hit.row);\n needsUpdate = true;\n }\n break;\n case 'column-header':\n if (!selection.containsColumn(hit.column)) {\n selection.selectColumns(hit.column);\n needsUpdate = true;\n }\n break;\n case 'cell': {\n const b = selection.getSelectionBounds();\n if (!b || hit.row < b.topRow || hit.row > b.bottomRow || hit.column < b.leftColumn || hit.column > b.rightColumn) {\n selection.begin(hit.row, hit.column);\n needsUpdate = true;\n }\n break;\n }\n case 'corner':\n selection.selectAll();\n needsUpdate = true;\n break;\n default:\n return;\n }\n if (needsUpdate) {\n this.worksheet.render();\n this.worksheet.notifySelectionChanged();\n }\n return;\n }\n\n // Left-click: normal selection + drag\n this.isDragging = true;\n switch (hit.type) {\n case 'cell':\n this.dragContext = { type: 'cell' };\n selection.begin(hit.row, hit.column);\n break;\n case 'row-header':\n this.dragContext = { type: 'row-header', anchorRow: hit.row };\n selection.selectRows(hit.row);\n break;\n case 'column-header':\n this.dragContext = { type: 'column-header', anchorColumn: hit.column };\n selection.selectColumns(hit.column);\n break;\n case 'corner':\n this.dragContext = { type: 'corner' };\n selection.selectAll();\n break;\n default:\n this.isDragging = false;\n this.dragContext = null;\n return;\n }\n\n this.worksheet.render();\n this.worksheet.notifySelectionChanged();\n };\n\n private handleMouseMove = (event: MouseEvent): void => {\n const point = this.getCanvasPoint(event);\n if (this.isResizing && this.resizeContext) {\n if (point) {\n event.preventDefault();\n this.handleResizeDrag(point);\n }\n return;\n }\n\n if (!this.isDragging || !this.dragContext) {\n this.updateHoverCursor(point);\n return;\n }\n\n if (!point) {\n return;\n }\n\n const hit = this.worksheet.hitTest(point.x, point.y);\n if (!hit) {\n return;\n }\n\n let updated = false;\n const { selection } = this.worksheet;\n\n switch (this.dragContext.type) {\n case 'cell':\n if (hit.type === 'cell') {\n selection.update(hit.row, hit.column);\n updated = true;\n }\n break;\n case 'row-header': {\n const row = this.resolveRowFromHit(hit);\n if (row !== null) {\n selection.selectRows(this.dragContext.anchorRow, row);\n updated = true;\n }\n break;\n }\n case 'column-header': {\n const column = this.resolveColumnFromHit(hit);\n if (column !== null) {\n selection.selectColumns(this.dragContext.anchorColumn, column);\n updated = true;\n }\n break;\n }\n case 'corner':\n default:\n break;\n }\n\n if (updated) {\n event.preventDefault();\n this.worksheet.render();\n this.worksheet.notifySelectionChanged();\n }\n };\n\n private handleMouseUp = (): void => {\n if (this.isResizing) {\n if (this.actionManager && this.resizeContext) {\n // Record the resize as an undoable action (originalSize → current size)\n if (this.resizeContext.type === 'column') {\n const col = this.resizeContext.column;\n const currentWidth = this.worksheet.getColumnWidth(col);\n if (currentWidth !== this.resizeContext.originalSize) {\n // Restore original so action.do() can capture old state and set new state\n this.worksheet.setColumnWidth(col, this.resizeContext.originalSize);\n this.actionManager.execute(new SetColumnWidthAction(col, currentWidth));\n }\n } else {\n const row = this.resizeContext.row;\n const currentHeight = this.worksheet.getRowHeight(row);\n if (currentHeight !== this.resizeContext.originalSize) {\n this.worksheet.setRowHeight(row, this.resizeContext.originalSize);\n this.actionManager.execute(new SetRowHeightAction(row, currentHeight));\n }\n }\n }\n this.isResizing = false;\n this.resizeContext = null;\n this.setCursor('default');\n this.worksheet.setResizeGuide(null);\n return;\n }\n\n if (!this.isDragging) {\n return;\n }\n\n this.isDragging = false;\n this.dragContext = null;\n };\n\n private handleDoubleClick = (event: MouseEvent): void => {\n const point = this.getCanvasPoint(event);\n if (!point) {\n return;\n }\n\n const columnHandle = this.worksheet.getColumnResizeHandle(point.x, point.y);\n if (columnHandle !== null) {\n event.preventDefault();\n this.worksheet.autoFitColumns({ columns: [columnHandle], respectCustomWidth: false });\n return;\n }\n\n const rowHandle = this.worksheet.getRowResizeHandle(point.x, point.y);\n if (rowHandle !== null) {\n event.preventDefault();\n this.worksheet.autoFitRows({ rows: [rowHandle], respectCustomHeight: false });\n return;\n }\n\n const hit = this.worksheet.hitTest(point.x, point.y);\n if (!hit || hit.type !== 'cell') {\n return;\n }\n\n // Suppress editing when cell has a type handler that replaces text\n const cellType = this.worksheet.getCellType(hit.row, hit.column);\n if (cellType) {\n const handler = getCellTypeHandler(cellType.type);\n if (handler && handler.replacesText !== false) return;\n }\n\n event.preventDefault();\n this.cellEditor.beginEdit(hit.row, hit.column);\n };\n\n private handleContextMenu = (event: MouseEvent): void => {\n event.preventDefault();\n\n const point = this.getCanvasPoint(event);\n if (!point) return;\n\n const hit = this.worksheet.hitTest(point.x, point.y);\n if (!hit) return;\n\n // Selection is already handled by handleMouseDown (fires before contextmenu).\n // Here we only emit the context menu event.\n const { selection } = this.worksheet;\n const base = { clientX: event.clientX, clientY: event.clientY, originalEvent: event };\n\n switch (hit.type) {\n case 'row-header': {\n const bounds = selection.getSelectionBounds()!;\n this.worksheet.emitContextMenu({\n ...base,\n area: 'row-header',\n row: hit.row,\n selectedRows: [bounds.topRow, bounds.bottomRow],\n });\n break;\n }\n case 'column-header': {\n const bounds = selection.getSelectionBounds()!;\n this.worksheet.emitContextMenu({\n ...base,\n area: 'column-header',\n column: hit.column,\n selectedColumns: [bounds.leftColumn, bounds.rightColumn],\n });\n break;\n }\n case 'cell':\n this.worksheet.emitContextMenu({\n ...base,\n area: 'cell',\n row: hit.row,\n column: hit.column,\n });\n break;\n case 'corner':\n this.worksheet.emitContextMenu({ ...base, area: 'corner' });\n break;\n default:\n break;\n }\n };\n\n private getCanvasPoint(event: MouseEvent): CanvasPoint | null {\n const rect = this.canvas.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0) {\n return null;\n }\n\n return {\n x: event.clientX - rect.left,\n y: event.clientY - rect.top,\n };\n }\n\n private resolveRowFromHit(hit: HitTestResult): number | null {\n if (hit.type === 'row-header' || hit.type === 'cell') {\n return hit.row;\n }\n return null;\n }\n\n private resolveColumnFromHit(hit: HitTestResult): number | null {\n if (hit.type === 'column-header' || hit.type === 'cell') {\n return hit.column;\n }\n return null;\n }\n\n private tryBeginResize(point: CanvasPoint): boolean {\n const columnHandle = this.worksheet.getColumnResizeHandle(point.x, point.y);\n if (columnHandle !== null) {\n this.isResizing = true;\n this.resizeContext = {\n type: 'column',\n column: columnHandle,\n origin: point.x,\n originalSize: this.worksheet.getColumnWidth(columnHandle),\n };\n this.setCursor('col-resize');\n this.worksheet.setResizeGuide({ type: 'column', position: point.x });\n return true;\n }\n\n const rowHandle = this.worksheet.getRowResizeHandle(point.x, point.y);\n if (rowHandle !== null) {\n this.isResizing = true;\n this.resizeContext = {\n type: 'row',\n row: rowHandle,\n origin: point.y,\n originalSize: this.worksheet.getRowHeight(rowHandle),\n };\n this.setCursor('row-resize');\n this.worksheet.setResizeGuide({ type: 'row', position: point.y });\n return true;\n }\n\n return false;\n }\n\n private handleResizeDrag(point: CanvasPoint): void {\n if (!this.resizeContext) {\n return;\n }\n\n if (this.resizeContext.type === 'column') {\n const delta = point.x - this.resizeContext.origin;\n this.worksheet.setResizeGuide({ type: 'column', position: point.x }, false);\n const nextWidth = this.resizeContext.originalSize + delta;\n this.worksheet.setColumnWidth(this.resizeContext.column, nextWidth);\n } else if (this.resizeContext.type === 'row') {\n const delta = point.y - this.resizeContext.origin;\n this.worksheet.setResizeGuide({ type: 'row', position: point.y }, false);\n const nextHeight = this.resizeContext.originalSize + delta;\n this.worksheet.setRowHeight(this.resizeContext.row, nextHeight);\n }\n }\n\n private updateHoverCursor(point: CanvasPoint | null): void {\n if (this.isResizing || this.isDragging) {\n return;\n }\n if (!point) {\n this.setCursor('default');\n return;\n }\n\n if (this.worksheet.getColumnResizeHandle(point.x, point.y) !== null) {\n this.setCursor('col-resize');\n } else if (this.worksheet.getRowResizeHandle(point.x, point.y) !== null) {\n this.setCursor('row-resize');\n } else {\n const hit = this.worksheet.hitTest(point.x, point.y);\n if (hit && (hit.type === 'outline-toggle' || hit.type === 'outline-level-button')) {\n this.setCursor('pointer');\n } else {\n this.setCursor('default');\n }\n }\n }\n\n private setCursor(cursor: string): void {\n if (this.canvas.style.cursor !== cursor) {\n this.canvas.style.cursor = cursor;\n }\n }\n}\n","import type { CanvasWorksheet } from '../../core/worksheet';\nimport type { ActionManager } from '../../core/action';\nimport { SetCellInputAction } from '../../core/action';\n\ninterface EditingCell {\n row: number;\n column: number;\n}\n\ninterface BeginEditOptions {\n presetValue?: string;\n selectAll?: boolean;\n}\n\nexport class CellEditor {\n private readonly worksheet: CanvasWorksheet;\n\n private readonly actionManager: ActionManager | null;\n\n private readonly input: HTMLTextAreaElement;\n\n private editingCell: EditingCell | null = null;\n\n constructor(worksheet: CanvasWorksheet, actionManager?: ActionManager) {\n this.worksheet = worksheet;\n this.actionManager = actionManager ?? null;\n this.input = this.createInput();\n window.addEventListener('resize', this.refreshPosition);\n }\n\n beginEdit(row: number, column: number, options: BeginEditOptions = {}): void {\n if (this.worksheet.isCellProtected(row, column)) {\n this.worksheet.emitProtectedCellEdit(row, column);\n return;\n }\n const { presetValue, selectAll = true } = options;\n this.editingCell = { row, column };\n if (presetValue !== undefined) {\n this.input.value = presetValue;\n } else {\n this.input.value = this.worksheet.getCellInput(row, column) ?? '';\n }\n const style = this.worksheet.getComputedCellStyle(row, column);\n this.input.style.textAlign = style.textAlign;\n const fontSizePx = this.worksheet.pointsToPixels(style.fontSize);\n this.input.style.fontSize = `${fontSizePx}px`;\n this.input.style.color = style.color;\n this.input.style.whiteSpace = style.textWrapMode === 'none' ? 'pre' : 'pre-wrap';\n this.input.style.wordBreak = style.textWrapMode === 'break-word' ? 'break-word' : 'normal';\n this.input.style.overflowWrap = style.textWrapMode === 'break-word' ? 'break-word' : 'normal';\n this.updateInputPosition();\n this.input.style.display = 'block';\n this.input.focus();\n if (selectAll) {\n this.input.select();\n } else {\n const pos = this.input.value.length;\n this.input.setSelectionRange(pos, pos);\n }\n }\n\n commit(): void {\n if (!this.editingCell) {\n return;\n }\n const { row, column } = this.editingCell;\n if (this.actionManager) {\n this.actionManager.execute(new SetCellInputAction(row, column, this.input.value));\n } else {\n this.worksheet.setCellInput(row, column, this.input.value);\n }\n this.hide();\n }\n\n cancel(): void {\n this.hide();\n }\n\n isEditing(): boolean {\n return this.editingCell !== null;\n }\n\n destroy(): void {\n window.removeEventListener('resize', this.refreshPosition);\n this.input.remove();\n }\n\n private hide(): void {\n this.editingCell = null;\n this.input.style.display = 'none';\n }\n\n private refreshPosition = (): void => {\n if (!this.editingCell) {\n return;\n }\n this.updateInputPosition();\n };\n\n private createInput(): HTMLTextAreaElement {\n const input = document.createElement('textarea');\n input.style.position = 'fixed';\n input.style.display = 'none';\n input.style.font = '14px sans-serif';\n input.style.padding = '2px 4px';\n input.style.border = '2px solid #2196f3';\n input.style.boxShadow = '0 2px 4px rgba(0, 0, 0, 0.15)';\n input.style.outline = 'none';\n input.style.background = '#fff';\n input.style.textAlign = 'left';\n input.style.zIndex = '1000';\n input.style.resize = 'none';\n input.style.whiteSpace = 'pre-wrap';\n input.style.overflow = 'hidden';\n input.addEventListener('keydown', (event) => {\n if (\n event.key === 'Enter' &&\n !event.shiftKey &&\n !event.altKey &&\n !event.ctrlKey &&\n !event.metaKey\n ) {\n event.preventDefault();\n this.commit();\n } else if (event.key === 'Escape') {\n event.preventDefault();\n this.cancel();\n } else if (\n (event.key === 'ArrowLeft' ||\n event.key === 'ArrowRight' ||\n event.key === 'ArrowUp' ||\n event.key === 'ArrowDown') &&\n !event.shiftKey &&\n !event.metaKey &&\n !event.ctrlKey &&\n !event.altKey\n ) {\n this.handleHorizontalNavigation(event);\n }\n });\n input.addEventListener('blur', () => {\n this.commit();\n });\n document.body.appendChild(input);\n return input;\n }\n\n private updateInputPosition(): void {\n if (!this.editingCell) {\n return;\n }\n\n const rect = this.worksheet.canvas.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0) {\n return;\n }\n\n const cellRect = this.worksheet.getCellRect(this.editingCell.row, this.editingCell.column);\n const left = rect.left + cellRect.x;\n const top = rect.top + cellRect.y;\n const width = cellRect.width;\n const height = cellRect.height;\n\n this.input.style.left = `${left}px`;\n this.input.style.top = `${top}px`;\n this.input.style.width = `${width}px`;\n this.input.style.height = `${height}px`;\n this.input.style.lineHeight = '1.4';\n }\n\n private handleHorizontalNavigation(event: KeyboardEvent): void {\n if (!this.editingCell) {\n return;\n }\n\n const selectionStart = this.input.selectionStart;\n const selectionEnd = this.input.selectionEnd;\n if (selectionStart === null || selectionEnd === null || selectionStart !== selectionEnd) {\n return;\n }\n\n if (event.key === 'ArrowRight' && selectionEnd === this.input.value.length) {\n event.preventDefault();\n this.commitAndMove(0, 1);\n } else if (event.key === 'ArrowLeft' && selectionStart === 0) {\n event.preventDefault();\n this.commitAndMove(0, -1);\n } else if (event.key === 'ArrowUp' && selectionStart === 0) {\n event.preventDefault();\n this.commitAndMove(-1, 0);\n } else if (event.key === 'ArrowDown' && selectionEnd === this.input.value.length) {\n event.preventDefault();\n this.commitAndMove(1, 0);\n }\n }\n\n private commitAndMove(rowDelta: number, columnDelta: number): void {\n if (!this.editingCell) {\n return;\n }\n this.commit();\n const next = this.worksheet.selection.moveActiveCell(rowDelta, columnDelta);\n this.worksheet.render();\n this.worksheet.notifySelectionChanged();\n this.beginEdit(next.row, next.column);\n }\n}\n","import type { CanvasWorksheet } from '../../core/worksheet';\n\nexport class DropdownOverlay {\n private readonly worksheet: CanvasWorksheet;\n private readonly listElement: HTMLDivElement;\n private currentCallback: ((value: string) => void) | null = null;\n private outsideClickHandler: ((e: MouseEvent) => void) | null = null;\n\n constructor(worksheet: CanvasWorksheet) {\n this.worksheet = worksheet;\n this.listElement = this.createListElement();\n }\n\n open(\n row: number,\n column: number,\n options: string[],\n onSelect: (value: string) => void,\n ): void {\n this.close();\n\n this.currentCallback = onSelect;\n\n // Position below the cell\n const canvasRect = this.worksheet.canvas.getBoundingClientRect();\n const cellRect = this.worksheet.getCellRect(row, column);\n const left = canvasRect.left + cellRect.x;\n const top = canvasRect.top + cellRect.y + cellRect.height;\n const width = cellRect.width;\n\n this.listElement.style.left = `${left}px`;\n this.listElement.style.top = `${top}px`;\n this.listElement.style.minWidth = `${width}px`;\n\n // Populate items\n this.listElement.innerHTML = '';\n for (const option of options) {\n const item = document.createElement('div');\n item.className = 'reogrid-dropdown-item';\n item.textContent = option;\n item.addEventListener('mousedown', (e) => {\n e.preventDefault();\n e.stopPropagation();\n this.selectItem(option);\n });\n this.listElement.appendChild(item);\n }\n\n this.listElement.style.display = 'block';\n\n // Close on outside click (capture phase)\n this.outsideClickHandler = (e: MouseEvent) => {\n if (!this.listElement.contains(e.target as Node)) {\n this.close();\n }\n };\n requestAnimationFrame(() => {\n document.addEventListener('mousedown', this.outsideClickHandler!, true);\n });\n }\n\n close(): void {\n this.listElement.style.display = 'none';\n this.listElement.innerHTML = '';\n this.currentCallback = null;\n if (this.outsideClickHandler) {\n document.removeEventListener('mousedown', this.outsideClickHandler, true);\n this.outsideClickHandler = null;\n }\n }\n\n isOpen(): boolean {\n return this.listElement.style.display !== 'none';\n }\n\n destroy(): void {\n this.close();\n this.listElement.remove();\n }\n\n private selectItem(value: string): void {\n const cb = this.currentCallback;\n this.close();\n if (cb) {\n cb(value);\n }\n }\n\n private createListElement(): HTMLDivElement {\n const el = document.createElement('div');\n el.className = 'reogrid-dropdown-list';\n el.style.position = 'fixed';\n el.style.display = 'none';\n el.style.zIndex = '1001';\n document.body.appendChild(el);\n return el;\n }\n}\n","import type { CanvasWorksheet } from '../../core/worksheet';\nimport type { SortOrder } from '../../core/sort/types';\n\nexport class FilterDropdownOverlay {\n private readonly worksheet: CanvasWorksheet;\n private readonly container: HTMLDivElement;\n private outsideClickHandler: ((e: MouseEvent) => void) | null = null;\n private currentApplyCallback: ((selected: Set<string>) => void) | null = null;\n private currentSortCallback: ((order: SortOrder) => void) | null = null;\n private allValues: string[] = [];\n private selectedValues: Set<string> = new Set();\n\n constructor(worksheet: CanvasWorksheet) {\n this.worksheet = worksheet;\n this.container = this.createContainer();\n }\n\n open(\n column: number,\n anchorRect: { x: number; y: number; width: number; height: number },\n values: string[],\n selectedValues: Set<string>,\n onApply: (newSelection: Set<string>) => void,\n onSort?: (order: SortOrder) => void,\n ): void {\n this.close();\n\n this.allValues = values;\n this.selectedValues = new Set(selectedValues);\n this.currentApplyCallback = onApply;\n this.currentSortCallback = onSort ?? null;\n\n // Position below the header cell\n const canvasRect = this.worksheet.canvas.getBoundingClientRect();\n const left = canvasRect.left + anchorRect.x;\n const top = canvasRect.top + anchorRect.y + anchorRect.height;\n\n this.container.style.left = `${left}px`;\n this.container.style.top = `${top}px`;\n this.container.style.minWidth = `${Math.max(160, anchorRect.width)}px`;\n\n this.buildContent();\n this.container.style.display = 'block';\n\n // Close on outside click\n this.outsideClickHandler = (e: MouseEvent) => {\n if (!this.container.contains(e.target as Node)) {\n this.close();\n }\n };\n requestAnimationFrame(() => {\n document.addEventListener('mousedown', this.outsideClickHandler!, true);\n });\n }\n\n close(): void {\n this.container.style.display = 'none';\n this.container.innerHTML = '';\n this.currentApplyCallback = null;\n this.currentSortCallback = null;\n if (this.outsideClickHandler) {\n document.removeEventListener('mousedown', this.outsideClickHandler, true);\n this.outsideClickHandler = null;\n }\n }\n\n isOpen(): boolean {\n return this.container.style.display !== 'none';\n }\n\n destroy(): void {\n this.close();\n this.container.remove();\n }\n\n private buildContent(): void {\n this.container.innerHTML = '';\n\n // Sort buttons\n if (this.currentSortCallback) {\n const sortBtns = document.createElement('div');\n sortBtns.className = 'reogrid-filter-sort-buttons';\n\n const sortAsc = document.createElement('button');\n sortAsc.className = 'reogrid-filter-sort-btn';\n sortAsc.textContent = 'Sort A \\u2192 Z';\n sortAsc.addEventListener('mousedown', (e) => {\n e.preventDefault();\n e.stopPropagation();\n this.sortAndClose('asc');\n });\n sortBtns.appendChild(sortAsc);\n\n const sortDesc = document.createElement('button');\n sortDesc.className = 'reogrid-filter-sort-btn';\n sortDesc.textContent = 'Sort Z \\u2192 A';\n sortDesc.addEventListener('mousedown', (e) => {\n e.preventDefault();\n e.stopPropagation();\n this.sortAndClose('desc');\n });\n sortBtns.appendChild(sortDesc);\n\n this.container.appendChild(sortBtns);\n\n // Separator\n const separator = document.createElement('hr');\n separator.className = 'reogrid-filter-separator';\n this.container.appendChild(separator);\n }\n\n // Search box\n const searchBox = document.createElement('input');\n searchBox.type = 'text';\n searchBox.className = 'reogrid-filter-search';\n searchBox.placeholder = 'Search...';\n searchBox.addEventListener('input', () => {\n this.filterItems(searchBox.value);\n });\n // Prevent keyboard controller from intercepting\n searchBox.addEventListener('keydown', (e) => e.stopPropagation());\n this.container.appendChild(searchBox);\n\n // Select All\n const selectAllRow = document.createElement('label');\n selectAllRow.className = 'reogrid-filter-select-all';\n const selectAllCb = document.createElement('input');\n selectAllCb.type = 'checkbox';\n selectAllCb.checked = this.selectedValues.size === this.allValues.length;\n selectAllCb.indeterminate = this.selectedValues.size > 0 && this.selectedValues.size < this.allValues.length;\n selectAllCb.addEventListener('change', () => {\n this.toggleSelectAll(selectAllCb.checked);\n });\n selectAllRow.appendChild(selectAllCb);\n selectAllRow.appendChild(document.createTextNode(' (Select All)'));\n this.container.appendChild(selectAllRow);\n\n // Items list\n const itemsList = document.createElement('div');\n itemsList.className = 'reogrid-filter-items';\n for (const value of this.allValues) {\n const label = document.createElement('label');\n label.className = 'reogrid-filter-item';\n label.dataset.value = value;\n const cb = document.createElement('input');\n cb.type = 'checkbox';\n cb.checked = this.selectedValues.has(value);\n cb.addEventListener('change', () => {\n if (cb.checked) {\n this.selectedValues.add(value);\n } else {\n this.selectedValues.delete(value);\n }\n this.updateSelectAll();\n });\n label.appendChild(cb);\n label.appendChild(document.createTextNode(` ${value}`));\n itemsList.appendChild(label);\n }\n this.container.appendChild(itemsList);\n\n // Actions\n const actions = document.createElement('div');\n actions.className = 'reogrid-filter-actions';\n\n const okBtn = document.createElement('button');\n okBtn.textContent = 'OK';\n okBtn.addEventListener('mousedown', (e) => {\n e.preventDefault();\n e.stopPropagation();\n this.applyAndClose();\n });\n actions.appendChild(okBtn);\n\n const cancelBtn = document.createElement('button');\n cancelBtn.textContent = 'Cancel';\n cancelBtn.addEventListener('mousedown', (e) => {\n e.preventDefault();\n e.stopPropagation();\n this.close();\n });\n actions.appendChild(cancelBtn);\n\n this.container.appendChild(actions);\n }\n\n private toggleSelectAll(checked: boolean): void {\n this.selectedValues.clear();\n if (checked) {\n for (const v of this.allValues) {\n this.selectedValues.add(v);\n }\n }\n // Update all visible checkboxes\n const items = this.container.querySelectorAll('.reogrid-filter-item input[type=\"checkbox\"]') as NodeListOf<HTMLInputElement>;\n for (const cb of items) {\n cb.checked = checked;\n }\n }\n\n private updateSelectAll(): void {\n const selectAllCb = this.container.querySelector('.reogrid-filter-select-all input[type=\"checkbox\"]') as HTMLInputElement | null;\n if (selectAllCb) {\n selectAllCb.checked = this.selectedValues.size === this.allValues.length;\n selectAllCb.indeterminate = this.selectedValues.size > 0 && this.selectedValues.size < this.allValues.length;\n }\n }\n\n private filterItems(query: string): void {\n const lowerQuery = query.toLowerCase();\n const items = this.container.querySelectorAll('.reogrid-filter-item') as NodeListOf<HTMLElement>;\n for (const item of items) {\n const value = item.dataset.value ?? '';\n item.style.display = value.toLowerCase().includes(lowerQuery) ? '' : 'none';\n }\n }\n\n private applyAndClose(): void {\n const cb = this.currentApplyCallback;\n const selected = new Set(this.selectedValues);\n this.close();\n if (cb) {\n cb(selected);\n }\n }\n\n private sortAndClose(order: SortOrder): void {\n const cb = this.currentSortCallback;\n this.close();\n if (cb) {\n cb(order);\n }\n }\n\n private createContainer(): HTMLDivElement {\n const el = document.createElement('div');\n el.className = 'reogrid-filter-dropdown';\n el.style.position = 'fixed';\n el.style.display = 'none';\n el.style.zIndex = '1001';\n document.body.appendChild(el);\n return el;\n }\n}\n","import type { CanvasWorksheet } from '../../core/worksheet';\nimport type { ActionManager } from '../../core/action';\nimport type { CellEditor } from '../editor/cellEditor';\nimport type { ClipboardService } from '../../core/clipboard';\n\nexport class KeyboardController {\n private readonly worksheet: CanvasWorksheet;\n\n private readonly cellEditor: CellEditor;\n\n private readonly actionManager: ActionManager;\n\n private readonly clipboardService: ClipboardService;\n\n constructor(\n worksheet: CanvasWorksheet,\n cellEditor: CellEditor,\n actionManager: ActionManager,\n clipboardService: ClipboardService,\n ) {\n this.worksheet = worksheet;\n this.cellEditor = cellEditor;\n this.actionManager = actionManager;\n this.clipboardService = clipboardService;\n window.addEventListener('keydown', this.handleKeyDown, { passive: false });\n window.addEventListener('paste', this.handlePaste);\n }\n\n destroy(): void {\n window.removeEventListener('keydown', this.handleKeyDown);\n window.removeEventListener('paste', this.handlePaste);\n }\n\n private handleKeyDown = (event: KeyboardEvent): void => {\n if (event.defaultPrevented) {\n return;\n }\n\n if (this.cellEditor.isEditing()) {\n return;\n }\n\n const focused = document.activeElement;\n if (\n focused instanceof HTMLInputElement ||\n focused instanceof HTMLTextAreaElement ||\n focused instanceof HTMLSelectElement ||\n (focused instanceof HTMLElement && focused.isContentEditable)\n ) {\n return;\n }\n\n const mod = event.metaKey || event.ctrlKey;\n if (mod && event.key === 'z' && !event.shiftKey) {\n event.preventDefault();\n this.actionManager.undo();\n return;\n }\n if (mod && (event.key === 'y' || (event.key === 'z' && event.shiftKey))) {\n event.preventDefault();\n this.actionManager.redo();\n return;\n }\n\n if (mod && event.key === 'c') {\n event.preventDefault();\n this.clipboardService.copy();\n return;\n }\n if (mod && event.key === 'x') {\n event.preventDefault();\n this.clipboardService.cut();\n return;\n }\n // Ctrl+V: do NOT preventDefault here — let the native paste event fire,\n // which is handled by handlePaste below.\n if (mod && event.key === 'v') {\n return;\n }\n\n if (event.key === 'Delete' || event.key === 'Backspace') {\n event.preventDefault();\n this.clipboardService.delete();\n return;\n }\n\n if (this.handleNavigationKeys(event)) {\n return;\n }\n\n const activeCell = this.ensureActiveCell();\n\n if (event.key === 'F2') {\n event.preventDefault();\n this.cellEditor.beginEdit(activeCell.row, activeCell.column);\n return;\n }\n\n if (event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {\n event.preventDefault();\n this.cellEditor.beginEdit(activeCell.row, activeCell.column, {\n presetValue: event.key,\n selectAll: false,\n });\n }\n };\n\n private handleNavigationKeys(event: KeyboardEvent): boolean {\n const selection = this.worksheet.selection;\n const key = event.key;\n let moved = false;\n switch (key) {\n case 'ArrowUp':\n selection.moveActiveCell(-1, 0);\n moved = true;\n break;\n case 'ArrowDown':\n selection.moveActiveCell(1, 0);\n moved = true;\n break;\n case 'ArrowLeft':\n selection.moveActiveCell(0, -1);\n moved = true;\n break;\n case 'ArrowRight':\n selection.moveActiveCell(0, 1);\n moved = true;\n break;\n default:\n break;\n }\n\n if (moved) {\n event.preventDefault();\n this.worksheet.render();\n this.worksheet.notifySelectionChanged();\n }\n return moved;\n }\n\n private handlePaste = (event: ClipboardEvent): void => {\n if (this.cellEditor.isEditing()) return;\n\n const focused = document.activeElement;\n if (\n focused instanceof HTMLInputElement ||\n focused instanceof HTMLTextAreaElement ||\n focused instanceof HTMLSelectElement ||\n (focused instanceof HTMLElement && focused.isContentEditable)\n ) {\n return;\n }\n\n event.preventDefault();\n this.clipboardService.pasteFromEvent(event);\n };\n\n private ensureActiveCell(): { row: number; column: number } {\n const active = this.worksheet.selection.getActiveCell();\n if (active) {\n return active;\n }\n const fallback = this.worksheet.selection.moveActiveCell(0, 0);\n this.worksheet.notifySelectionChanged();\n return fallback;\n }\n}\n","import type { Worksheet } from '../worksheet/worksheet';\n\n/**\n * Serialize the given range of cells into a TSV string (tab-separated, newline-delimited).\n *\n * Values containing tabs, newlines, or double-quotes are quoted per the\n * \"CSV/TSV quoting\" convention (double-quotes escaped as \"\").\n */\nexport function serializeRangeToTsv(\n worksheet: Worksheet,\n topRow: number,\n leftColumn: number,\n bottomRow: number,\n rightColumn: number,\n): string {\n const lines: string[] = [];\n for (let r = topRow; r <= bottomRow; r++) {\n const fields: string[] = [];\n for (let c = leftColumn; c <= rightColumn; c++) {\n const raw = worksheet.getCellInput(r, c) ?? '';\n fields.push(quoteTsvField(raw));\n }\n lines.push(fields.join('\\t'));\n }\n return lines.join('\\n');\n}\n\nfunction quoteTsvField(value: string): string {\n if (value.includes('\\t') || value.includes('\\n') || value.includes('\"')) {\n return '\"' + value.replace(/\"/g, '\"\"') + '\"';\n }\n return value;\n}\n","import type { ClipboardRangeData, ClipboardCellData } from './types';\n\n/**\n * Parse a TSV (tab-separated, newline-delimited) string into ClipboardRangeData.\n *\n * Handles quoted fields (double-quote escaping) per the standard CSV/TSV convention.\n */\nexport function parseTsv(tsv: string): ClipboardRangeData {\n const rows = splitTsvRows(tsv);\n const maxCols = rows.reduce((max, row) => Math.max(max, row.length), 0);\n\n const cells: (ClipboardCellData | null)[][] = rows.map((row) => {\n const rowCells: (ClipboardCellData | null)[] = [];\n for (let c = 0; c < maxCols; c++) {\n const value = c < row.length ? row[c] : '';\n rowCells.push(value.length > 0 ? { value } : null);\n }\n return rowCells;\n });\n\n return {\n rows: rows.length,\n columns: maxCols,\n cells,\n };\n}\n\n/**\n * Split TSV text into a 2D array of strings, handling quoted fields.\n */\nfunction splitTsvRows(text: string): string[][] {\n const rows: string[][] = [];\n let current: string[] = [];\n let field = '';\n let inQuotes = false;\n let i = 0;\n\n while (i < text.length) {\n const ch = text[i];\n\n if (inQuotes) {\n if (ch === '\"') {\n if (i + 1 < text.length && text[i + 1] === '\"') {\n field += '\"';\n i += 2;\n } else {\n inQuotes = false;\n i++;\n }\n } else {\n field += ch;\n i++;\n }\n } else {\n if (ch === '\"' && field.length === 0) {\n inQuotes = true;\n i++;\n } else if (ch === '\\t') {\n current.push(field);\n field = '';\n i++;\n } else if (ch === '\\r') {\n // Handle \\r\\n and bare \\r\n current.push(field);\n field = '';\n rows.push(current);\n current = [];\n i++;\n if (i < text.length && text[i] === '\\n') {\n i++;\n }\n } else if (ch === '\\n') {\n current.push(field);\n field = '';\n rows.push(current);\n current = [];\n i++;\n } else {\n field += ch;\n i++;\n }\n }\n }\n\n // Last field / row\n if (field.length > 0 || current.length > 0) {\n current.push(field);\n rows.push(current);\n }\n\n return rows;\n}\n","import type { Worksheet } from '../worksheet/worksheet';\nimport type { WorksheetAction, ActionTargetRange } from '../action/types';\nimport type { ClipboardRangeData, ClipboardCellData } from './types';\n\n// ---------------------------------------------------------------------------\n// PasteAction — pastes ClipboardRangeData at the target position (undoable)\n// ---------------------------------------------------------------------------\n\nexport class PasteAction implements WorksheetAction {\n readonly name = 'Paste';\n readonly modifiesCellData = true;\n\n private readonly targetRow: number;\n private readonly targetColumn: number;\n private readonly data: ClipboardRangeData;\n\n /** Snapshot of overwritten cells, captured during do(). */\n private previousValues: (string | undefined)[][] | null = null;\n\n constructor(targetRow: number, targetColumn: number, data: ClipboardRangeData) {\n this.targetRow = targetRow;\n this.targetColumn = targetColumn;\n this.data = data;\n }\n\n do(worksheet: Worksheet): void {\n const { rows, columns, cells } = this.data;\n\n // Snapshot the existing values before overwriting\n this.previousValues = [];\n for (let r = 0; r < rows; r++) {\n const rowSnap: (string | undefined)[] = [];\n for (let c = 0; c < columns; c++) {\n rowSnap.push(worksheet.getCellInput(this.targetRow + r, this.targetColumn + c));\n }\n this.previousValues.push(rowSnap);\n }\n\n // Write new values\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < columns; c++) {\n const cell = cells[r]?.[c];\n const value = cell?.value ?? '';\n worksheet.setCellInput(this.targetRow + r, this.targetColumn + c, value);\n }\n }\n }\n\n undo(worksheet: Worksheet): void {\n if (!this.previousValues) return;\n const { rows, columns } = this.data;\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < columns; c++) {\n const old = this.previousValues[r]?.[c] ?? '';\n worksheet.setCellInput(this.targetRow + r, this.targetColumn + c, old);\n }\n }\n }\n\n getTargetRange(): ActionTargetRange {\n return {\n topRow: this.targetRow,\n leftColumn: this.targetColumn,\n bottomRow: this.targetRow + this.data.rows - 1,\n rightColumn: this.targetColumn + this.data.columns - 1,\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// ClearRangeAction — clears cell values in a range (undoable)\n// ---------------------------------------------------------------------------\n\nexport class ClearRangeAction implements WorksheetAction {\n readonly name = 'Clear';\n readonly modifiesCellData = true;\n\n private readonly topRow: number;\n private readonly leftColumn: number;\n private readonly bottomRow: number;\n private readonly rightColumn: number;\n\n private previousValues: (string | undefined)[][] | null = null;\n\n constructor(topRow: number, leftColumn: number, bottomRow: number, rightColumn: number) {\n this.topRow = topRow;\n this.leftColumn = leftColumn;\n this.bottomRow = bottomRow;\n this.rightColumn = rightColumn;\n }\n\n do(worksheet: Worksheet): void {\n this.previousValues = [];\n for (let r = this.topRow; r <= this.bottomRow; r++) {\n const rowSnap: (string | undefined)[] = [];\n for (let c = this.leftColumn; c <= this.rightColumn; c++) {\n rowSnap.push(worksheet.getCellInput(r, c));\n worksheet.setCellInput(r, c, '');\n }\n this.previousValues.push(rowSnap);\n }\n }\n\n undo(worksheet: Worksheet): void {\n if (!this.previousValues) return;\n for (let r = this.topRow; r <= this.bottomRow; r++) {\n for (let c = this.leftColumn; c <= this.rightColumn; c++) {\n const old = this.previousValues[r - this.topRow]?.[c - this.leftColumn] ?? '';\n worksheet.setCellInput(r, c, old);\n }\n }\n }\n\n getTargetRange(): ActionTargetRange {\n return {\n topRow: this.topRow,\n leftColumn: this.leftColumn,\n bottomRow: this.bottomRow,\n rightColumn: this.rightColumn,\n };\n }\n}\n","import type { Worksheet } from '../worksheet/worksheet';\nimport type { ActionManager } from '../action';\nimport type { ClipboardRangeData, CutOrigin } from './types';\nimport { serializeRangeToTsv } from './tsvSerializer';\nimport { parseTsv } from './tsvParser';\nimport { PasteAction, ClearRangeAction } from './clipboardActions';\nimport { ActionGroup } from '../action';\n\nexport class ClipboardService {\n private readonly worksheet: Worksheet;\n private readonly actionManager: ActionManager;\n\n /** Internal buffer for same-instance paste and cut tracking. */\n private internalBuffer: ClipboardRangeData | null = null;\n private cutOrigin: CutOrigin | null = null;\n\n constructor(worksheet: Worksheet, actionManager: ActionManager) {\n this.worksheet = worksheet;\n this.actionManager = actionManager;\n }\n\n // ---------------------------------------------------------------------------\n // Copy\n // ---------------------------------------------------------------------------\n\n async copy(): Promise<void> {\n const bounds = this.worksheet.selection.getSelectionBounds();\n if (!bounds) return;\n\n const { topRow, leftColumn, bottomRow, rightColumn } = bounds;\n const tsv = serializeRangeToTsv(this.worksheet, topRow, leftColumn, bottomRow, rightColumn);\n this.internalBuffer = this.buildRangeData(topRow, leftColumn, bottomRow, rightColumn);\n this.cutOrigin = null;\n\n await this.writeToClipboard(tsv);\n }\n\n // ---------------------------------------------------------------------------\n // Cut\n // ---------------------------------------------------------------------------\n\n async cut(): Promise<void> {\n const bounds = this.worksheet.selection.getSelectionBounds();\n if (!bounds) return;\n\n const { topRow, leftColumn, bottomRow, rightColumn } = bounds;\n const tsv = serializeRangeToTsv(this.worksheet, topRow, leftColumn, bottomRow, rightColumn);\n this.internalBuffer = this.buildRangeData(topRow, leftColumn, bottomRow, rightColumn);\n this.cutOrigin = { topRow, leftColumn, bottomRow, rightColumn };\n\n await this.writeToClipboard(tsv);\n }\n\n // ---------------------------------------------------------------------------\n // Paste (from paste event — preferred path)\n // ---------------------------------------------------------------------------\n\n pasteFromEvent(event: ClipboardEvent): void {\n const text = event.clipboardData?.getData('text/plain');\n if (text === undefined || text === null) return;\n this.pasteText(text);\n }\n\n // ---------------------------------------------------------------------------\n // Paste (from Clipboard API — fallback)\n // ---------------------------------------------------------------------------\n\n async pasteFromClipboardApi(): Promise<void> {\n if (!navigator.clipboard?.readText) return;\n const text = await navigator.clipboard.readText();\n this.pasteText(text);\n }\n\n // ---------------------------------------------------------------------------\n // Delete (clear selection)\n // ---------------------------------------------------------------------------\n\n delete(): void {\n const bounds = this.worksheet.selection.getSelectionBounds();\n if (!bounds) return;\n\n const { topRow, leftColumn, bottomRow, rightColumn } = bounds;\n const action = new ClearRangeAction(topRow, leftColumn, bottomRow, rightColumn);\n this.actionManager.execute(action);\n }\n\n // ---------------------------------------------------------------------------\n // Private helpers\n // ---------------------------------------------------------------------------\n\n private pasteText(text: string): void {\n const active = this.worksheet.selection.getActiveCell();\n if (!active) return;\n\n const data = parseTsv(text);\n if (data.rows === 0 || data.columns === 0) return;\n\n // If this paste corresponds to a prior cut, clear the source range\n if (this.cutOrigin) {\n const clearAction = new ClearRangeAction(\n this.cutOrigin.topRow,\n this.cutOrigin.leftColumn,\n this.cutOrigin.bottomRow,\n this.cutOrigin.rightColumn,\n );\n const pasteAction = new PasteAction(active.row, active.column, data);\n const group = new ActionGroup('Cut & Paste', [clearAction, pasteAction]);\n this.actionManager.execute(group);\n this.cutOrigin = null;\n } else {\n const action = new PasteAction(active.row, active.column, data);\n this.actionManager.execute(action);\n }\n\n // Select the pasted range\n this.worksheet.setSelectionRange(\n active.row,\n active.column,\n active.row + data.rows - 1,\n active.column + data.columns - 1,\n );\n }\n\n private buildRangeData(\n topRow: number,\n leftColumn: number,\n bottomRow: number,\n rightColumn: number,\n ): ClipboardRangeData {\n const rows = bottomRow - topRow + 1;\n const columns = rightColumn - leftColumn + 1;\n const cells: ({ value: string } | null)[][] = [];\n\n for (let r = topRow; r <= bottomRow; r++) {\n const rowCells: ({ value: string } | null)[] = [];\n for (let c = leftColumn; c <= rightColumn; c++) {\n const value = this.worksheet.getCellInput(r, c);\n rowCells.push(value ? { value } : null);\n }\n cells.push(rowCells);\n }\n\n return { rows, columns, cells };\n }\n\n private async writeToClipboard(tsv: string): Promise<void> {\n try {\n if (navigator.clipboard?.writeText) {\n await navigator.clipboard.writeText(tsv);\n return;\n }\n } catch {\n // Clipboard API not available or permission denied — fall through to fallback\n }\n\n // Fallback: execCommand\n this.fallbackCopy(tsv);\n }\n\n private fallbackCopy(text: string): void {\n const textarea = document.createElement('textarea');\n textarea.value = text;\n textarea.style.position = 'fixed';\n textarea.style.left = '-9999px';\n document.body.appendChild(textarea);\n textarea.select();\n try {\n document.execCommand('copy');\n } finally {\n document.body.removeChild(textarea);\n }\n }\n}\n","import type { CanvasWorksheet, WorksheetImageInfo, WorksheetImagePlacement } from '../../core/worksheet/canvasWorksheet';\n\ntype ImageEntry = {\n element: HTMLImageElement;\n info: WorksheetImageInfo;\n};\n\nexport class WorksheetImageLayer {\n private readonly worksheet: CanvasWorksheet;\n\n private readonly container: HTMLDivElement;\n\n private readonly images: Map<string, ImageEntry> = new Map();\n\n private unsubscribeScroll: (() => void) | null = null;\n\n private unsubscribeStructure: (() => void) | null = null;\n\n private unsubscribeImages: (() => void) | null = null;\n\n constructor(worksheet: CanvasWorksheet, host: HTMLElement) {\n this.worksheet = worksheet;\n this.container = document.createElement('div');\n this.container.className = 'reogrid-image-layer';\n this.container.style.position = 'absolute';\n this.container.style.inset = '0';\n this.container.style.pointerEvents = 'none';\n this.container.style.zIndex = '2';\n host.appendChild(this.container);\n this.unsubscribeScroll = this.worksheet.onScrollChange((offset) => {\n this.syncScroll(offset.x, offset.y);\n });\n this.syncScroll(this.worksheet.getScrollOffset().x, this.worksheet.getScrollOffset().y);\n this.unsubscribeStructure = this.worksheet.onStructureChange(() => this.layoutAll());\n this.unsubscribeImages = this.worksheet.onImagesChange((images) => this.setImages(images));\n }\n\n destroy(): void {\n this.clearImages();\n if (this.unsubscribeScroll) {\n this.unsubscribeScroll();\n this.unsubscribeScroll = null;\n }\n if (this.unsubscribeStructure) {\n this.unsubscribeStructure();\n this.unsubscribeStructure = null;\n }\n if (this.unsubscribeImages) {\n this.unsubscribeImages();\n this.unsubscribeImages = null;\n }\n this.container.remove();\n }\n\n private setImages(images: WorksheetImageInfo[]): void {\n const nextIds = new Set(images.map((image) => image.id));\n for (const [id, entry] of this.images.entries()) {\n if (!nextIds.has(id)) {\n this.removeImageEntry(entry);\n this.images.delete(id);\n }\n }\n images.forEach((image) => {\n const existing = this.images.get(image.id);\n if (existing) {\n existing.info = image;\n this.layoutImage(existing.element, image.anchor);\n return;\n }\n const element = document.createElement('img');\n element.draggable = false;\n element.alt = '';\n element.decoding = 'async';\n element.loading = 'lazy';\n element.style.position = 'absolute';\n element.style.pointerEvents = 'none';\n element.style.userSelect = 'none';\n element.style.display = 'block';\n element.style.maxWidth = 'none';\n element.style.maxHeight = 'none';\n element.src = this.worksheet.createImageUrl(image.id);\n this.container.appendChild(element);\n this.layoutImage(element, image.anchor);\n this.images.set(image.id, { element, info: image });\n });\n }\n\n private clearImages(): void {\n for (const entry of this.images.values()) {\n this.removeImageEntry(entry);\n }\n this.images.clear();\n }\n\n private layoutAll(): void {\n for (const entry of this.images.values()) {\n this.layoutImage(entry.element, entry.info.anchor);\n }\n }\n\n private removeImageEntry(entry: ImageEntry): void {\n entry.element.remove();\n this.worksheet.revokeImageUrl(entry.info.id);\n }\n\n private layoutImage(element: HTMLImageElement, anchor: WorksheetImagePlacement): void {\n if (anchor.type === 'oneCell') {\n const point = this.getAnchorPoint(anchor.from);\n const width = Math.max(0, anchor.width);\n const height = Math.max(0, anchor.height);\n element.style.left = `${point.x}px`;\n element.style.top = `${point.y}px`;\n element.style.width = `${width}px`;\n element.style.height = `${height}px`;\n return;\n }\n const from = this.getAnchorPoint(anchor.from);\n const to = this.getAnchorPoint(anchor.to);\n const width = Math.max(0, to.x - from.x);\n const height = Math.max(0, to.y - from.y);\n element.style.left = `${from.x}px`;\n element.style.top = `${from.y}px`;\n element.style.width = `${width}px`;\n element.style.height = `${height}px`;\n }\n\n private getAnchorPoint(anchor: WorksheetImagePlacement['from']): { x: number; y: number } {\n const x = this.worksheet.getColumnStart(anchor.column) + anchor.offsetX;\n const y = this.worksheet.getRowStart(anchor.row) + anchor.offsetY;\n return { x, y };\n }\n\n private syncScroll(scrollX: number, scrollY: number): void {\n this.container.style.transform = `translate(${-scrollX}px, ${-scrollY}px)`;\n }\n}\n","import { registerCellTypeHandler } from '../cellTypeRegistry';\nimport type { CellTypeHandler, CellTypeRenderContext, CellTypeClickContext } from '../cellTypeHandler';\n\nconst BOX_SIZE = 14;\n\nfunction drawRoundRect(\n ctx: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, r: number,\n): void {\n ctx.beginPath();\n ctx.moveTo(x + r, y);\n ctx.lineTo(x + w - r, y);\n ctx.arcTo(x + w, y, x + w, y + r, r);\n ctx.lineTo(x + w, y + h - r);\n ctx.arcTo(x + w, y + h, x + w - r, y + h, r);\n ctx.lineTo(x + r, y + h);\n ctx.arcTo(x, y + h, x, y + h - r, r);\n ctx.lineTo(x, y + r);\n ctx.arcTo(x, y, x + r, y, r);\n ctx.closePath();\n}\n\nconst checkboxHandler: CellTypeHandler = {\n render({ ctx, rect, value, style, pixelRatio, cellPadding }: CellTypeRenderContext) {\n const checked = value === 'true';\n\n let boxX: number;\n if (style.textAlign === 'center') {\n boxX = Math.round(rect.x + (rect.width - BOX_SIZE) / 2);\n } else if (style.textAlign === 'right') {\n boxX = Math.round(rect.x + rect.width - cellPadding - BOX_SIZE);\n } else {\n boxX = Math.round(rect.x + cellPadding);\n }\n\n let boxY: number;\n if (style.verticalAlign === 'top') {\n boxY = Math.round(rect.y + cellPadding);\n } else if (style.verticalAlign === 'bottom') {\n boxY = Math.round(rect.y + rect.height - cellPadding - BOX_SIZE);\n } else {\n boxY = Math.round(rect.y + (rect.height - BOX_SIZE) / 2);\n }\n\n ctx.save();\n drawRoundRect(ctx, boxX, boxY, BOX_SIZE, BOX_SIZE, 2);\n if (checked) {\n ctx.fillStyle = '#4a90d9';\n ctx.fill();\n } else {\n ctx.fillStyle = '#ffffff';\n ctx.fill();\n ctx.strokeStyle = '#9ca3af';\n ctx.lineWidth = 1.5 / pixelRatio;\n ctx.stroke();\n }\n\n if (checked) {\n ctx.strokeStyle = '#ffffff';\n ctx.lineWidth = 2 / pixelRatio;\n ctx.lineCap = 'round';\n ctx.lineJoin = 'round';\n ctx.beginPath();\n ctx.moveTo(boxX + 3, boxY + 7);\n ctx.lineTo(boxX + 6, boxY + 11);\n ctx.lineTo(boxX + 11, boxY + 4);\n ctx.stroke();\n }\n ctx.restore();\n },\n\n onClick(ctx: CellTypeClickContext) {\n if (ctx.isProtected) return { handled: true };\n return { handled: true, newValue: ctx.value === 'true' ? 'false' : 'true' };\n },\n\n renderHTML(value) {\n return value === 'true' ? '&#9745;' : '&#9744;';\n },\n};\n\nregisterCellTypeHandler('checkbox', checkboxHandler);\n","import { registerCellTypeHandler } from '../cellTypeRegistry';\nimport type { CellTypeHandler, CellTypeRenderContext, CellTypeClickContext } from '../cellTypeHandler';\n\nconst BUTTON_WIDTH = 20;\n\nconst dropdownHandler: CellTypeHandler = {\n render({ ctx, rect, value, style, cellPadding, pixelRatio }: CellTypeRenderContext, config) {\n // Draw text in the cell area (clipped to leave room for arrow button)\n if (value !== null) {\n const fontFamily = style.fontFamily.includes(' ') ? `\"${style.fontFamily}\"` : style.fontFamily;\n const fontParts: string[] = [];\n if (style.italic) fontParts.push('italic');\n if (style.bold) fontParts.push('bold');\n // fontSize is in points — approximate px conversion (already in render context as style)\n fontParts.push(`${style.fontSize}pt`);\n fontParts.push(fontFamily);\n ctx.font = fontParts.join(' ');\n ctx.fillStyle = style.color || '#000';\n\n const textX = rect.x + cellPadding;\n const baselineY = rect.y + (rect.height + style.fontSize) / 2;\n ctx.save();\n ctx.beginPath();\n ctx.rect(rect.x, rect.y, rect.width - BUTTON_WIDTH, rect.height);\n ctx.clip();\n ctx.fillText(value, textX, baselineY);\n ctx.restore();\n }\n\n // Draw dropdown arrow button\n const btnX = rect.x + rect.width - BUTTON_WIDTH;\n const btnY = rect.y;\n const btnH = rect.height;\n\n ctx.save();\n // Separator line\n ctx.strokeStyle = '#c0c0c0';\n ctx.lineWidth = 1 / pixelRatio;\n ctx.beginPath();\n ctx.moveTo(btnX, btnY + 3);\n ctx.lineTo(btnX, btnY + btnH - 3);\n ctx.stroke();\n\n // Triangle arrow\n const arrowW = 8;\n const arrowH = 5;\n const cx = btnX + BUTTON_WIDTH / 2;\n const cy = btnY + btnH / 2;\n ctx.fillStyle = '#666666';\n ctx.beginPath();\n ctx.moveTo(cx - arrowW / 2, cy - arrowH / 2);\n ctx.lineTo(cx + arrowW / 2, cy - arrowH / 2);\n ctx.lineTo(cx, cy + arrowH / 2);\n ctx.closePath();\n ctx.fill();\n ctx.restore();\n },\n\n onClick(ctx: CellTypeClickContext, config) {\n if (ctx.isProtected) return { handled: true };\n\n // Only handle click on the dropdown button area (right side)\n const buttonLeft = ctx.rect.x + ctx.rect.width - BUTTON_WIDTH;\n if (ctx.screenX < buttonLeft) return { handled: false };\n\n const options = (config as { options?: string[] }).options;\n const onclick = (config as { onclick?: (c: { row: number; column: number; isHeader: boolean }) => void }).onclick;\n\n if (options && options.length > 0) {\n return {\n handled: true,\n openDropdown: {\n options,\n onSelect: (value: string) => {\n if (onclick) onclick({ row: ctx.row, column: ctx.column, isHeader: false });\n },\n },\n };\n }\n\n if (onclick) {\n onclick({ row: ctx.row, column: ctx.column, isHeader: false });\n }\n return { handled: true };\n },\n};\n\nregisterCellTypeHandler('dropdown', dropdownHandler);\n","import { registerCellTypeHandler } from '../cellTypeRegistry';\nimport type { CellTypeHandler, CellTypeRenderContext, CellTypeClickContext } from '../cellTypeHandler';\n\nconst buttonHandler: CellTypeHandler = {\n render({ ctx, rect, value, style, cellPadding, pixelRatio }: CellTypeRenderContext, config) {\n const label = (config as { label?: string }).label ?? value ?? '';\n const pad = 4;\n const btnX = rect.x + pad;\n const btnY = rect.y + pad;\n const btnW = rect.width - pad * 2;\n const btnH = rect.height - pad * 2;\n const radius = 3;\n\n ctx.save();\n\n // Button background\n ctx.beginPath();\n ctx.moveTo(btnX + radius, btnY);\n ctx.lineTo(btnX + btnW - radius, btnY);\n ctx.arcTo(btnX + btnW, btnY, btnX + btnW, btnY + radius, radius);\n ctx.lineTo(btnX + btnW, btnY + btnH - radius);\n ctx.arcTo(btnX + btnW, btnY + btnH, btnX + btnW - radius, btnY + btnH, radius);\n ctx.lineTo(btnX + radius, btnY + btnH);\n ctx.arcTo(btnX, btnY + btnH, btnX, btnY + btnH - radius, radius);\n ctx.lineTo(btnX, btnY + radius);\n ctx.arcTo(btnX, btnY, btnX + radius, btnY, radius);\n ctx.closePath();\n\n ctx.fillStyle = '#f0f0f0';\n ctx.fill();\n ctx.strokeStyle = '#b0b0b0';\n ctx.lineWidth = 1 / pixelRatio;\n ctx.stroke();\n\n // Label text\n if (label) {\n const fontSize = Math.min(style.fontSize, btnH * 0.6);\n ctx.font = `${fontSize}pt ${style.fontFamily}`;\n ctx.fillStyle = style.color || '#333';\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n ctx.fillText(label, btnX + btnW / 2, btnY + btnH / 2);\n }\n\n ctx.restore();\n },\n\n onClick(ctx: CellTypeClickContext, config) {\n if (ctx.isProtected) return { handled: true };\n const onClick = (config as { onClick?: () => void }).onClick;\n if (onClick) onClick();\n return { handled: true };\n },\n\n renderHTML(value, config) {\n const label = (config as { label?: string }).label ?? value ?? '';\n return `<span style=\"display:inline-block;padding:2px 8px;border:1px solid #b0b0b0;border-radius:3px;background:#f0f0f0;font-size:inherit\">${label}</span>`;\n },\n};\n\nregisterCellTypeHandler('button', buttonHandler);\n","import { registerCellTypeHandler } from '../cellTypeRegistry';\nimport type { CellTypeHandler, CellTypeRenderContext } from '../cellTypeHandler';\n\nconst progressHandler: CellTypeHandler = {\n render({ ctx, rect, value, pixelRatio }: CellTypeRenderContext, config) {\n const max = (config as { max?: number }).max ?? 100;\n const bidirectional = (config as { bidirectional?: boolean }).bidirectional ?? false;\n const customColor = (config as { color?: string }).color;\n const num = parseFloat(value ?? '0') || 0;\n const pad = 4;\n const barX = rect.x + pad;\n const barY = rect.y + Math.floor(rect.height * 0.3);\n const barW = rect.width - pad * 2;\n const barH = Math.max(rect.height * 0.4, 6);\n\n ctx.save();\n\n // Background track\n ctx.fillStyle = '#e8e8e8';\n ctx.fillRect(barX, barY, barW, barH);\n\n if (bidirectional) {\n // Center = 0, left = negative (red), right = positive (green)\n const center = barX + barW / 2;\n const ratio = Math.min(Math.abs(num) / max, 1);\n const fillW = ratio * (barW / 2);\n if (num >= 0) {\n ctx.fillStyle = customColor ?? '#4caf50';\n ctx.fillRect(center, barY, fillW, barH);\n } else {\n ctx.fillStyle = '#ef5350';\n ctx.fillRect(center - fillW, barY, fillW, barH);\n }\n // Center line\n ctx.strokeStyle = '#999';\n ctx.lineWidth = 1 / pixelRatio;\n ctx.beginPath();\n ctx.moveTo(center, barY);\n ctx.lineTo(center, barY + barH);\n ctx.stroke();\n } else {\n // Simple left-to-right bar\n const ratio = Math.max(0, Math.min(num / max, 1));\n const fillW = ratio * barW;\n ctx.fillStyle = customColor ?? '#4caf50';\n ctx.fillRect(barX, barY, fillW, barH);\n }\n\n // Border\n ctx.strokeStyle = '#ccc';\n ctx.lineWidth = 1 / pixelRatio;\n ctx.strokeRect(barX, barY, barW, barH);\n\n // Value text\n const text = `${Math.round(num)}`;\n ctx.fillStyle = '#333';\n ctx.font = `${Math.max(8, rect.height * 0.3)}px sans-serif`;\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n ctx.fillText(text, rect.x + rect.width / 2, rect.y + rect.height / 2);\n\n ctx.restore();\n },\n\n renderHTML(value, config) {\n const max = (config as { max?: number }).max ?? 100;\n const bidirectional = (config as { bidirectional?: boolean }).bidirectional ?? false;\n const num = parseFloat(value ?? '0') || 0;\n const ratio = Math.min(Math.abs(num) / max, 1);\n const pct = (ratio * 100).toFixed(1);\n\n if (bidirectional) {\n const color = num >= 0 ? '#4caf50' : '#ef5350';\n const half = (ratio * 50).toFixed(1);\n if (num >= 0) {\n return `<div style=\"height:12px;background:#e8e8e8;position:relative\"><div style=\"position:absolute;left:50%;top:0;width:${half}%;height:100%;background:${color}\"></div></div>`;\n }\n return `<div style=\"height:12px;background:#e8e8e8;position:relative\"><div style=\"position:absolute;right:50%;top:0;width:${half}%;height:100%;background:${color}\"></div></div>`;\n }\n return `<div style=\"height:12px;background:#e8e8e8\"><div style=\"width:${pct}%;height:100%;background:#4caf50\"></div></div>`;\n },\n};\n\nregisterCellTypeHandler('progress', progressHandler);\n","import { registerCellTypeHandler } from '../cellTypeRegistry';\nimport type { CellTypeHandler, CellTypeRenderContext, CellTypeClickContext } from '../cellTypeHandler';\n\nconst STAR_FILLED = '\\u2605'; // ★\nconst STAR_EMPTY = '\\u2606'; // ☆\n\nconst ratingHandler: CellTypeHandler = {\n render({ ctx, rect, value, style }: CellTypeRenderContext, config) {\n const maxStars = (config as { maxStars?: number }).maxStars ?? 5;\n const rating = Math.max(0, Math.min(parseInt(value ?? '0', 10) || 0, maxStars));\n\n const starSize = Math.min(rect.height * 0.7, rect.width / maxStars * 0.9, 16);\n\n ctx.save();\n ctx.font = `${starSize}px sans-serif`;\n ctx.textBaseline = 'middle';\n\n const totalW = starSize * maxStars;\n let startX: number;\n if (style.textAlign === 'center') {\n startX = rect.x + (rect.width - totalW) / 2;\n } else if (style.textAlign === 'right') {\n startX = rect.x + rect.width - totalW - 4;\n } else {\n startX = rect.x + 4;\n }\n const centerY = rect.y + rect.height / 2;\n\n for (let i = 0; i < maxStars; i++) {\n ctx.fillStyle = i < rating ? '#f5a623' : '#d0d0d0';\n ctx.fillText(i < rating ? STAR_FILLED : STAR_EMPTY, startX + i * starSize, centerY);\n }\n\n ctx.restore();\n },\n\n onClick(ctx: CellTypeClickContext, config) {\n if (ctx.isProtected) return { handled: false };\n const maxStars = (config as { maxStars?: number }).maxStars ?? 5;\n\n // Determine which star was clicked based on X position\n const totalW = Math.min(ctx.rect.height * 0.7, ctx.rect.width / maxStars * 0.9, 16) * maxStars;\n const startX = ctx.rect.x + 4;\n const relX = ctx.screenX - startX;\n\n if (relX < 0 || relX > totalW) return { handled: false };\n\n const starW = totalW / maxStars;\n const clicked = Math.min(Math.floor(relX / starW) + 1, maxStars);\n // Click same value = clear to 0\n const current = parseInt(ctx.value ?? '0', 10) || 0;\n const newVal = clicked === current ? 0 : clicked;\n\n return { handled: true, newValue: String(newVal) };\n },\n\n renderHTML(value, config) {\n const maxStars = (config as { maxStars?: number }).maxStars ?? 5;\n const rating = Math.max(0, Math.min(parseInt(value ?? '0', 10) || 0, maxStars));\n let html = '';\n for (let i = 0; i < maxStars; i++) {\n html += i < rating\n ? '<span style=\"color:#f5a623\">\\u2605</span>'\n : '<span style=\"color:#d0d0d0\">\\u2606</span>';\n }\n return html;\n },\n};\n\nregisterCellTypeHandler('rating', ratingHandler);\n","import { registerCellTypeHandler } from '../cellTypeRegistry';\nimport type { CellTypeHandler, CellTypeRenderContext } from '../cellTypeHandler';\n\nfunction parseValues(value: string | null): number[] {\n if (!value) return [];\n return value.split(',').map((s) => parseFloat(s.trim())).filter((n) => Number.isFinite(n));\n}\n\nconst sparklineLineHandler: CellTypeHandler = {\n render({ ctx, rect, value }: CellTypeRenderContext, config) {\n const nums = parseValues(value);\n if (nums.length < 2) return;\n\n const color = (config as { color?: string }).color ?? '#2196f3';\n const pad = 4;\n const x0 = rect.x + pad;\n const y0 = rect.y + pad;\n const w = rect.width - pad * 2;\n const h = rect.height - pad * 2;\n\n const min = Math.min(...nums);\n const max = Math.max(...nums);\n const range = max - min || 1;\n\n ctx.save();\n ctx.strokeStyle = color;\n ctx.lineWidth = 1.5;\n ctx.lineJoin = 'round';\n ctx.beginPath();\n\n for (let i = 0; i < nums.length; i++) {\n const px = x0 + (i / (nums.length - 1)) * w;\n const py = y0 + h - ((nums[i] - min) / range) * h;\n if (i === 0) ctx.moveTo(px, py);\n else ctx.lineTo(px, py);\n }\n\n ctx.stroke();\n ctx.restore();\n },\n\n renderHTML(value, config) {\n const nums = parseValues(value);\n if (nums.length < 2) return value ?? '';\n const color = (config as { color?: string }).color ?? '#2196f3';\n const w = 80;\n const h = 20;\n const min = Math.min(...nums);\n const max = Math.max(...nums);\n const range = max - min || 1;\n const points = nums.map((n, i) => {\n const px = (i / (nums.length - 1)) * w;\n const py = h - ((n - min) / range) * h;\n return `${px.toFixed(1)},${py.toFixed(1)}`;\n }).join(' ');\n return `<svg width=\"${w}\" height=\"${h}\" style=\"vertical-align:middle\"><polyline points=\"${points}\" fill=\"none\" stroke=\"${color}\" stroke-width=\"1.5\"/></svg>`;\n },\n};\n\nregisterCellTypeHandler('sparkline-line', sparklineLineHandler);\n","import { registerCellTypeHandler } from '../cellTypeRegistry';\nimport type { CellTypeHandler, CellTypeRenderContext } from '../cellTypeHandler';\n\nfunction parseValues(value: string | null): number[] {\n if (!value) return [];\n return value.split(',').map((s) => parseFloat(s.trim())).filter((n) => Number.isFinite(n));\n}\n\nconst sparklineAreaHandler: CellTypeHandler = {\n render({ ctx, rect, value }: CellTypeRenderContext, config) {\n const nums = parseValues(value);\n if (nums.length < 2) return;\n\n const color = (config as { color?: string }).color ?? '#2196f3';\n const fillColor = (config as { fillColor?: string }).fillColor ?? color + '40'; // 25% opacity\n const pad = 4;\n const x0 = rect.x + pad;\n const y0 = rect.y + pad;\n const w = rect.width - pad * 2;\n const h = rect.height - pad * 2;\n\n const min = Math.min(...nums);\n const max = Math.max(...nums);\n const range = max - min || 1;\n\n const points: Array<{ x: number; y: number }> = [];\n for (let i = 0; i < nums.length; i++) {\n points.push({\n x: x0 + (i / (nums.length - 1)) * w,\n y: y0 + h - ((nums[i] - min) / range) * h,\n });\n }\n\n ctx.save();\n\n // Filled area\n ctx.beginPath();\n ctx.moveTo(points[0].x, y0 + h);\n for (const p of points) ctx.lineTo(p.x, p.y);\n ctx.lineTo(points[points.length - 1].x, y0 + h);\n ctx.closePath();\n ctx.fillStyle = fillColor;\n ctx.fill();\n\n // Line\n ctx.beginPath();\n for (let i = 0; i < points.length; i++) {\n if (i === 0) ctx.moveTo(points[i].x, points[i].y);\n else ctx.lineTo(points[i].x, points[i].y);\n }\n ctx.strokeStyle = color;\n ctx.lineWidth = 1.5;\n ctx.lineJoin = 'round';\n ctx.stroke();\n\n ctx.restore();\n },\n\n renderHTML(value, config) {\n const nums = parseValues(value);\n if (nums.length < 2) return value ?? '';\n const color = (config as { color?: string }).color ?? '#2196f3';\n const fillColor = (config as { fillColor?: string }).fillColor ?? color + '40';\n const w = 80;\n const h = 20;\n const min = Math.min(...nums);\n const max = Math.max(...nums);\n const range = max - min || 1;\n const linePoints = nums.map((n, i) => {\n const px = (i / (nums.length - 1)) * w;\n const py = h - ((n - min) / range) * h;\n return `${px.toFixed(1)},${py.toFixed(1)}`;\n }).join(' ');\n const areaPoints = `0,${h} ${linePoints} ${w},${h}`;\n return `<svg width=\"${w}\" height=\"${h}\" style=\"vertical-align:middle\"><polygon points=\"${areaPoints}\" fill=\"${fillColor}\" stroke=\"none\"/><polyline points=\"${linePoints}\" fill=\"none\" stroke=\"${color}\" stroke-width=\"1.5\"/></svg>`;\n },\n};\n\nregisterCellTypeHandler('sparkline-area', sparklineAreaHandler);\n","import { registerCellTypeHandler } from '../cellTypeRegistry';\nimport type { CellTypeHandler, CellTypeRenderContext, CellTypeClickContext } from '../cellTypeHandler';\n\nfunction parseLink(value: string | null, config: Record<string, unknown>): { text: string; url: string } {\n const configUrl = config.url as string | undefined;\n if (!value) return { text: configUrl ?? '', url: configUrl ?? '' };\n // Support \"label|url\" format\n const pipeIdx = value.indexOf('|');\n if (pipeIdx >= 0) {\n return { text: value.slice(0, pipeIdx), url: value.slice(pipeIdx + 1) };\n }\n return { text: value, url: configUrl ?? value };\n}\n\nconst hyperlinkHandler: CellTypeHandler = {\n render({ ctx, rect, value, style, cellPadding }: CellTypeRenderContext, config) {\n const { text } = parseLink(value, config);\n if (!text) return;\n\n const fontFamily = style.fontFamily.includes(' ') ? `\"${style.fontFamily}\"` : style.fontFamily;\n const fontParts: string[] = [];\n if (style.italic) fontParts.push('italic');\n if (style.bold) fontParts.push('bold');\n fontParts.push(`${style.fontSize}pt`);\n fontParts.push(fontFamily);\n\n ctx.save();\n ctx.font = fontParts.join(' ');\n ctx.fillStyle = '#1a73e8';\n\n let textX: number;\n if (style.textAlign === 'center') {\n ctx.textAlign = 'center';\n textX = rect.x + rect.width / 2;\n } else if (style.textAlign === 'right') {\n ctx.textAlign = 'right';\n textX = rect.x + rect.width - cellPadding;\n } else {\n ctx.textAlign = 'left';\n textX = rect.x + cellPadding;\n }\n\n const baselineY = rect.y + (rect.height + style.fontSize) / 2;\n\n ctx.save();\n ctx.beginPath();\n ctx.rect(rect.x, rect.y, rect.width, rect.height);\n ctx.clip();\n ctx.fillText(text, textX, baselineY);\n\n // Underline\n const metrics = ctx.measureText(text);\n let lineX: number;\n if (style.textAlign === 'center') {\n lineX = textX - metrics.width / 2;\n } else if (style.textAlign === 'right') {\n lineX = textX - metrics.width;\n } else {\n lineX = textX;\n }\n ctx.strokeStyle = '#1a73e8';\n ctx.lineWidth = 1;\n ctx.beginPath();\n ctx.moveTo(lineX, baselineY + 1);\n ctx.lineTo(lineX + metrics.width, baselineY + 1);\n ctx.stroke();\n\n ctx.restore();\n ctx.restore();\n },\n\n onClick(ctx: CellTypeClickContext, config) {\n if (ctx.isProtected) return { handled: false };\n const { url } = parseLink(ctx.value, config);\n if (url) {\n window.open(url, '_blank', 'noopener');\n }\n return { handled: true };\n },\n\n renderHTML(value, config) {\n const { text, url } = parseLink(value, config);\n if (url) {\n const safeUrl = url.replace(/\"/g, '&quot;');\n const safeText = (text || url).replace(/</g, '&lt;').replace(/>/g, '&gt;');\n return `<a href=\"${safeUrl}\" target=\"_blank\" rel=\"noopener\" style=\"color:#1a73e8\">${safeText}</a>`;\n }\n return text || '';\n },\n};\n\nregisterCellTypeHandler('hyperlink', hyperlinkHandler);\n","import { CANVAS_ID, WORKSPACE_ID } from './app/domIds';\nimport {\n GRID_LAYER_CLASS,\n GRID_SCROLL_CLASS,\n GRID_SPACER_CLASS,\n WORKBOOK_CLASS,\n WORKSPACE_CLASS,\n WORKSHEET_CONTAINER_CLASS,\n ensureWorkspaceStyles,\n} from './app/styles';\nimport { CanvasWorksheet } from './core/worksheet';\nimport { PointerController } from './render/controllers/pointerController';\nimport { CellEditor } from './render/editor/cellEditor';\nimport { DropdownOverlay } from './render/editor/dropdownOverlay';\nimport { FilterDropdownOverlay } from './render/editor/filterDropdownOverlay';\nimport { KeyboardController } from './render/controllers/keyboardController';\nimport { ActionManager } from './core/action';\nimport { SortColumnAction } from './core/action/actions';\nimport { ClipboardService } from './core/clipboard';\nimport { WorksheetImageLayer } from './render/layers/imageLayer';\nimport type { SortOrder } from './core/sort/types';\n\ntype WorkspaceSurface = {\n canvas: HTMLCanvasElement;\n scrollContainer: HTMLDivElement;\n spacer: HTMLDivElement;\n worksheetContainer: HTMLDivElement;\n};\n\nexport type ReogridMountTarget = string | HTMLElement;\n\nexport interface ReogridOptions {\n workspace?: ReogridMountTarget;\n workspaceId?: string;\n canvasId?: string;\n injectStyles?: boolean;\n /** Maximum number of rows. Writes beyond this limit are silently ignored. */\n maxRows?: number;\n /** Maximum number of columns. Writes beyond this limit are silently ignored. */\n maxCols?: number;\n /** Maximum number of undo/redo steps (default: 30). */\n undoCapacity?: number;\n /** Options forwarded to the FormulaEngine (e.g. disable built-in functions for Lite). */\n formula?: import('./core/worksheet/worksheet').WorksheetOptions['formula'];\n}\n\nexport interface ReogridInstance {\n worksheet: CanvasWorksheet;\n actionManager: ActionManager;\n cellEditor: CellEditor;\n pointerController: PointerController;\n keyboardController: KeyboardController;\n destroy: () => void;\n}\n\nconst WORKSPACE_DATASET_FLAG = 'reogridMounted';\nconst WHEEL_LISTENER_OPTIONS: AddEventListenerOptions = { passive: false };\n\nexport function createReogrid(options: ReogridOptions | ReogridMountTarget = {}): ReogridInstance {\n if (typeof document === 'undefined') {\n throw new Error('createReogrid requires a browser environment.');\n }\n\n const opts: ReogridOptions =\n typeof options === 'string' || options instanceof HTMLElement\n ? { workspace: options }\n : options;\n\n if (opts.injectStyles !== false) {\n ensureWorkspaceStyles();\n }\n\n const workspace = resolveWorkspaceElement(opts.workspace, opts.workspaceId ?? WORKSPACE_ID);\n const canvasId = opts.canvasId ?? CANVAS_ID;\n const surface = ensureWorkspaceSurface(workspace, canvasId);\n const { worksheet, destroy: teardownWorksheet } = initCanvasWorksheet(surface, {\n maxRows: opts.maxRows,\n maxCols: opts.maxCols,\n }, opts.formula ? { formula: opts.formula } : undefined);\n\n const actionManager = new ActionManager(worksheet, opts.undoCapacity);\n const cellEditor = new CellEditor(worksheet, actionManager);\n const dropdownOverlay = new DropdownOverlay(worksheet);\n const filterDropdownOverlay = new FilterDropdownOverlay(worksheet);\n const clipboardService = new ClipboardService(worksheet, actionManager);\n const pointerController = new PointerController(worksheet, cellEditor, dropdownOverlay, surface.worksheetContainer, actionManager);\n const keyboardController = new KeyboardController(worksheet, cellEditor, actionManager, clipboardService);\n const imageLayer = new WorksheetImageLayer(worksheet, surface.worksheetContainer);\n const detachFontSync = attachFontRenderSync(worksheet);\n\n // Wire filter dropdown overlay to auto-filter header clicks\n const detachFilterDropdown = worksheet.onFilterDropdownClick((column) => {\n const filter = worksheet.getAutoFilter();\n if (!filter) return;\n const values = filter.getColumnValues(column);\n const currentFilter = filter.getColumnFilter(column);\n const selected = currentFilter?.selectedValues ?? new Set(values);\n // Compute anchor rect from column header\n const colBoundaries = worksheet.getColumnBoundaries();\n const anchorRect = {\n x: worksheet.headerColumnWidth + colBoundaries[column] - worksheet.getScrollOffset().x,\n y: 0,\n width: colBoundaries[column + 1] - colBoundaries[column],\n height: worksheet.headerRowHeight,\n };\n filterDropdownOverlay.open(column, anchorRect, values, selected, (newSelection) => {\n if (newSelection.size === values.length) {\n // All selected = clear filter for this column\n filter.setColumnFilter(column, null);\n } else {\n filter.setColumnFilter(column, newSelection);\n }\n filter.apply();\n }, (order: SortOrder) => {\n const config = filter.getConfig();\n actionManager.execute(new SortColumnAction({\n column,\n order,\n startRow: config.headerRow + 1,\n endRow: worksheet.rows - 1,\n startColumn: config.startColumn,\n endColumn: config.endColumn,\n }));\n filter.setSortState(column, order);\n worksheet.render();\n });\n });\n\n worksheet.notifySelectionChanged();\n\n const destroy = (): void => {\n detachFilterDropdown();\n filterDropdownOverlay.destroy();\n detachFontSync();\n imageLayer.destroy();\n pointerController.destroy();\n keyboardController.destroy();\n dropdownOverlay.destroy();\n cellEditor.destroy();\n teardownWorksheet();\n delete workspace.dataset[WORKSPACE_DATASET_FLAG];\n };\n\n return {\n worksheet,\n actionManager,\n cellEditor,\n pointerController,\n keyboardController,\n destroy,\n };\n}\n\nfunction resolveWorkspaceElement(\n target: ReogridMountTarget | undefined,\n fallbackId: string,\n): HTMLElement {\n if (target instanceof HTMLElement) {\n return target;\n }\n\n if (typeof target === 'string') {\n const element = document.querySelector<HTMLElement>(target);\n if (element) {\n return element;\n }\n throw new Error(`Workspace element \"${target}\" was not found.`);\n }\n\n const fallback = document.getElementById(fallbackId);\n if (fallback instanceof HTMLElement) {\n return fallback;\n }\n\n throw new Error(`Workspace element \"#${fallbackId}\" was not found.`);\n}\n\nfunction ensureWorkspaceSurface(workspace: HTMLElement, canvasId: string): WorkspaceSurface {\n if (workspace.dataset[WORKSPACE_DATASET_FLAG]) {\n throw new Error('A ReoGrid instance is already mounted on this workspace.');\n }\n\n const doc = workspace.ownerDocument ?? document;\n workspace.classList.add(WORKSPACE_CLASS);\n\n let workbook = workspace.querySelector<HTMLDivElement>(`.${WORKBOOK_CLASS}`);\n if (!workbook) {\n workbook = doc.createElement('div');\n workbook.className = WORKBOOK_CLASS;\n workspace.appendChild(workbook);\n }\n\n let worksheetContainer = workbook.querySelector<HTMLDivElement>(`.${WORKSHEET_CONTAINER_CLASS}`);\n if (!worksheetContainer) {\n worksheetContainer = doc.createElement('div');\n worksheetContainer.className = WORKSHEET_CONTAINER_CLASS;\n workbook.appendChild(worksheetContainer);\n }\n\n let scrollContainer = worksheetContainer.querySelector<HTMLDivElement>(`.${GRID_SCROLL_CLASS}`);\n if (!scrollContainer) {\n scrollContainer = doc.createElement('div');\n scrollContainer.className = GRID_SCROLL_CLASS;\n worksheetContainer.appendChild(scrollContainer);\n }\n\n let spacer = scrollContainer.querySelector<HTMLDivElement>(`.${GRID_SPACER_CLASS}`);\n if (!spacer) {\n spacer = doc.createElement('div');\n spacer.className = GRID_SPACER_CLASS;\n scrollContainer.appendChild(spacer);\n }\n\n let canvas = worksheetContainer.querySelector<HTMLCanvasElement>(`#${canvasId}`);\n if (!canvas) {\n canvas = doc.createElement('canvas');\n canvas.id = canvasId;\n worksheetContainer.appendChild(canvas);\n }\n canvas.classList.add(GRID_LAYER_CLASS);\n\n workspace.dataset[WORKSPACE_DATASET_FLAG] = 'true';\n\n return { canvas, scrollContainer, spacer, worksheetContainer };\n}\n\nfunction initCanvasWorksheet(\n surface: WorkspaceSurface,\n constraints: { maxRows?: number; maxCols?: number },\n worksheetOptions?: import('./core/worksheet/worksheet').WorksheetOptions,\n): {\n worksheet: CanvasWorksheet;\n destroy: () => void;\n} {\n const worksheet = new CanvasWorksheet(surface.canvas, constraints, worksheetOptions);\n\n const syncScrollFromWorksheet = (): void => {\n const { x, y } = worksheet.getScrollOffset();\n if (Math.abs(surface.scrollContainer.scrollLeft - x) > 0.5) {\n surface.scrollContainer.scrollLeft = x;\n }\n if (Math.abs(surface.scrollContainer.scrollTop - y) > 0.5) {\n surface.scrollContainer.scrollTop = y;\n }\n };\n\n const updateSpacerSize = (): void => {\n const size = worksheet.getScrollContentSize();\n const frozenWidth = worksheet.getFrozenWidth();\n const frozenHeight = worksheet.getFrozenHeight();\n // Spacer represents the scrollable content only (excludes frozen area and headers)\n surface.spacer.style.width = `${Math.max(0, size.width - worksheet.headerColumnWidth - frozenWidth)}px`;\n surface.spacer.style.height = `${Math.max(0, size.height - worksheet.headerRowHeight - frozenHeight)}px`;\n syncScrollFromWorksheet();\n };\n\n const handleScroll = (): void => {\n worksheet.setScrollOffset(\n surface.scrollContainer.scrollLeft,\n surface.scrollContainer.scrollTop,\n );\n };\n\n const handleWheel = (event: WheelEvent): void => {\n if (event.ctrlKey || event.metaKey) {\n return;\n }\n surface.scrollContainer.scrollBy({\n left: event.deltaX,\n top: event.deltaY,\n behavior: 'auto',\n });\n event.preventDefault();\n };\n\n const handleResize = (): void => {\n worksheet.resize();\n };\n\n const positionScrollContainer = (): void => {\n const frozenWidth = worksheet.getFrozenWidth();\n const frozenHeight = worksheet.getFrozenHeight();\n surface.scrollContainer.style.top = `${worksheet.headerRowHeight + frozenHeight}px`;\n surface.scrollContainer.style.left = `${worksheet.headerColumnWidth + frozenWidth}px`;\n surface.scrollContainer.style.right = '0';\n surface.scrollContainer.style.bottom = '0';\n };\n\n surface.scrollContainer.addEventListener('scroll', handleScroll);\n surface.worksheetContainer.addEventListener('wheel', handleWheel, WHEEL_LISTENER_OPTIONS);\n const stopScrollbarPointerEvents = (event: MouseEvent): void => {\n if (isPointerEventOnScrollbar(event, surface.scrollContainer)) {\n event.stopPropagation();\n }\n };\n surface.scrollContainer.addEventListener('mousedown', stopScrollbarPointerEvents);\n surface.scrollContainer.addEventListener('dblclick', stopScrollbarPointerEvents);\n\n const unsubscribeViewport = worksheet.onViewportSizeChange(updateSpacerSize);\n const unsubscribeScroll = worksheet.onScrollChange(syncScrollFromWorksheet);\n const detachStructureListener = worksheet.onStructureChange(positionScrollContainer);\n const detachViewportSizeListener = worksheet.onViewportSizeChange(positionScrollContainer);\n\n if (typeof window !== 'undefined') {\n window.addEventListener('resize', handleResize);\n }\n\n updateSpacerSize();\n positionScrollContainer();\n\n return {\n worksheet,\n destroy: () => {\n surface.scrollContainer.removeEventListener('scroll', handleScroll);\n surface.scrollContainer.removeEventListener('mousedown', stopScrollbarPointerEvents);\n surface.scrollContainer.removeEventListener('dblclick', stopScrollbarPointerEvents);\n surface.worksheetContainer.removeEventListener('wheel', handleWheel, WHEEL_LISTENER_OPTIONS);\n if (typeof window !== 'undefined') {\n window.removeEventListener('resize', handleResize);\n }\n unsubscribeViewport();\n unsubscribeScroll();\n detachStructureListener();\n detachViewportSizeListener();\n },\n };\n}\n\nfunction isPointerEventOnScrollbar(event: MouseEvent, container: HTMLDivElement): boolean {\n const rect = container.getBoundingClientRect();\n const verticalScrollbarWidth = rect.width - container.clientWidth;\n const horizontalScrollbarHeight = rect.height - container.clientHeight;\n const isOverVerticalScrollbar =\n verticalScrollbarWidth > 0 && event.clientX >= rect.right - verticalScrollbarWidth;\n const isOverHorizontalScrollbar =\n horizontalScrollbarHeight > 0 && event.clientY >= rect.bottom - horizontalScrollbarHeight;\n return isOverVerticalScrollbar || isOverHorizontalScrollbar;\n}\n\nfunction attachFontRenderSync(worksheet: CanvasWorksheet): () => void {\n if (typeof document === 'undefined' || typeof document.fonts === 'undefined') {\n return () => {};\n }\n const fonts = document.fonts;\n let disposed = false;\n const rerender = (): void => {\n if (!disposed) {\n worksheet.render();\n }\n };\n if (fonts.ready && typeof fonts.ready.then === 'function') {\n fonts.ready.then(rerender).catch(() => {});\n }\n const handleLoadingDone = (): void => {\n rerender();\n };\n if (typeof fonts.addEventListener === 'function' && typeof fonts.removeEventListener === 'function') {\n fonts.addEventListener('loadingdone', handleLoadingDone);\n return () => {\n disposed = true;\n fonts.removeEventListener('loadingdone', handleLoadingDone);\n };\n }\n return () => {\n disposed = true;\n };\n}\n\nexport { CanvasWorksheet } from './core/worksheet';\nexport type { CellStyleInput } from './core/worksheet/handles';\nexport type {\n WorksheetImageInfo,\n WorksheetImagePlacement,\n WorksheetImageAnchorPosition,\n SaveXlsxOptions,\n LoadXlsxOptions,\n} from './core/worksheet/canvasWorksheet';\nexport type { TextAlign, VerticalAlign, CellStyle } from './core/style/cellStyle';\nexport type { CellTypeConfig, CheckboxConfig, DropdownConfig, DropdownClickContext } from './core/cell/cellTypeRegistry';\nexport { DropdownOverlay } from './render/editor/dropdownOverlay';\nexport { FilterDropdownOverlay } from './render/editor/filterDropdownOverlay';\nexport { AutoColumnFilter } from './core/filter/autoColumnFilter';\nexport type { AutoFilterConfig, ColumnFilterState, FilterChangeEvent } from './core/filter/types';\nexport type { SortOrder, SortConfig, SortResult, SortEvent } from './core/sort/types';\nexport type { MergedCellRange } from './core/cell/types';\nexport type {\n ContextMenuEvent,\n RowHeaderContextMenu,\n ColumnHeaderContextMenu,\n CellContextMenu,\n CornerContextMenu,\n} from './core/worksheet/types';\nexport { Worksheet } from './core/worksheet/worksheet';\nexport { ActionManager, ActionGroup } from './core/action';\nexport type { WorksheetAction } from './core/action';\nexport {\n SetCellInputAction,\n SetCellStyleAction,\n createSetRangeStyleAction,\n SetColumnWidthAction,\n SetRowHeightAction,\n SetRangeBorderAction,\n MergeCellsAction,\n UnmergeCellsAction,\n SetCellNumberFormatAction,\n SetRowHiddenAction,\n SetColumnHiddenAction,\n InsertRowsAction,\n DeleteRowsAction,\n InsertColumnsAction,\n DeleteColumnsAction,\n SortColumnAction,\n} from './core/action';\nexport {\n GroupRowsAction,\n UngroupRowsAction,\n GroupColumnsAction,\n UngroupColumnsAction,\n ToggleOutlineAction,\n CollapseToLevelAction,\n} from './core/action';\nexport { CellEditor } from './render/editor/cellEditor';\nexport { PointerController } from './render/controllers/pointerController';\nexport { KeyboardController } from './render/controllers/keyboardController';\nexport { ClipboardService, PasteAction, ClearRangeAction } from './core/clipboard';\nexport * from './constants';\nexport { buildXlsxFromSnapshot } from './io/xlsxWriter';\nexport { NumberFormat } from './core/style/numberFormatUtils';\nexport { printWorksheet } from './print/printWorksheet';\nexport type { PrintOptions } from './print/printWorksheet';\nexport type { CellTypeHandler, CellTypeRenderContext, CellTypeClickContext, CellTypeClickResult } from './core/cell/cellTypeHandler';\nexport { registerCellTypeHandler, getCellTypeHandler } from './core/cell/cellTypeRegistry';\nexport type {\n ButtonConfig,\n ProgressConfig,\n RatingConfig,\n SparklineLineConfig,\n SparklineAreaConfig,\n HyperlinkConfig,\n} from './core/cell/cellTypeRegistry';\n\n// Register all built-in cell type handlers\nimport './core/cell/handlers';\n","import { createReogrid as createReogridCore, type ReogridInstance, type ReogridOptions } from '../index';\n\nexport type { ReogridInstance };\nexport type { ReogridOptions };\n\n// ── Lite restriction constants ────────────────────────────────────────────────\nconst LITE_MAX_ROWS = 100;\nconst LITE_MAX_COLS = 26; // A–Z\n\nfunction applyLiteRestrictions(instance: ReogridInstance): void {\n // xlsx export is not available without a valid license\n instance.worksheet.saveAsXlsx = () => {\n console.warn(\n '[ReoGrid Pro] xlsx export requires a valid license key. ' +\n 'Visit https://unvell.com/portal to manage your license.',\n );\n };\n}\n\n// ── License validation ────────────────────────────────────────────────────────\n\ninterface LicenseCache {\n valid: boolean;\n cachedAt: number;\n plan?: string;\n expiresAt?: string | null;\n}\n\nconst CACHE_KEY = '__reogrid_pro_license__';\nconst CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000; // re-validate after 7 days\nconst GRACE_PERIOD_MS = 30 * 24 * 60 * 60 * 1000; // offline grace: 30 days\n\nfunction readCache(): LicenseCache | null {\n try {\n if (typeof localStorage !== 'undefined') {\n const raw = localStorage.getItem(CACHE_KEY);\n if (raw) return JSON.parse(raw) as LicenseCache;\n }\n } catch { /* ignore */ }\n return null;\n}\n\nfunction writeCache(data: LicenseCache): void {\n try {\n if (typeof localStorage !== 'undefined') {\n localStorage.setItem(CACHE_KEY, JSON.stringify(data));\n }\n } catch { /* ignore */ }\n}\n\nasync function validateRemote(key: string, endpoint: string): Promise<LicenseCache> {\n const res = await fetch(`${endpoint}/reogrid/license/validate`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ key }),\n });\n const data = await res.json() as { valid: boolean; plan?: string; expiresAt?: string | null };\n return {\n valid: !!data.valid,\n plan: data.plan,\n expiresAt: data.expiresAt,\n cachedAt: Date.now(),\n };\n}\n\nasync function checkLicense(key: string, endpoint: string): Promise<boolean> {\n const cached = readCache();\n const now = Date.now();\n\n // Cache still fresh — skip network call\n if (cached && now - cached.cachedAt < CACHE_TTL_MS) {\n return cached.valid;\n }\n\n try {\n const result = await validateRemote(key, endpoint);\n writeCache(result);\n if (!result.valid) {\n console.warn('[ReoGrid Pro] License validation failed. Please check your license key.');\n }\n return result.valid;\n } catch {\n // Server unreachable — fall back to cached result within grace period\n if (cached && now - cached.cachedAt < GRACE_PERIOD_MS) {\n console.warn('[ReoGrid Pro] License server unreachable. Using cached result (grace period).');\n return cached.valid;\n }\n console.warn('[ReoGrid Pro] License server unreachable and no valid cache. License unverified.');\n return false;\n }\n}\n\n/** Read cached license validity synchronously (for immediate grid sizing). */\nfunction isCachedValid(): boolean | null {\n const cached = readCache();\n if (!cached) return null; // no cache — unknown\n const now = Date.now();\n if (now - cached.cachedAt < GRACE_PERIOD_MS) return cached.valid;\n return null; // cache too old — unknown\n}\n\n// ── Public API ────────────────────────────────────────────────────────────────\n\nexport interface ReogridProOptions extends ReogridOptions {\n /**\n * Your ReoGrid Pro license key (issued from the Unvell customer portal).\n */\n licenseKey?: string;\n\n /**\n * License validation endpoint base URL.\n * Defaults to the official Unvell API server.\n */\n licenseEndpoint?: string;\n}\n\nconst DEFAULT_ENDPOINT = 'https://api.unvell.com';\n\n/**\n * Creates a ReoGrid Pro instance with license validation.\n *\n * Grid sizing is determined synchronously from cached license state:\n * - Cached valid → unlimited rows/cols\n * - Cached invalid or no cache → Lite limits (100 rows × 26 cols) as safe default\n *\n * After async validation completes, xlsx export may be disabled on failure.\n * If the cached state changes, a reload is recommended.\n */\nexport function createReogrid(options: ReogridProOptions = {}): ReogridInstance {\n const { licenseKey, licenseEndpoint = DEFAULT_ENDPOINT, ...gridOptions } = options;\n\n if (!licenseKey) {\n // No key — apply Lite limits immediately\n console.warn(\n '[ReoGrid Pro] No license key provided. ' +\n 'A license key is required for production use. ' +\n 'Visit https://unvell.com/portal to obtain one.',\n );\n const instance = createReogridCore({\n ...gridOptions,\n maxRows: LITE_MAX_ROWS,\n maxCols: LITE_MAX_COLS,\n });\n applyLiteRestrictions(instance);\n return instance;\n }\n\n // Determine grid limits from synchronous cache check\n const cachedValid = isCachedValid();\n const startWithLimits = cachedValid === false; // only restrict when we know it's invalid\n\n const instance = createReogridCore({\n ...gridOptions,\n ...(startWithLimits ? { maxRows: LITE_MAX_ROWS, maxCols: LITE_MAX_COLS } : {}),\n });\n\n if (startWithLimits) {\n applyLiteRestrictions(instance);\n }\n\n // Async validation — updates cache and applies restrictions if invalid\n checkLicense(licenseKey, licenseEndpoint).then(valid => {\n if (!valid) {\n console.warn(\n '[ReoGrid Pro] Invalid or expired license key. ' +\n 'Visit https://unvell.com/portal to manage your license.',\n );\n // Disable xlsx export retroactively if not already done\n if (!startWithLimits) {\n applyLiteRestrictions(instance);\n // Note: row/col limits cannot be applied retroactively — a page reload\n // will pick up the cached invalid state and start with Lite limits.\n }\n }\n });\n\n return instance;\n}\n"],"mappings":"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","names":["n","left","right","cellKey","parseCellKey","parseCellKey","parseCellKey","r","parseCellKey","HEADER_DROPDOWN_BUTTON_WIDTH","textDecoder","valueNode","decodeUtf8","LOCAL_FILE_HEADER_SIGNATURE","parseCellKey","toShow","lines","maxWidth","width","height","parseValues","createReogrid","instance","createReogrid"]}