@ricsam/formula-engine 0.0.9 → 0.0.10

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.
@@ -35,6 +35,7 @@ module.exports = __toCommonJS(exports_copy_manager);
35
35
  var import_parser = require("../../parser/parser.cjs");
36
36
  var import_formatter = require("../../parser/formatter.cjs");
37
37
  var import_ast_traverser = require("../ast-traverser.cjs");
38
+ var import_range_utils = require("../utils/range-utils.cjs");
38
39
 
39
40
  class CopyManager {
40
41
  workbookManager;
@@ -183,29 +184,35 @@ class CopyManager {
183
184
  const allCellStyles = this.styleManager.getAllCellStyles();
184
185
  const sourceRange = this.getBoundingBox(sourceCells);
185
186
  for (const style of allConditionalStyles) {
186
- if (style.area.workbookName === sourceTopLeft.workbookName && style.area.sheetName === sourceTopLeft.sheetName && this.rangesIntersect(style.area.range, sourceRange)) {
187
- const newStyle = {
188
- area: {
189
- workbookName: target.workbookName,
190
- sheetName: target.sheetName,
191
- range: this.adjustRange(style.area.range, rowOffset, colOffset)
192
- },
193
- condition: style.condition
194
- };
195
- this.styleManager.addConditionalStyle(newStyle);
187
+ if (style.area.workbookName === sourceTopLeft.workbookName && style.area.sheetName === sourceTopLeft.sheetName) {
188
+ const intersection = import_range_utils.intersectRanges(style.area.range, sourceRange);
189
+ if (intersection) {
190
+ const newStyle = {
191
+ area: {
192
+ workbookName: target.workbookName,
193
+ sheetName: target.sheetName,
194
+ range: this.adjustRange(intersection, rowOffset, colOffset)
195
+ },
196
+ condition: style.condition
197
+ };
198
+ this.styleManager.addConditionalStyle(newStyle);
199
+ }
196
200
  }
197
201
  }
198
202
  for (const style of allCellStyles) {
199
- if (style.area.workbookName === sourceTopLeft.workbookName && style.area.sheetName === sourceTopLeft.sheetName && this.rangesIntersect(style.area.range, sourceRange)) {
200
- const newStyle = {
201
- area: {
202
- workbookName: target.workbookName,
203
- sheetName: target.sheetName,
204
- range: this.adjustRange(style.area.range, rowOffset, colOffset)
205
- },
206
- style: style.style
207
- };
208
- this.styleManager.addCellStyle(newStyle);
203
+ if (style.area.workbookName === sourceTopLeft.workbookName && style.area.sheetName === sourceTopLeft.sheetName) {
204
+ const intersection = import_range_utils.intersectRanges(style.area.range, sourceRange);
205
+ if (intersection) {
206
+ const newStyle = {
207
+ area: {
208
+ workbookName: target.workbookName,
209
+ sheetName: target.sheetName,
210
+ range: this.adjustRange(intersection, rowOffset, colOffset)
211
+ },
212
+ style: style.style
213
+ };
214
+ this.styleManager.addCellStyle(newStyle);
215
+ }
209
216
  }
210
217
  }
211
218
  }
@@ -228,15 +235,6 @@ class CopyManager {
228
235
  }
229
236
  };
230
237
  }
231
- rangesIntersect(range1, range2) {
232
- const r1EndCol = range1.end.col.type === "number" ? range1.end.col.value : Infinity;
233
- const r1EndRow = range1.end.row.type === "number" ? range1.end.row.value : Infinity;
234
- const r2EndCol = range2.end.col.type === "number" ? range2.end.col.value : Infinity;
235
- const r2EndRow = range2.end.row.type === "number" ? range2.end.row.value : Infinity;
236
- const colOverlap = range1.start.col <= r2EndCol && range2.start.col <= r1EndCol;
237
- const rowOverlap = range1.start.row <= r2EndRow && range2.start.row <= r1EndRow;
238
- return colOverlap && rowOverlap;
239
- }
240
238
  adjustRange(range, rowOffset, colOffset) {
241
239
  return {
242
240
  start: {
@@ -263,4 +261,4 @@ class CopyManager {
263
261
  }
264
262
  }
265
263
 
266
- //# debugId=A0756D3B2D95576C64756E2164756E21
264
+ //# debugId=75D1B0CA340D7EDA64756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/core/managers/copy-manager.ts"],
4
4
  "sourcesContent": [
5
- "/**\n * CopyManager - Manages cell copy/paste operations\n */\n\nimport type {\n CellAddress,\n CopyCellsOptions,\n ConditionalStyle,\n DirectCellStyle,\n LocalCellAddress,\n SerializedCellValue,\n SpreadsheetRange,\n} from \"../types.cjs\";\nimport type { WorkbookManager } from \"./workbook-manager.cjs\";\nimport type { EvaluationManager } from \"./evaluation-manager.cjs\";\nimport type { StyleManager } from \"./style-manager.cjs\";\nimport { parseFormula } from \"../../parser/parser.cjs\";\nimport { astToString } from \"../../parser/formatter.cjs\";\nimport { transformAST } from \"../ast-traverser.cjs\";\nimport type { ReferenceNode, RangeNode } from \"../../parser/ast.cjs\";\nimport { isCellInRange } from \"../utils.cjs\";\n\nexport class CopyManager {\n constructor(\n private workbookManager: WorkbookManager,\n private evaluationManager: EvaluationManager,\n private styleManager: StyleManager\n ) {}\n\n /**\n * Copy cells from source to target\n */\n copyCells(\n source: CellAddress[],\n target: CellAddress,\n options: CopyCellsOptions\n ): void {\n if (source.length === 0) {\n return;\n }\n\n // Find top-left cell of source (minimum row/col indices)\n const topLeft = this.findTopLeft(source);\n\n // Calculate offset from source top-left to target\n const rowOffset = target.rowIndex - topLeft.rowIndex;\n const colOffset = target.colIndex - topLeft.colIndex;\n\n // Copy cell contents\n for (const sourceCell of source) {\n const targetCell: CellAddress = {\n workbookName: target.workbookName,\n sheetName: target.sheetName,\n colIndex: sourceCell.colIndex + colOffset,\n rowIndex: sourceCell.rowIndex + rowOffset,\n };\n\n this.copyCellContent(sourceCell, targetCell, topLeft, options);\n }\n\n // Copy formatting if requested\n if (options.formatting) {\n this.copyFormatting(source, topLeft, target, rowOffset, colOffset);\n }\n\n // Clear source cells if cut\n if (options.cut) {\n this.clearSourceCells(source);\n }\n }\n\n /**\n * Find the top-left cell (minimum row/col indices)\n */\n private findTopLeft(cells: CellAddress[]): CellAddress {\n let minRow = Infinity;\n let minCol = Infinity;\n let topLeftCell = cells[0]!;\n\n for (const cell of cells) {\n if (\n cell.rowIndex < minRow ||\n (cell.rowIndex === minRow && cell.colIndex < minCol)\n ) {\n minRow = cell.rowIndex;\n minCol = cell.colIndex;\n topLeftCell = cell;\n }\n }\n\n return topLeftCell;\n }\n\n /**\n * Copy content from one cell to another\n */\n private copyCellContent(\n sourceCell: CellAddress,\n targetCell: CellAddress,\n sourceTopLeft: CellAddress,\n options: CopyCellsOptions\n ): void {\n const sheet = this.workbookManager.getSheet({\n workbookName: sourceCell.workbookName,\n sheetName: sourceCell.sheetName,\n });\n\n if (!sheet) {\n return;\n }\n\n const key = `${String.fromCharCode(65 + sourceCell.colIndex)}${\n sourceCell.rowIndex + 1\n }`;\n const cellContent = sheet.content.get(key);\n\n if (!cellContent) {\n // Source cell is empty\n return;\n }\n\n let targetContent: SerializedCellValue;\n\n if (options.type === \"value\") {\n // Copy evaluated value\n const evalResult = this.evaluationManager.getCellEvaluationResult(sourceCell);\n \n if (!evalResult || evalResult.type !== \"value\") {\n // If evaluation failed or is not a value, copy as-is\n targetContent = cellContent;\n } else {\n // Convert to literal value\n const result = evalResult.result;\n if (result.type === \"number\") {\n targetContent = result.value;\n } else if (result.type === \"string\") {\n targetContent = result.value;\n } else if (result.type === \"boolean\") {\n targetContent = result.value;\n } else {\n // Error or other type, copy as-is\n targetContent = cellContent;\n }\n }\n } else {\n // Copy formula\n if (typeof cellContent === \"string\" && cellContent.startsWith(\"=\")) {\n // Adjust formula references\n targetContent = this.adjustFormulaReferences(\n cellContent,\n {\n colIndex: sourceCell.colIndex,\n rowIndex: sourceCell.rowIndex,\n },\n {\n colIndex: targetCell.colIndex,\n rowIndex: targetCell.rowIndex,\n }\n );\n } else {\n // Not a formula, copy as-is\n targetContent = cellContent;\n }\n }\n\n // Set target cell content (using the engine's method through workbook manager)\n const targetSheet = this.workbookManager.getSheet({\n workbookName: targetCell.workbookName,\n sheetName: targetCell.sheetName,\n });\n\n if (targetSheet) {\n const targetKey = `${String.fromCharCode(65 + targetCell.colIndex)}${\n targetCell.rowIndex + 1\n }`;\n targetSheet.content.set(targetKey, targetContent);\n }\n }\n\n /**\n * Adjust formula references when copying\n * Based on autofill-utils.ts adjustFormulaReferences\n */\n private adjustFormulaReferences(\n formula: string,\n sourceAddress: LocalCellAddress,\n targetAddress: LocalCellAddress\n ): string {\n try {\n const ast = parseFormula(formula.slice(1)); // Remove the \"=\" sign\n\n const rowDelta = targetAddress.rowIndex - sourceAddress.rowIndex;\n const colDelta = targetAddress.colIndex - sourceAddress.colIndex;\n\n const adjustedAst = transformAST(ast, (node) => {\n if (node.type === \"reference\") {\n const refNode = node as ReferenceNode;\n return {\n ...refNode,\n address: {\n colIndex: refNode.isAbsolute.col\n ? refNode.address.colIndex\n : refNode.address.colIndex + colDelta,\n rowIndex: refNode.isAbsolute.row\n ? refNode.address.rowIndex\n : refNode.address.rowIndex + rowDelta,\n },\n };\n } else if (node.type === \"range\") {\n const rangeNode = node as RangeNode;\n return {\n ...rangeNode,\n range: {\n start: {\n col: rangeNode.isAbsolute.start.col\n ? rangeNode.range.start.col\n : rangeNode.range.start.col + colDelta,\n row: rangeNode.isAbsolute.start.row\n ? rangeNode.range.start.row\n : rangeNode.range.start.row + rowDelta,\n },\n end: {\n col:\n rangeNode.range.end.col.type === \"number\"\n ? rangeNode.isAbsolute.end.col\n ? rangeNode.range.end.col\n : {\n type: \"number\" as const,\n value: rangeNode.range.end.col.value + colDelta,\n }\n : rangeNode.range.end.col,\n row:\n rangeNode.range.end.row.type === \"number\"\n ? rangeNode.isAbsolute.end.row\n ? rangeNode.range.end.row\n : {\n type: \"number\" as const,\n value: rangeNode.range.end.row.value + rowDelta,\n }\n : rangeNode.range.end.row,\n },\n },\n };\n }\n return node;\n });\n\n return `=${astToString(adjustedAst)}`;\n } catch (error) {\n // If parsing fails, return the original formula\n console.warn(\"Failed to adjust formula references:\", error);\n return formula;\n }\n }\n\n /**\n * Copy formatting (cellStyles and conditionalStyles) from source to target\n */\n private copyFormatting(\n sourceCells: CellAddress[],\n sourceTopLeft: CellAddress,\n target: CellAddress,\n rowOffset: number,\n colOffset: number\n ): void {\n // Get all styles for the source workbook\n const allConditionalStyles = this.styleManager.getAllConditionalStyles();\n const allCellStyles = this.styleManager.getAllCellStyles();\n\n // Find styles that intersect with source cells\n const sourceRange = this.getBoundingBox(sourceCells);\n\n // Copy conditional styles\n for (const style of allConditionalStyles) {\n if (\n style.area.workbookName === sourceTopLeft.workbookName &&\n style.area.sheetName === sourceTopLeft.sheetName &&\n this.rangesIntersect(style.area.range, sourceRange)\n ) {\n // Create a new style with adjusted range\n const newStyle: ConditionalStyle = {\n area: {\n workbookName: target.workbookName,\n sheetName: target.sheetName,\n range: this.adjustRange(style.area.range, rowOffset, colOffset),\n },\n condition: style.condition,\n };\n this.styleManager.addConditionalStyle(newStyle);\n }\n }\n\n // Copy cell styles\n for (const style of allCellStyles) {\n if (\n style.area.workbookName === sourceTopLeft.workbookName &&\n style.area.sheetName === sourceTopLeft.sheetName &&\n this.rangesIntersect(style.area.range, sourceRange)\n ) {\n // Create a new style with adjusted range\n const newStyle: DirectCellStyle = {\n area: {\n workbookName: target.workbookName,\n sheetName: target.sheetName,\n range: this.adjustRange(style.area.range, rowOffset, colOffset),\n },\n style: style.style,\n };\n this.styleManager.addCellStyle(newStyle);\n }\n }\n }\n\n /**\n * Get bounding box for a set of cells\n */\n private getBoundingBox(cells: CellAddress[]): SpreadsheetRange {\n let minRow = Infinity;\n let maxRow = -Infinity;\n let minCol = Infinity;\n let maxCol = -Infinity;\n\n for (const cell of cells) {\n minRow = Math.min(minRow, cell.rowIndex);\n maxRow = Math.max(maxRow, cell.rowIndex);\n minCol = Math.min(minCol, cell.colIndex);\n maxCol = Math.max(maxCol, cell.colIndex);\n }\n\n return {\n start: { col: minCol, row: minRow },\n end: {\n col: { type: \"number\", value: maxCol },\n row: { type: \"number\", value: maxRow },\n },\n };\n }\n\n /**\n * Check if two ranges intersect\n */\n private rangesIntersect(\n range1: SpreadsheetRange,\n range2: SpreadsheetRange\n ): boolean {\n // Get finite end values\n const r1EndCol =\n range1.end.col.type === \"number\" ? range1.end.col.value : Infinity;\n const r1EndRow =\n range1.end.row.type === \"number\" ? range1.end.row.value : Infinity;\n const r2EndCol =\n range2.end.col.type === \"number\" ? range2.end.col.value : Infinity;\n const r2EndRow =\n range2.end.row.type === \"number\" ? range2.end.row.value : Infinity;\n\n // Check if ranges overlap\n const colOverlap =\n range1.start.col <= r2EndCol && range2.start.col <= r1EndCol;\n const rowOverlap =\n range1.start.row <= r2EndRow && range2.start.row <= r1EndRow;\n\n return colOverlap && rowOverlap;\n }\n\n /**\n * Adjust a range by row and column offsets\n */\n private adjustRange(\n range: SpreadsheetRange,\n rowOffset: number,\n colOffset: number\n ): SpreadsheetRange {\n return {\n start: {\n col: range.start.col + colOffset,\n row: range.start.row + rowOffset,\n },\n end: {\n col:\n range.end.col.type === \"number\"\n ? { type: \"number\", value: range.end.col.value + colOffset }\n : range.end.col,\n row:\n range.end.row.type === \"number\"\n ? { type: \"number\", value: range.end.row.value + rowOffset }\n : range.end.row,\n },\n };\n }\n\n /**\n * Clear source cells (for cut operation)\n */\n private clearSourceCells(cells: CellAddress[]): void {\n for (const cell of cells) {\n const sheet = this.workbookManager.getSheet({\n workbookName: cell.workbookName,\n sheetName: cell.sheetName,\n });\n\n if (sheet) {\n const key = `${String.fromCharCode(65 + cell.colIndex)}${\n cell.rowIndex + 1\n }`;\n sheet.content.delete(key);\n }\n }\n }\n}\n\n"
5
+ "/**\n * CopyManager - Manages cell copy/paste operations\n */\n\nimport type {\n CellAddress,\n CopyCellsOptions,\n ConditionalStyle,\n DirectCellStyle,\n LocalCellAddress,\n SerializedCellValue,\n SpreadsheetRange,\n} from \"../types.cjs\";\nimport type { WorkbookManager } from \"./workbook-manager.cjs\";\nimport type { EvaluationManager } from \"./evaluation-manager.cjs\";\nimport type { StyleManager } from \"./style-manager.cjs\";\nimport { parseFormula } from \"../../parser/parser.cjs\";\nimport { astToString } from \"../../parser/formatter.cjs\";\nimport { transformAST } from \"../ast-traverser.cjs\";\nimport type { ReferenceNode, RangeNode } from \"../../parser/ast.cjs\";\nimport { isCellInRange } from \"../utils.cjs\";\nimport { intersectRanges } from \"../utils/range-utils.cjs\";\n\nexport class CopyManager {\n constructor(\n private workbookManager: WorkbookManager,\n private evaluationManager: EvaluationManager,\n private styleManager: StyleManager\n ) {}\n\n /**\n * Copy cells from source to target\n */\n copyCells(\n source: CellAddress[],\n target: CellAddress,\n options: CopyCellsOptions\n ): void {\n if (source.length === 0) {\n return;\n }\n\n // Find top-left cell of source (minimum row/col indices)\n const topLeft = this.findTopLeft(source);\n\n // Calculate offset from source top-left to target\n const rowOffset = target.rowIndex - topLeft.rowIndex;\n const colOffset = target.colIndex - topLeft.colIndex;\n\n // Copy cell contents\n for (const sourceCell of source) {\n const targetCell: CellAddress = {\n workbookName: target.workbookName,\n sheetName: target.sheetName,\n colIndex: sourceCell.colIndex + colOffset,\n rowIndex: sourceCell.rowIndex + rowOffset,\n };\n\n this.copyCellContent(sourceCell, targetCell, topLeft, options);\n }\n\n // Copy formatting if requested\n if (options.formatting) {\n this.copyFormatting(source, topLeft, target, rowOffset, colOffset);\n }\n\n // Clear source cells if cut\n if (options.cut) {\n this.clearSourceCells(source);\n }\n }\n\n /**\n * Find the top-left cell (minimum row/col indices)\n */\n private findTopLeft(cells: CellAddress[]): CellAddress {\n let minRow = Infinity;\n let minCol = Infinity;\n let topLeftCell = cells[0]!;\n\n for (const cell of cells) {\n if (\n cell.rowIndex < minRow ||\n (cell.rowIndex === minRow && cell.colIndex < minCol)\n ) {\n minRow = cell.rowIndex;\n minCol = cell.colIndex;\n topLeftCell = cell;\n }\n }\n\n return topLeftCell;\n }\n\n /**\n * Copy content from one cell to another\n */\n private copyCellContent(\n sourceCell: CellAddress,\n targetCell: CellAddress,\n sourceTopLeft: CellAddress,\n options: CopyCellsOptions\n ): void {\n const sheet = this.workbookManager.getSheet({\n workbookName: sourceCell.workbookName,\n sheetName: sourceCell.sheetName,\n });\n\n if (!sheet) {\n return;\n }\n\n const key = `${String.fromCharCode(65 + sourceCell.colIndex)}${\n sourceCell.rowIndex + 1\n }`;\n const cellContent = sheet.content.get(key);\n\n if (!cellContent) {\n // Source cell is empty\n return;\n }\n\n let targetContent: SerializedCellValue;\n\n if (options.type === \"value\") {\n // Copy evaluated value\n const evalResult = this.evaluationManager.getCellEvaluationResult(sourceCell);\n \n if (!evalResult || evalResult.type !== \"value\") {\n // If evaluation failed or is not a value, copy as-is\n targetContent = cellContent;\n } else {\n // Convert to literal value\n const result = evalResult.result;\n if (result.type === \"number\") {\n targetContent = result.value;\n } else if (result.type === \"string\") {\n targetContent = result.value;\n } else if (result.type === \"boolean\") {\n targetContent = result.value;\n } else {\n // Error or other type, copy as-is\n targetContent = cellContent;\n }\n }\n } else {\n // Copy formula\n if (typeof cellContent === \"string\" && cellContent.startsWith(\"=\")) {\n // Adjust formula references\n targetContent = this.adjustFormulaReferences(\n cellContent,\n {\n colIndex: sourceCell.colIndex,\n rowIndex: sourceCell.rowIndex,\n },\n {\n colIndex: targetCell.colIndex,\n rowIndex: targetCell.rowIndex,\n }\n );\n } else {\n // Not a formula, copy as-is\n targetContent = cellContent;\n }\n }\n\n // Set target cell content (using the engine's method through workbook manager)\n const targetSheet = this.workbookManager.getSheet({\n workbookName: targetCell.workbookName,\n sheetName: targetCell.sheetName,\n });\n\n if (targetSheet) {\n const targetKey = `${String.fromCharCode(65 + targetCell.colIndex)}${\n targetCell.rowIndex + 1\n }`;\n targetSheet.content.set(targetKey, targetContent);\n }\n }\n\n /**\n * Adjust formula references when copying\n * Based on autofill-utils.ts adjustFormulaReferences\n */\n private adjustFormulaReferences(\n formula: string,\n sourceAddress: LocalCellAddress,\n targetAddress: LocalCellAddress\n ): string {\n try {\n const ast = parseFormula(formula.slice(1)); // Remove the \"=\" sign\n\n const rowDelta = targetAddress.rowIndex - sourceAddress.rowIndex;\n const colDelta = targetAddress.colIndex - sourceAddress.colIndex;\n\n const adjustedAst = transformAST(ast, (node) => {\n if (node.type === \"reference\") {\n const refNode = node as ReferenceNode;\n return {\n ...refNode,\n address: {\n colIndex: refNode.isAbsolute.col\n ? refNode.address.colIndex\n : refNode.address.colIndex + colDelta,\n rowIndex: refNode.isAbsolute.row\n ? refNode.address.rowIndex\n : refNode.address.rowIndex + rowDelta,\n },\n };\n } else if (node.type === \"range\") {\n const rangeNode = node as RangeNode;\n return {\n ...rangeNode,\n range: {\n start: {\n col: rangeNode.isAbsolute.start.col\n ? rangeNode.range.start.col\n : rangeNode.range.start.col + colDelta,\n row: rangeNode.isAbsolute.start.row\n ? rangeNode.range.start.row\n : rangeNode.range.start.row + rowDelta,\n },\n end: {\n col:\n rangeNode.range.end.col.type === \"number\"\n ? rangeNode.isAbsolute.end.col\n ? rangeNode.range.end.col\n : {\n type: \"number\" as const,\n value: rangeNode.range.end.col.value + colDelta,\n }\n : rangeNode.range.end.col,\n row:\n rangeNode.range.end.row.type === \"number\"\n ? rangeNode.isAbsolute.end.row\n ? rangeNode.range.end.row\n : {\n type: \"number\" as const,\n value: rangeNode.range.end.row.value + rowDelta,\n }\n : rangeNode.range.end.row,\n },\n },\n };\n }\n return node;\n });\n\n return `=${astToString(adjustedAst)}`;\n } catch (error) {\n // If parsing fails, return the original formula\n console.warn(\"Failed to adjust formula references:\", error);\n return formula;\n }\n }\n\n /**\n * Copy formatting (cellStyles and conditionalStyles) from source to target\n */\n private copyFormatting(\n sourceCells: CellAddress[],\n sourceTopLeft: CellAddress,\n target: CellAddress,\n rowOffset: number,\n colOffset: number\n ): void {\n // Get all styles for the source workbook\n const allConditionalStyles = this.styleManager.getAllConditionalStyles();\n const allCellStyles = this.styleManager.getAllCellStyles();\n\n // Find styles that intersect with source cells\n const sourceRange = this.getBoundingBox(sourceCells);\n\n // Copy conditional styles\n for (const style of allConditionalStyles) {\n if (\n style.area.workbookName === sourceTopLeft.workbookName &&\n style.area.sheetName === sourceTopLeft.sheetName\n ) {\n // Calculate intersection of style range with source bounding box\n const intersection = intersectRanges(style.area.range, sourceRange);\n if (intersection) {\n // Copy only the intersection, offset to target\n const newStyle: ConditionalStyle = {\n area: {\n workbookName: target.workbookName,\n sheetName: target.sheetName,\n range: this.adjustRange(intersection, rowOffset, colOffset),\n },\n condition: style.condition,\n };\n this.styleManager.addConditionalStyle(newStyle);\n }\n }\n }\n\n // Copy cell styles\n for (const style of allCellStyles) {\n if (\n style.area.workbookName === sourceTopLeft.workbookName &&\n style.area.sheetName === sourceTopLeft.sheetName\n ) {\n // Calculate intersection of style range with source bounding box\n const intersection = intersectRanges(style.area.range, sourceRange);\n if (intersection) {\n // Copy only the intersection, offset to target\n const newStyle: DirectCellStyle = {\n area: {\n workbookName: target.workbookName,\n sheetName: target.sheetName,\n range: this.adjustRange(intersection, rowOffset, colOffset),\n },\n style: style.style,\n };\n this.styleManager.addCellStyle(newStyle);\n }\n }\n }\n }\n\n /**\n * Get bounding box for a set of cells\n */\n private getBoundingBox(cells: CellAddress[]): SpreadsheetRange {\n let minRow = Infinity;\n let maxRow = -Infinity;\n let minCol = Infinity;\n let maxCol = -Infinity;\n\n for (const cell of cells) {\n minRow = Math.min(minRow, cell.rowIndex);\n maxRow = Math.max(maxRow, cell.rowIndex);\n minCol = Math.min(minCol, cell.colIndex);\n maxCol = Math.max(maxCol, cell.colIndex);\n }\n\n return {\n start: { col: minCol, row: minRow },\n end: {\n col: { type: \"number\", value: maxCol },\n row: { type: \"number\", value: maxRow },\n },\n };\n }\n\n\n /**\n * Adjust a range by row and column offsets\n */\n private adjustRange(\n range: SpreadsheetRange,\n rowOffset: number,\n colOffset: number\n ): SpreadsheetRange {\n return {\n start: {\n col: range.start.col + colOffset,\n row: range.start.row + rowOffset,\n },\n end: {\n col:\n range.end.col.type === \"number\"\n ? { type: \"number\", value: range.end.col.value + colOffset }\n : range.end.col,\n row:\n range.end.row.type === \"number\"\n ? { type: \"number\", value: range.end.row.value + rowOffset }\n : range.end.row,\n },\n };\n }\n\n /**\n * Clear source cells (for cut operation)\n */\n private clearSourceCells(cells: CellAddress[]): void {\n for (const cell of cells) {\n const sheet = this.workbookManager.getSheet({\n workbookName: cell.workbookName,\n sheetName: cell.sheetName,\n });\n\n if (sheet) {\n const key = `${String.fromCharCode(65 + cell.colIndex)}${\n cell.rowIndex + 1\n }`;\n sheet.content.delete(key);\n }\n }\n }\n}\n\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "A0756D3B2D95576C64756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "75D1B0CA340D7EDA64756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -31,7 +31,8 @@ var exports_range_utils = {};
31
31
  __export(exports_range_utils, {
32
32
  subtractRange: () => subtractRange,
33
33
  rangesIntersect: () => rangesIntersect,
34
- isRangeContained: () => isRangeContained
34
+ isRangeContained: () => isRangeContained,
35
+ intersectRanges: () => intersectRanges
35
36
  });
36
37
  module.exports = __toCommonJS(exports_range_utils);
37
38
  function rangesIntersect(range1, range2) {
@@ -110,5 +111,25 @@ function createRangeEnd(value) {
110
111
  }
111
112
  return { type: "number", value };
112
113
  }
114
+ function intersectRanges(range1, range2) {
115
+ if (!rangesIntersect(range1, range2)) {
116
+ return null;
117
+ }
118
+ const r1EndCol = range1.end.col.type === "number" ? range1.end.col.value : Infinity;
119
+ const r1EndRow = range1.end.row.type === "number" ? range1.end.row.value : Infinity;
120
+ const r2EndCol = range2.end.col.type === "number" ? range2.end.col.value : Infinity;
121
+ const r2EndRow = range2.end.row.type === "number" ? range2.end.row.value : Infinity;
122
+ const startCol = Math.max(range1.start.col, range2.start.col);
123
+ const startRow = Math.max(range1.start.row, range2.start.row);
124
+ const endCol = Math.min(r1EndCol, r2EndCol);
125
+ const endRow = Math.min(r1EndRow, r2EndRow);
126
+ return {
127
+ start: { col: startCol, row: startRow },
128
+ end: {
129
+ col: createRangeEnd(endCol),
130
+ row: createRangeEnd(endRow)
131
+ }
132
+ };
133
+ }
113
134
 
114
- //# debugId=E61D49F827B99F2964756E2164756E21
135
+ //# debugId=0414292CC0A19A3264756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/core/utils/range-utils.ts"],
4
4
  "sourcesContent": [
5
- "/**\n * Range utility functions for handling range arithmetic and operations\n */\n\nimport type { SpreadsheetRange, SpreadsheetRangeEnd } from \"../types.cjs\";\n\n/**\n * Check if two ranges intersect\n */\nexport function rangesIntersect(\n range1: SpreadsheetRange,\n range2: SpreadsheetRange\n): boolean {\n // Get finite end values\n const r1EndCol =\n range1.end.col.type === \"number\" ? range1.end.col.value : Infinity;\n const r1EndRow =\n range1.end.row.type === \"number\" ? range1.end.row.value : Infinity;\n const r2EndCol =\n range2.end.col.type === \"number\" ? range2.end.col.value : Infinity;\n const r2EndRow =\n range2.end.row.type === \"number\" ? range2.end.row.value : Infinity;\n\n // Check if ranges overlap\n const colOverlap =\n range1.start.col <= r2EndCol && range2.start.col <= r1EndCol;\n const rowOverlap =\n range1.start.row <= r2EndRow && range2.start.row <= r1EndRow;\n\n return colOverlap && rowOverlap;\n}\n\n/**\n * Check if one range is completely contained within another\n */\nexport function isRangeContained(\n inner: SpreadsheetRange,\n outer: SpreadsheetRange\n): boolean {\n const innerEndCol =\n inner.end.col.type === \"number\" ? inner.end.col.value : Infinity;\n const innerEndRow =\n inner.end.row.type === \"number\" ? inner.end.row.value : Infinity;\n const outerEndCol =\n outer.end.col.type === \"number\" ? outer.end.col.value : Infinity;\n const outerEndRow =\n outer.end.row.type === \"number\" ? outer.end.row.value : Infinity;\n\n return (\n inner.start.col >= outer.start.col &&\n inner.start.row >= outer.start.row &&\n innerEndCol <= outerEndCol &&\n innerEndRow <= outerEndRow\n );\n}\n\n/**\n * Subtract one range from another, returning the remaining ranges\n * Returns an array of ranges representing `original - subtract`\n * \n * For infinite ranges in the original:\n * - If subtract range is finite, we still return the infinite portions\n * - This can result in up to 4 ranges (4 sides around the subtracted area)\n */\nexport function subtractRange(\n original: SpreadsheetRange,\n subtract: SpreadsheetRange\n): SpreadsheetRange[] {\n // If ranges don't intersect, return original unchanged\n if (!rangesIntersect(original, subtract)) {\n return [original];\n }\n\n // If original is completely contained in subtract, return empty\n if (isRangeContained(original, subtract)) {\n return [];\n }\n\n const result: SpreadsheetRange[] = [];\n\n // Get finite end values for easier arithmetic\n const origEndCol =\n original.end.col.type === \"number\" ? original.end.col.value : Infinity;\n const origEndRow =\n original.end.row.type === \"number\" ? original.end.row.value : Infinity;\n const subEndCol =\n subtract.end.col.type === \"number\" ? subtract.end.col.value : Infinity;\n const subEndRow =\n subtract.end.row.type === \"number\" ? subtract.end.row.value : Infinity;\n\n // Calculate the intersection bounds\n const intersectStartCol = Math.max(original.start.col, subtract.start.col);\n const intersectStartRow = Math.max(original.start.row, subtract.start.row);\n const intersectEndCol = Math.min(origEndCol, subEndCol);\n const intersectEndRow = Math.min(origEndRow, subEndRow);\n\n // Create up to 4 rectangles around the intersection:\n // Top, Bottom, Left, Right\n\n // Top rectangle (above the intersection)\n if (original.start.row < intersectStartRow) {\n result.push({\n start: { col: original.start.col, row: original.start.row },\n end: {\n col: createRangeEnd(origEndCol),\n row: createRangeEnd(intersectStartRow - 1),\n },\n });\n }\n\n // Bottom rectangle (below the intersection)\n if (origEndRow > intersectEndRow) {\n result.push({\n start: { col: original.start.col, row: intersectEndRow + 1 },\n end: {\n col: createRangeEnd(origEndCol),\n row: createRangeEnd(origEndRow),\n },\n });\n }\n\n // Left rectangle (left of the intersection, within the vertical bounds of intersection)\n if (original.start.col < intersectStartCol) {\n result.push({\n start: { col: original.start.col, row: intersectStartRow },\n end: {\n col: createRangeEnd(intersectStartCol - 1),\n row: createRangeEnd(intersectEndRow),\n },\n });\n }\n\n // Right rectangle (right of the intersection, within the vertical bounds of intersection)\n if (origEndCol > intersectEndCol) {\n result.push({\n start: { col: intersectEndCol + 1, row: intersectStartRow },\n end: {\n col: createRangeEnd(origEndCol),\n row: createRangeEnd(intersectEndRow),\n },\n });\n }\n\n return result;\n}\n\n/**\n * Helper to create a SpreadsheetRangeEnd from a number (handles infinity)\n */\nfunction createRangeEnd(value: number): SpreadsheetRangeEnd {\n if (!isFinite(value)) {\n return { type: \"infinity\", sign: \"positive\" };\n }\n return { type: \"number\", value };\n}\n\n"
5
+ "/**\n * Range utility functions for handling range arithmetic and operations\n */\n\nimport type { SpreadsheetRange, SpreadsheetRangeEnd } from \"../types.cjs\";\n\n/**\n * Check if two ranges intersect\n */\nexport function rangesIntersect(\n range1: SpreadsheetRange,\n range2: SpreadsheetRange\n): boolean {\n // Get finite end values\n const r1EndCol =\n range1.end.col.type === \"number\" ? range1.end.col.value : Infinity;\n const r1EndRow =\n range1.end.row.type === \"number\" ? range1.end.row.value : Infinity;\n const r2EndCol =\n range2.end.col.type === \"number\" ? range2.end.col.value : Infinity;\n const r2EndRow =\n range2.end.row.type === \"number\" ? range2.end.row.value : Infinity;\n\n // Check if ranges overlap\n const colOverlap =\n range1.start.col <= r2EndCol && range2.start.col <= r1EndCol;\n const rowOverlap =\n range1.start.row <= r2EndRow && range2.start.row <= r1EndRow;\n\n return colOverlap && rowOverlap;\n}\n\n/**\n * Check if one range is completely contained within another\n */\nexport function isRangeContained(\n inner: SpreadsheetRange,\n outer: SpreadsheetRange\n): boolean {\n const innerEndCol =\n inner.end.col.type === \"number\" ? inner.end.col.value : Infinity;\n const innerEndRow =\n inner.end.row.type === \"number\" ? inner.end.row.value : Infinity;\n const outerEndCol =\n outer.end.col.type === \"number\" ? outer.end.col.value : Infinity;\n const outerEndRow =\n outer.end.row.type === \"number\" ? outer.end.row.value : Infinity;\n\n return (\n inner.start.col >= outer.start.col &&\n inner.start.row >= outer.start.row &&\n innerEndCol <= outerEndCol &&\n innerEndRow <= outerEndRow\n );\n}\n\n/**\n * Subtract one range from another, returning the remaining ranges\n * Returns an array of ranges representing `original - subtract`\n * \n * For infinite ranges in the original:\n * - If subtract range is finite, we still return the infinite portions\n * - This can result in up to 4 ranges (4 sides around the subtracted area)\n */\nexport function subtractRange(\n original: SpreadsheetRange,\n subtract: SpreadsheetRange\n): SpreadsheetRange[] {\n // If ranges don't intersect, return original unchanged\n if (!rangesIntersect(original, subtract)) {\n return [original];\n }\n\n // If original is completely contained in subtract, return empty\n if (isRangeContained(original, subtract)) {\n return [];\n }\n\n const result: SpreadsheetRange[] = [];\n\n // Get finite end values for easier arithmetic\n const origEndCol =\n original.end.col.type === \"number\" ? original.end.col.value : Infinity;\n const origEndRow =\n original.end.row.type === \"number\" ? original.end.row.value : Infinity;\n const subEndCol =\n subtract.end.col.type === \"number\" ? subtract.end.col.value : Infinity;\n const subEndRow =\n subtract.end.row.type === \"number\" ? subtract.end.row.value : Infinity;\n\n // Calculate the intersection bounds\n const intersectStartCol = Math.max(original.start.col, subtract.start.col);\n const intersectStartRow = Math.max(original.start.row, subtract.start.row);\n const intersectEndCol = Math.min(origEndCol, subEndCol);\n const intersectEndRow = Math.min(origEndRow, subEndRow);\n\n // Create up to 4 rectangles around the intersection:\n // Top, Bottom, Left, Right\n\n // Top rectangle (above the intersection)\n if (original.start.row < intersectStartRow) {\n result.push({\n start: { col: original.start.col, row: original.start.row },\n end: {\n col: createRangeEnd(origEndCol),\n row: createRangeEnd(intersectStartRow - 1),\n },\n });\n }\n\n // Bottom rectangle (below the intersection)\n if (origEndRow > intersectEndRow) {\n result.push({\n start: { col: original.start.col, row: intersectEndRow + 1 },\n end: {\n col: createRangeEnd(origEndCol),\n row: createRangeEnd(origEndRow),\n },\n });\n }\n\n // Left rectangle (left of the intersection, within the vertical bounds of intersection)\n if (original.start.col < intersectStartCol) {\n result.push({\n start: { col: original.start.col, row: intersectStartRow },\n end: {\n col: createRangeEnd(intersectStartCol - 1),\n row: createRangeEnd(intersectEndRow),\n },\n });\n }\n\n // Right rectangle (right of the intersection, within the vertical bounds of intersection)\n if (origEndCol > intersectEndCol) {\n result.push({\n start: { col: intersectEndCol + 1, row: intersectStartRow },\n end: {\n col: createRangeEnd(origEndCol),\n row: createRangeEnd(intersectEndRow),\n },\n });\n }\n\n return result;\n}\n\n/**\n * Helper to create a SpreadsheetRangeEnd from a number (handles infinity)\n */\nfunction createRangeEnd(value: number): SpreadsheetRangeEnd {\n if (!isFinite(value)) {\n return { type: \"infinity\", sign: \"positive\" };\n }\n return { type: \"number\", value };\n}\n\n/**\n * Calculate the intersection of two ranges\n * Returns the overlapping rectangle, or null if ranges don't intersect\n */\nexport function intersectRanges(\n range1: SpreadsheetRange,\n range2: SpreadsheetRange\n): SpreadsheetRange | null {\n if (!rangesIntersect(range1, range2)) {\n return null;\n }\n\n // Get finite end values\n const r1EndCol =\n range1.end.col.type === \"number\" ? range1.end.col.value : Infinity;\n const r1EndRow =\n range1.end.row.type === \"number\" ? range1.end.row.value : Infinity;\n const r2EndCol =\n range2.end.col.type === \"number\" ? range2.end.col.value : Infinity;\n const r2EndRow =\n range2.end.row.type === \"number\" ? range2.end.row.value : Infinity;\n\n // Calculate intersection bounds\n const startCol = Math.max(range1.start.col, range2.start.col);\n const startRow = Math.max(range1.start.row, range2.start.row);\n const endCol = Math.min(r1EndCol, r2EndCol);\n const endRow = Math.min(r1EndRow, r2EndRow);\n\n return {\n start: { col: startCol, row: startRow },\n end: {\n col: createRangeEnd(endCol),\n row: createRangeEnd(endRow),\n },\n };\n}\n\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "E61D49F827B99F2964756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "0414292CC0A19A3264756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@ricsam/formula-engine",
3
- "version": "0.0.9",
3
+ "version": "0.0.10",
4
4
  "type": "commonjs"
5
5
  }
@@ -2,6 +2,7 @@
2
2
  import { parseFormula } from "../../parser/parser.mjs";
3
3
  import { astToString } from "../../parser/formatter.mjs";
4
4
  import { transformAST } from "../ast-traverser.mjs";
5
+ import { intersectRanges } from "../utils/range-utils.mjs";
5
6
 
6
7
  class CopyManager {
7
8
  workbookManager;
@@ -150,29 +151,35 @@ class CopyManager {
150
151
  const allCellStyles = this.styleManager.getAllCellStyles();
151
152
  const sourceRange = this.getBoundingBox(sourceCells);
152
153
  for (const style of allConditionalStyles) {
153
- if (style.area.workbookName === sourceTopLeft.workbookName && style.area.sheetName === sourceTopLeft.sheetName && this.rangesIntersect(style.area.range, sourceRange)) {
154
- const newStyle = {
155
- area: {
156
- workbookName: target.workbookName,
157
- sheetName: target.sheetName,
158
- range: this.adjustRange(style.area.range, rowOffset, colOffset)
159
- },
160
- condition: style.condition
161
- };
162
- this.styleManager.addConditionalStyle(newStyle);
154
+ if (style.area.workbookName === sourceTopLeft.workbookName && style.area.sheetName === sourceTopLeft.sheetName) {
155
+ const intersection = intersectRanges(style.area.range, sourceRange);
156
+ if (intersection) {
157
+ const newStyle = {
158
+ area: {
159
+ workbookName: target.workbookName,
160
+ sheetName: target.sheetName,
161
+ range: this.adjustRange(intersection, rowOffset, colOffset)
162
+ },
163
+ condition: style.condition
164
+ };
165
+ this.styleManager.addConditionalStyle(newStyle);
166
+ }
163
167
  }
164
168
  }
165
169
  for (const style of allCellStyles) {
166
- if (style.area.workbookName === sourceTopLeft.workbookName && style.area.sheetName === sourceTopLeft.sheetName && this.rangesIntersect(style.area.range, sourceRange)) {
167
- const newStyle = {
168
- area: {
169
- workbookName: target.workbookName,
170
- sheetName: target.sheetName,
171
- range: this.adjustRange(style.area.range, rowOffset, colOffset)
172
- },
173
- style: style.style
174
- };
175
- this.styleManager.addCellStyle(newStyle);
170
+ if (style.area.workbookName === sourceTopLeft.workbookName && style.area.sheetName === sourceTopLeft.sheetName) {
171
+ const intersection = intersectRanges(style.area.range, sourceRange);
172
+ if (intersection) {
173
+ const newStyle = {
174
+ area: {
175
+ workbookName: target.workbookName,
176
+ sheetName: target.sheetName,
177
+ range: this.adjustRange(intersection, rowOffset, colOffset)
178
+ },
179
+ style: style.style
180
+ };
181
+ this.styleManager.addCellStyle(newStyle);
182
+ }
176
183
  }
177
184
  }
178
185
  }
@@ -195,15 +202,6 @@ class CopyManager {
195
202
  }
196
203
  };
197
204
  }
198
- rangesIntersect(range1, range2) {
199
- const r1EndCol = range1.end.col.type === "number" ? range1.end.col.value : Infinity;
200
- const r1EndRow = range1.end.row.type === "number" ? range1.end.row.value : Infinity;
201
- const r2EndCol = range2.end.col.type === "number" ? range2.end.col.value : Infinity;
202
- const r2EndRow = range2.end.row.type === "number" ? range2.end.row.value : Infinity;
203
- const colOverlap = range1.start.col <= r2EndCol && range2.start.col <= r1EndCol;
204
- const rowOverlap = range1.start.row <= r2EndRow && range2.start.row <= r1EndRow;
205
- return colOverlap && rowOverlap;
206
- }
207
205
  adjustRange(range, rowOffset, colOffset) {
208
206
  return {
209
207
  start: {
@@ -233,4 +231,4 @@ export {
233
231
  CopyManager
234
232
  };
235
233
 
236
- //# debugId=8CA951C1BABE115764756E2164756E21
234
+ //# debugId=1490ADF5C784502364756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/core/managers/copy-manager.ts"],
4
4
  "sourcesContent": [
5
- "/**\n * CopyManager - Manages cell copy/paste operations\n */\n\nimport type {\n CellAddress,\n CopyCellsOptions,\n ConditionalStyle,\n DirectCellStyle,\n LocalCellAddress,\n SerializedCellValue,\n SpreadsheetRange,\n} from \"../types.mjs\";\nimport type { WorkbookManager } from \"./workbook-manager.mjs\";\nimport type { EvaluationManager } from \"./evaluation-manager.mjs\";\nimport type { StyleManager } from \"./style-manager.mjs\";\nimport { parseFormula } from \"../../parser/parser.mjs\";\nimport { astToString } from \"../../parser/formatter.mjs\";\nimport { transformAST } from \"../ast-traverser.mjs\";\nimport type { ReferenceNode, RangeNode } from \"../../parser/ast.mjs\";\nimport { isCellInRange } from \"../utils.mjs\";\n\nexport class CopyManager {\n constructor(\n private workbookManager: WorkbookManager,\n private evaluationManager: EvaluationManager,\n private styleManager: StyleManager\n ) {}\n\n /**\n * Copy cells from source to target\n */\n copyCells(\n source: CellAddress[],\n target: CellAddress,\n options: CopyCellsOptions\n ): void {\n if (source.length === 0) {\n return;\n }\n\n // Find top-left cell of source (minimum row/col indices)\n const topLeft = this.findTopLeft(source);\n\n // Calculate offset from source top-left to target\n const rowOffset = target.rowIndex - topLeft.rowIndex;\n const colOffset = target.colIndex - topLeft.colIndex;\n\n // Copy cell contents\n for (const sourceCell of source) {\n const targetCell: CellAddress = {\n workbookName: target.workbookName,\n sheetName: target.sheetName,\n colIndex: sourceCell.colIndex + colOffset,\n rowIndex: sourceCell.rowIndex + rowOffset,\n };\n\n this.copyCellContent(sourceCell, targetCell, topLeft, options);\n }\n\n // Copy formatting if requested\n if (options.formatting) {\n this.copyFormatting(source, topLeft, target, rowOffset, colOffset);\n }\n\n // Clear source cells if cut\n if (options.cut) {\n this.clearSourceCells(source);\n }\n }\n\n /**\n * Find the top-left cell (minimum row/col indices)\n */\n private findTopLeft(cells: CellAddress[]): CellAddress {\n let minRow = Infinity;\n let minCol = Infinity;\n let topLeftCell = cells[0]!;\n\n for (const cell of cells) {\n if (\n cell.rowIndex < minRow ||\n (cell.rowIndex === minRow && cell.colIndex < minCol)\n ) {\n minRow = cell.rowIndex;\n minCol = cell.colIndex;\n topLeftCell = cell;\n }\n }\n\n return topLeftCell;\n }\n\n /**\n * Copy content from one cell to another\n */\n private copyCellContent(\n sourceCell: CellAddress,\n targetCell: CellAddress,\n sourceTopLeft: CellAddress,\n options: CopyCellsOptions\n ): void {\n const sheet = this.workbookManager.getSheet({\n workbookName: sourceCell.workbookName,\n sheetName: sourceCell.sheetName,\n });\n\n if (!sheet) {\n return;\n }\n\n const key = `${String.fromCharCode(65 + sourceCell.colIndex)}${\n sourceCell.rowIndex + 1\n }`;\n const cellContent = sheet.content.get(key);\n\n if (!cellContent) {\n // Source cell is empty\n return;\n }\n\n let targetContent: SerializedCellValue;\n\n if (options.type === \"value\") {\n // Copy evaluated value\n const evalResult = this.evaluationManager.getCellEvaluationResult(sourceCell);\n \n if (!evalResult || evalResult.type !== \"value\") {\n // If evaluation failed or is not a value, copy as-is\n targetContent = cellContent;\n } else {\n // Convert to literal value\n const result = evalResult.result;\n if (result.type === \"number\") {\n targetContent = result.value;\n } else if (result.type === \"string\") {\n targetContent = result.value;\n } else if (result.type === \"boolean\") {\n targetContent = result.value;\n } else {\n // Error or other type, copy as-is\n targetContent = cellContent;\n }\n }\n } else {\n // Copy formula\n if (typeof cellContent === \"string\" && cellContent.startsWith(\"=\")) {\n // Adjust formula references\n targetContent = this.adjustFormulaReferences(\n cellContent,\n {\n colIndex: sourceCell.colIndex,\n rowIndex: sourceCell.rowIndex,\n },\n {\n colIndex: targetCell.colIndex,\n rowIndex: targetCell.rowIndex,\n }\n );\n } else {\n // Not a formula, copy as-is\n targetContent = cellContent;\n }\n }\n\n // Set target cell content (using the engine's method through workbook manager)\n const targetSheet = this.workbookManager.getSheet({\n workbookName: targetCell.workbookName,\n sheetName: targetCell.sheetName,\n });\n\n if (targetSheet) {\n const targetKey = `${String.fromCharCode(65 + targetCell.colIndex)}${\n targetCell.rowIndex + 1\n }`;\n targetSheet.content.set(targetKey, targetContent);\n }\n }\n\n /**\n * Adjust formula references when copying\n * Based on autofill-utils.ts adjustFormulaReferences\n */\n private adjustFormulaReferences(\n formula: string,\n sourceAddress: LocalCellAddress,\n targetAddress: LocalCellAddress\n ): string {\n try {\n const ast = parseFormula(formula.slice(1)); // Remove the \"=\" sign\n\n const rowDelta = targetAddress.rowIndex - sourceAddress.rowIndex;\n const colDelta = targetAddress.colIndex - sourceAddress.colIndex;\n\n const adjustedAst = transformAST(ast, (node) => {\n if (node.type === \"reference\") {\n const refNode = node as ReferenceNode;\n return {\n ...refNode,\n address: {\n colIndex: refNode.isAbsolute.col\n ? refNode.address.colIndex\n : refNode.address.colIndex + colDelta,\n rowIndex: refNode.isAbsolute.row\n ? refNode.address.rowIndex\n : refNode.address.rowIndex + rowDelta,\n },\n };\n } else if (node.type === \"range\") {\n const rangeNode = node as RangeNode;\n return {\n ...rangeNode,\n range: {\n start: {\n col: rangeNode.isAbsolute.start.col\n ? rangeNode.range.start.col\n : rangeNode.range.start.col + colDelta,\n row: rangeNode.isAbsolute.start.row\n ? rangeNode.range.start.row\n : rangeNode.range.start.row + rowDelta,\n },\n end: {\n col:\n rangeNode.range.end.col.type === \"number\"\n ? rangeNode.isAbsolute.end.col\n ? rangeNode.range.end.col\n : {\n type: \"number\" as const,\n value: rangeNode.range.end.col.value + colDelta,\n }\n : rangeNode.range.end.col,\n row:\n rangeNode.range.end.row.type === \"number\"\n ? rangeNode.isAbsolute.end.row\n ? rangeNode.range.end.row\n : {\n type: \"number\" as const,\n value: rangeNode.range.end.row.value + rowDelta,\n }\n : rangeNode.range.end.row,\n },\n },\n };\n }\n return node;\n });\n\n return `=${astToString(adjustedAst)}`;\n } catch (error) {\n // If parsing fails, return the original formula\n console.warn(\"Failed to adjust formula references:\", error);\n return formula;\n }\n }\n\n /**\n * Copy formatting (cellStyles and conditionalStyles) from source to target\n */\n private copyFormatting(\n sourceCells: CellAddress[],\n sourceTopLeft: CellAddress,\n target: CellAddress,\n rowOffset: number,\n colOffset: number\n ): void {\n // Get all styles for the source workbook\n const allConditionalStyles = this.styleManager.getAllConditionalStyles();\n const allCellStyles = this.styleManager.getAllCellStyles();\n\n // Find styles that intersect with source cells\n const sourceRange = this.getBoundingBox(sourceCells);\n\n // Copy conditional styles\n for (const style of allConditionalStyles) {\n if (\n style.area.workbookName === sourceTopLeft.workbookName &&\n style.area.sheetName === sourceTopLeft.sheetName &&\n this.rangesIntersect(style.area.range, sourceRange)\n ) {\n // Create a new style with adjusted range\n const newStyle: ConditionalStyle = {\n area: {\n workbookName: target.workbookName,\n sheetName: target.sheetName,\n range: this.adjustRange(style.area.range, rowOffset, colOffset),\n },\n condition: style.condition,\n };\n this.styleManager.addConditionalStyle(newStyle);\n }\n }\n\n // Copy cell styles\n for (const style of allCellStyles) {\n if (\n style.area.workbookName === sourceTopLeft.workbookName &&\n style.area.sheetName === sourceTopLeft.sheetName &&\n this.rangesIntersect(style.area.range, sourceRange)\n ) {\n // Create a new style with adjusted range\n const newStyle: DirectCellStyle = {\n area: {\n workbookName: target.workbookName,\n sheetName: target.sheetName,\n range: this.adjustRange(style.area.range, rowOffset, colOffset),\n },\n style: style.style,\n };\n this.styleManager.addCellStyle(newStyle);\n }\n }\n }\n\n /**\n * Get bounding box for a set of cells\n */\n private getBoundingBox(cells: CellAddress[]): SpreadsheetRange {\n let minRow = Infinity;\n let maxRow = -Infinity;\n let minCol = Infinity;\n let maxCol = -Infinity;\n\n for (const cell of cells) {\n minRow = Math.min(minRow, cell.rowIndex);\n maxRow = Math.max(maxRow, cell.rowIndex);\n minCol = Math.min(minCol, cell.colIndex);\n maxCol = Math.max(maxCol, cell.colIndex);\n }\n\n return {\n start: { col: minCol, row: minRow },\n end: {\n col: { type: \"number\", value: maxCol },\n row: { type: \"number\", value: maxRow },\n },\n };\n }\n\n /**\n * Check if two ranges intersect\n */\n private rangesIntersect(\n range1: SpreadsheetRange,\n range2: SpreadsheetRange\n ): boolean {\n // Get finite end values\n const r1EndCol =\n range1.end.col.type === \"number\" ? range1.end.col.value : Infinity;\n const r1EndRow =\n range1.end.row.type === \"number\" ? range1.end.row.value : Infinity;\n const r2EndCol =\n range2.end.col.type === \"number\" ? range2.end.col.value : Infinity;\n const r2EndRow =\n range2.end.row.type === \"number\" ? range2.end.row.value : Infinity;\n\n // Check if ranges overlap\n const colOverlap =\n range1.start.col <= r2EndCol && range2.start.col <= r1EndCol;\n const rowOverlap =\n range1.start.row <= r2EndRow && range2.start.row <= r1EndRow;\n\n return colOverlap && rowOverlap;\n }\n\n /**\n * Adjust a range by row and column offsets\n */\n private adjustRange(\n range: SpreadsheetRange,\n rowOffset: number,\n colOffset: number\n ): SpreadsheetRange {\n return {\n start: {\n col: range.start.col + colOffset,\n row: range.start.row + rowOffset,\n },\n end: {\n col:\n range.end.col.type === \"number\"\n ? { type: \"number\", value: range.end.col.value + colOffset }\n : range.end.col,\n row:\n range.end.row.type === \"number\"\n ? { type: \"number\", value: range.end.row.value + rowOffset }\n : range.end.row,\n },\n };\n }\n\n /**\n * Clear source cells (for cut operation)\n */\n private clearSourceCells(cells: CellAddress[]): void {\n for (const cell of cells) {\n const sheet = this.workbookManager.getSheet({\n workbookName: cell.workbookName,\n sheetName: cell.sheetName,\n });\n\n if (sheet) {\n const key = `${String.fromCharCode(65 + cell.colIndex)}${\n cell.rowIndex + 1\n }`;\n sheet.content.delete(key);\n }\n }\n }\n}\n\n"
5
+ "/**\n * CopyManager - Manages cell copy/paste operations\n */\n\nimport type {\n CellAddress,\n CopyCellsOptions,\n ConditionalStyle,\n DirectCellStyle,\n LocalCellAddress,\n SerializedCellValue,\n SpreadsheetRange,\n} from \"../types.mjs\";\nimport type { WorkbookManager } from \"./workbook-manager.mjs\";\nimport type { EvaluationManager } from \"./evaluation-manager.mjs\";\nimport type { StyleManager } from \"./style-manager.mjs\";\nimport { parseFormula } from \"../../parser/parser.mjs\";\nimport { astToString } from \"../../parser/formatter.mjs\";\nimport { transformAST } from \"../ast-traverser.mjs\";\nimport type { ReferenceNode, RangeNode } from \"../../parser/ast.mjs\";\nimport { isCellInRange } from \"../utils.mjs\";\nimport { intersectRanges } from \"../utils/range-utils.mjs\";\n\nexport class CopyManager {\n constructor(\n private workbookManager: WorkbookManager,\n private evaluationManager: EvaluationManager,\n private styleManager: StyleManager\n ) {}\n\n /**\n * Copy cells from source to target\n */\n copyCells(\n source: CellAddress[],\n target: CellAddress,\n options: CopyCellsOptions\n ): void {\n if (source.length === 0) {\n return;\n }\n\n // Find top-left cell of source (minimum row/col indices)\n const topLeft = this.findTopLeft(source);\n\n // Calculate offset from source top-left to target\n const rowOffset = target.rowIndex - topLeft.rowIndex;\n const colOffset = target.colIndex - topLeft.colIndex;\n\n // Copy cell contents\n for (const sourceCell of source) {\n const targetCell: CellAddress = {\n workbookName: target.workbookName,\n sheetName: target.sheetName,\n colIndex: sourceCell.colIndex + colOffset,\n rowIndex: sourceCell.rowIndex + rowOffset,\n };\n\n this.copyCellContent(sourceCell, targetCell, topLeft, options);\n }\n\n // Copy formatting if requested\n if (options.formatting) {\n this.copyFormatting(source, topLeft, target, rowOffset, colOffset);\n }\n\n // Clear source cells if cut\n if (options.cut) {\n this.clearSourceCells(source);\n }\n }\n\n /**\n * Find the top-left cell (minimum row/col indices)\n */\n private findTopLeft(cells: CellAddress[]): CellAddress {\n let minRow = Infinity;\n let minCol = Infinity;\n let topLeftCell = cells[0]!;\n\n for (const cell of cells) {\n if (\n cell.rowIndex < minRow ||\n (cell.rowIndex === minRow && cell.colIndex < minCol)\n ) {\n minRow = cell.rowIndex;\n minCol = cell.colIndex;\n topLeftCell = cell;\n }\n }\n\n return topLeftCell;\n }\n\n /**\n * Copy content from one cell to another\n */\n private copyCellContent(\n sourceCell: CellAddress,\n targetCell: CellAddress,\n sourceTopLeft: CellAddress,\n options: CopyCellsOptions\n ): void {\n const sheet = this.workbookManager.getSheet({\n workbookName: sourceCell.workbookName,\n sheetName: sourceCell.sheetName,\n });\n\n if (!sheet) {\n return;\n }\n\n const key = `${String.fromCharCode(65 + sourceCell.colIndex)}${\n sourceCell.rowIndex + 1\n }`;\n const cellContent = sheet.content.get(key);\n\n if (!cellContent) {\n // Source cell is empty\n return;\n }\n\n let targetContent: SerializedCellValue;\n\n if (options.type === \"value\") {\n // Copy evaluated value\n const evalResult = this.evaluationManager.getCellEvaluationResult(sourceCell);\n \n if (!evalResult || evalResult.type !== \"value\") {\n // If evaluation failed or is not a value, copy as-is\n targetContent = cellContent;\n } else {\n // Convert to literal value\n const result = evalResult.result;\n if (result.type === \"number\") {\n targetContent = result.value;\n } else if (result.type === \"string\") {\n targetContent = result.value;\n } else if (result.type === \"boolean\") {\n targetContent = result.value;\n } else {\n // Error or other type, copy as-is\n targetContent = cellContent;\n }\n }\n } else {\n // Copy formula\n if (typeof cellContent === \"string\" && cellContent.startsWith(\"=\")) {\n // Adjust formula references\n targetContent = this.adjustFormulaReferences(\n cellContent,\n {\n colIndex: sourceCell.colIndex,\n rowIndex: sourceCell.rowIndex,\n },\n {\n colIndex: targetCell.colIndex,\n rowIndex: targetCell.rowIndex,\n }\n );\n } else {\n // Not a formula, copy as-is\n targetContent = cellContent;\n }\n }\n\n // Set target cell content (using the engine's method through workbook manager)\n const targetSheet = this.workbookManager.getSheet({\n workbookName: targetCell.workbookName,\n sheetName: targetCell.sheetName,\n });\n\n if (targetSheet) {\n const targetKey = `${String.fromCharCode(65 + targetCell.colIndex)}${\n targetCell.rowIndex + 1\n }`;\n targetSheet.content.set(targetKey, targetContent);\n }\n }\n\n /**\n * Adjust formula references when copying\n * Based on autofill-utils.ts adjustFormulaReferences\n */\n private adjustFormulaReferences(\n formula: string,\n sourceAddress: LocalCellAddress,\n targetAddress: LocalCellAddress\n ): string {\n try {\n const ast = parseFormula(formula.slice(1)); // Remove the \"=\" sign\n\n const rowDelta = targetAddress.rowIndex - sourceAddress.rowIndex;\n const colDelta = targetAddress.colIndex - sourceAddress.colIndex;\n\n const adjustedAst = transformAST(ast, (node) => {\n if (node.type === \"reference\") {\n const refNode = node as ReferenceNode;\n return {\n ...refNode,\n address: {\n colIndex: refNode.isAbsolute.col\n ? refNode.address.colIndex\n : refNode.address.colIndex + colDelta,\n rowIndex: refNode.isAbsolute.row\n ? refNode.address.rowIndex\n : refNode.address.rowIndex + rowDelta,\n },\n };\n } else if (node.type === \"range\") {\n const rangeNode = node as RangeNode;\n return {\n ...rangeNode,\n range: {\n start: {\n col: rangeNode.isAbsolute.start.col\n ? rangeNode.range.start.col\n : rangeNode.range.start.col + colDelta,\n row: rangeNode.isAbsolute.start.row\n ? rangeNode.range.start.row\n : rangeNode.range.start.row + rowDelta,\n },\n end: {\n col:\n rangeNode.range.end.col.type === \"number\"\n ? rangeNode.isAbsolute.end.col\n ? rangeNode.range.end.col\n : {\n type: \"number\" as const,\n value: rangeNode.range.end.col.value + colDelta,\n }\n : rangeNode.range.end.col,\n row:\n rangeNode.range.end.row.type === \"number\"\n ? rangeNode.isAbsolute.end.row\n ? rangeNode.range.end.row\n : {\n type: \"number\" as const,\n value: rangeNode.range.end.row.value + rowDelta,\n }\n : rangeNode.range.end.row,\n },\n },\n };\n }\n return node;\n });\n\n return `=${astToString(adjustedAst)}`;\n } catch (error) {\n // If parsing fails, return the original formula\n console.warn(\"Failed to adjust formula references:\", error);\n return formula;\n }\n }\n\n /**\n * Copy formatting (cellStyles and conditionalStyles) from source to target\n */\n private copyFormatting(\n sourceCells: CellAddress[],\n sourceTopLeft: CellAddress,\n target: CellAddress,\n rowOffset: number,\n colOffset: number\n ): void {\n // Get all styles for the source workbook\n const allConditionalStyles = this.styleManager.getAllConditionalStyles();\n const allCellStyles = this.styleManager.getAllCellStyles();\n\n // Find styles that intersect with source cells\n const sourceRange = this.getBoundingBox(sourceCells);\n\n // Copy conditional styles\n for (const style of allConditionalStyles) {\n if (\n style.area.workbookName === sourceTopLeft.workbookName &&\n style.area.sheetName === sourceTopLeft.sheetName\n ) {\n // Calculate intersection of style range with source bounding box\n const intersection = intersectRanges(style.area.range, sourceRange);\n if (intersection) {\n // Copy only the intersection, offset to target\n const newStyle: ConditionalStyle = {\n area: {\n workbookName: target.workbookName,\n sheetName: target.sheetName,\n range: this.adjustRange(intersection, rowOffset, colOffset),\n },\n condition: style.condition,\n };\n this.styleManager.addConditionalStyle(newStyle);\n }\n }\n }\n\n // Copy cell styles\n for (const style of allCellStyles) {\n if (\n style.area.workbookName === sourceTopLeft.workbookName &&\n style.area.sheetName === sourceTopLeft.sheetName\n ) {\n // Calculate intersection of style range with source bounding box\n const intersection = intersectRanges(style.area.range, sourceRange);\n if (intersection) {\n // Copy only the intersection, offset to target\n const newStyle: DirectCellStyle = {\n area: {\n workbookName: target.workbookName,\n sheetName: target.sheetName,\n range: this.adjustRange(intersection, rowOffset, colOffset),\n },\n style: style.style,\n };\n this.styleManager.addCellStyle(newStyle);\n }\n }\n }\n }\n\n /**\n * Get bounding box for a set of cells\n */\n private getBoundingBox(cells: CellAddress[]): SpreadsheetRange {\n let minRow = Infinity;\n let maxRow = -Infinity;\n let minCol = Infinity;\n let maxCol = -Infinity;\n\n for (const cell of cells) {\n minRow = Math.min(minRow, cell.rowIndex);\n maxRow = Math.max(maxRow, cell.rowIndex);\n minCol = Math.min(minCol, cell.colIndex);\n maxCol = Math.max(maxCol, cell.colIndex);\n }\n\n return {\n start: { col: minCol, row: minRow },\n end: {\n col: { type: \"number\", value: maxCol },\n row: { type: \"number\", value: maxRow },\n },\n };\n }\n\n\n /**\n * Adjust a range by row and column offsets\n */\n private adjustRange(\n range: SpreadsheetRange,\n rowOffset: number,\n colOffset: number\n ): SpreadsheetRange {\n return {\n start: {\n col: range.start.col + colOffset,\n row: range.start.row + rowOffset,\n },\n end: {\n col:\n range.end.col.type === \"number\"\n ? { type: \"number\", value: range.end.col.value + colOffset }\n : range.end.col,\n row:\n range.end.row.type === \"number\"\n ? { type: \"number\", value: range.end.row.value + rowOffset }\n : range.end.row,\n },\n };\n }\n\n /**\n * Clear source cells (for cut operation)\n */\n private clearSourceCells(cells: CellAddress[]): void {\n for (const cell of cells) {\n const sheet = this.workbookManager.getSheet({\n workbookName: cell.workbookName,\n sheetName: cell.sheetName,\n });\n\n if (sheet) {\n const key = `${String.fromCharCode(65 + cell.colIndex)}${\n cell.rowIndex + 1\n }`;\n sheet.content.delete(key);\n }\n }\n }\n}\n\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "8CA951C1BABE115764756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "1490ADF5C784502364756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -75,10 +75,31 @@ function createRangeEnd(value) {
75
75
  }
76
76
  return { type: "number", value };
77
77
  }
78
+ function intersectRanges(range1, range2) {
79
+ if (!rangesIntersect(range1, range2)) {
80
+ return null;
81
+ }
82
+ const r1EndCol = range1.end.col.type === "number" ? range1.end.col.value : Infinity;
83
+ const r1EndRow = range1.end.row.type === "number" ? range1.end.row.value : Infinity;
84
+ const r2EndCol = range2.end.col.type === "number" ? range2.end.col.value : Infinity;
85
+ const r2EndRow = range2.end.row.type === "number" ? range2.end.row.value : Infinity;
86
+ const startCol = Math.max(range1.start.col, range2.start.col);
87
+ const startRow = Math.max(range1.start.row, range2.start.row);
88
+ const endCol = Math.min(r1EndCol, r2EndCol);
89
+ const endRow = Math.min(r1EndRow, r2EndRow);
90
+ return {
91
+ start: { col: startCol, row: startRow },
92
+ end: {
93
+ col: createRangeEnd(endCol),
94
+ row: createRangeEnd(endRow)
95
+ }
96
+ };
97
+ }
78
98
  export {
79
99
  subtractRange,
80
100
  rangesIntersect,
81
- isRangeContained
101
+ isRangeContained,
102
+ intersectRanges
82
103
  };
83
104
 
84
- //# debugId=F3D0BBCF4CE38B2764756E2164756E21
105
+ //# debugId=B86D083DE55A429D64756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/core/utils/range-utils.ts"],
4
4
  "sourcesContent": [
5
- "/**\n * Range utility functions for handling range arithmetic and operations\n */\n\nimport type { SpreadsheetRange, SpreadsheetRangeEnd } from \"../types.mjs\";\n\n/**\n * Check if two ranges intersect\n */\nexport function rangesIntersect(\n range1: SpreadsheetRange,\n range2: SpreadsheetRange\n): boolean {\n // Get finite end values\n const r1EndCol =\n range1.end.col.type === \"number\" ? range1.end.col.value : Infinity;\n const r1EndRow =\n range1.end.row.type === \"number\" ? range1.end.row.value : Infinity;\n const r2EndCol =\n range2.end.col.type === \"number\" ? range2.end.col.value : Infinity;\n const r2EndRow =\n range2.end.row.type === \"number\" ? range2.end.row.value : Infinity;\n\n // Check if ranges overlap\n const colOverlap =\n range1.start.col <= r2EndCol && range2.start.col <= r1EndCol;\n const rowOverlap =\n range1.start.row <= r2EndRow && range2.start.row <= r1EndRow;\n\n return colOverlap && rowOverlap;\n}\n\n/**\n * Check if one range is completely contained within another\n */\nexport function isRangeContained(\n inner: SpreadsheetRange,\n outer: SpreadsheetRange\n): boolean {\n const innerEndCol =\n inner.end.col.type === \"number\" ? inner.end.col.value : Infinity;\n const innerEndRow =\n inner.end.row.type === \"number\" ? inner.end.row.value : Infinity;\n const outerEndCol =\n outer.end.col.type === \"number\" ? outer.end.col.value : Infinity;\n const outerEndRow =\n outer.end.row.type === \"number\" ? outer.end.row.value : Infinity;\n\n return (\n inner.start.col >= outer.start.col &&\n inner.start.row >= outer.start.row &&\n innerEndCol <= outerEndCol &&\n innerEndRow <= outerEndRow\n );\n}\n\n/**\n * Subtract one range from another, returning the remaining ranges\n * Returns an array of ranges representing `original - subtract`\n * \n * For infinite ranges in the original:\n * - If subtract range is finite, we still return the infinite portions\n * - This can result in up to 4 ranges (4 sides around the subtracted area)\n */\nexport function subtractRange(\n original: SpreadsheetRange,\n subtract: SpreadsheetRange\n): SpreadsheetRange[] {\n // If ranges don't intersect, return original unchanged\n if (!rangesIntersect(original, subtract)) {\n return [original];\n }\n\n // If original is completely contained in subtract, return empty\n if (isRangeContained(original, subtract)) {\n return [];\n }\n\n const result: SpreadsheetRange[] = [];\n\n // Get finite end values for easier arithmetic\n const origEndCol =\n original.end.col.type === \"number\" ? original.end.col.value : Infinity;\n const origEndRow =\n original.end.row.type === \"number\" ? original.end.row.value : Infinity;\n const subEndCol =\n subtract.end.col.type === \"number\" ? subtract.end.col.value : Infinity;\n const subEndRow =\n subtract.end.row.type === \"number\" ? subtract.end.row.value : Infinity;\n\n // Calculate the intersection bounds\n const intersectStartCol = Math.max(original.start.col, subtract.start.col);\n const intersectStartRow = Math.max(original.start.row, subtract.start.row);\n const intersectEndCol = Math.min(origEndCol, subEndCol);\n const intersectEndRow = Math.min(origEndRow, subEndRow);\n\n // Create up to 4 rectangles around the intersection:\n // Top, Bottom, Left, Right\n\n // Top rectangle (above the intersection)\n if (original.start.row < intersectStartRow) {\n result.push({\n start: { col: original.start.col, row: original.start.row },\n end: {\n col: createRangeEnd(origEndCol),\n row: createRangeEnd(intersectStartRow - 1),\n },\n });\n }\n\n // Bottom rectangle (below the intersection)\n if (origEndRow > intersectEndRow) {\n result.push({\n start: { col: original.start.col, row: intersectEndRow + 1 },\n end: {\n col: createRangeEnd(origEndCol),\n row: createRangeEnd(origEndRow),\n },\n });\n }\n\n // Left rectangle (left of the intersection, within the vertical bounds of intersection)\n if (original.start.col < intersectStartCol) {\n result.push({\n start: { col: original.start.col, row: intersectStartRow },\n end: {\n col: createRangeEnd(intersectStartCol - 1),\n row: createRangeEnd(intersectEndRow),\n },\n });\n }\n\n // Right rectangle (right of the intersection, within the vertical bounds of intersection)\n if (origEndCol > intersectEndCol) {\n result.push({\n start: { col: intersectEndCol + 1, row: intersectStartRow },\n end: {\n col: createRangeEnd(origEndCol),\n row: createRangeEnd(intersectEndRow),\n },\n });\n }\n\n return result;\n}\n\n/**\n * Helper to create a SpreadsheetRangeEnd from a number (handles infinity)\n */\nfunction createRangeEnd(value: number): SpreadsheetRangeEnd {\n if (!isFinite(value)) {\n return { type: \"infinity\", sign: \"positive\" };\n }\n return { type: \"number\", value };\n}\n\n"
5
+ "/**\n * Range utility functions for handling range arithmetic and operations\n */\n\nimport type { SpreadsheetRange, SpreadsheetRangeEnd } from \"../types.mjs\";\n\n/**\n * Check if two ranges intersect\n */\nexport function rangesIntersect(\n range1: SpreadsheetRange,\n range2: SpreadsheetRange\n): boolean {\n // Get finite end values\n const r1EndCol =\n range1.end.col.type === \"number\" ? range1.end.col.value : Infinity;\n const r1EndRow =\n range1.end.row.type === \"number\" ? range1.end.row.value : Infinity;\n const r2EndCol =\n range2.end.col.type === \"number\" ? range2.end.col.value : Infinity;\n const r2EndRow =\n range2.end.row.type === \"number\" ? range2.end.row.value : Infinity;\n\n // Check if ranges overlap\n const colOverlap =\n range1.start.col <= r2EndCol && range2.start.col <= r1EndCol;\n const rowOverlap =\n range1.start.row <= r2EndRow && range2.start.row <= r1EndRow;\n\n return colOverlap && rowOverlap;\n}\n\n/**\n * Check if one range is completely contained within another\n */\nexport function isRangeContained(\n inner: SpreadsheetRange,\n outer: SpreadsheetRange\n): boolean {\n const innerEndCol =\n inner.end.col.type === \"number\" ? inner.end.col.value : Infinity;\n const innerEndRow =\n inner.end.row.type === \"number\" ? inner.end.row.value : Infinity;\n const outerEndCol =\n outer.end.col.type === \"number\" ? outer.end.col.value : Infinity;\n const outerEndRow =\n outer.end.row.type === \"number\" ? outer.end.row.value : Infinity;\n\n return (\n inner.start.col >= outer.start.col &&\n inner.start.row >= outer.start.row &&\n innerEndCol <= outerEndCol &&\n innerEndRow <= outerEndRow\n );\n}\n\n/**\n * Subtract one range from another, returning the remaining ranges\n * Returns an array of ranges representing `original - subtract`\n * \n * For infinite ranges in the original:\n * - If subtract range is finite, we still return the infinite portions\n * - This can result in up to 4 ranges (4 sides around the subtracted area)\n */\nexport function subtractRange(\n original: SpreadsheetRange,\n subtract: SpreadsheetRange\n): SpreadsheetRange[] {\n // If ranges don't intersect, return original unchanged\n if (!rangesIntersect(original, subtract)) {\n return [original];\n }\n\n // If original is completely contained in subtract, return empty\n if (isRangeContained(original, subtract)) {\n return [];\n }\n\n const result: SpreadsheetRange[] = [];\n\n // Get finite end values for easier arithmetic\n const origEndCol =\n original.end.col.type === \"number\" ? original.end.col.value : Infinity;\n const origEndRow =\n original.end.row.type === \"number\" ? original.end.row.value : Infinity;\n const subEndCol =\n subtract.end.col.type === \"number\" ? subtract.end.col.value : Infinity;\n const subEndRow =\n subtract.end.row.type === \"number\" ? subtract.end.row.value : Infinity;\n\n // Calculate the intersection bounds\n const intersectStartCol = Math.max(original.start.col, subtract.start.col);\n const intersectStartRow = Math.max(original.start.row, subtract.start.row);\n const intersectEndCol = Math.min(origEndCol, subEndCol);\n const intersectEndRow = Math.min(origEndRow, subEndRow);\n\n // Create up to 4 rectangles around the intersection:\n // Top, Bottom, Left, Right\n\n // Top rectangle (above the intersection)\n if (original.start.row < intersectStartRow) {\n result.push({\n start: { col: original.start.col, row: original.start.row },\n end: {\n col: createRangeEnd(origEndCol),\n row: createRangeEnd(intersectStartRow - 1),\n },\n });\n }\n\n // Bottom rectangle (below the intersection)\n if (origEndRow > intersectEndRow) {\n result.push({\n start: { col: original.start.col, row: intersectEndRow + 1 },\n end: {\n col: createRangeEnd(origEndCol),\n row: createRangeEnd(origEndRow),\n },\n });\n }\n\n // Left rectangle (left of the intersection, within the vertical bounds of intersection)\n if (original.start.col < intersectStartCol) {\n result.push({\n start: { col: original.start.col, row: intersectStartRow },\n end: {\n col: createRangeEnd(intersectStartCol - 1),\n row: createRangeEnd(intersectEndRow),\n },\n });\n }\n\n // Right rectangle (right of the intersection, within the vertical bounds of intersection)\n if (origEndCol > intersectEndCol) {\n result.push({\n start: { col: intersectEndCol + 1, row: intersectStartRow },\n end: {\n col: createRangeEnd(origEndCol),\n row: createRangeEnd(intersectEndRow),\n },\n });\n }\n\n return result;\n}\n\n/**\n * Helper to create a SpreadsheetRangeEnd from a number (handles infinity)\n */\nfunction createRangeEnd(value: number): SpreadsheetRangeEnd {\n if (!isFinite(value)) {\n return { type: \"infinity\", sign: \"positive\" };\n }\n return { type: \"number\", value };\n}\n\n/**\n * Calculate the intersection of two ranges\n * Returns the overlapping rectangle, or null if ranges don't intersect\n */\nexport function intersectRanges(\n range1: SpreadsheetRange,\n range2: SpreadsheetRange\n): SpreadsheetRange | null {\n if (!rangesIntersect(range1, range2)) {\n return null;\n }\n\n // Get finite end values\n const r1EndCol =\n range1.end.col.type === \"number\" ? range1.end.col.value : Infinity;\n const r1EndRow =\n range1.end.row.type === \"number\" ? range1.end.row.value : Infinity;\n const r2EndCol =\n range2.end.col.type === \"number\" ? range2.end.col.value : Infinity;\n const r2EndRow =\n range2.end.row.type === \"number\" ? range2.end.row.value : Infinity;\n\n // Calculate intersection bounds\n const startCol = Math.max(range1.start.col, range2.start.col);\n const startRow = Math.max(range1.start.row, range2.start.row);\n const endCol = Math.min(r1EndCol, r2EndCol);\n const endRow = Math.min(r1EndRow, r2EndRow);\n\n return {\n start: { col: startCol, row: startRow },\n end: {\n col: createRangeEnd(endCol),\n row: createRangeEnd(endRow),\n },\n };\n}\n\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "F3D0BBCF4CE38B2764756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "B86D083DE55A429D64756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@ricsam/formula-engine",
3
- "version": "0.0.9",
3
+ "version": "0.0.10",
4
4
  "type": "module"
5
5
  }
@@ -35,10 +35,6 @@ export declare class CopyManager {
35
35
  * Get bounding box for a set of cells
36
36
  */
37
37
  private getBoundingBox;
38
- /**
39
- * Check if two ranges intersect
40
- */
41
- private rangesIntersect;
42
38
  /**
43
39
  * Adjust a range by row and column offsets
44
40
  */
@@ -19,3 +19,8 @@ export declare function isRangeContained(inner: SpreadsheetRange, outer: Spreads
19
19
  * - This can result in up to 4 ranges (4 sides around the subtracted area)
20
20
  */
21
21
  export declare function subtractRange(original: SpreadsheetRange, subtract: SpreadsheetRange): SpreadsheetRange[];
22
+ /**
23
+ * Calculate the intersection of two ranges
24
+ * Returns the overlapping rectangle, or null if ranges don't intersect
25
+ */
26
+ export declare function intersectRanges(range1: SpreadsheetRange, range2: SpreadsheetRange): SpreadsheetRange | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ricsam/formula-engine",
3
- "version": "0.0.9",
3
+ "version": "0.0.10",
4
4
  "module": "./dist/mjs/lib.mjs",
5
5
  "scripts": {
6
6
  "test": "bun test",