{
  "version": 3,
  "sources": ["../../../../../src/functions/math/ceiling/ceiling.ts"],
  "sourcesContent": [
    "import {\n  FormulaError,\n  type CellAddress,\n  type CellInfinity,\n  type CellNumber,\n  type ErrorEvaluationResult,\n  type FunctionDefinition,\n  type FunctionEvaluationResult,\n  type SingleEvaluationResult,\n  type SpilledValuesEvaluationResult,\n  type SpreadsheetRange\n} from \"../../../core/types.mjs\";\nimport type { EvaluationContext } from \"../../../evaluator/evaluation-context.mjs\";\nimport type { FormulaEvaluator } from \"../../../evaluator/formula-evaluator.mjs\";\n\n/**\n * CEILING function - Rounds a number up to the nearest multiple of significance\n *\n * Usage: CEILING(number, significance)\n *\n * number: The number to round up (required)\n * significance: The multiple to round up to (required)\n *\n * Examples:\n *   CEILING(4.3) returns 5 (rounds up to nearest integer)\n *   CEILING(4.3, 0.5) returns 4.5 (rounds up to nearest 0.5)\n *   CEILING(-2.1, -1) returns -3 (rounds away from zero)\n *\n * Note:\n * - Both arguments are required and must be numbers (no type coercion)\n * - Positive number with negative significance returns #NUM! error\n * - Supports spilled values (dynamic arrays)\n * - Handles infinity values appropriately\n */\n\n/**\n * Helper function to perform CEILING operation\n */\nfunction ceilingOperation(\n  numberValue: CellNumber | CellInfinity,\n  significanceValue: CellNumber | CellInfinity,\n  context: EvaluationContext\n): CellNumber | CellInfinity | ErrorEvaluationResult {\n  // Handle infinity cases\n  if (numberValue.type === \"infinity\") {\n    return numberValue; // Infinity remains infinity\n  }\n\n  if (significanceValue.type === \"infinity\") {\n    return {\n      type: \"error\",\n      err: FormulaError.VALUE,\n      message: \"Cannot use infinity as significance\",\n      errAddress: context.dependencyNode,\n    };\n  }\n\n  // Both are numbers\n  const num = numberValue.value;\n  const sig = significanceValue.value;\n\n  // Significance cannot be zero\n  if (sig === 0) {\n    return {\n      type: \"error\",\n      err: FormulaError.DIV0,\n      message: \"Significance cannot be zero\",\n      errAddress: context.dependencyNode,\n    };\n  }\n\n  // Excel CEILING behavior based on testing:\n  // - Always rounds away from zero\n  // - Positive number with negative significance gives #NUM! error\n\n  if (num > 0 && sig < 0) {\n    return {\n      type: \"error\",\n      err: FormulaError.NUM,\n      message: \"Positive number cannot be used with negative significance\",\n      errAddress: context.dependencyNode,\n    };\n  }\n\n  if (num < 0 && sig > 0) {\n    return {\n      type: \"error\",\n      err: FormulaError.NUM,\n      message: \"Negative number cannot be used with positive significance\",\n      errAddress: context.dependencyNode,\n    };\n  }\n\n  // Calculate result - always rounds away from zero\n  let result: number;\n\n  if (sig > 0) {\n    // Positive significance with positive/zero number\n    result = Math.ceil(num / sig) * sig;\n  } else {\n    // Negative significance with negative/zero number\n    // Round away from zero: -2.1/-1 = 2.1, ceil(2.1) = 3, 3*-1 = -3\n    result = Math.ceil(num / sig) * sig;\n  }\n\n  return { type: \"number\", value: result };\n}\n\n/**\n * Helper for creating spilled-values result for CEILING function\n */\nfunction createCeilingSpilledResult(\n  this: FormulaEvaluator,\n  {\n    numberResult,\n    significanceResult,\n    context,\n  }: {\n    numberResult: FunctionEvaluationResult;\n    significanceResult: FunctionEvaluationResult;\n    context: EvaluationContext;\n  }\n): SpilledValuesEvaluationResult | ErrorEvaluationResult {\n  const hasSpilledNumber = numberResult.type === \"spilled-values\";\n  const hasSpilledSignificance = significanceResult.type === \"spilled-values\";\n\n  if (!hasSpilledNumber && !hasSpilledSignificance) {\n    throw new Error(\"createCeilingSpilledResult 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      if (hasSpilledNumber && numberResult.type === \"spilled-values\") {\n        const spillArea = numberResult.spillArea(origin);\n        if (\n          hasSpilledSignificance &&\n          significanceResult.type === \"spilled-values\"\n        ) {\n          return this.unionRanges(\n            this.projectRange(spillArea, origin),\n            this.projectRange(significanceResult.spillArea(origin), origin)\n          );\n        }\n        return spillArea;\n      } else if (\n        hasSpilledSignificance &&\n        significanceResult.type === \"spilled-values\"\n      ) {\n        return significanceResult.spillArea(origin);\n      } else {\n        throw new Error(\"No spilled values found\");\n      }\n    },\n    source: \"CEILING with spilled values\",\n    evaluate: (spilledCell: any, evalContext: any): SingleEvaluationResult => {\n      // Evaluate arguments at this spilled position\n      const spillNumberResult = hasSpilledNumber\n        ? numberResult.evaluate(spilledCell, evalContext)\n        : numberResult;\n      const spillSigResult = hasSpilledSignificance\n        ? significanceResult.evaluate(spilledCell, evalContext)\n        : significanceResult;\n\n      if (spillNumberResult === undefined || spillSigResult === undefined) {\n        return {\n          type: \"error\",\n          err: FormulaError.REF,\n          message: \"The spilled results have not been evaluated\",\n          errAddress: context.dependencyNode,\n        };\n      }\n\n      if (spillNumberResult.type === \"error\") {\n        return spillNumberResult;\n      }\n      if (spillSigResult.type === \"error\") {\n        return spillSigResult;\n      }\n\n      if (\n        spillNumberResult.type !== \"value\" ||\n        spillSigResult.type !== \"value\"\n      ) {\n        return {\n          type: \"error\",\n          err: FormulaError.VALUE,\n          message: \"Invalid spilled result for CEILING\",\n          errAddress: context.dependencyNode,\n        };\n      }\n\n      // Type checking\n      if (\n        spillNumberResult.result.type !== \"number\" &&\n        spillNumberResult.result.type !== \"infinity\"\n      ) {\n        return {\n          type: \"error\",\n          err: FormulaError.VALUE,\n          message: \"Number argument must be a number\",\n          errAddress: context.dependencyNode,\n        };\n      }\n\n      if (\n        spillSigResult.result.type !== \"number\" &&\n        spillSigResult.result.type !== \"infinity\"\n      ) {\n        return {\n          type: \"error\",\n          err: FormulaError.VALUE,\n          message: \"Significance argument must be a number\",\n          errAddress: context.dependencyNode,\n        };\n      }\n\n      const result = ceilingOperation(\n        spillNumberResult.result,\n        spillSigResult.result,\n        context\n      );\n      if (result.type === \"error\" || result.type === \"awaiting-evaluation\") {\n        return result;\n      }\n      return { type: \"value\", result };\n    },\n    evaluateAllCells: (intersectingRange: any) => {\n      throw new Error(\"WIP: evaluateAllCells for CEILING is not implemented\");\n    },\n  };\n}\n\n/**\n * CEILING function implementation\n */\nexport const CEILING: FunctionDefinition = {\n  name: \"CEILING\",\n  evaluate: function (node, context): FunctionEvaluationResult {\n    if (node.args.length !== 2) {\n      return {\n        type: \"error\",\n        err: FormulaError.VALUE,\n        message: \"CEILING function takes exactly 2 arguments\",\n        errAddress: context.dependencyNode,\n      };\n    }\n\n    // Evaluate number argument\n    const numberResult = this.evaluateNode(node.args[0]!, context);\n    if (numberResult.type === \"error\" || numberResult.type === \"awaiting-evaluation\") {\n      return numberResult;\n    }\n\n    // Evaluate significance argument (required)\n    const significanceResult = this.evaluateNode(node.args[1]!, context);\n    if (significanceResult.type === \"error\" || significanceResult.type === \"awaiting-evaluation\") {\n      return significanceResult;\n    }\n\n    // Handle spilled values\n    const hasSpilledValues =\n      numberResult.type === \"spilled-values\" ||\n      significanceResult.type === \"spilled-values\";\n\n    if (hasSpilledValues) {\n      return createCeilingSpilledResult.call(this, {\n        numberResult,\n        significanceResult,\n        context,\n      });\n    }\n\n    // Both arguments are single values\n    if (numberResult.type !== \"value\" || significanceResult.type !== \"value\") {\n      return {\n        type: \"error\",\n        err: FormulaError.VALUE,\n        message: \"Invalid argument type\",\n        errAddress: context.dependencyNode,\n      };\n    }\n\n    // Type checking - only numbers and infinity allowed\n    if (\n      numberResult.result.type !== \"number\" &&\n      numberResult.result.type !== \"infinity\"\n    ) {\n      return {\n        type: \"error\",\n        err: FormulaError.VALUE,\n        message: \"Number argument must be a number\",\n        errAddress: context.dependencyNode,\n      };\n    }\n\n    if (\n      significanceResult.result.type !== \"number\" &&\n      significanceResult.result.type !== \"infinity\"\n    ) {\n      return {\n        type: \"error\",\n        err: FormulaError.VALUE,\n        message: \"Significance argument must be a number\",\n        errAddress: context.dependencyNode,\n      };\n    }\n\n    // Perform CEILING operation\n    const result = ceilingOperation(\n      numberResult.result,\n      significanceResult.result,\n      context\n    );\n    if (result.type === \"error\" || result.type === \"awaiting-evaluation\") {\n      return result;\n    }\n    return { type: \"value\", result };\n  },\n};\n"
  ],
  "mappings": ";AAAA;AAAA;AAAA;AAsCA,SAAS,gBAAgB,CACvB,aACA,mBACA,SACmD;AAAA,EAEnD,IAAI,YAAY,SAAS,YAAY;AAAA,IACnC,OAAO;AAAA,EACT;AAAA,EAEA,IAAI,kBAAkB,SAAS,YAAY;AAAA,IACzC,OAAO;AAAA,MACL,MAAM;AAAA,MACN,KAAK,aAAa;AAAA,MAClB,SAAS;AAAA,MACT,YAAY,QAAQ;AAAA,IACtB;AAAA,EACF;AAAA,EAGA,MAAM,MAAM,YAAY;AAAA,EACxB,MAAM,MAAM,kBAAkB;AAAA,EAG9B,IAAI,QAAQ,GAAG;AAAA,IACb,OAAO;AAAA,MACL,MAAM;AAAA,MACN,KAAK,aAAa;AAAA,MAClB,SAAS;AAAA,MACT,YAAY,QAAQ;AAAA,IACtB;AAAA,EACF;AAAA,EAMA,IAAI,MAAM,KAAK,MAAM,GAAG;AAAA,IACtB,OAAO;AAAA,MACL,MAAM;AAAA,MACN,KAAK,aAAa;AAAA,MAClB,SAAS;AAAA,MACT,YAAY,QAAQ;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,IAAI,MAAM,KAAK,MAAM,GAAG;AAAA,IACtB,OAAO;AAAA,MACL,MAAM;AAAA,MACN,KAAK,aAAa;AAAA,MAClB,SAAS;AAAA,MACT,YAAY,QAAQ;AAAA,IACtB;AAAA,EACF;AAAA,EAGA,IAAI;AAAA,EAEJ,IAAI,MAAM,GAAG;AAAA,IAEX,SAAS,KAAK,KAAK,MAAM,GAAG,IAAI;AAAA,EAClC,EAAO;AAAA,IAGL,SAAS,KAAK,KAAK,MAAM,GAAG,IAAI;AAAA;AAAA,EAGlC,OAAO,EAAE,MAAM,UAAU,OAAO,OAAO;AAAA;AAMzC,SAAS,0BAA0B;AAAA,EAG/B;AAAA,EACA;AAAA,EACA;AAAA,GAMqD;AAAA,EACvD,MAAM,mBAAmB,aAAa,SAAS;AAAA,EAC/C,MAAM,yBAAyB,mBAAmB,SAAS;AAAA,EAE3D,IAAI,CAAC,oBAAoB,CAAC,wBAAwB;AAAA,IAChD,MAAM,IAAI,MAAM,0DAA0D;AAAA,EAC5E;AAAA,EAEA,OAAO;AAAA,IACL,MAAM;AAAA,IACN,WAAW,CAAC,WAA0C;AAAA,MAEpD,IAAI,oBAAoB,aAAa,SAAS,kBAAkB;AAAA,QAC9D,MAAM,YAAY,aAAa,UAAU,MAAM;AAAA,QAC/C,IACE,0BACA,mBAAmB,SAAS,kBAC5B;AAAA,UACA,OAAO,KAAK,YACV,KAAK,aAAa,WAAW,MAAM,GACnC,KAAK,aAAa,mBAAmB,UAAU,MAAM,GAAG,MAAM,CAChE;AAAA,QACF;AAAA,QACA,OAAO;AAAA,MACT,EAAO,SACL,0BACA,mBAAmB,SAAS,kBAC5B;AAAA,QACA,OAAO,mBAAmB,UAAU,MAAM;AAAA,MAC5C,EAAO;AAAA,QACL,MAAM,IAAI,MAAM,yBAAyB;AAAA;AAAA;AAAA,IAG7C,QAAQ;AAAA,IACR,UAAU,CAAC,aAAkB,gBAA6C;AAAA,MAExE,MAAM,oBAAoB,mBACtB,aAAa,SAAS,aAAa,WAAW,IAC9C;AAAA,MACJ,MAAM,iBAAiB,yBACnB,mBAAmB,SAAS,aAAa,WAAW,IACpD;AAAA,MAEJ,IAAI,sBAAsB,aAAa,mBAAmB,WAAW;AAAA,QACnE,OAAO;AAAA,UACL,MAAM;AAAA,UACN,KAAK,aAAa;AAAA,UAClB,SAAS;AAAA,UACT,YAAY,QAAQ;AAAA,QACtB;AAAA,MACF;AAAA,MAEA,IAAI,kBAAkB,SAAS,SAAS;AAAA,QACtC,OAAO;AAAA,MACT;AAAA,MACA,IAAI,eAAe,SAAS,SAAS;AAAA,QACnC,OAAO;AAAA,MACT;AAAA,MAEA,IACE,kBAAkB,SAAS,WAC3B,eAAe,SAAS,SACxB;AAAA,QACA,OAAO;AAAA,UACL,MAAM;AAAA,UACN,KAAK,aAAa;AAAA,UAClB,SAAS;AAAA,UACT,YAAY,QAAQ;AAAA,QACtB;AAAA,MACF;AAAA,MAGA,IACE,kBAAkB,OAAO,SAAS,YAClC,kBAAkB,OAAO,SAAS,YAClC;AAAA,QACA,OAAO;AAAA,UACL,MAAM;AAAA,UACN,KAAK,aAAa;AAAA,UAClB,SAAS;AAAA,UACT,YAAY,QAAQ;AAAA,QACtB;AAAA,MACF;AAAA,MAEA,IACE,eAAe,OAAO,SAAS,YAC/B,eAAe,OAAO,SAAS,YAC/B;AAAA,QACA,OAAO;AAAA,UACL,MAAM;AAAA,UACN,KAAK,aAAa;AAAA,UAClB,SAAS;AAAA,UACT,YAAY,QAAQ;AAAA,QACtB;AAAA,MACF;AAAA,MAEA,MAAM,SAAS,iBACb,kBAAkB,QAClB,eAAe,QACf,OACF;AAAA,MACA,IAAI,OAAO,SAAS,WAAW,OAAO,SAAS,uBAAuB;AAAA,QACpE,OAAO;AAAA,MACT;AAAA,MACA,OAAO,EAAE,MAAM,SAAS,OAAO;AAAA;AAAA,IAEjC,kBAAkB,CAAC,sBAA2B;AAAA,MAC5C,MAAM,IAAI,MAAM,sDAAsD;AAAA;AAAA,EAE1E;AAAA;AAMK,IAAM,UAA8B;AAAA,EACzC,MAAM;AAAA,EACN,UAAU,QAAS,CAAC,MAAM,SAAmC;AAAA,IAC3D,IAAI,KAAK,KAAK,WAAW,GAAG;AAAA,MAC1B,OAAO;AAAA,QACL,MAAM;AAAA,QACN,KAAK,aAAa;AAAA,QAClB,SAAS;AAAA,QACT,YAAY,QAAQ;AAAA,MACtB;AAAA,IACF;AAAA,IAGA,MAAM,eAAe,KAAK,aAAa,KAAK,KAAK,IAAK,OAAO;AAAA,IAC7D,IAAI,aAAa,SAAS,WAAW,aAAa,SAAS,uBAAuB;AAAA,MAChF,OAAO;AAAA,IACT;AAAA,IAGA,MAAM,qBAAqB,KAAK,aAAa,KAAK,KAAK,IAAK,OAAO;AAAA,IACnE,IAAI,mBAAmB,SAAS,WAAW,mBAAmB,SAAS,uBAAuB;AAAA,MAC5F,OAAO;AAAA,IACT;AAAA,IAGA,MAAM,mBACJ,aAAa,SAAS,oBACtB,mBAAmB,SAAS;AAAA,IAE9B,IAAI,kBAAkB;AAAA,MACpB,OAAO,2BAA2B,KAAK,MAAM;AAAA,QAC3C;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IAGA,IAAI,aAAa,SAAS,WAAW,mBAAmB,SAAS,SAAS;AAAA,MACxE,OAAO;AAAA,QACL,MAAM;AAAA,QACN,KAAK,aAAa;AAAA,QAClB,SAAS;AAAA,QACT,YAAY,QAAQ;AAAA,MACtB;AAAA,IACF;AAAA,IAGA,IACE,aAAa,OAAO,SAAS,YAC7B,aAAa,OAAO,SAAS,YAC7B;AAAA,MACA,OAAO;AAAA,QACL,MAAM;AAAA,QACN,KAAK,aAAa;AAAA,QAClB,SAAS;AAAA,QACT,YAAY,QAAQ;AAAA,MACtB;AAAA,IACF;AAAA,IAEA,IACE,mBAAmB,OAAO,SAAS,YACnC,mBAAmB,OAAO,SAAS,YACnC;AAAA,MACA,OAAO;AAAA,QACL,MAAM;AAAA,QACN,KAAK,aAAa;AAAA,QAClB,SAAS;AAAA,QACT,YAAY,QAAQ;AAAA,MACtB;AAAA,IACF;AAAA,IAGA,MAAM,SAAS,iBACb,aAAa,QACb,mBAAmB,QACnB,OACF;AAAA,IACA,IAAI,OAAO,SAAS,WAAW,OAAO,SAAS,uBAAuB;AAAA,MACpE,OAAO;AAAA,IACT;AAAA,IACA,OAAO,EAAE,MAAM,SAAS,OAAO;AAAA;AAEnC;",
  "debugId": "6037C40785822EEF64756E2164756E21",
  "names": []
}