{
  "version": 3,
  "sources": ["../../../../src/core/managers/range-eval-order-builder.ts"],
  "sourcesContent": [
    "import { EvaluationError } from \"../../evaluator/evaluation-error.mjs\";\nimport {\n  FormulaError,\n  type CellAddress,\n  type RangeAddress,\n  type Sheet\n} from \"../types.mjs\";\nimport { getCellReference } from \"../utils.mjs\";\nimport {\n  IndexEntryBinarySearch,\n  type SheetIndexes,\n  type WorkbookManager,\n} from \"./workbook-manager.mjs\";\n\nexport type LookupOrder = \"row-major\" | \"col-major\";\n\nexport type RangeEvalOrderEntryDict = {\n  value: {\n    type: \"value\";\n    address: CellAddress;\n  };\n  empty_cell: {\n    type: \"empty_cell\";\n    address: CellAddress;\n    candidates: CellAddress[];\n  };\n  empty_range: {\n    type: \"empty_range\";\n    address: RangeAddress;\n    candidates: CellAddress[];\n  };\n};\n\nexport type RangeEvalOrderEntry =\n  | RangeEvalOrderEntryDict[\"value\"]\n  | RangeEvalOrderEntryDict[\"empty_cell\"]\n  | RangeEvalOrderEntryDict[\"empty_range\"];\n\n/**\n * Build a deterministic, ordered list describing every cell inside a lookup range.\n * This function analyzes the range and classifies each cell/range as either:\n * - A value-like cell (occupied)\n * - An empty cell with 0-2 frontier candidates\n * - An empty range with 0-2 frontier candidates\n *\n * @param this - WorkbookManager instance\n * @param lookupOrder - \"row-major\" or \"col-major\" iteration order\n * @param lookupRange - The range to analyze\n * @returns Ordered array of entries describing the range\n */\nexport function buildRangeEvalOrder(\n  this: WorkbookManager,\n  lookupOrder: LookupOrder,\n  lookupRange: RangeAddress\n): RangeEvalOrderEntry[] {\n  const sheet = this.getSheet(lookupRange);\n  if (!sheet) {\n    throw new EvaluationError(\n      FormulaError.REF,\n      `Sheet ${lookupRange.sheetName} not found`\n    );\n  }\n\n  const result: RangeEvalOrderEntry[] = [];\n\n  // Get range bounds\n  const startRow = lookupRange.range.start.row;\n  const startCol = lookupRange.range.start.col;\n\n  // Build a map of occupied cells within the range\n  const occupiedCells = new Map<string, CellAddress>();\n  let maxRow = startRow;\n  let maxCol = startCol;\n\n  for (const cellAddr of this.iterateCellsInRange(lookupRange)) {\n    occupiedCells.set(getCellReference(cellAddr), cellAddr);\n    maxRow = Math.max(maxRow, cellAddr.rowIndex);\n    maxCol = Math.max(maxCol, cellAddr.colIndex);\n  }\n\n  // For infinite ranges, also consider ALL occupied cells in the sheet\n  // (including frontier candidates and their spills) to determine extent\n  if (\n    lookupRange.range.end.row.type === \"infinity\" ||\n    lookupRange.range.end.col.type === \"infinity\"\n  ) {\n    // Get all cells in the sheet to find the full extent\n    const allCells = this.iterateCellsInRange({\n      workbookName: lookupRange.workbookName,\n      sheetName: lookupRange.sheetName,\n      range: {\n        start: { row: 0, col: 0 },\n        end: {\n          row: { type: \"infinity\", sign: \"positive\" },\n          col: { type: \"infinity\", sign: \"positive\" },\n        },\n      },\n    });\n\n    for (const cellAddr of allCells) {\n      // Consider all occupied cells (formulas and values) to determine extent\n      maxRow = Math.max(maxRow, cellAddr.rowIndex);\n      maxCol = Math.max(maxCol, cellAddr.colIndex);\n    }\n  }\n\n  // Determine the effective end bounds\n  // For finite ranges, use the specified end\n  // For infinite ranges, use the maximum cell found (including frontier candidates)\n  const endRow =\n    lookupRange.range.end.row.type === \"number\"\n      ? lookupRange.range.end.row.value\n      : maxRow;\n  const endCol =\n    lookupRange.range.end.col.type === \"number\"\n      ? lookupRange.range.end.col.value\n      : maxCol;\n\n  // Optimization: If the lookup range is infinite and has NO occupied cells within it,\n  // emit a single infinite range with ALL candidates from the sheet that could affect it\n  const isInfinite =\n    lookupRange.range.end.row.type === \"infinity\" ||\n    lookupRange.range.end.col.type === \"infinity\";\n\n  if (isInfinite && occupiedCells.size === 0) {\n    // Find all formula candidates that could spill into this range\n    // by checking formulas to the left and above of the range\n    const leftCandidates = new Map<string, CellAddress>();\n    const aboveCandidates = new Map<string, CellAddress>();\n    const diagonalCandidates = new Map<string, CellAddress>();\n\n    // Iterate all cells in the sheet to find candidates\n    // (formulas to the left or above that could spill into the range)\n    const allCells = this.iterateCellsInRange({\n      workbookName: lookupRange.workbookName,\n      sheetName: lookupRange.sheetName,\n      range: {\n        start: { row: 0, col: 0 },\n        end: {\n          row: { type: \"infinity\", sign: \"positive\" },\n          col: { type: \"infinity\", sign: \"positive\" },\n        },\n      },\n    });\n\n    for (const cellAddr of allCells) {\n      const cellRef = getCellReference(cellAddr);\n      const content = sheet.content.get(cellRef);\n\n      // Only consider formula cells\n      if (typeof content === \"string\" && content.startsWith(\"=\")) {\n        // Check if this formula could spill into the lookup range\n        // A formula at (r, c) can spill into a range starting at (startRow, startCol) if:\n        // 1. It's directly to the left: c < startCol AND r >= startRow (same row or below)\n        // 2. It's directly above: r < startRow AND c >= startCol (same column or to the right)\n        // 3. It's diagonal: r < startRow AND c < startCol (can spill down-right)\n\n        const isLeftCandidate =\n          cellAddr.colIndex < startCol && cellAddr.rowIndex >= startRow;\n        const isAboveCandidate =\n          cellAddr.rowIndex < startRow && cellAddr.colIndex >= startCol;\n        const isDiagonalCandidate =\n          cellAddr.rowIndex < startRow && cellAddr.colIndex < startCol;\n\n        if (isLeftCandidate) {\n          leftCandidates.set(cellRef, cellAddr);\n        } else if (isAboveCandidate) {\n          aboveCandidates.set(cellRef, cellAddr);\n        } else if (isDiagonalCandidate) {\n          diagonalCandidates.set(cellRef, cellAddr);\n        }\n      }\n    }\n\n    // Only include diagonal candidates if there are NO direct left/above candidates\n    const candidateMap = new Map<string, CellAddress>();\n    if (leftCandidates.size > 0 || aboveCandidates.size > 0) {\n      // Have direct candidates - use only those\n      for (const [ref, addr] of leftCandidates) {\n        candidateMap.set(ref, addr);\n      }\n      for (const [ref, addr] of aboveCandidates) {\n        candidateMap.set(ref, addr);\n      }\n    } else {\n      // No direct candidates - use diagonals\n      for (const [ref, addr] of diagonalCandidates) {\n        candidateMap.set(ref, addr);\n      }\n    }\n\n    const candidates = sortCandidates(\n      Array.from(candidateMap.values()),\n      lookupOrder\n    );\n\n    result.push({\n      type: \"empty_range\",\n      address: lookupRange,\n      candidates,\n    });\n    return result;\n  }\n\n  if (lookupOrder === \"row-major\") {\n    // Get indexes for efficient row/column lookups\n    const indexes = this.getSheetIndexes({\n      workbookName: lookupRange.workbookName,\n      sheetName: lookupRange.sheetName,\n    });\n\n    // Iterate row by row, left to right\n    for (let row = startRow; row <= endRow; row++) {\n      // Check if this row has any occupied cells using indexes\n      const hasOccupiedInRow = indexes.rowGroups.has(row);\n\n      // If the row has no occupied cells and the range is infinite in columns,\n      // emit a single infinite range for the entire row\n      if (!hasOccupiedInRow && lookupRange.range.end.col.type === \"infinity\") {\n        const firstCell: CellAddress = {\n          rowIndex: row,\n          colIndex: startCol,\n          sheetName: lookupRange.sheetName,\n          workbookName: lookupRange.workbookName,\n        };\n\n        const candidates = findCandidatesForCell.call(\n          this,\n          firstCell,\n          sheet,\n          lookupOrder\n        );\n\n        result.push({\n          type: \"empty_range\",\n          address: {\n            workbookName: lookupRange.workbookName,\n            sheetName: lookupRange.sheetName,\n            range: {\n              start: {\n                row: row,\n                col: startCol,\n              },\n              end: {\n                row: { type: \"number\", value: row },\n                col: lookupRange.range.end.col,\n              },\n            },\n          },\n          candidates,\n        });\n        continue; // Skip normal processing for this row\n      }\n\n      processRowMajorRow.call(\n        this,\n        row,\n        startCol,\n        endCol,\n        lookupRange,\n        occupiedCells,\n        sheet,\n        result,\n        indexes\n      );\n\n      // If the lookup range is infinite in columns, emit a final infinite range for this row ONLY\n      if (lookupRange.range.end.col.type === \"infinity\") {\n        const nextCol = endCol + 1;\n        const firstCellBeyondEnd: CellAddress = {\n          rowIndex: row,\n          colIndex: nextCol,\n          sheetName: lookupRange.sheetName,\n          workbookName: lookupRange.workbookName,\n        };\n\n        const candidates = findCandidatesForCell.call(\n          this,\n          firstCellBeyondEnd,\n          sheet,\n          lookupOrder\n        );\n\n        result.push({\n          type: \"empty_range\",\n          address: {\n            workbookName: lookupRange.workbookName,\n            sheetName: lookupRange.sheetName,\n            range: {\n              start: {\n                row: row,\n                col: nextCol,\n              },\n              end: {\n                // Always constrain to this row only in row-major\n                row: { type: \"number\", value: row },\n                col: lookupRange.range.end.col,\n              },\n            },\n          },\n          candidates,\n        });\n      }\n    }\n\n    // If the lookup range is infinite in rows, emit a final infinite range\n    if (lookupRange.range.end.row.type === \"infinity\") {\n      // Find candidates for cells beyond the last processed row\n      const nextRow = endRow + 1;\n      const firstCellInNextRow: CellAddress = {\n        rowIndex: nextRow,\n        colIndex: startCol,\n        sheetName: lookupRange.sheetName,\n        workbookName: lookupRange.workbookName,\n      };\n\n      const candidates = findCandidatesForCell.call(\n        this,\n        firstCellInNextRow,\n        sheet,\n        lookupOrder\n      );\n\n      result.push({\n        type: \"empty_range\",\n        address: {\n          workbookName: lookupRange.workbookName,\n          sheetName: lookupRange.sheetName,\n          range: {\n            start: {\n              row: nextRow,\n              col: startCol,\n            },\n            end: {\n              row: lookupRange.range.end.row,\n              col: lookupRange.range.end.col,\n            },\n          },\n        },\n        candidates,\n      });\n    }\n  } else {\n    // Get indexes for efficient row/column lookups\n    const indexes = this.getSheetIndexes({\n      workbookName: lookupRange.workbookName,\n      sheetName: lookupRange.sheetName,\n    });\n\n    // col-major: iterate column by column, top to bottom\n    for (let col = startCol; col <= endCol; col++) {\n      // Check if this column has any occupied cells using indexes\n      const hasOccupiedInColumn = indexes.colGroups.has(col);\n\n      // If the column has no occupied cells and the range is infinite in rows,\n      // emit a single infinite range for the entire column\n      if (\n        !hasOccupiedInColumn &&\n        lookupRange.range.end.row.type === \"infinity\"\n      ) {\n        const firstCell: CellAddress = {\n          rowIndex: startRow,\n          colIndex: col,\n          sheetName: lookupRange.sheetName,\n          workbookName: lookupRange.workbookName,\n        };\n\n        const candidates = findCandidatesForCell.call(\n          this,\n          firstCell,\n          sheet,\n          lookupOrder\n        );\n\n        result.push({\n          type: \"empty_range\",\n          address: {\n            workbookName: lookupRange.workbookName,\n            sheetName: lookupRange.sheetName,\n            range: {\n              start: {\n                row: startRow,\n                col: col,\n              },\n              end: {\n                row: lookupRange.range.end.row,\n                col: { type: \"number\", value: col },\n              },\n            },\n          },\n          candidates,\n        });\n        continue; // Skip normal processing for this column\n      }\n\n      processColMajorColumn.call(\n        this,\n        col,\n        startRow,\n        endRow,\n        lookupRange,\n        occupiedCells,\n        sheet,\n        result,\n        indexes\n      );\n\n      // If the lookup range is infinite in rows, emit a final infinite range for this column ONLY\n      if (lookupRange.range.end.row.type === \"infinity\") {\n        const nextRow = endRow + 1;\n        const firstCellBeyondEnd: CellAddress = {\n          rowIndex: nextRow,\n          colIndex: col,\n          sheetName: lookupRange.sheetName,\n          workbookName: lookupRange.workbookName,\n        };\n\n        const candidates = findCandidatesForCell.call(\n          this,\n          firstCellBeyondEnd,\n          sheet,\n          lookupOrder\n        );\n\n        result.push({\n          type: \"empty_range\",\n          address: {\n            workbookName: lookupRange.workbookName,\n            sheetName: lookupRange.sheetName,\n            range: {\n              start: {\n                row: nextRow,\n                col: col,\n              },\n              end: {\n                row: lookupRange.range.end.row,\n                // Always constrain to this column only in col-major\n                col: { type: \"number\", value: col },\n              },\n            },\n          },\n          candidates,\n        });\n      }\n    }\n\n    // If the lookup range is infinite in columns, emit a final infinite range\n    if (lookupRange.range.end.col.type === \"infinity\") {\n      // Find candidates for cells beyond the last processed column\n      const nextCol = endCol + 1;\n      const firstCellInNextCol: CellAddress = {\n        rowIndex: startRow,\n        colIndex: nextCol,\n        sheetName: lookupRange.sheetName,\n        workbookName: lookupRange.workbookName,\n      };\n\n      const candidates = findCandidatesForCell.call(\n        this,\n        firstCellInNextCol,\n        sheet,\n        lookupOrder\n      );\n\n      result.push({\n        type: \"empty_range\",\n        address: {\n          workbookName: lookupRange.workbookName,\n          sheetName: lookupRange.sheetName,\n          range: {\n            start: {\n              row: startRow,\n              col: nextCol,\n            },\n            end: {\n              row: lookupRange.range.end.row,\n              col: lookupRange.range.end.col,\n            },\n          },\n        },\n        candidates,\n      });\n    }\n  }\n\n  return result;\n}\n\n/**\n * Process a single row in row-major order\n */\nfunction processRowMajorRow(\n  this: WorkbookManager,\n  row: number,\n  startCol: number,\n  endCol: number,\n  lookupRange: RangeAddress,\n  occupiedCells: Map<string, CellAddress>,\n  sheet: Sheet,\n  result: RangeEvalOrderEntry[],\n  indexes: SheetIndexes\n): void {\n  let col = startCol;\n\n  while (col <= endCol) {\n    const cellAddr: CellAddress = {\n      rowIndex: row,\n      colIndex: col,\n      sheetName: lookupRange.sheetName,\n      workbookName: lookupRange.workbookName,\n    };\n    const cellRef = getCellReference(cellAddr);\n\n    if (occupiedCells.has(cellRef)) {\n      // This cell is occupied (has a value or formula)\n      result.push({\n        type: \"value\",\n        address: cellAddr,\n      });\n      col++;\n    } else {\n      // This cell is empty - find the contiguous empty range in this row with same candidates\n      const emptyRangeStart = col;\n      let emptyRangeEnd = endCol;\n\n      // Find next occupied cell in this row using binary search (O(log n))\n      const rowGroup = indexes.rowGroups.get(row);\n      if (rowGroup) {\n        // Binary search for the first cell in this row with colIndex > col\n        const nextCellIdx = IndexEntryBinarySearch.findFirstGreaterOrEqual(\n          rowGroup,\n          col + 1\n        );\n        if (nextCellIdx !== -1) {\n          emptyRangeEnd = rowGroup[nextCellIdx]!.number - 1;\n        }\n      }\n\n      // Find ALL unique candidates across the entire empty range\n      const allCandidates = findAllCandidatesForRange(\n        this,\n        {\n          workbookName: lookupRange.workbookName,\n          sheetName: lookupRange.sheetName,\n          range: {\n            start: { row, col: emptyRangeStart },\n            end: {\n              row: { type: \"number\", value: row },\n              col: { type: \"number\", value: emptyRangeEnd },\n            },\n          },\n        },\n        sheet,\n        \"row-major\"\n      );\n\n      // If the empty range is a single cell, emit as empty_cell\n      if (emptyRangeStart === emptyRangeEnd) {\n        result.push({\n          type: \"empty_cell\",\n          address: cellAddr,\n          candidates: allCandidates,\n        });\n      } else {\n        // Emit as empty_range\n        result.push({\n          type: \"empty_range\",\n          address: {\n            workbookName: lookupRange.workbookName,\n            sheetName: lookupRange.sheetName,\n            range: {\n              start: {\n                row,\n                col: emptyRangeStart,\n              },\n              end: {\n                row: { type: \"number\", value: row },\n                col: { type: \"number\", value: emptyRangeEnd },\n              },\n            },\n          },\n          candidates: allCandidates,\n        });\n      }\n\n      col = emptyRangeEnd + 1;\n    }\n  }\n}\n\n/**\n * Process a single column in col-major order\n */\nfunction processColMajorColumn(\n  this: WorkbookManager,\n  col: number,\n  startRow: number,\n  endRow: number,\n  lookupRange: RangeAddress,\n  occupiedCells: Map<string, CellAddress>,\n  sheet: Sheet,\n  result: RangeEvalOrderEntry[],\n  indexes: SheetIndexes\n): void {\n  let row = startRow;\n\n  while (row <= endRow) {\n    const cellAddr: CellAddress = {\n      rowIndex: row,\n      colIndex: col,\n      sheetName: lookupRange.sheetName,\n      workbookName: lookupRange.workbookName,\n    };\n    const cellRef = getCellReference(cellAddr);\n\n    if (occupiedCells.has(cellRef)) {\n      // This cell is occupied (has a value or formula)\n      result.push({\n        type: \"value\",\n        address: cellAddr,\n      });\n      row++;\n    } else {\n      // This cell is empty - find the contiguous empty range in this column with same candidates\n      const emptyRangeStart = row;\n      let emptyRangeEnd = endRow;\n\n      // Find next occupied cell in this column using binary search (O(log n))\n      const colGroup = indexes.colGroups.get(col);\n      if (colGroup) {\n        // Binary search for the first cell in this column with rowIndex > row\n        const nextCellIdx = IndexEntryBinarySearch.findFirstGreaterOrEqual(\n          colGroup,\n          row + 1\n        );\n        if (nextCellIdx !== -1) {\n          emptyRangeEnd = colGroup[nextCellIdx]!.number - 1;\n        }\n      }\n\n      // Find ALL unique candidates across the entire empty range\n      const allCandidates = findAllCandidatesForRange(\n        this,\n        {\n          workbookName: lookupRange.workbookName,\n          sheetName: lookupRange.sheetName,\n          range: {\n            start: { row: emptyRangeStart, col },\n            end: {\n              row: { type: \"number\", value: emptyRangeEnd },\n              col: { type: \"number\", value: col },\n            },\n          },\n        },\n        sheet,\n        \"col-major\"\n      );\n\n      // If the empty range is a single cell, emit as empty_cell\n      if (emptyRangeStart === emptyRangeEnd) {\n        result.push({\n          type: \"empty_cell\",\n          address: cellAddr,\n          candidates: allCandidates,\n        });\n      } else {\n        // Emit as empty_range\n        result.push({\n          type: \"empty_range\",\n          address: {\n            workbookName: lookupRange.workbookName,\n            sheetName: lookupRange.sheetName,\n            range: {\n              start: {\n                row: emptyRangeStart,\n                col,\n              },\n              end: {\n                row: { type: \"number\", value: emptyRangeEnd },\n                col: { type: \"number\", value: col },\n              },\n            },\n          },\n          candidates: allCandidates,\n        });\n      }\n\n      row = emptyRangeEnd + 1;\n    }\n  }\n}\n\n/**\n * Find ALL unique candidates that could affect any cell in the given empty range\n * Returns the union of candidates from all cells in the range, sorted deterministically\n */\nfunction findAllCandidatesForRange(\n  manager: WorkbookManager,\n  emptyRange: RangeAddress,\n  sheet: Sheet,\n  lookupOrder: LookupOrder\n): CellAddress[] {\n  const candidateMap = new Map<string, CellAddress>();\n\n  const startRow = emptyRange.range.start.row;\n  const startCol = emptyRange.range.start.col;\n  const endRow =\n    emptyRange.range.end.row.type === \"number\"\n      ? emptyRange.range.end.row.value\n      : startRow;\n  const endCol =\n    emptyRange.range.end.col.type === \"number\"\n      ? emptyRange.range.end.col.value\n      : startCol;\n\n  // We need to check positions that could have different candidates:\n  // - Different columns might have different \"above\" candidates\n  // - Different rows might have different \"left\" candidates\n  const positionsToCheck: Array<{ row: number; col: number }> = [];\n\n  // For single-row ranges: check each column (different above candidates)\n  // For single-column ranges: sample rows efficiently\n  // For rectangular ranges: check corners only\n\n  if (startRow === endRow) {\n    // Single row: check each column (each column might have different above candidates)\n    for (let col = startCol; col <= endCol; col++) {\n      positionsToCheck.push({ row: startRow, col });\n    }\n  } else if (startCol === endCol) {\n    // Single column: For large ranges, sample rows instead of checking all\n    // We check where occupied cells exist, plus endpoints\n    const maxSamples = 100; // Performance limit\n    const numRows = endRow - startRow + 1;\n\n    if (numRows <= maxSamples) {\n      // Small range: check every row\n      for (let row = startRow; row <= endRow; row++) {\n        positionsToCheck.push({ row, col: startCol });\n      }\n    } else {\n      // Large range: sample at occupied cell rows + endpoints\n      positionsToCheck.push({ row: startRow, col: startCol }); // First\n      positionsToCheck.push({ row: endRow, col: startCol }); // Last\n\n      // Add samples at rows where there are occupied cells to the left\n      // (these are the rows that might have different left candidates)\n      // Use indexes to efficiently find occupied cells instead of nested loop\n      const indexes = manager.getSheetIndexes({\n        workbookName: emptyRange.workbookName,\n        sheetName: emptyRange.sheetName,\n      });\n\n      const seenRows = new Set<number>();\n      for (let c = 0; c < startCol; c++) {\n        const colGroup = indexes.colGroups.get(c);\n        if (colGroup) {\n          // Use binary search to find cells in this column within the row range\n          const startIdx = IndexEntryBinarySearch.findFirstGreaterOrEqual(\n            colGroup,\n            startRow\n          );\n          if (startIdx !== -1) {\n            for (let i = startIdx; i < colGroup.length; i++) {\n              const entry = colGroup[i];\n              if (!entry || entry.number > endRow) break;\n              if (!seenRows.has(entry.number)) {\n                seenRows.add(entry.number);\n                positionsToCheck.push({ row: entry.number, col: startCol });\n              }\n            }\n          }\n        }\n      }\n    }\n  } else {\n    // Rectangular range: check corners only for performance\n    positionsToCheck.push({ row: startRow, col: startCol }); // Top-left\n    positionsToCheck.push({ row: startRow, col: endCol }); // Top-right\n    positionsToCheck.push({ row: endRow, col: startCol }); // Bottom-left\n    positionsToCheck.push({ row: endRow, col: endCol }); // Bottom-right\n  }\n\n  // For each position, find candidates\n  for (const pos of positionsToCheck) {\n    const candidates = findCandidatesForCell.call(\n      manager,\n      {\n        rowIndex: pos.row,\n        colIndex: pos.col,\n        sheetName: emptyRange.sheetName,\n        workbookName: emptyRange.workbookName,\n      },\n      sheet,\n      lookupOrder\n    );\n\n    for (const cand of candidates) {\n      candidateMap.set(getCellReference(cand), cand);\n    }\n  }\n\n  // Return unique candidates, sorted\n  return sortCandidates(Array.from(candidateMap.values()), lookupOrder);\n}\n\n/**\n * Find frontier candidates for a single empty cell\n * Returns candidates that could spill into this cell:\n * - If there's a direct left or above candidate, return those (max 2)\n * - Otherwise, return ALL step-pattern diagonal candidates\n * Candidates are sorted deterministically based on lookup order\n */\nfunction findCandidatesForCell(\n  this: WorkbookManager,\n  cellAddr: CellAddress,\n  sheet: Sheet,\n  lookupOrder: LookupOrder\n): CellAddress[] {\n  // Find nearest-left anchor (same row)\n  const leftCandidate = findNearestLeftAnchor.call(this, cellAddr, sheet);\n\n  // Find nearest-above anchor (same column)\n  const aboveCandidate = findNearestAboveAnchor.call(this, cellAddr, sheet);\n\n  // If we have direct candidates (left and/or above), use those\n  if (leftCandidate || aboveCandidate) {\n    const candidates: CellAddress[] = [];\n    if (leftCandidate) candidates.push(leftCandidate);\n    if (aboveCandidate) candidates.push(aboveCandidate);\n\n    // Sort candidates deterministically based on lookup order\n    return sortCandidates(candidates, lookupOrder);\n  }\n\n  // No direct candidates - find ALL step-pattern diagonal candidates\n  const diagonalCandidates = findAllDiagonalStepCandidates.call(\n    this,\n    cellAddr,\n    sheet\n  );\n\n  // Sort diagonal candidates\n  return sortCandidates(diagonalCandidates, lookupOrder);\n}\n\n/**\n * Sort candidates deterministically based on lookup order\n * - Row-major: sort by col first, then row (left-to-right takes priority)\n * - Col-major: sort by row first, then col (top-to-bottom takes priority)\n */\nfunction sortCandidates(\n  candidates: CellAddress[],\n  lookupOrder: LookupOrder\n): CellAddress[] {\n  return candidates.sort((a, b) => {\n    if (lookupOrder === \"row-major\") {\n      // Row-major: col first, then row\n      if (a.colIndex !== b.colIndex) return a.colIndex - b.colIndex;\n      return a.rowIndex - b.rowIndex;\n    } else {\n      // Col-major: row first, then col\n      if (a.rowIndex !== b.rowIndex) return a.rowIndex - b.rowIndex;\n      return a.colIndex - b.colIndex;\n    }\n  });\n}\n\n/**\n * Check if two cell addresses refer to the same cell\n */\nfunction isSameCell(a: CellAddress, b: CellAddress): boolean {\n  return (\n    a.rowIndex === b.rowIndex &&\n    a.colIndex === b.colIndex &&\n    a.sheetName === b.sheetName &&\n    a.workbookName === b.workbookName\n  );\n}\n\n/**\n * Find the nearest anchor (formula cell) to the left of the target cell\n * within the same row\n * Only finds cells with formulas (starting with \"=\")\n * Searches both inside and outside the lookup range boundaries\n * OPTIMIZED: Uses indexes to avoid O(n) scan\n */\nfunction findNearestLeftAnchor(\n  this: WorkbookManager,\n  targetCell: CellAddress,\n  sheet: Sheet\n): CellAddress | null {\n  const row = targetCell.rowIndex;\n  const targetCol = targetCell.colIndex;\n\n  // Use indexes to get cells in this row (O(1) lookup + O(cells_in_row) scan)\n  const indexes = this.getSheetIndexes({\n    workbookName: targetCell.workbookName,\n    sheetName: targetCell.sheetName,\n  });\n\n  const rowGroup = indexes.rowGroups.get(row);\n  if (!rowGroup) {\n    return null; // No cells in this row\n  }\n\n  // Search backwards through the sorted array to find nearest left formula\n  // rowGroup is sorted by column index\n  for (let i = rowGroup.length - 1; i >= 0; i--) {\n    const entry = rowGroup[i];\n    if (!entry || entry.number >= targetCol) {\n      continue; // Skip cells at or right of target\n    }\n\n    const content = sheet.content.get(entry.key);\n    // Only consider formula cells (starting with \"=\")\n    if (typeof content === \"string\" && content.startsWith(\"=\")) {\n      return {\n        rowIndex: row,\n        colIndex: entry.number,\n        sheetName: targetCell.sheetName,\n        workbookName: targetCell.workbookName,\n      };\n    }\n  }\n\n  return null;\n}\n\n/**\n * Find the nearest anchor (formula cell) above the target cell\n * within the same column\n * Only finds cells with formulas (starting with \"=\")\n * Searches outside the lookup range boundaries\n * OPTIMIZED: Uses indexes to avoid O(n) scan\n */\nfunction findNearestAboveAnchor(\n  this: WorkbookManager,\n  targetCell: CellAddress,\n  sheet: Sheet\n): CellAddress | null {\n  const col = targetCell.colIndex;\n  const targetRow = targetCell.rowIndex;\n\n  // Use indexes to get cells in this column (O(1) lookup + O(cells_in_col) scan)\n  const indexes = this.getSheetIndexes({\n    workbookName: targetCell.workbookName,\n    sheetName: targetCell.sheetName,\n  });\n\n  const colGroup = indexes.colGroups.get(col);\n  if (!colGroup) {\n    return null; // No cells in this column\n  }\n\n  // Search backwards through the sorted array to find nearest above formula\n  // colGroup is sorted by row index\n  for (let i = colGroup.length - 1; i >= 0; i--) {\n    const entry = colGroup[i];\n    if (!entry || entry.number >= targetRow) {\n      continue; // Skip cells at or below target\n    }\n\n    const content = sheet.content.get(entry.key);\n    // Only consider formula cells (starting with \"=\")\n    if (typeof content === \"string\" && content.startsWith(\"=\")) {\n      return {\n        rowIndex: entry.number,\n        colIndex: col,\n        sheetName: targetCell.sheetName,\n        workbookName: targetCell.workbookName,\n      };\n    }\n  }\n\n  return null;\n}\n\n/**\n * Find ALL step-pattern candidates in the top-left diagonal quadrant\n * These are formulas that could spill diagonally to reach the target cell\n * and don't block each other (forming a \"staircase\" pattern)\n * Searches outside the lookup range boundaries (like direct left/above search)\n * OPTIMIZED: Uses indexes to avoid O(n²) scan\n *\n * For example, for target D7, candidates might be A6, B5, C4\n * - A6 at (5,0) could spill right and down to reach D7\n * - B5 at (4,1) could spill right and down to reach D7\n * - C4 at (3,2) could spill right and down to reach D7\n * - None blocks the others because each is further from origin (A1)\n */\nfunction findAllDiagonalStepCandidates(\n  this: WorkbookManager,\n  targetCell: CellAddress,\n  sheet: Sheet\n): CellAddress[] {\n  const targetRow = targetCell.rowIndex;\n  const targetCol = targetCell.colIndex;\n\n  // Use indexes to efficiently find all formula cells in the top-left quadrant\n  const allCandidates: CellAddress[] = [];\n\n  const indexes = this.getSheetIndexes({\n    workbookName: targetCell.workbookName,\n    sheetName: targetCell.sheetName,\n  });\n\n  // Iterate only through columns that exist in the top-left quadrant\n  for (let col = 0; col < targetCol; col++) {\n    const colGroup = indexes.colGroups.get(col);\n    if (!colGroup) {\n      continue; // No cells in this column\n    }\n\n    // For each cell in this column, check if it's above target row and is a formula\n    for (const entry of colGroup) {\n      if (entry.number >= targetRow) {\n        break; // Cells are sorted by row, so we can stop early\n      }\n\n      const content = sheet.content.get(entry.key);\n      // Only consider formula cells (starting with \"=\")\n      if (typeof content === \"string\" && content.startsWith(\"=\")) {\n        allCandidates.push({\n          rowIndex: entry.number,\n          colIndex: col,\n          sheetName: targetCell.sheetName,\n          workbookName: targetCell.workbookName,\n        });\n      }\n    }\n  }\n\n  // Filter out candidates that are blocked by other candidates\n  // OPTIMIZED: O(n log n) instead of O(n²) using sweep-line algorithm\n  //\n  // A candidate at (r1, c1) is blocked by another at (r2, c2) if:\n  // - r2 >= r1 AND c2 >= c1 (other is at same position or down-right)\n  // - This is a 2D dominance problem: find Pareto frontier (undominated points)\n  //\n  // Algorithm:\n  // 1. Sort candidates by row DESCENDING, then col DESCENDING\n  // 2. Sweep through, tracking MAXIMUM column seen so far\n  // 3. A candidate is unblocked if its col > max col seen\n  // 4. For same-row candidates, only the first (largest col) can be unblocked\n\n  // Sort by row descending, then col descending\n  allCandidates.sort((a, b) => {\n    if (a.rowIndex !== b.rowIndex) return b.rowIndex - a.rowIndex; // descending\n    return b.colIndex - a.colIndex; // descending\n  });\n\n  const unblockedCandidates: CellAddress[] = [];\n  let maxColSeen = -1;\n  let prevRow = -1;\n\n  for (const candidate of allCandidates) {\n    // First candidate in each row: check if undominated by candidates in rows above\n    // Subsequent candidates in same row: dominated by first in row (larger col)\n    if (candidate.rowIndex !== prevRow) {\n      // New row - check if this candidate's col > max col from rows above\n      if (candidate.colIndex > maxColSeen) {\n        unblockedCandidates.push(candidate);\n        maxColSeen = candidate.colIndex;\n      }\n      prevRow = candidate.rowIndex;\n    }\n    // Else: same row as previous, dominated by previous (which had larger col)\n  }\n\n  return unblockedCandidates;\n}\n"
  ],
  "mappings": "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",
  "debugId": "5006D0CC3F4E0DC564756E2164756E21",
  "names": []
}