{
  "version": 3,
  "sources": ["../../../../../src/functions/text/exact/exact.ts"],
  "sourcesContent": [
    "import {\n  FormulaError,\n  type CellValue,\n  type CellNumber,\n  type FunctionDefinition,\n  type FunctionEvaluationResult,\n  type ValueEvaluationResult,\n  type CellAddress,\n  type SpreadsheetRange,\n  type SpilledValuesEvaluationResult,\n  type SingleEvaluationResult,\n  type ErrorEvaluationResult,\n} from \"../../../core/types.mjs\";\nimport type { FormulaEvaluator } from \"../../../evaluator/formula-evaluator.mjs\";\nimport type { EvaluationContext } from \"../../../evaluator/evaluation-context.mjs\";\n\n/**\n * EXACT function - Compares two text strings and returns TRUE if they are exactly the same, FALSE otherwise\n * \n * Usage: EXACT(text1, text2)\n * \n * text1: Required. The first text string\n * text2: Required. The second text string\n * \n * Examples:\n *   EXACT(\"Apple\", \"Apple\") - returns TRUE\n *   EXACT(\"Apple\", \"apple\") - returns FALSE (case-sensitive)\n *   EXACT(\"123\", \"123\") - returns TRUE\n *   EXACT(\"\", \"\") - returns TRUE (empty strings are equal)\n * \n * Note:\n * - The comparison is case-sensitive\n * - Non-text values are converted to text before comparison\n * - Supports spilled values (dynamic arrays) for both arguments\n */\n\n/**\n * Convert a cell value to string for text comparison\n */\nfunction cellValueToString(value: CellValue): string {\n  switch (value.type) {\n    case \"string\":\n      return value.value;\n    case \"number\":\n      return value.value.toString();\n    case \"boolean\":\n      return value.value ? \"TRUE\" : \"FALSE\";\n    case \"infinity\":\n      return value.sign === \"positive\" ? \"INFINITY\" : \"-INFINITY\";\n    default:\n      return \"\";\n  }\n}\n\n/**\n * Helper for creating spilled-values result for EXACT function\n */\nfunction createExactSpilledResult(\n  this: FormulaEvaluator,\n  {\n    text1Result,\n    text2Result,\n    context,\n  }: {\n    text1Result: FunctionEvaluationResult;\n    text2Result: FunctionEvaluationResult;\n    context: EvaluationContext;\n  }\n): SpilledValuesEvaluationResult | ErrorEvaluationResult {\n  const hasSpilledText1 = text1Result.type === \"spilled-values\";\n  const hasSpilledText2 = text2Result.type === \"spilled-values\";\n\n  if (!hasSpilledText1 && !hasSpilledText2) {\n    throw new Error(\"createExactSpilledResult called without spilled values\");\n  }\n\n  return {\n    type: \"spilled-values\",\n    spillArea: (origin: CellAddress): SpreadsheetRange => {\n      // Calculate spill area (union of spilled ranges)\n      let spillArea: SpreadsheetRange | undefined;\n\n      const spilledResults = [\n        hasSpilledText1 ? text1Result : null,\n        hasSpilledText2 ? text2Result : null,\n      ].filter(Boolean) as SpilledValuesEvaluationResult[];\n\n      for (const result of spilledResults) {\n        const currentSpillArea = result.spillArea(origin);\n        if (!spillArea) {\n          spillArea = currentSpillArea;\n        } else {\n          spillArea = this.unionRanges(\n            this.projectRange(spillArea, origin),\n            this.projectRange(currentSpillArea, origin)\n          );\n        }\n      }\n\n      if (!spillArea) {\n        throw new Error(\"No spilled values found\");\n      }\n      return spillArea;\n    },\n    source: \"EXACT with spilled values\",\n    evaluate: (spilledCell: any, evalContext: any): SingleEvaluationResult => {\n      // Evaluate both arguments at this spilled position\n      const spillText1Result = hasSpilledText1\n        ? text1Result.evaluate(spilledCell, evalContext)\n        : text1Result;\n      const spillText2Result = hasSpilledText2\n        ? text2Result.evaluate(spilledCell, evalContext)\n        : text2Result;\n\n      // Check for errors\n      if (spillText1Result === undefined) {\n        return {\n          type: \"error\",\n          err: FormulaError.REF,\n          message: \"The spilled text1 argument has not been evaluated\",\n          errAddress: context.dependencyNode,\n        };\n      }\n      if (spillText1Result.type === \"error\" || spillText1Result.type === \"awaiting-evaluation\") {\n        return spillText1Result;\n      }\n\n      if (spillText2Result === undefined) {\n        return {\n          type: \"error\",\n          err: FormulaError.REF,\n          message: \"The spilled text2 argument has not been evaluated\",\n          errAddress: context.dependencyNode,\n        };\n      }\n      if (spillText2Result.type === \"error\" || spillText2Result.type === \"awaiting-evaluation\") {\n        return spillText2Result;\n      }\n\n      // Perform EXACT comparison\n      if (spillText1Result.type !== \"value\" || spillText2Result.type !== \"value\") {\n        return {\n          type: \"error\",\n          err: FormulaError.VALUE,\n          message: \"Invalid argument types for EXACT function #1\",\n          errAddress: context.dependencyNode,\n        };\n      }\n\n      const text1 = cellValueToString(spillText1Result.result);\n      const text2 = cellValueToString(spillText2Result.result);\n\n      return {\n        type: \"value\",\n        result: { type: \"boolean\", value: text1 === text2 },\n      };\n    },\n    evaluateAllCells: (intersectingRange: any) => {\n      throw new Error(\"WIP: evaluateAllCells for EXACT is not implemented\");\n    },\n  };\n}\n\n/**\n * EXACT function implementation\n */\nexport const EXACT: FunctionDefinition = {\n  name: \"EXACT\",\n  evaluate: function (node, context): FunctionEvaluationResult {\n    if (node.args.length !== 2) {\n      return {\n        type: \"error\",\n        err: FormulaError.VALUE,\n        message: \"EXACT function takes exactly 2 arguments\",\n        errAddress: context.dependencyNode,\n      };\n    }\n\n    // Evaluate both text arguments\n    const text1Result = this.evaluateNode(node.args[0]!, context);\n    if (text1Result.type === \"error\" || text1Result.type === \"awaiting-evaluation\") {\n      return text1Result;\n    }\n\n    const text2Result = this.evaluateNode(node.args[1]!, context);\n    if (text2Result.type === \"error\" || text2Result.type === \"awaiting-evaluation\") {\n      return text2Result;\n    }\n\n    // Handle spilled values\n    const hasSpilledValues = \n      text1Result.type === \"spilled-values\" ||\n      text2Result.type === \"spilled-values\";\n\n    if (hasSpilledValues) {\n      return createExactSpilledResult.call(this, {\n        text1Result,\n        text2Result,\n        context,\n      });\n    }\n\n    // Both arguments are single values\n    if (text1Result.type !== \"value\" || text2Result.type !== \"value\") {\n      return {\n        type: \"error\",\n        err: FormulaError.VALUE,\n        message: \"Invalid argument types for EXACT function #2\",\n        errAddress: context.dependencyNode,\n      };\n    }\n\n    // Convert both values to strings and compare\n    const text1 = cellValueToString(text1Result.result);\n    const text2 = cellValueToString(text2Result.result);\n\n    return {\n      type: \"value\",\n      result: { type: \"boolean\", value: text1 === text2 },\n    };\n  },\n};\n"
  ],
  "mappings": "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",
  "debugId": "D9302603025B202B64756E2164756E21",
  "names": []
}