{
  "version": 3,
  "sources": ["../../../../src/core/managers/workbook-manager.ts"],
  "sourcesContent": [
    "import {\n  FormulaError,\n  type CellAddress,\n  type FiniteSpreadsheetRange,\n  type LocalCellAddress,\n  type ReplaceChange,\n  type ReplaceTarget,\n  type SearchMatch,\n  type SearchOptions,\n  type SerializedCellValue,\n  type Sheet,\n  type SpreadsheetRange,\n  type Workbook,\n} from \"../types.mjs\";\nimport type { WorkbookManagerSnapshot } from \"../engine-snapshot.mjs\";\nimport { getCellReference, parseCellReference } from \"../utils.mjs\";\n\nimport type { RangeAddress } from \"../types.mjs\";\nimport { buildRangeEvalOrder } from \"./range-eval-order-builder.mjs\";\nimport {\n  EvaluationError,\n  SheetNotFoundError,\n  WorkbookNotFoundError,\n} from \"../../evaluator/evaluation-error.mjs\";\nimport { normalizeSerializedCellValue } from \"../../parser/formatter.mjs\";\n\ninterface IndexEntry {\n  number: number;\n  key: string;\n}\n\nexport interface SheetIndexes {\n  // lookup maps - cells grouped by row/column\n  rowGroups: Map<number, IndexEntry[]>; // row number -> cells in that row (sorted by col)\n  colGroups: Map<number, IndexEntry[]>; // col number -> cells in that col (sorted by row)\n\n  // Sorted flat indexes - for finding cells before a given row/col\n  cellsSortedByRow: IndexEntry[];\n  cellsSortedByCol: IndexEntry[];\n}\n\ntype SearchScopeSheet = {\n  workbookName: string;\n  sheet: Sheet;\n};\n\ntype SortableSearchMatch = SearchMatch & {\n  rowIndex: number;\n  colIndex: number;\n};\n\ntype StringCellMatch = Pick<\n  SearchMatch,\n  \"occurrenceIndex\" | \"startIndex\" | \"endIndexExclusive\" | \"matchedText\"\n>;\n\ntype PreparedReplace = {\n  address: CellAddress;\n  beforeContent: string;\n  afterContent: string;\n  change: ReplaceChange;\n};\n\ntype PreparedCellReplaceAll = {\n  address: CellAddress;\n  beforeContent: string;\n  afterContent: string;\n  changes: ReplaceChange[];\n};\n\n/**\n * Utility class for binary search operations on IndexEntry arrays\n */\nexport class IndexEntryBinarySearch {\n  /**\n   * Find the insertion point for a number in a sorted IndexEntry array\n   * Returns the index where the number should be inserted to maintain sort order\n   */\n  static findInsertionPoint(entries: IndexEntry[], target: number): number {\n    let left = 0;\n    let right = entries.length;\n\n    while (left < right) {\n      const mid = Math.floor((left + right) / 2);\n      const midEntry = entries[mid];\n      if (midEntry && midEntry.number < target) {\n        left = mid + 1;\n      } else {\n        right = mid;\n      }\n    }\n\n    return left;\n  }\n\n  /**\n   * Find the first element >= target\n   * Returns the index of the first element, or -1 if not found\n   */\n  static findFirstGreaterOrEqual(\n    entries: IndexEntry[],\n    target: number\n  ): number {\n    if (entries.length === 0) return -1;\n\n    let left = 0;\n    let right = entries.length - 1;\n    let result = -1;\n\n    while (left <= right) {\n      const mid = Math.floor((left + right) / 2);\n      const midEntry = entries[mid];\n      if (midEntry && midEntry.number >= target) {\n        result = mid;\n        right = mid - 1;\n      } else {\n        left = mid + 1;\n      }\n    }\n\n    return result;\n  }\n\n  /**\n   * Find the rightmost position where we could insert a target value\n   * Useful for finding elements that come before a target\n   */\n  static findRightmostInsertionPoint(\n    entries: IndexEntry[],\n    target: number\n  ): number {\n    return IndexEntryBinarySearch.findInsertionPoint(entries, target);\n  }\n}\n\nexport class WorkbookManager {\n  private workbooks: Map<string, Workbook> = new Map();\n\n  // Map from \"workbookName|sheetName\" to indexes\n  private sheetIndexes: Map<string, SheetIndexes> = new Map();\n\n  /**\n   * Generate a key for the sheet indexes map\n   */\n  private getSheetIndexKey(workbookName: string, sheetName: string): string {\n    return `${workbookName}|${sheetName}`;\n  }\n\n  /**\n   * Get or create indexes for a sheet\n   */\n  public getSheetIndexes(opts: {\n    workbookName: string;\n    sheetName: string;\n  }): SheetIndexes {\n    const key = this.getSheetIndexKey(opts.workbookName, opts.sheetName);\n    let indexes = this.sheetIndexes.get(key);\n\n    if (!indexes) {\n      indexes = {\n        rowGroups: new Map(),\n        colGroups: new Map(),\n        cellsSortedByRow: [],\n        cellsSortedByCol: [],\n      };\n      this.sheetIndexes.set(key, indexes);\n    }\n\n    return indexes;\n  }\n\n  getSheets(workbookName: string): Map<string, Sheet> {\n    const workbook = this.workbooks.get(workbookName);\n    if (!workbook) {\n      throw new WorkbookNotFoundError(workbookName);\n    }\n    return workbook.sheets;\n  }\n\n  getOrderedSheets(workbookName: string): Sheet[] {\n    const workbook = this.workbooks.get(workbookName);\n    if (!workbook) {\n      throw new WorkbookNotFoundError(workbookName);\n    }\n\n    return Array.from(workbook.sheets.entries())\n      .map(([name, sheet], insertionOrder) => ({\n        name,\n        sheet,\n        insertionOrder,\n      }))\n      .sort((left, right) => {\n        if (left.sheet.index !== right.sheet.index) {\n          return left.sheet.index - right.sheet.index;\n        }\n        return left.insertionOrder - right.insertionOrder;\n      })\n      .map(({ sheet }) => sheet);\n  }\n\n  getOrderedSheetNames(workbookName: string): string[] {\n    return this.getOrderedSheets(workbookName).map((sheet) => sheet.name);\n  }\n\n  getNextAvailableSheetName(\n    workbookName: string,\n    baseName: string = \"Sheet\"\n  ): string {\n    const workbook = this.workbooks.get(workbookName);\n    if (!workbook) {\n      throw new WorkbookNotFoundError(workbookName);\n    }\n\n    let suffix = 1;\n    while (workbook.sheets.has(`${baseName}${suffix}`)) {\n      suffix++;\n    }\n\n    return `${baseName}${suffix}`;\n  }\n\n  getWorkbooks(): Map<string, Workbook> {\n    return this.workbooks;\n  }\n\n  addWorkbook(workbookName: string): void {\n    if (this.workbooks.has(workbookName)) {\n      throw new Error(\"Workbook already exists\");\n    }\n    this.workbooks.set(workbookName, {\n      name: workbookName,\n      sheets: new Map(),\n      workbookMetadata: undefined,\n    });\n  }\n\n  removeWorkbook(workbookName: string): void {\n    const workbook = this.workbooks.get(workbookName);\n    if (!workbook) {\n      throw new WorkbookNotFoundError(workbookName);\n    }\n\n    // Clean up indexes for all sheets in this workbook\n    for (const sheetName of workbook.sheets.keys()) {\n      const key = this.getSheetIndexKey(workbookName, sheetName);\n      this.sheetIndexes.delete(key);\n    }\n\n    this.workbooks.delete(workbookName);\n  }\n\n  isContentEmpty(content: SerializedCellValue): boolean {\n    return content === \"\" || content === undefined;\n  }\n\n  renameWorkbook(opts: {\n    workbookName: string;\n    newWorkbookName: string;\n  }): void {\n    const workbook = this.workbooks.get(opts.workbookName);\n    if (!workbook) {\n      throw new Error(\"Workbook not found\");\n    }\n\n    // Update indexes for all sheets in this workbook\n    for (const sheetName of workbook.sheets.keys()) {\n      const oldKey = this.getSheetIndexKey(opts.workbookName, sheetName);\n      const newKey = this.getSheetIndexKey(opts.newWorkbookName, sheetName);\n      const indexes = this.sheetIndexes.get(oldKey);\n      if (indexes) {\n        this.sheetIndexes.set(newKey, indexes);\n        this.sheetIndexes.delete(oldKey);\n      }\n    }\n\n    this.workbooks.set(opts.newWorkbookName, workbook);\n    this.workbooks.delete(opts.workbookName);\n    workbook.name = opts.newWorkbookName;\n  }\n\n  resetWorkbooks(workbooks: Map<string, Workbook>): void {\n    this.workbooks.clear();\n    this.sheetIndexes.clear();\n\n    workbooks.forEach((workbook, workbookName) => {\n      this.workbooks.set(workbookName, workbook);\n      workbook.sheets.forEach((sheet) => {\n        // Initialize indexes for this sheet\n        const indexes = this.getSheetIndexes({\n          workbookName,\n          sheetName: sheet.name,\n        });\n        indexes.rowGroups.clear();\n        indexes.colGroups.clear();\n        indexes.cellsSortedByRow = [];\n        indexes.cellsSortedByCol = [];\n\n        sheet.content.forEach((value, key) => {\n          this.setCellContent(\n            {\n              workbookName,\n              sheetName: sheet.name,\n              colIndex: parseCellReference(key).colIndex,\n              rowIndex: parseCellReference(key).rowIndex,\n            },\n            value,\n            {\n              sheet,\n              buildingFromScratch: true,\n            }\n          );\n        });\n      });\n    });\n  }\n\n  toSnapshot(): WorkbookManagerSnapshot {\n    return this.getWorkbooks();\n  }\n\n  restoreFromSnapshot(snapshot: WorkbookManagerSnapshot): void {\n    this.resetWorkbooks(snapshot);\n  }\n\n  getSheet({\n    workbookName,\n    sheetName,\n  }: {\n    workbookName: string;\n    sheetName: string;\n  }): Sheet | undefined {\n    const workbook = this.workbooks.get(workbookName);\n    const sheet = workbook?.sheets.get(sheetName);\n    return sheet;\n  }\n\n  addSheet({\n    workbookName,\n    sheetName,\n  }: {\n    workbookName: string;\n    sheetName: string;\n  }): Sheet {\n    const workbook = this.workbooks.get(workbookName);\n    if (!workbook) {\n      throw new WorkbookNotFoundError(workbookName);\n    }\n\n    let nextSheetIndex = -1;\n    for (const existingSheet of workbook.sheets.values()) {\n      nextSheetIndex = Math.max(nextSheetIndex, existingSheet.index);\n    }\n\n    const sheet = {\n      name: sheetName,\n      index: nextSheetIndex + 1,\n      content: new Map(),\n      metadata: new Map(),\n      sheetMetadata: undefined,\n    };\n\n    if (workbook.sheets.has(sheet.name)) {\n      throw new Error(\"Sheet already exists\");\n    }\n\n    workbook.sheets.set(sheetName, sheet);\n\n    // Initialize empty indexes for this sheet\n    this.getSheetIndexes({ workbookName, sheetName });\n\n    return sheet;\n  }\n\n  removeSheet({\n    workbookName,\n    sheetName,\n  }: {\n    workbookName: string;\n    sheetName: string;\n  }): Sheet {\n    const workbook = this.workbooks.get(workbookName);\n    if (!workbook) {\n      throw new WorkbookNotFoundError(workbookName);\n    }\n    const sheet = workbook.sheets.get(sheetName);\n    if (!sheet) {\n      throw new Error(\"Sheet not found\");\n    }\n\n    // Remove the sheet\n    workbook.sheets.delete(sheetName);\n\n    // Clean up indexes for this sheet\n    const key = this.getSheetIndexKey(workbookName, sheetName);\n    this.sheetIndexes.delete(key);\n\n    return sheet;\n  }\n\n  renameSheet({\n    workbookName,\n    sheetName,\n    newSheetName,\n  }: {\n    workbookName: string;\n    sheetName: string;\n    newSheetName: string;\n  }): Sheet {\n    const workbook = this.workbooks.get(workbookName);\n    if (!workbook) {\n      throw new WorkbookNotFoundError(workbookName);\n    }\n    const sheet = workbook.sheets.get(sheetName);\n    if (!sheet) {\n      throw new SheetNotFoundError(sheetName);\n    }\n\n    if (workbook.sheets.has(newSheetName)) {\n      throw new Error(\"Sheet with new name already exists\");\n    }\n\n    // Update sheet name\n    sheet.name = newSheetName;\n\n    // Rebuild the map so the renamed sheet keeps its original position\n    const renamedSheets = new Map<string, Sheet>();\n    for (const [existingSheetName, existingSheet] of workbook.sheets.entries()) {\n      if (existingSheetName === sheetName) {\n        renamedSheets.set(newSheetName, sheet);\n      } else {\n        renamedSheets.set(existingSheetName, existingSheet);\n      }\n    }\n    workbook.sheets.clear();\n    for (const [existingSheetName, existingSheet] of renamedSheets.entries()) {\n      workbook.sheets.set(existingSheetName, existingSheet);\n    }\n\n    // Move indexes to new key\n    const oldKey = this.getSheetIndexKey(workbookName, sheetName);\n    const newKey = this.getSheetIndexKey(workbookName, newSheetName);\n    const indexes = this.sheetIndexes.get(oldKey);\n    if (indexes) {\n      this.sheetIndexes.set(newKey, indexes);\n      this.sheetIndexes.delete(oldKey);\n    }\n\n    return sheet;\n  }\n\n  updateAllFormulas(updateCallback: (formula: string) => string): CellAddress[] {\n    const changed: CellAddress[] = [];\n\n    const update = (workbookName: string, map: Map<string, Sheet>) => {\n      map.forEach((sheet, sheetName) => {\n        sheet.content.forEach((cell, key) => {\n          if (typeof cell === \"string\" && cell.startsWith(\"=\")) {\n            const formula = cell.slice(1);\n            const updatedFormula = updateCallback(formula);\n\n            // Only update if the formula actually changed\n            if (updatedFormula !== formula) {\n              sheet.content.set(key, `=${updatedFormula}`);\n              const { colIndex, rowIndex } = parseCellReference(key);\n              changed.push({\n                workbookName,\n                sheetName,\n                colIndex,\n                rowIndex,\n              });\n            }\n          }\n        });\n      });\n    };\n\n    this.workbooks.forEach((workbook, workbookName) => {\n      update(workbookName, workbook.sheets);\n    });\n\n    return changed;\n  }\n\n  updateFormulasExcluding(\n    excludeCellsSet: Set<string>,\n    updateCallback: (formula: string) => string\n  ): void {\n    this.workbooks.forEach((workbook, workbookName) => {\n      workbook.sheets.forEach((sheet, sheetName) => {\n        sheet.content.forEach((cell, key) => {\n          if (typeof cell === \"string\" && cell.startsWith(\"=\")) {\n            const { colIndex, rowIndex } = parseCellReference(key);\n            const cellKey = `${workbookName}:${sheetName}:${colIndex}:${rowIndex}`;\n            \n            // Skip if this cell is in the exclude set\n            if (excludeCellsSet.has(cellKey)) {\n              return;\n            }\n\n            const formula = cell.slice(1);\n            const updatedFormula = updateCallback(formula);\n\n            // Only update if the formula actually changed\n            if (updatedFormula !== formula) {\n              sheet.content.set(key, `=${updatedFormula}`);\n            }\n          }\n        });\n      });\n    });\n  }\n\n  updateFormulasForWorkbook(\n    workbookName: string,\n    updateCallback: (formula: string) => string\n  ): void {\n    const workbook = this.workbooks.get(workbookName);\n    if (!workbook) {\n      throw new WorkbookNotFoundError(workbookName);\n    }\n\n    workbook.sheets.forEach((sheet) => {\n      sheet.content.forEach((cell, key) => {\n        if (typeof cell === \"string\" && cell.startsWith(\"=\")) {\n          const formula = cell.slice(1);\n          const updatedFormula = updateCallback(formula);\n\n          // Only update if the formula actually changed\n          if (updatedFormula !== formula) {\n            sheet.content.set(key, `=${updatedFormula}`);\n          }\n        }\n      });\n    });\n  }\n\n  getSheetSerialized({\n    workbookName,\n    sheetName,\n  }: {\n    workbookName: string;\n    sheetName: string;\n  }): Map<string, SerializedCellValue> {\n    const workbook = this.workbooks.get(workbookName);\n    if (!workbook) {\n      throw new WorkbookNotFoundError(workbookName);\n    }\n    const sheet = workbook.sheets.get(sheetName);\n    if (!sheet) {\n      throw new SheetNotFoundError(sheetName);\n    }\n\n    return sheet.content;\n  }\n\n  private resolveSearchScope(\n    options?: SearchOptions\n  ): SearchScopeSheet[] {\n    if (options?.sheetName && !options.workbookName) {\n      throw new Error(\"workbookName is required when sheetName is provided\");\n    }\n\n    if (!options?.workbookName) {\n      const scopedSheets: SearchScopeSheet[] = [];\n      for (const workbookName of this.workbooks.keys()) {\n        for (const sheet of this.getOrderedSheets(workbookName)) {\n          scopedSheets.push({ workbookName, sheet });\n        }\n      }\n      return scopedSheets;\n    }\n\n    const workbookName = options.workbookName;\n    if (!this.workbooks.has(workbookName)) {\n      throw new WorkbookNotFoundError(workbookName);\n    }\n\n    if (!options.sheetName) {\n      return this.getOrderedSheets(workbookName).map((sheet) => ({\n        workbookName,\n        sheet,\n      }));\n    }\n\n    const sheet = this.getSheet({\n      workbookName,\n      sheetName: options.sheetName,\n    });\n\n    if (!sheet) {\n      throw new SheetNotFoundError(options.sheetName);\n    }\n\n    return [{ workbookName, sheet }];\n  }\n\n  private getStringContentKind(cellContent: string): SearchMatch[\"contentKind\"] {\n    return cellContent.startsWith(\"=\") ? \"formula\" : \"text\";\n  }\n\n  private findMatchesInString(\n    cellContent: string,\n    query: string,\n    caseSensitive: boolean\n  ): StringCellMatch[] {\n    if (query.length === 0) {\n      return [];\n    }\n\n    const normalizedContent = caseSensitive\n      ? cellContent\n      : cellContent.toLowerCase();\n    const normalizedQuery = caseSensitive ? query : query.toLowerCase();\n    const matches: StringCellMatch[] = [];\n    let searchFromIndex = 0;\n\n    while (searchFromIndex <= normalizedContent.length - normalizedQuery.length) {\n      const startIndex = normalizedContent.indexOf(normalizedQuery, searchFromIndex);\n      if (startIndex === -1) {\n        break;\n      }\n\n      const endIndexExclusive = startIndex + normalizedQuery.length;\n      matches.push({\n        occurrenceIndex: matches.length,\n        startIndex,\n        endIndexExclusive,\n        matchedText: cellContent.slice(startIndex, endIndexExclusive),\n      });\n      searchFromIndex = endIndexExclusive;\n    }\n\n    return matches;\n  }\n\n  private buildSearchMatchesInScope(\n    query: string,\n    scopedSheets: SearchScopeSheet[],\n    caseSensitive: boolean\n  ): SearchMatch[] {\n    const results: SearchMatch[] = [];\n\n    for (const { workbookName, sheet } of scopedSheets) {\n      const sheetMatches: SortableSearchMatch[] = [];\n\n      for (const [cellReference, value] of sheet.content.entries()) {\n        if (typeof value !== \"string\") {\n          continue;\n        }\n\n        const matches = this.findMatchesInString(value, query, caseSensitive);\n        if (matches.length === 0) {\n          continue;\n        }\n\n        const { rowIndex, colIndex } = parseCellReference(cellReference);\n        const contentKind = this.getStringContentKind(value);\n\n        sheetMatches.push(\n          ...matches.map((match) => ({\n            workbookName,\n            sheetName: sheet.name,\n            cellReference,\n            cellContent: value,\n            contentKind,\n            occurrenceIndex: match.occurrenceIndex,\n            startIndex: match.startIndex,\n            endIndexExclusive: match.endIndexExclusive,\n            matchedText: match.matchedText,\n            rowIndex,\n            colIndex,\n          }))\n        );\n      }\n\n      sheetMatches.sort(\n        (left, right) =>\n          left.rowIndex - right.rowIndex ||\n          left.colIndex - right.colIndex ||\n          left.occurrenceIndex - right.occurrenceIndex\n      );\n\n      results.push(\n        ...sheetMatches.map(({ rowIndex: _rowIndex, colIndex: _colIndex, ...match }) => match)\n      );\n    }\n\n    return results;\n  }\n\n  search(\n    query: string,\n    options?: SearchOptions\n  ): SearchMatch[] {\n    const scopedSheets = this.resolveSearchScope(options);\n\n    if (query.length === 0) {\n      return [];\n    }\n\n    return this.buildSearchMatchesInScope(\n      query,\n      scopedSheets,\n      options?.caseSensitive === true\n    );\n  }\n\n  private buildReplacedContent(\n    beforeContent: string,\n    matches: Array<Pick<SearchMatch, \"startIndex\" | \"endIndexExclusive\">>,\n    replacement: string\n  ): string {\n    let cursor = 0;\n    let replacedContent = \"\";\n\n    for (const match of matches) {\n      replacedContent += beforeContent.slice(cursor, match.startIndex);\n      replacedContent += replacement;\n      cursor = match.endIndexExclusive;\n    }\n\n    replacedContent += beforeContent.slice(cursor);\n    return replacedContent;\n  }\n\n  prepareReplace(\n    query: string,\n    replacement: string,\n    target: ReplaceTarget,\n    options?: { caseSensitive?: boolean }\n  ): PreparedReplace {\n    if (query.length === 0) {\n      throw new Error(\"replace requires a non-empty query\");\n    }\n\n    const address: CellAddress = {\n      workbookName: target.workbookName,\n      sheetName: target.sheetName,\n      ...parseCellReference(target.cellReference),\n    };\n    const beforeContent = this.getCellContent(address);\n\n    if (typeof beforeContent !== \"string\") {\n      throw new Error(\n        `replace requires target cell ${target.cellReference} to contain a string`\n      );\n    }\n\n    const matches = this.findMatchesInString(\n      beforeContent,\n      query,\n      options?.caseSensitive === true\n    );\n    const match = matches[target.occurrenceIndex];\n\n    if (!match) {\n      throw new Error(\n        `Occurrence ${target.occurrenceIndex} not found in cell ${target.cellReference}`\n      );\n    }\n\n    const afterContent = this.buildReplacedContent(beforeContent, [match], replacement);\n    const contentKind = this.getStringContentKind(beforeContent);\n\n    return {\n      address,\n      beforeContent,\n      afterContent,\n      change: {\n        workbookName: target.workbookName,\n        sheetName: target.sheetName,\n        cellReference: target.cellReference,\n        contentKind,\n        occurrenceIndex: match.occurrenceIndex,\n        startIndex: match.startIndex,\n        endIndexExclusive: match.endIndexExclusive,\n        matchedText: match.matchedText,\n        replacementText: replacement,\n        beforeContent,\n        afterContent,\n      },\n    };\n  }\n\n  prepareReplaceAll(\n    query: string,\n    replacement: string,\n    options?: SearchOptions\n  ): PreparedCellReplaceAll[] {\n    const scopedSheets = this.resolveSearchScope(options);\n\n    if (query.length === 0) {\n      throw new Error(\"replaceAll requires a non-empty query\");\n    }\n\n    const matches = this.buildSearchMatchesInScope(\n      query,\n      scopedSheets,\n      options?.caseSensitive === true\n    );\n    const matchesByCell = new Map<string, SearchMatch[]>();\n\n    for (const match of matches) {\n      const cellKey = `${match.workbookName}:${match.sheetName}:${match.cellReference}`;\n      const existing = matchesByCell.get(cellKey);\n      if (existing) {\n        existing.push(match);\n      } else {\n        matchesByCell.set(cellKey, [match]);\n      }\n    }\n\n    return Array.from(matchesByCell.values()).map((cellMatches) => {\n      const [firstMatch] = cellMatches;\n      if (!firstMatch) {\n        throw new Error(\"Expected at least one match per cell\");\n      }\n\n      const address: CellAddress = {\n        workbookName: firstMatch.workbookName,\n        sheetName: firstMatch.sheetName,\n        ...parseCellReference(firstMatch.cellReference),\n      };\n      const afterContent = this.buildReplacedContent(\n        firstMatch.cellContent,\n        cellMatches,\n        replacement\n      );\n\n      return {\n        address,\n        beforeContent: firstMatch.cellContent,\n        afterContent,\n        changes: cellMatches.map((match) => ({\n          workbookName: match.workbookName,\n          sheetName: match.sheetName,\n          cellReference: match.cellReference,\n          contentKind: match.contentKind,\n          occurrenceIndex: match.occurrenceIndex,\n          startIndex: match.startIndex,\n          endIndexExclusive: match.endIndexExclusive,\n          matchedText: match.matchedText,\n          replacementText: replacement,\n          beforeContent: firstMatch.cellContent,\n          afterContent,\n        })),\n      };\n    });\n  }\n\n  /**\n   * Add a cell to the grouped indexes\n   */\n  private addCellToGroups(\n    indexes: SheetIndexes,\n    rowIndex: number,\n    colIndex: number,\n    key: string\n  ): void {\n    // Add to row group (cells in this row, sorted by column)\n    let rowGroup = indexes.rowGroups.get(rowIndex);\n    if (!rowGroup) {\n      rowGroup = [];\n      indexes.rowGroups.set(rowIndex, rowGroup);\n    }\n    const colEntry: IndexEntry = { number: colIndex, key };\n    const colInsertIdx = this.findInsertIndex(rowGroup, colIndex);\n    rowGroup.splice(colInsertIdx, 0, colEntry);\n\n    // Add to column group (cells in this column, sorted by row)\n    let colGroup = indexes.colGroups.get(colIndex);\n    if (!colGroup) {\n      colGroup = [];\n      indexes.colGroups.set(colIndex, colGroup);\n    }\n    const rowEntry: IndexEntry = { number: rowIndex, key };\n    const rowInsertIdx = this.findInsertIndex(colGroup, rowIndex);\n    colGroup.splice(rowInsertIdx, 0, rowEntry);\n\n    // Add to sorted flat indexes\n    this.insertSorted(indexes.cellsSortedByRow, { number: rowIndex, key });\n    this.insertSorted(indexes.cellsSortedByCol, { number: colIndex, key });\n  }\n\n  /**\n   * Remove a cell from the grouped indexes\n   */\n  private removeCellFromGroups(\n    indexes: SheetIndexes,\n    rowIndex: number,\n    colIndex: number,\n    key: string\n  ): void {\n    // Remove from row group\n    const rowGroup = indexes.rowGroups.get(rowIndex);\n    if (rowGroup) {\n      const filteredGroup = rowGroup.filter((e) => e.key !== key);\n      if (filteredGroup.length === 0) {\n        indexes.rowGroups.delete(rowIndex);\n      } else {\n        indexes.rowGroups.set(rowIndex, filteredGroup);\n      }\n    }\n\n    // Remove from column group\n    const colGroup = indexes.colGroups.get(colIndex);\n    if (colGroup) {\n      const filteredGroup = colGroup.filter((e) => e.key !== key);\n      if (filteredGroup.length === 0) {\n        indexes.colGroups.delete(colIndex);\n      } else {\n        indexes.colGroups.set(colIndex, filteredGroup);\n      }\n    }\n\n    // Remove from sorted flat indexes\n    indexes.cellsSortedByRow = indexes.cellsSortedByRow.filter(\n      (item) => item.key !== key\n    );\n    indexes.cellsSortedByCol = indexes.cellsSortedByCol.filter(\n      (item) => item.key !== key\n    );\n  }\n\n  /**\n   * Find insertion index in sorted array\n   */\n  private findInsertIndex(entries: IndexEntry[], n: number): number {\n    return IndexEntryBinarySearch.findInsertionPoint(entries, n);\n  }\n\n  /**\n   * Inserts an item into a sorted array by number, maintaining sort order.\n   * If an item with the same number and key already exists, it won't be added again.\n   */\n  private insertSorted(array: IndexEntry[], item: IndexEntry): void {\n    // Check if item already exists (same number and key)\n    const existingIndex = array.findIndex(\n      (existing) => existing.number === item.number && existing.key === item.key\n    );\n\n    if (existingIndex !== -1) {\n      // Item already exists, no need to add it again\n      return;\n    }\n\n    // Find the insertion point using binary search for efficiency\n    const insertionPoint = IndexEntryBinarySearch.findInsertionPoint(\n      array,\n      item.number\n    );\n\n    // Insert at the found position\n    array.splice(insertionPoint, 0, item);\n  }\n\n  setCellContent(\n    address: CellAddress,\n    content: SerializedCellValue,\n    options?: {\n      /**\n       * for extra performance, if the sheet is already known, it can be passed in\n       */\n      sheet?: Sheet;\n      /**\n       * if the sheet is being built from scratch, we can skip some checks\n       */\n      buildingFromScratch?: boolean;\n    }\n  ): void {\n    const sheet =\n      options?.sheet ||\n      this.getSheet({\n        sheetName: address.sheetName,\n        workbookName: address.workbookName,\n      });\n\n    if (!sheet) {\n      throw new SheetNotFoundError(address.sheetName);\n    }\n\n    const indexes = this.getSheetIndexes({\n      workbookName: address.workbookName,\n      sheetName: address.sheetName,\n    });\n    const adr = getCellReference(address);\n\n    if (this.isContentEmpty(content)) {\n      if (!options?.buildingFromScratch) {\n        sheet.content.delete(adr);\n        // Remove from all indexes\n        this.removeCellFromGroups(\n          indexes,\n          address.rowIndex,\n          address.colIndex,\n          adr\n        );\n      }\n    } else {\n      sheet.content.set(adr, content);\n      // Add to all indexes\n      this.addCellToGroups(indexes, address.rowIndex, address.colIndex, adr);\n    }\n  }\n\n  /**\n   * Set metadata for a cell\n   */\n  setCellMetadata<TMetadata = unknown>(address: CellAddress, metadata: TMetadata | undefined): void {\n    const sheet = this.getSheet({\n      workbookName: address.workbookName,\n      sheetName: address.sheetName,\n    });\n    if (!sheet) {\n      throw new SheetNotFoundError(address.sheetName);\n    }\n\n    const key = getCellReference(address);\n    if (metadata === undefined) {\n      sheet.metadata.delete(key);\n    } else {\n      sheet.metadata.set(key, metadata);\n    }\n  }\n\n  /**\n   * Get metadata for a cell\n   */\n  getCellMetadata<TMetadata = unknown>(address: CellAddress): TMetadata | undefined {\n    const sheet = this.getSheet({\n      workbookName: address.workbookName,\n      sheetName: address.sheetName,\n    });\n    if (!sheet) {\n      return undefined;\n    }\n\n    const key = getCellReference(address);\n    return sheet.metadata.get(key) as TMetadata | undefined;\n  }\n\n  /**\n   * Get all metadata for a sheet\n   */\n  getSheetMetadataSerialized<TMetadata = unknown>(opts: {\n    sheetName: string;\n    workbookName: string;\n  }): Map<string, TMetadata> {\n    const sheet = this.getSheet(opts);\n    return sheet?.metadata || new Map();\n  }\n\n  /**\n   * Set metadata for a sheet\n   */\n  setSheetMetadata<TSheetMetadata = unknown>(\n    opts: { workbookName: string; sheetName: string },\n    metadata: TSheetMetadata\n  ): void {\n    const sheet = this.getSheet(opts);\n    if (!sheet) {\n      throw new SheetNotFoundError(opts.sheetName);\n    }\n    sheet.sheetMetadata = metadata;\n  }\n\n  /**\n   * Get metadata for a sheet\n   */\n  getSheetMetadata<TSheetMetadata = unknown>(\n    opts: { workbookName: string; sheetName: string }\n  ): TSheetMetadata | undefined {\n    const sheet = this.getSheet(opts);\n    if (!sheet) {\n      return undefined;\n    }\n    return sheet.sheetMetadata as TSheetMetadata | undefined;\n  }\n\n  /**\n   * Set metadata for a workbook\n   */\n  setWorkbookMetadata<TWorkbookMetadata = unknown>(\n    workbookName: string,\n    metadata: TWorkbookMetadata\n  ): void {\n    const workbook = this.workbooks.get(workbookName);\n    if (!workbook) {\n      throw new Error(`Workbook \"${workbookName}\" not found`);\n    }\n    workbook.workbookMetadata = metadata;\n  }\n\n  /**\n   * Get metadata for a workbook\n   */\n  getWorkbookMetadata<TWorkbookMetadata = unknown>(\n    workbookName: string\n  ): TWorkbookMetadata | undefined {\n    const workbook = this.workbooks.get(workbookName);\n    if (!workbook) {\n      return undefined;\n    }\n    return workbook.workbookMetadata as TWorkbookMetadata | undefined;\n  }\n\n  /**\n   * Replace all content for a sheet (safely, without breaking references)\n   * This method clears the existing Map and repopulates it rather than replacing the Map reference\n   */\n  setSheetContent(\n    opts: { sheetName: string; workbookName: string },\n    newContent: Map<string, SerializedCellValue>\n  ): void {\n    const sheet = this.getSheet(opts);\n    if (!sheet) {\n      throw new SheetNotFoundError(opts.sheetName);\n    }\n\n    // Clear existing content without breaking the Map reference\n    sheet.content.clear();\n\n    // Clean up indexes for this sheet\n    const key = this.getSheetIndexKey(opts.workbookName, opts.sheetName);\n    this.sheetIndexes.delete(key);\n\n    // Repopulate with new content\n    newContent.forEach((value, key) => {\n      this.setCellContent(\n        {\n          workbookName: opts.workbookName,\n          sheetName: opts.sheetName,\n          colIndex: parseCellReference(key).colIndex,\n          rowIndex: parseCellReference(key).rowIndex,\n        },\n        value,\n        {\n          sheet,\n          buildingFromScratch: true,\n        }\n      );\n    });\n  }\n\n  /**\n   * Removes the content in the spreadsheet that is inside the range.\n   * OPTIMIZED: Uses indexes to only process cells that actually exist.\n   * ENHANCED: Now supports infinite ranges.\n   */\n  clearSpreadsheetRange(address: RangeAddress) {\n    const sheet = this.getSheet(address);\n\n    if (!sheet) {\n      throw new SheetNotFoundError(address.sheetName);\n    }\n\n    // Get current sheet content and prepare new content with cleared cells\n    const newContent = new Map(sheet.content);\n    const newMetadata = new Map(sheet.metadata);\n\n    // Use iterateCellsInRange to only process cells that actually exist\n    // This handles both finite and infinite ranges efficiently\n    for (const cellAddress of this.iterateCellsInRange(address)) {\n      const cellRef = getCellReference(cellAddress);\n\n      // Remove from content and metadata\n      newContent.delete(cellRef);\n      newMetadata.delete(cellRef);\n    }\n\n    // Update content\n    this.setSheetContent(address, newContent);\n    \n    // Update metadata\n    sheet.metadata = newMetadata;\n  }\n\n  /**\n   * Optimized generator to iterate over cells defined in the content within a range\n   * Uses indexes to efficiently find and yield only cells that exist within the range\n   */\n  *iterateCellsInRange(address: RangeAddress): Generator<CellAddress> {\n    // First check if the sheet exists\n    const sheet = this.getSheet(address);\n    if (!sheet) {\n      throw new SheetNotFoundError(address.sheetName);\n    }\n\n    const indexes = this.getSheetIndexes(address);\n\n    const range = address.range;\n\n    // Use the sorted index to find only rows that actually contain cells\n    // This avoids iterating through empty rows regardless of finite/infinite bounds\n\n    if (range.end.row.type === \"number\") {\n      // Finite bounds: Use binary search to find the range of cells to check\n      const startIndex = IndexEntryBinarySearch.findFirstGreaterOrEqual(\n        indexes.cellsSortedByRow,\n        range.start.row\n      );\n\n      if (startIndex === -1) return; // No cells at or after start row\n\n      // Process cells from startIndex until we exceed the end row\n      for (let i = startIndex; i < indexes.cellsSortedByRow.length; i++) {\n        const cellEntry = indexes.cellsSortedByRow[i];\n        if (!cellEntry) continue;\n\n        const parsed = parseCellReference(cellEntry.key);\n\n        // Stop if we've gone beyond the row range\n        if (parsed.rowIndex > range.end.row.value) break;\n\n        // Check if cell is within column bounds\n        if (parsed.colIndex < range.start.col) continue;\n\n        if (\n          range.end.col.type === \"number\" &&\n          parsed.colIndex > range.end.col.value\n        ) {\n          continue; // Skip this cell but keep checking others in different rows\n        }\n\n        yield {\n          rowIndex: parsed.rowIndex,\n          colIndex: parsed.colIndex,\n          sheetName: address.sheetName,\n          workbookName: address.workbookName,\n        };\n      }\n    } else {\n      // Infinite row bounds: Use binary search to find starting point\n      const startIndex = IndexEntryBinarySearch.findFirstGreaterOrEqual(\n        indexes.cellsSortedByRow,\n        range.start.row\n      );\n\n      if (startIndex === -1) return; // No cells at or after start row\n\n      // Process all cells from startIndex to end\n      for (let i = startIndex; i < indexes.cellsSortedByRow.length; i++) {\n        const cellEntry = indexes.cellsSortedByRow[i];\n        if (!cellEntry) continue;\n\n        const parsed = parseCellReference(cellEntry.key);\n\n        // Check if cell is within column bounds\n        if (parsed.colIndex < range.start.col) continue;\n\n        if (\n          range.end.col.type === \"number\" &&\n          parsed.colIndex > range.end.col.value\n        ) {\n          continue; // Skip this cell but keep checking others in different rows\n        }\n\n        yield {\n          rowIndex: parsed.rowIndex,\n          colIndex: parsed.colIndex,\n          sheetName: address.sheetName,\n          workbookName: address.workbookName,\n        };\n      }\n    }\n  }\n\n  getCellsInRange(address: RangeAddress): CellAddress[] {\n    return Array.from(this.iterateCellsInRange(address));\n  }\n\n  public getCellContent(cellAddress: CellAddress): SerializedCellValue {\n    const sheet = this.getSheet(cellAddress);\n    if (!sheet) {\n      throw new SheetNotFoundError(cellAddress.sheetName);\n    }\n    return sheet.content.get(getCellReference(cellAddress));\n  }\n\n  public getSerializedCellValue(cellAddress: CellAddress): SerializedCellValue {\n    const sheet = this.getSheet(cellAddress);\n    if (!sheet) {\n      throw new SheetNotFoundError(cellAddress.sheetName);\n    }\n    return normalizeSerializedCellValue(\n      sheet.content.get(getCellReference(cellAddress))\n    );\n  }\n\n  public isCellEmpty(cellAddress: CellAddress): boolean {\n    const content = this.getCellContent(cellAddress);\n    return (\n      content === undefined || (typeof content === \"string\" && content === \"\")\n    );\n  }\n  public isFormulaCell(cellAddress: CellAddress): boolean {\n    const content = this.getCellContent(cellAddress);\n    return typeof content === \"string\" && content.startsWith(\"=\");\n  }\n\n  /**\n   * Build evaluation order for a range\n   * Delegates to the buildRangeEvalOrder function\n   */\n  public buildRangeEvalOrder(\n    lookupOrder: \"row-major\" | \"col-major\",\n    lookupRange: RangeAddress\n  ) {\n    // Import and call the function\n    return buildRangeEvalOrder.call(this, lookupOrder, lookupRange);\n  }\n}\n"
  ],
  "mappings": "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",
  "debugId": "30E4B573D7FD281D64756E2164756E21",
  "names": []
}