{"version":3,"sources":["../wasm/src/swisseph.ts","../src/astrology/swisseph.ts","../src/astrology/astrocartography.ts","../src/astrology/aspects.ts","../src/astrology/dignity.ts","../src/astrology/decans.ts","../src/astrology/dodecatemoria.ts","../src/astrology/profections.ts","../src/astrology/firdaria.ts","../src/astrology/index.ts"],"names":["Planet","VirtualNodes","HouseSystem","CalcFlag","RiseTransitFlag","bundledAssets"],"mappings":"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","sourcesContent":["/**\n * TypeScript wrapper for Swiss Ephemeris WebAssembly module\n */\n\nimport type {\n  SweAzalt,\n  SweCalcUt,\n  SweClose,\n  SweHousePos,\n  SweHouses,\n  SweJulDay,\n  SweRiseTrans,\n  SweSetEphePath,\n  SweSetSidMode,\n  SweSetTopo,\n  SwissEphModule,\n} from \"./types\";\n\n// Exported planet constants\nexport enum Planet {\n  SUN = 0,\n  MOON = 1,\n  MERCURY = 2,\n  VENUS = 3,\n  MARS = 4,\n  JUPITER = 5,\n  SATURN = 6,\n  URANUS = 7,\n  NEPTUNE = 8,\n  PLUTO = 9,\n  MEAN_NODE = 10,\n  TRUE_NODE = 11,\n  LILITH_MEAN = 12,\n  LILITH_TRUE = 13,\n  CHIRON = 15,\n}\n\nexport enum VirtualNodes {\n  PARS_FORTUNAE = \"parsFortunae\",\n}\n\nexport const PLANET_AND_NODE_NAMES: Record<string, string> = {\n  [Planet.SUN]: \"Sun\",\n  [Planet.MOON]: \"Moon\",\n  [Planet.MERCURY]: \"Mercury\",\n  [Planet.VENUS]: \"Venus\",\n  [Planet.MARS]: \"Mars\",\n  [Planet.JUPITER]: \"Jupiter\",\n  [Planet.SATURN]: \"Saturn\",\n  [Planet.URANUS]: \"Uranus\",\n  [Planet.NEPTUNE]: \"Neptune\",\n  [Planet.PLUTO]: \"Pluto\",\n  [Planet.MEAN_NODE]: \"Mean Node\",\n  [Planet.TRUE_NODE]: \"True Node\",\n  [Planet.LILITH_MEAN]: \"Lilith Mean\",\n  [Planet.LILITH_TRUE]: \"Lilith True\",\n  [Planet.CHIRON]: \"Chiron\",\n  [VirtualNodes.PARS_FORTUNAE]: \"Wheel of Fortune\",\n} as const;\n\n// House systems\nexport enum HouseSystem {\n  PLACIDUS = \"P\",\n  KOCH = \"K\",\n  PORPHYRIUS = \"O\",\n  REGIOMONTANUS = \"R\",\n  CAMPANUS = \"C\",\n  EQUAL = \"E\",\n  WHOLE_SIGN = \"W\",\n  MERIDIAN = \"X\",\n  MORINUS = \"M\",\n  KRUSINSKI = \"U\",\n  ALCABITIUS = \"B\",\n}\n\n// Calculation flag constants\nexport enum CalcFlag {\n  JPL_EPH = 1,\n  SWISS_EPH = 2,\n  MOSHIER = 4,\n  HELIOCENTRIC = 8,\n  TRUE_POS = 16,\n  J2000 = 32,\n  NONUT = 64,\n  SPEED3 = 128,\n  SPEED = 256,\n  EQUATORIAL = 2048,\n  TOPOCTR = 32768,\n  SIDEREAL = 65536,\n}\n\n// Rise/set/meridian transit flags for swe_rise_trans\nexport enum RiseTransitFlag {\n  RISE = 1,\n  SET = 2,\n  UPPER_MERIDIAN = 4,\n  LOWER_MERIDIAN = 8,\n  DISC_CENTER = 256,\n  NO_REFRACTION = 512,\n}\n\n// Azimuth/altitude result from swe_azalt\nexport interface AzaltResult {\n  azimuth: number;\n  trueAltitude: number;\n  apparentAltitude: number;\n}\n\n// SE_ECL2HOR / SE_EQU2HOR constants for swe_azalt\nexport const SE_ECL2HOR = 0;\nexport const SE_EQU2HOR = 1;\n\n// Planet position result\nexport interface PlanetPosition {\n  longitude: number;\n  latitude: number;\n  distance: number;\n  longitudeSpeed?: number;\n  latitudeSpeed?: number;\n  distanceSpeed?: number;\n}\n\n// Houses calculation result\nexport interface Houses {\n  ascendant: number;\n  mc: number;\n  houses: number[];\n  // extras of ASCMC (useful for Vertex etc.)\n  ascmc?: {\n    armc: number;\n    vertex: number;\n    equasc: number;\n    coasc1: number;\n    coasc2: number;\n    polasc: number;\n  };\n}\n\n// Offset for asteroids (MPC)\nexport const SE_AST_OFFSET = 10000;\n\nexport const BODY = {\n  MEAN_APOGEE: 12, // Lilith mean\n  OSC_APOGEE: 13, // Lilith true\n  PHOLUS: 16,\n  CERES: 17,\n  PALLAS: 18,\n  JUNO: 19,\n  VESTA: 20,\n} as const;\n\nexport const normalizeAngle = (deg: number) => ((deg % 360) + 360) % 360;\n\n// Swiss Ephemeris class\nexport class SwissEph {\n  private module: SwissEphModule;\n  private swe_julday: SweJulDay | null = null;\n  private swe_calc_ut: SweCalcUt | null = null;\n  private swe_houses: SweHouses | null = null;\n  private swe_house_pos: SweHousePos | null = null;\n  private swe_set_ephe_path: SweSetEphePath | null = null;\n  private swe_close: SweClose | null = null;\n  private swe_set_topo: SweSetTopo | null = null;\n  private swe_set_sid_mode: SweSetSidMode | null = null;\n  private swe_azalt_fn: SweAzalt | null = null;\n  private swe_rise_trans_fn: SweRiseTrans | null = null;\n\n  /**\n   * Constructor that accepts a pre-initialized Swiss Ephemeris module\n   */\n  constructor(module: SwissEphModule) {\n    this.module = module;\n\n    // Create wrapped functions with specific types\n    this.swe_julday = this.module.cwrap<SweJulDay>(\"swe_julday\", \"number\", [\n      \"number\",\n      \"number\",\n      \"number\",\n      \"number\",\n      \"number\",\n    ]);\n    this.swe_calc_ut = this.module.cwrap<SweCalcUt>(\"swe_calc_ut\", \"number\", [\n      \"number\",\n      \"number\",\n      \"number\",\n      \"number\",\n      \"number\",\n    ]);\n    this.swe_houses = this.module.cwrap<SweHouses>(\"swe_houses\", \"number\", [\n      \"number\",\n      \"number\",\n      \"number\",\n      \"number\",\n      \"number\",\n      \"number\",\n    ]);\n    this.swe_house_pos = this.module.cwrap<SweHousePos>(\n      \"swe_house_pos\",\n      \"number\",\n      [\"number\", \"number\", \"number\", \"string\", \"number\", \"number\"]\n    );\n    this.swe_set_ephe_path = this.module.cwrap<SweSetEphePath>(\n      \"swe_set_ephe_path\",\n      null,\n      [\"number\"]\n    );\n    this.swe_close = this.module.cwrap<SweClose>(\"swe_close\", null, []);\n    this.swe_set_topo = this.module.cwrap<SweSetTopo>(\"swe_set_topo\", null, [\n      \"number\",\n      \"number\",\n      \"number\",\n    ]);\n    this.swe_set_sid_mode = this.module.cwrap<SweSetSidMode>(\n      \"swe_set_sid_mode\",\n      null,\n      [\"number\", \"number\", \"number\"]\n    );\n    this.swe_azalt_fn = this.module.cwrap<SweAzalt>(\n      \"swe_azalt\",\n      null,\n      [\"number\", \"number\", \"number\", \"number\", \"number\", \"number\", \"number\"]\n    );\n    this.swe_rise_trans_fn = this.module.cwrap<SweRiseTrans>(\n      \"swe_rise_trans\",\n      \"number\",\n      [\"number\", \"number\", \"number\", \"number\", \"number\", \"number\", \"number\", \"number\", \"number\", \"number\"]\n    );\n  }\n\n  private checkInitialized(): void {\n    if (!this.module) {\n      throw new Error(\"Swiss Ephemeris module not available.\");\n    }\n  }\n\n  /**\n   * Sets the path to the ephemeris data files.\n   * @param path - The path to the directory containing ephemeris files.\n   */\n  setEphemerisPath(path: string): void {\n    this.checkInitialized();\n    if (path && this.swe_set_ephe_path) {\n      const pathPtr = this.module._malloc(path.length + 1);\n      if (!pathPtr) {\n        throw new Error(\"Failed to allocate memory for ephemeris path\");\n      }\n      this.module.stringToUTF8(path, pathPtr, path.length + 1);\n      this.swe_set_ephe_path(pathPtr);\n      this.module._free(pathPtr);\n    }\n  }\n\n  /**\n   * Calculate Julian day number for a given date and time\n   */\n  getJulianDay(date: Date): number {\n    this.checkInitialized();\n    if (!this.swe_julday) {\n      throw new Error(\"Julian day calculation function not available\");\n    }\n\n    // Get UTC components\n    const year = date.getUTCFullYear();\n    const month = date.getUTCMonth() + 1; // JavaScript months are 0-based\n    const day = date.getUTCDate();\n    const hour =\n      date.getUTCHours() +\n      date.getUTCMinutes() / 60 +\n      date.getUTCSeconds() / 3600;\n\n    // Use Gregorian calendar (flag = 1)\n    return this.swe_julday(year, month, day, hour, 1);\n  }\n\n  /**\n   * Calculate planet position at a given Julian day\n   */\n  calculatePlanetPosition(\n    julday: number,\n    planet: Planet | number,\n    flags = CalcFlag.SWISS_EPH\n  ): PlanetPosition {\n    this.checkInitialized();\n    if (!this.swe_calc_ut || !this.module) {\n      throw new Error(\"Planet calculation function not available\");\n    }\n\n    const resultPtr = this.module._malloc(6 * 8);\n    if (!resultPtr) {\n      throw new Error(\"Failed to allocate memory for planet position\");\n    }\n\n    // allocate an error buffer for swe_calc_ut to write into\n    const ERR_BYTES = 512;\n    const errPtr = this.module._malloc(ERR_BYTES);\n    if (!errPtr) {\n      this.module._free(resultPtr);\n      throw new Error(\"Failed to allocate memory for error buffer\");\n    }\n    // zero the buffer to ensure a clean C string\n    this.module.HEAP8.fill(0, errPtr, errPtr + ERR_BYTES);\n\n    try {\n      let ret = this.swe_calc_ut(julday, planet, flags, resultPtr, errPtr);\n\n      // // If Chiron via SE_CHIRON (15) fails, retry using MPC 2060 (asteroid id = offset + 2060)\n      // if (ret < 0 && planet === Planet.CHIRON) {\n      //   const mpcPlanetId = SE_AST_OFFSET + 2060; // 2060 = Chiron\n      //   this.module.HEAP8.fill(0, errPtr, errPtr + ERR_BYTES);\n      //   ret = this.swe_calc_ut(julday, mpcPlanetId, flags, resultPtr, errPtr);\n      // }\n\n      if (ret < 0) {\n        const msg = this.module.UTF8ToString(errPtr);\n        throw new Error(msg && msg.length ? msg : `Swiss Ephemeris calculation failed with error code ${ret}`);\n      }\n\n      const position: PlanetPosition = {\n        longitude: this.module.getValue(resultPtr, \"double\"),\n        latitude: this.module.getValue(resultPtr + 8, \"double\"),\n        distance: this.module.getValue(resultPtr + 16, \"double\"),\n      };\n\n      if (flags & CalcFlag.SPEED) {\n        position.longitudeSpeed = this.module.getValue(resultPtr + 24, \"double\");\n        position.latitudeSpeed = this.module.getValue(resultPtr + 32, \"double\");\n        position.distanceSpeed = this.module.getValue(resultPtr + 40, \"double\");\n      }\n\n      return position;\n    } finally {\n      this.module._free(errPtr);\n      this.module._free(resultPtr);\n    }\n  }\n\n  /**\n   * Calculate houses for a given date, location, and house system\n   */\n  calculateHouses(\n    julday: number,\n    latitude: number,\n    longitude: number,\n    hsys: HouseSystem = HouseSystem.PLACIDUS\n  ): Houses {\n    this.checkInitialized();\n    if (!this.swe_houses || !this.module) {\n      throw new Error(\"Houses calculation function not available\");\n    }\n\n    // Validate input parameters\n    if (latitude < -90 || latitude > 90) {\n      throw new Error(\"Latitude must be between -90 and 90 degrees\");\n    }\n    if (longitude < -180 || longitude > 180) {\n      throw new Error(\"Longitude must be between -180 and 180 degrees\");\n    }\n\n    // Swiss Ephemeris: cusps[0..12] (0 not used), ascmc[0..9]\n    const HOUSES_DOUBLES = 13;\n    const ASCMC_DOUBLES = 10;\n    const BYTES_PER_F64 = 8;\n\n    // Create a single contiguous memory block for both houses and ascmc\n    const totalBytes = (HOUSES_DOUBLES + ASCMC_DOUBLES) * BYTES_PER_F64;\n    const memoryPtr = this.module._malloc(totalBytes);\n\n    if (!memoryPtr) throw new Error(\"Memory allocation failed\");\n\n    const housesPtr = memoryPtr; // 13 * f64\n    const ascmcPtr = memoryPtr + HOUSES_DOUBLES * BYTES_PER_F64; // 10 * f64\n\n    try {\n      // Calculate houses\n      // passar código do caractere (ex.: 'P' -> 80)\n      const hsysCode = hsys.charCodeAt(0);\n      const ret = this.swe_houses(\n        julday,\n        latitude,\n        longitude,\n        hsysCode,\n        housesPtr,\n        ascmcPtr\n      );\n\n      if (ret < 0) {\n        throw new Error(`Houses calculation failed with error code ${ret}`);\n      }\n\n      // Extract all data before any memory operations\n      const houses: number[] = new Array(HOUSES_DOUBLES);\n      for (let i = 0; i < HOUSES_DOUBLES; i++) {\n        houses[i] = this.module.getValue(\n          housesPtr + i * BYTES_PER_F64,\n          \"double\"\n        );\n      }\n\n      const ascendant = this.module.getValue(\n        ascmcPtr + 0 * BYTES_PER_F64,\n        \"double\"\n      ); // 0\n      const mc = this.module.getValue(ascmcPtr + 1 * BYTES_PER_F64, \"double\"); // 1\n      const armc = this.module.getValue(ascmcPtr + 2 * BYTES_PER_F64, \"double\"); // 2\n      const vertex = this.module.getValue(\n        ascmcPtr + 3 * BYTES_PER_F64,\n        \"double\"\n      ); // 3\n      const equasc = this.module.getValue(\n        ascmcPtr + 4 * BYTES_PER_F64,\n        \"double\"\n      ); // 4\n      const coasc1 = this.module.getValue(\n        ascmcPtr + 5 * BYTES_PER_F64,\n        \"double\"\n      ); // 5\n      const coasc2 = this.module.getValue(\n        ascmcPtr + 6 * BYTES_PER_F64,\n        \"double\"\n      ); // 6\n      const polasc = this.module.getValue(\n        ascmcPtr + 7 * BYTES_PER_F64,\n        \"double\"\n      ); // 7\n\n      return {\n        ascendant,\n        mc,\n        houses,\n        ascmc: {\n          armc,\n          vertex,\n          equasc,\n          coasc1,\n          coasc2,\n          polasc,\n        },\n      };\n    } finally {\n      // Always free memory\n      this.module._free(memoryPtr);\n    }\n  }\n\n  /**\n   * Clean up and close the Swiss Ephemeris\n   */\n  close(): void {\n    this.checkInitialized();\n    if (this.swe_close) {\n      this.swe_close();\n    }\n  }\n\n  /**\n   * Set topocentric observer\n   */\n  setTopocentric(\n    longitude: number,\n    latitude: number,\n    altitudeMeters = 0\n  ): void {\n    this.checkInitialized();\n\n    if (!this.swe_set_topo) {\n      throw new Error(\"Topocentric calculation function not available\");\n    }\n\n    this.swe_set_topo(longitude, latitude, altitudeMeters);\n  }\n\n  /**\n   * Set sidereal mode\n   * Ex.: mode=1 (Lahiri). See Swiss Ephemeris mode table.\n   */\n  setSiderealMode(mode: number, t0 = 0, ayan_t0 = 0): void {\n    this.checkInitialized();\n    this.swe_set_sid_mode?.(mode, t0, ayan_t0);\n  }\n\n  /**\n   * Asteroid by MPC number\n   */\n  calculateAsteroidPosition(\n    julday: number,\n    mpcNumber: number,\n    flags = CalcFlag.SWISS_EPH\n  ): PlanetPosition {\n    return this.calculatePlanetPosition(\n      julday,\n      SE_AST_OFFSET + mpcNumber,\n      flags\n    );\n  }\n\n  /**\n   * Lilith mean (12) and true (13)\n   */\n  calculateLilith(\n    julday: number,\n    kind: \"mean\" | \"true\" = \"mean\",\n    flags = CalcFlag.SWISS_EPH\n  ): PlanetPosition {\n    const id = kind === \"mean\" ? BODY.MEAN_APOGEE : BODY.OSC_APOGEE;\n    return this.calculatePlanetPosition(julday, id, flags);\n  }\n  /**\n   * Convert ecliptic (or equatorial) coordinates to horizon coordinates.\n   * Returns azimuth (0=south, 90=west, 180=north, 270=east) and altitude.\n   */\n  azalt(\n    julday: number,\n    longitude: number,\n    latitude: number,\n    altitude: number,\n    xinLon: number,\n    xinLat: number,\n    xinDist: number,\n    fromEquatorial = false\n  ): AzaltResult {\n    this.checkInitialized();\n    if (!this.swe_azalt_fn) {\n      throw new Error(\"swe_azalt function not available\");\n    }\n\n    const BYTES = 8;\n    const geoPtr = this.module._malloc(3 * BYTES);\n    const xinPtr = this.module._malloc(3 * BYTES);\n    const xazPtr = this.module._malloc(3 * BYTES);\n\n    if (!geoPtr || !xinPtr || !xazPtr) {\n      if (geoPtr) this.module._free(geoPtr);\n      if (xinPtr) this.module._free(xinPtr);\n      if (xazPtr) this.module._free(xazPtr);\n      throw new Error(\"Memory allocation failed for azalt\");\n    }\n\n    try {\n      this.module.setValue(geoPtr, longitude, \"double\");\n      this.module.setValue(geoPtr + BYTES, latitude, \"double\");\n      this.module.setValue(geoPtr + 2 * BYTES, altitude, \"double\");\n\n      this.module.setValue(xinPtr, xinLon, \"double\");\n      this.module.setValue(xinPtr + BYTES, xinLat, \"double\");\n      this.module.setValue(xinPtr + 2 * BYTES, xinDist, \"double\");\n\n      this.swe_azalt_fn(\n        julday,\n        fromEquatorial ? SE_EQU2HOR : SE_ECL2HOR,\n        geoPtr,\n        0, // atpress (0 = default 1013.25 mbar)\n        0, // attemp (0 = default 15°C)\n        xinPtr,\n        xazPtr\n      );\n\n      return {\n        azimuth: this.module.getValue(xazPtr, \"double\"),\n        trueAltitude: this.module.getValue(xazPtr + BYTES, \"double\"),\n        apparentAltitude: this.module.getValue(xazPtr + 2 * BYTES, \"double\"),\n      };\n    } finally {\n      this.module._free(geoPtr);\n      this.module._free(xinPtr);\n      this.module._free(xazPtr);\n    }\n  }\n\n  /**\n   * Find the next rise, set, or meridian transit of a planet.\n   * Returns the Julian day of the event.\n   */\n  riseTransit(\n    julday: number,\n    planet: Planet | number,\n    rsmi: RiseTransitFlag,\n    longitude: number,\n    latitude: number,\n    altitude = 0,\n    flags = CalcFlag.SWISS_EPH\n  ): number {\n    this.checkInitialized();\n    if (!this.swe_rise_trans_fn) {\n      throw new Error(\"swe_rise_trans function not available\");\n    }\n\n    const BYTES = 8;\n    const geoPtr = this.module._malloc(3 * BYTES);\n    const tretPtr = this.module._malloc(BYTES);\n    const ERR_BYTES = 512;\n    const errPtr = this.module._malloc(ERR_BYTES);\n\n    if (!geoPtr || !tretPtr || !errPtr) {\n      if (geoPtr) this.module._free(geoPtr);\n      if (tretPtr) this.module._free(tretPtr);\n      if (errPtr) this.module._free(errPtr);\n      throw new Error(\"Memory allocation failed for riseTransit\");\n    }\n\n    this.module.HEAP8.fill(0, errPtr, errPtr + ERR_BYTES);\n\n    try {\n      this.module.setValue(geoPtr, longitude, \"double\");\n      this.module.setValue(geoPtr + BYTES, latitude, \"double\");\n      this.module.setValue(geoPtr + 2 * BYTES, altitude, \"double\");\n\n      const ret = this.swe_rise_trans_fn(\n        julday,\n        planet,\n        0,       // starname pointer (0 = planet, not fixed star)\n        flags,\n        rsmi,\n        geoPtr,\n        0,       // atpress\n        0,       // attemp\n        tretPtr,\n        errPtr\n      );\n\n      if (ret < 0) {\n        const msg = this.module.UTF8ToString(errPtr);\n        throw new Error(msg || `swe_rise_trans failed with code ${ret}`);\n      }\n\n      return this.module.getValue(tretPtr, \"double\");\n    } finally {\n      this.module._free(geoPtr);\n      this.module._free(tretPtr);\n      this.module._free(errPtr);\n    }\n  }\n}\n\n/**\n * Fortune part (in ecliptic longitude)\n */\nexport function parsFortunae(\n  asc: number,\n  sunLon: number,\n  moonLon: number,\n  diurnal: boolean\n): number {\n  const val = diurnal ? asc + moonLon - sunLon : asc + sunLon - moonLon;\n  return normalizeAngle(val);\n}\n","/**\n * Integration with the Swiss Ephemeris WebAssembly module\n */\nimport wasmPathNode from \"../../wasm/build/swisseph.node.wasm?url\";\nimport wasmPathWeb from \"../../wasm/build/swisseph.web.wasm?url\";\nimport type { SwissEphModule, SwissEphModuleFactory } from \"../../wasm/src/types\";\n\n// Note: In the production code, you'll need to include the compiled WASM files\n// and update the import path. This is a placeholder that would work once the\n// compilation is complete.\n\n// Import from the actual WASM wrapper\nimport {\n  type AzaltResult,\n  CalcFlag,\n  Houses,\n  HouseSystem,\n  normalizeAngle,\n  parsFortunae,\n  Planet,\n  PLANET_AND_NODE_NAMES,\n  PlanetPosition,\n  RiseTransitFlag,\n  SwissEph,\n  VirtualNodes,\n} from \"../../wasm/src/swisseph\";\n\n// We'll use this singleton pattern to manage the Swiss Ephemeris instance\nlet swissEph: SwissEph | null = null;\n\nconst DEFAULT_FLAGS = CalcFlag.SWISS_EPH | CalcFlag.SPEED;\nexport const REQUIRED_EPHE_FILES = [\"seas_18.se1\", \"semo_18.se1\", \"sepl_18.se1\"] as const;\n\nconst NODE_EPHE_MOUNT_POINT = \"/ephefs\";\nconst NODE_EPHE_MEMFS_PATH = \"/ephemem\";\n\nfunction emitRuntimeNotice(message: string): void {\n  if (typeof process !== \"undefined\" && process.stderr && typeof process.stderr.write === \"function\") {\n    process.stderr.write(`${message}\\n`);\n    return;\n  }\n\n  console.info(message);\n}\n\ntype EmscriptenFs = NonNullable<SwissEphModule[\"FS\"]>;\n\ntype NodeEphemerisStrategy = \"nodefs-mount\" | \"host-path\" | \"memfs-copy\";\n\ninterface VirtualEphemerisCheck {\n  rootExists: boolean | null;\n  visibleEntries: string[];\n  missingFiles: string[];\n}\n\ninterface ResolvedNodeEphemerisPath {\n  path: string;\n  strategy: NodeEphemerisStrategy;\n}\n\ninterface NodeFsLike {\n  readFileSync(path: string): Uint8Array;\n}\n\ninterface PathModuleLike {\n  join(...paths: string[]): string;\n}\n\ninterface ResolveNodeEphemerisPathOptions {\n  nodeFs?: NodeFsLike;\n  pathModule?: PathModuleLike;\n  mountPoint?: string;\n  memfsPath?: string;\n  requiredFiles?: readonly string[];\n}\n\ntype RuntimeAssetSource = \"explicit\" | \"env\" | \"candidate\" | \"bundled\";\n\nexport interface SwissEphRuntimeAssetPaths {\n  wasmPath: string;\n  ephePath: string;\n  wasmPathSource: RuntimeAssetSource;\n  ephePathSource: RuntimeAssetSource;\n}\n\nexport interface ResolveSwissEphRuntimeAssetsOptions {\n  wasmPath?: string;\n  ephePath?: string;\n  wasmPathCandidates?: string[];\n  ephePathCandidates?: string[];\n  env?: Record<string, string | undefined>;\n}\n\ninterface ResolveSwissEphRuntimeAssetsInternalOptions\n  extends ResolveSwissEphRuntimeAssetsOptions {\n  isBrowser?: boolean;\n  existsSync?: (path: string) => boolean;\n  nodePathResolve?: (...paths: string[]) => string;\n  bundledNodeWasmPath?: string;\n  bundledNodeEphePath?: string;\n  bundledBrowserWasmPath?: string;\n  bundledBrowserEphePath?: string;\n}\n\nconst SWISS_EPH_RUNTIME_WASM_ENV_KEYS = [\n  \"KAABALAH_SWISSEPH_WASM_PATH\",\n  \"KAABALAH_WASM_PATH\"\n] as const;\n\nconst SWISS_EPH_RUNTIME_EPHE_ENV_KEYS = [\n  \"KAABALAH_SWISSEPH_EPHE_PATH\",\n  \"KAABALAH_EPHE_PATH\"\n] as const;\n\nfunction getRuntimeEnv(\n  env: ResolveSwissEphRuntimeAssetsOptions[\"env\"]\n): Record<string, string | undefined> {\n  if (env) {\n    return env;\n  }\n\n  if (typeof process !== \"undefined\" && process.env) {\n    return process.env;\n  }\n\n  return {};\n}\n\nfunction firstDefinedEnvValue(\n  env: Record<string, string | undefined>,\n  keys: readonly string[]\n): string | undefined {\n  for (const key of keys) {\n    const value = env[key];\n    if (typeof value === \"string\" && value.length > 0) {\n      return value;\n    }\n  }\n\n  return undefined;\n}\n\nfunction getBundledNodeSwissEphAssets(\n  options: ResolveSwissEphRuntimeAssetsInternalOptions\n): { wasmPaths: string[]; ephePaths: string[] } {\n  if (options.bundledNodeWasmPath && options.bundledNodeEphePath) {\n    return {\n      wasmPaths: [options.bundledNodeWasmPath],\n      ephePaths: [options.bundledNodeEphePath]\n    };\n  }\n\n  const resolvePath =\n    options.nodePathResolve ??\n    ((...paths: string[]) => (require(\"path\") as typeof import(\"path\")).resolve(...paths));\n\n  return {\n    wasmPaths: [\n      options.bundledNodeWasmPath,\n      resolvePath(__dirname, wasmPathNode),\n      resolvePath(__dirname, \"../../wasm/build/swisseph.node.wasm\"),\n      resolvePath(__dirname, \"../wasm/build/swisseph.node.wasm\")\n    ].filter((value): value is string => typeof value === \"string\"),\n    ephePaths: [\n      options.bundledNodeEphePath,\n      resolvePath(__dirname, \"../../ephe\"),\n      resolvePath(__dirname, \"../ephe\")\n    ].filter((value): value is string => typeof value === \"string\")\n  };\n}\n\nfunction getBundledBrowserSwissEphAssets(\n  options: ResolveSwissEphRuntimeAssetsInternalOptions\n): { wasmPath: string; ephePath: string } {\n  return {\n    wasmPath: options.bundledBrowserWasmPath ?? wasmPathWeb,\n    ephePath: options.bundledBrowserEphePath ?? \"../ephe\"\n  };\n}\n\nfunction formatCandidatePaths(paths: string[]): string {\n  return paths.length > 0 ? paths.join(\", \") : \"(none)\";\n}\n\nfunction resolveBundledRuntimeAssetPath(\n  label: \"wasmPath\" | \"ephePath\",\n  bundledPaths: string[],\n  existsSync: (path: string) => boolean\n): { path: string; source: RuntimeAssetSource } {\n  for (const bundledPath of bundledPaths) {\n    if (existsSync(bundledPath)) {\n      return {\n        path: bundledPath,\n        source: \"bundled\"\n      };\n    }\n  }\n\n  throw new Error(\n    `Unable to resolve Swiss Ephemeris ${label}. Bundled paths checked: ${formatCandidatePaths(\n      bundledPaths\n    )}.`\n  );\n}\n\nfunction resolveRuntimeAssetPath(\n  label: \"wasmPath\" | \"ephePath\",\n  explicitPath: string | undefined,\n  envPath: string | undefined,\n  candidatePaths: string[],\n  bundledPaths: string[],\n  existsSync: (path: string) => boolean\n): { path: string; source: RuntimeAssetSource } {\n  if (explicitPath) {\n    if (!existsSync(explicitPath)) {\n      throw new Error(\n        `Swiss Ephemeris ${label} override does not exist: \"${explicitPath}\".`\n      );\n    }\n\n    return {\n      path: explicitPath,\n      source: \"explicit\"\n    };\n  }\n\n  if (envPath) {\n    if (!existsSync(envPath)) {\n      throw new Error(\n        `Swiss Ephemeris ${label} from environment does not exist: \"${envPath}\".`\n      );\n    }\n\n    return {\n      path: envPath,\n      source: \"env\"\n    };\n  }\n\n  for (const candidatePath of candidatePaths) {\n    if (existsSync(candidatePath)) {\n      return {\n        path: candidatePath,\n        source: \"candidate\"\n      };\n    }\n  }\n\n  try {\n    return resolveBundledRuntimeAssetPath(label, bundledPaths, existsSync);\n  } catch (error) {\n    throw new Error(\n      `Unable to resolve Swiss Ephemeris ${label}. Checked candidate paths: ${formatCandidatePaths(\n        candidatePaths\n      )}. ${toError(error).message}`\n    );\n  }\n}\n\nfunction resolveSwissEphRuntimeAssetsInternal(\n  options: ResolveSwissEphRuntimeAssetsInternalOptions = {}\n): SwissEphRuntimeAssetPaths {\n  const isBrowser =\n    options.isBrowser ?? typeof window !== \"undefined\";\n\n  if (isBrowser) {\n    const bundledAssets = getBundledBrowserSwissEphAssets(options);\n    return {\n      wasmPath: options.wasmPath ?? bundledAssets.wasmPath,\n      ephePath: options.ephePath ?? bundledAssets.ephePath,\n      wasmPathSource: options.wasmPath ? \"explicit\" : \"bundled\",\n      ephePathSource: options.ephePath ? \"explicit\" : \"bundled\"\n    };\n  }\n\n  const env = getRuntimeEnv(options.env);\n  const existsSync =\n    options.existsSync ??\n    ((path: string) =>\n      (require(\"fs\") as typeof import(\"fs\")).existsSync(path));\n  const bundledAssets = getBundledNodeSwissEphAssets(options);\n  const envWasmPath = firstDefinedEnvValue(env, SWISS_EPH_RUNTIME_WASM_ENV_KEYS);\n  const envEphePath = firstDefinedEnvValue(env, SWISS_EPH_RUNTIME_EPHE_ENV_KEYS);\n  const resolvedWasm = resolveRuntimeAssetPath(\n    \"wasmPath\",\n    options.wasmPath,\n    envWasmPath,\n    options.wasmPathCandidates ?? [],\n    bundledAssets.wasmPaths,\n    existsSync\n  );\n  const resolvedEphe = resolveRuntimeAssetPath(\n    \"ephePath\",\n    options.ephePath,\n    envEphePath,\n    options.ephePathCandidates ?? [],\n    bundledAssets.ephePaths,\n    existsSync\n  );\n\n  return {\n    wasmPath: resolvedWasm.path,\n    ephePath: resolvedEphe.path,\n    wasmPathSource: resolvedWasm.source,\n    ephePathSource: resolvedEphe.source\n  };\n}\n\nexport function resolveSwissEphRuntimeAssets(\n  options: ResolveSwissEphRuntimeAssetsOptions = {}\n): SwissEphRuntimeAssetPaths {\n  return resolveSwissEphRuntimeAssetsInternal(options);\n}\n\nfunction normalizeVirtualPath(path: string): string {\n  if (path === \"/\") {\n    return path;\n  }\n\n  return path.replace(/\\/+$/, \"\") || \"/\";\n}\n\nfunction joinVirtualPath(rootPath: string, leaf: string): string {\n  const normalizedRoot = normalizeVirtualPath(rootPath);\n  return normalizedRoot === \"/\" ? `/${leaf}` : `${normalizedRoot}/${leaf}`;\n}\n\nfunction ensureVirtualDir(fs: EmscriptenFs, path: string): void {\n  try {\n    fs.mkdir(path);\n  } catch {\n    // Ignore existing directories and readonly mount roots.\n  }\n}\n\nfunction safeAnalyzePath(fs: EmscriptenFs, path: string): boolean | null {\n  if (!fs.analyzePath) {\n    return null;\n  }\n\n  try {\n    return fs.analyzePath(path).exists === true;\n  } catch {\n    return false;\n  }\n}\n\nfunction safeReaddir(fs: EmscriptenFs, path: string): string[] {\n  if (!fs.readdir) {\n    return [];\n  }\n\n  try {\n    return fs.readdir(path).filter((entry) => entry !== \".\" && entry !== \"..\");\n  } catch {\n    return [];\n  }\n}\n\nexport function inspectVirtualEphemerisPath(\n  fs: EmscriptenFs | undefined,\n  rootPath: string,\n  requiredFiles: readonly string[] = REQUIRED_EPHE_FILES\n): VirtualEphemerisCheck {\n  if (!fs) {\n    return {\n      rootExists: null,\n      visibleEntries: [],\n      missingFiles: [...requiredFiles],\n    };\n  }\n\n  const rootExists = safeAnalyzePath(fs, rootPath);\n  const visibleEntries = safeReaddir(fs, rootPath);\n  const missingFiles = requiredFiles.filter((file) => {\n    const filePath = joinVirtualPath(rootPath, file);\n    return !visibleEntries.includes(file) && safeAnalyzePath(fs, filePath) !== true;\n  });\n\n  return {\n    rootExists,\n    visibleEntries,\n    missingFiles,\n  };\n}\n\nfunction formatVirtualPathCheck(label: string, path: string, check: VirtualEphemerisCheck | null): string {\n  if (!check) {\n    return `${label} \"${path}\" could not be inspected.`;\n  }\n\n  const exists = check.rootExists == null ? \"unknown\" : check.rootExists ? \"yes\" : \"no\";\n  const visibleEntries = check.visibleEntries.length > 0 ? check.visibleEntries.join(\", \") : \"(none)\";\n  const missingFiles = check.missingFiles.length > 0 ? check.missingFiles.join(\", \") : \"(none)\";\n\n  return `${label} \"${path}\" exists: ${exists}; visible entries: ${visibleEntries}; missing required files: ${missingFiles}.`;\n}\n\nfunction normalizeHostFileData(data: Uint8Array): Uint8Array {\n  return data instanceof Uint8Array ? data : new Uint8Array(data);\n}\n\nfunction loadHostEphemerisFiles(\n  ephePath: string,\n  requiredFiles: readonly string[],\n  nodeFs: NodeFsLike,\n  pathModule: PathModuleLike\n): Map<string, Uint8Array> {\n  const files = new Map<string, Uint8Array>();\n\n  for (const file of requiredFiles) {\n    files.set(file, normalizeHostFileData(nodeFs.readFileSync(pathModule.join(ephePath, file))));\n  }\n\n  return files;\n}\n\nfunction writeEphemerisFilesToMemfs(\n  fs: EmscriptenFs,\n  targetPath: string,\n  files: Map<string, Uint8Array>\n): void {\n  ensureVirtualDir(fs, targetPath);\n\n  for (const [fileName, fileData] of files.entries()) {\n    fs.writeFile(joinVirtualPath(targetPath, fileName), fileData);\n  }\n}\n\nfunction toError(err: unknown): Error {\n  return err instanceof Error ? err : new Error(String(err));\n}\n\nfunction buildEphemerisResolutionError(\n  finalEphePath: string,\n  requiredFiles: readonly string[],\n  details: {\n    mountAttempted: boolean;\n    mountPoint: string;\n    mountCheck: VirtualEphemerisCheck | null;\n    mountError: Error | null;\n    hostCheck: VirtualEphemerisCheck | null;\n    memfsPath: string;\n    memfsCheck: VirtualEphemerisCheck | null;\n    hostReadError: Error | null;\n  }\n): string {\n  const parts = [\n    `Unable to resolve Swiss Ephemeris data files. Expected ${requiredFiles.join(\", \")} under \"${finalEphePath}\".`,\n  ];\n\n  if (details.mountAttempted) {\n    parts.push(\n      `${formatVirtualPathCheck(\"Mounted ephemeris path\", details.mountPoint, details.mountCheck)} The NODEFS mount may have failed silently.`\n    );\n  }\n\n  if (details.mountError) {\n    parts.push(`Mounting the ephemeris directory failed: ${details.mountError.message}.`);\n  }\n\n  parts.push(formatVirtualPathCheck(\"Direct host ephemeris path\", finalEphePath, details.hostCheck));\n\n  if (details.memfsCheck) {\n    parts.push(formatVirtualPathCheck(\"MEMFS ephemeris copy\", details.memfsPath, details.memfsCheck));\n  }\n\n  if (details.hostReadError) {\n    parts.push(`Reading host ephemeris files failed: ${details.hostReadError.message}.`);\n  }\n\n  parts.push(\n    `Pass an explicit ephePath that contains ${requiredFiles.join(\", \")} or ensure the packaged ephemeris directory is readable.`\n  );\n\n  return parts.join(\" \");\n}\n\nexport function resolveNodeEphemerisPath(\n  module: SwissEphModule,\n  finalEphePath: string,\n  options: ResolveNodeEphemerisPathOptions = {}\n): ResolvedNodeEphemerisPath {\n  const fs = module.FS;\n  const requiredFiles = options.requiredFiles ?? REQUIRED_EPHE_FILES;\n  const mountPoint = options.mountPoint ?? NODE_EPHE_MOUNT_POINT;\n  const memfsPath = options.memfsPath ?? NODE_EPHE_MEMFS_PATH;\n  const nodeFs = options.nodeFs ?? (require(\"fs\") as NodeFsLike);\n  const pathModule = options.pathModule ?? (require(\"path\") as PathModuleLike);\n\n  let mountAttempted = false;\n  let mountCheck: VirtualEphemerisCheck | null = null;\n  let mountError: Error | null = null;\n  let hostCheck: VirtualEphemerisCheck | null = null;\n  let memfsCheck: VirtualEphemerisCheck | null = null;\n  let hostReadError: Error | null = null;\n\n  if (fs?.mount && fs.filesystems?.NODEFS) {\n    mountAttempted = true;\n    ensureVirtualDir(fs, mountPoint);\n\n    try {\n      fs.mount(fs.filesystems.NODEFS, { root: finalEphePath }, mountPoint);\n      mountCheck = inspectVirtualEphemerisPath(fs, mountPoint, requiredFiles);\n\n      if (mountCheck.missingFiles.length === 0) {\n        return { path: mountPoint, strategy: \"nodefs-mount\" };\n      }\n    } catch (mountErr) {\n      mountError = toError(mountErr);\n    }\n  }\n\n  hostCheck = inspectVirtualEphemerisPath(fs, finalEphePath, requiredFiles);\n  if (fs && hostCheck.missingFiles.length === 0) {\n    return { path: finalEphePath, strategy: \"host-path\" };\n  }\n\n  let hostFiles: Map<string, Uint8Array> | null = null;\n  try {\n    hostFiles = loadHostEphemerisFiles(finalEphePath, requiredFiles, nodeFs, pathModule);\n  } catch (err) {\n    hostReadError = toError(err);\n  }\n\n  if (hostFiles && fs?.writeFile) {\n    writeEphemerisFilesToMemfs(fs, memfsPath, hostFiles);\n    memfsCheck = inspectVirtualEphemerisPath(fs, memfsPath, requiredFiles);\n\n    if (memfsCheck.missingFiles.length === 0) {\n      return { path: memfsPath, strategy: \"memfs-copy\" };\n    }\n  }\n\n  if (hostFiles) {\n    return { path: finalEphePath, strategy: \"host-path\" };\n  }\n\n  throw new Error(\n    buildEphemerisResolutionError(finalEphePath, requiredFiles, {\n      mountAttempted,\n      mountPoint,\n      mountCheck,\n      mountError,\n      hostCheck,\n      memfsPath,\n      memfsCheck,\n      hostReadError,\n    })\n  );\n}\n\n/**\n * Initializes and returns the Swiss Ephemeris instance.\n * In a browser environment, assets are loaded relative to the script.\n * In Node.js, assets are loaded from the package's 'dist' directory.\n * @param options - Optional overrides for asset paths.\n * @param options.ephePath - Path to the directory containing ephemeris data files.\n * @param options.wasmPath - Path to the `swisseph.wasm` file.\n */\nexport async function getSwissEph(\n  options: { ephePath?: string; wasmPath?: string } = {}\n): Promise<void> {\n  if (swissEph) {\n    return;\n  }\n\n  try {\n    const isBrowser = typeof window !== \"undefined\";\n    const runtimeAssets = resolveSwissEphRuntimeAssets({\n      wasmPath: options.wasmPath,\n      ephePath: options.ephePath\n    });\n    const finalWasmPath = runtimeAssets.wasmPath;\n\n    const moduleFactory: SwissEphModuleFactory = isBrowser\n      ? (await import(\"../../wasm/build/swisseph.web.js\")).default as unknown as SwissEphModuleFactory\n      : (await import(\"../../wasm/build/swisseph.node.js\")).default as unknown as SwissEphModuleFactory;\n\n    const module = await moduleFactory({\n      locateFile: () => finalWasmPath,\n    });\n\n    const instance = new SwissEph(module);\n\n    const finalEphePath = runtimeAssets.ephePath;\n\n    if (isBrowser) {\n      // In the browser, synchronously fetch and write ephemeris files into MEMFS\n      const epheFsPath = \"/ephe\";\n      try {\n        module.FS?.mkdir?.(epheFsPath);\n      } catch {\n        // ignore if exists\n      }\n      const files = [\"seas_18.se1\", \"semo_18.se1\", \"sepl_18.se1\"];\n      await Promise.all(\n        files.map(async (name) => {\n          const url = `${finalEphePath}/${name}`;\n          const res = await fetch(url);\n          if (!res.ok) {\n            throw new Error(`Failed to fetch ephemeris file: ${url}`);\n          }\n          const buf = await res.arrayBuffer();\n          module.FS?.writeFile?.(\n            `${epheFsPath}/${name}`,\n            new Uint8Array(buf)\n          );\n        })\n      );\n      const browserCheck = inspectVirtualEphemerisPath(module.FS, epheFsPath, REQUIRED_EPHE_FILES);\n      if (browserCheck.missingFiles.length > 0) {\n        throw new Error(\n          `Failed to materialize browser ephemeris files at \"${epheFsPath}\". Missing: ${browserCheck.missingFiles.join(\", \")}.`\n        );\n      }\n      emitRuntimeNotice(`Setting ephemeris path to: ${epheFsPath}`);\n      instance.setEphemerisPath(epheFsPath);\n    } else {\n      const resolution = resolveNodeEphemerisPath(module, finalEphePath);\n      if (resolution.strategy === \"nodefs-mount\") {\n        emitRuntimeNotice(`Setting ephemeris path to: ${resolution.path} (mounted from ${finalEphePath})`);\n      } else if (resolution.strategy === \"memfs-copy\") {\n        emitRuntimeNotice(`Setting ephemeris path to: ${resolution.path} (copied from ${finalEphePath})`);\n      } else {\n        emitRuntimeNotice(`Setting ephemeris path to: ${resolution.path}`);\n      }\n      instance.setEphemerisPath(resolution.path);\n    }\n\n    swissEph = instance;\n  } catch (error) {\n    console.error(\"Error initializing Swiss Ephemeris:\", error);\n    throw error;\n  }\n}\n\n/**\n * Calculate planetary positions for a given date\n */\n/**\n * Calculate the position of a single planet by its enum ID.\n * Much cheaper than calculatePlanetaryPositions when only one body is needed.\n */\nexport function calculateSinglePlanetPosition(\n  date: Date,\n  planet: Planet\n): PlanetPosition {\n  checkInitialization();\n  const julday = swissEph!.getJulianDay(date);\n  return swissEph!.calculatePlanetPosition(julday, planet, DEFAULT_FLAGS);\n}\n\n/**\n * Calculate equatorial coordinates (Right Ascension / Declination) for a planet.\n * Uses the existing EQUATORIAL flag — RA is returned in the longitude field,\n * Dec in the latitude field by Swiss Ephemeris convention.\n */\nexport interface EquatorialPosition {\n  rightAscension: number;\n  declination: number;\n  distance: number;\n}\n\nexport function calculateEquatorialPosition(\n  date: Date,\n  planet: Planet\n): EquatorialPosition {\n  checkInitialization();\n  const julday = swissEph!.getJulianDay(date);\n  const pos = swissEph!.calculatePlanetPosition(\n    julday,\n    planet,\n    CalcFlag.SWISS_EPH | CalcFlag.EQUATORIAL\n  );\n  return {\n    rightAscension: pos.longitude,\n    declination: pos.latitude,\n    distance: pos.distance,\n  };\n}\n\n/**\n * Get the Julian day for a Date (UTC).\n */\nexport function getJulianDay(date: Date): number {\n  checkInitialization();\n  return swissEph!.getJulianDay(date);\n}\n\n/**\n * Find the next rise, set, or meridian transit of a planet at a location.\n * Returns the Julian day of the event.\n */\nexport function calculateRiseTransit(\n  date: Date,\n  planet: Planet,\n  latitude: number,\n  longitude: number,\n  event: RiseTransitFlag\n): number {\n  checkInitialization();\n  const julday = swissEph!.getJulianDay(date);\n  return swissEph!.riseTransit(julday, planet, event, longitude, latitude);\n}\n\n/**\n * Convert ecliptic coordinates to horizon coordinates (azimuth/altitude).\n */\nexport function calculateAzalt(\n  date: Date,\n  latitude: number,\n  longitude: number,\n  eclLon: number,\n  eclLat: number,\n  dist: number\n): AzaltResult {\n  checkInitialization();\n  const julday = swissEph!.getJulianDay(date);\n  return swissEph!.azalt(julday, longitude, latitude, 0, eclLon, eclLat, dist);\n}\n\nexport async function calculatePlanetaryPositions(\n  date: Date\n): Promise<Record<Planet, PlanetPosition>> {\n  try {\n    checkInitialization();\n\n    const julday = swissEph!.getJulianDay(date);\n    const flags = DEFAULT_FLAGS;\n    const planets: Record<string, Planet> = {\n      sun: Planet.SUN,\n      moon: Planet.MOON,\n      mercury: Planet.MERCURY,\n      venus: Planet.VENUS,\n      mars: Planet.MARS,\n      jupiter: Planet.JUPITER,\n      saturn: Planet.SATURN,\n      uranus: Planet.URANUS,\n      neptune: Planet.NEPTUNE,\n      pluto: Planet.PLUTO,\n      meanNode: Planet.MEAN_NODE,\n      trueNode: Planet.TRUE_NODE,\n      chiron: Planet.CHIRON,\n      lilithMean: Planet.LILITH_MEAN,\n      lilithTrue: Planet.LILITH_TRUE,\n    };\n\n    const positions: Record<Planet, PlanetPosition> = {} as Record<\n      Planet,\n      PlanetPosition\n    >;\n    for (const id of Object.values(planets)) {\n      try {\n        positions[id] = swissEph!.calculatePlanetPosition(julday, id, flags);\n      } catch (error) {\n        throw new Error(\n          `Failed to calculate position for ${PLANET_AND_NODE_NAMES[id]}: ${error}`\n        );\n      }\n    }\n\n    return positions;\n  } catch (error) {\n    console.error(\"Error calculating planetary positions:\", error);\n    throw error;\n  }\n}\n\n/**\n * Calculate houses for a given date and location\n */\nexport async function calculateHouses(\n  date: Date | LocalDateTimeParts,\n  latitude: number,\n  longitude: number,\n  houseSystem: HouseSystem,\n  options: TimeZoneOptions = {}\n): Promise<Houses> {\n  try {\n    checkInitialization();\n\n    // Interpret the provided date as local civil time by default.\n    // For backward compatibility, allow callers to treat the date as UT.\n    const dateForUt =\n      options.treatAsUTC === true\n        ? (date instanceof Date ? date : createUtcDateFromParts(buildLocalParts(date)))\n        : await localToUtcDate(date, latitude, longitude, options);\n\n    const julday = swissEph!.getJulianDay(dateForUt);\n    return swissEph!.calculateHouses(\n      julday,\n      latitude,\n      longitude,\n      houseSystem\n    );\n  } catch (error) {\n    console.error(\"Error calculating houses:\", error);\n    throw error;\n  }\n}\n/**\n * Calculate an asteroid by MPC number\n */\nexport async function calculateAsteroidPosition(\n  date: Date,\n  mpcNumber: number\n): Promise<PlanetPosition> {\n  try {\n    checkInitialization();\n\n    const julday = swissEph!.getJulianDay(date);\n    return swissEph!.calculateAsteroidPosition(\n      julday,\n      mpcNumber,\n      DEFAULT_FLAGS\n    );\n  } catch (error) {\n    console.error(\"Error calculating asteroid:\", error);\n    throw error;\n  }\n}\n\n/**\n * Fortune part utility (requires Asc, Sun, Moon and diurnal/nocturnal)\n * diurnal: Asc + Moon - Sun ; nocturnal: Asc + Sun - Moon\n */\nexport function calcParsFortunae(\n  asc: number,\n  sunLon: number,\n  moonLon: number,\n  isDiurnal: boolean\n): number {\n  return parsFortunae(asc, sunLon, moonLon, isDiurnal);\n}\n\n/**\n * Clean up Swiss Ephemeris resources\n */\nexport function closeSwissEph(): void {\n  if (swissEph) {\n    try {\n      swissEph.close();\n      swissEph = null;\n    } catch (error) {\n      console.error(\"Error closing Swiss Ephemeris:\", error);\n      throw error;\n    }\n  }\n}\n\nfunction checkInitialization(): void {\n  if (!swissEph) {\n    throw new Error(\n      \"Swiss Ephemeris not initialized. Call getSwissEph() first.\"\n    );\n  }\n}\n\n// Re-export types and enums for convenience\nexport {\n  type AzaltResult,\n  CalcFlag,\n  HouseSystem,\n  normalizeAngle,\n  Planet,\n  PLANET_AND_NODE_NAMES,\n  PlanetPosition,\n  RiseTransitFlag,\n  VirtualNodes\n};\n\n/**\n * Local civil time handling (DST-aware)\n * Convert a local date-time (given via IANA time zone, explicit UTC offset, or auto from lat/lon)\n * into a UTC Date for Swiss Ephemeris (which expects UT).\n */\nexport interface LocalDateTimeParts {\n  year: number;\n  month: number; // 1-12\n  day: number; // 1-31\n  hour?: number; // 0-23\n  minute?: number; // 0-59\n  second?: number; // 0-59\n}\n\nexport type TimeZoneOptions = {\n  /**\n   * IANA time zone\n   * If provided, DST is handled automatically via Intl API.\n   */\n  timeZone?: string;\n  /**\n   * Explicit UTC offset in minutes for the local civil time.\n   * Positive for east of Greenwich, negative for west (e.g., -180 for UTC-3).\n   * If provided, overrides timeZone.\n   */\n  utcOffsetMinutes?: number;\n  /**\n   * Optional resolver to derive an IANA time zone from coordinates and date.\n   * Use an external library (e.g., tz-lookup) and pass it here.\n   */\n  resolveTimeZone?: (latitude: number, longitude: number, local: LocalDateTimeParts) => string | undefined;\n  /**\n   * When true (default), try to auto-resolve the IANA time zone from lat/lon using tz-lookup\n   * if no explicit offset/timeZone is provided.\n   */\n  autoTimeZone?: boolean;\n  /**\n   * When true, the date is treated as UTC instead of local civil time.\n   */\n  treatAsUTC?: boolean;\n};\n\nfunction buildLocalParts(date: Date | LocalDateTimeParts): LocalDateTimeParts {\n  if (date instanceof Date) {\n    return {\n      year: date.getFullYear(),\n      month: date.getMonth() + 1,\n      day: date.getDate(),\n      hour: date.getHours(),\n      minute: date.getMinutes(),\n      second: date.getSeconds(),\n    };\n  }\n  return date;\n}\n\nfunction createUtcDateFromParts(parts: LocalDateTimeParts): Date {\n  const { year, month, day, hour = 0, minute = 0, second = 0 } = parts;\n  return new Date(Date.UTC(year, month - 1, day, hour, minute, second));\n}\n\n/**\n * Compute the time zone offset (in ms) for a given instant and IANA time zone.\n * Based on the approach used by date-fns-tz.\n */\nfunction getTimeZoneOffsetMs(instant: Date, timeZone: string): number {\n  const dtf = new Intl.DateTimeFormat(\"en-US\", {\n    timeZone,\n    year: \"numeric\",\n    month: \"2-digit\",\n    day: \"2-digit\",\n    hour: \"2-digit\",\n    minute: \"2-digit\",\n    second: \"2-digit\",\n    hour12: false,\n  });\n  const parts = dtf.formatToParts(instant);\n  const map: Record<string, string> = {};\n  for (const p of parts) {\n    map[p.type] = p.value;\n  }\n  const asUTC = Date.UTC(\n    Number(map.year),\n    Number(map.month) - 1,\n    Number(map.day),\n    Number(map.hour),\n    Number(map.minute),\n    Number(map.second)\n  );\n  return asUTC - instant.getTime();\n}\n\n/**\n * Convert a local civil date-time to a UTC Date using either an explicit offset,\n * an IANA time zone (DST-aware), a custom resolver, or auto lat/lon resolution.\n * If no time zone information can be derived, throws.\n */\nasync function localToUtcDate(\n  local: Date | LocalDateTimeParts,\n  latitude?: number,\n  longitude?: number,\n  opts: TimeZoneOptions = {}\n): Promise<Date> {\n  // Treat the date as already UTC — no conversion needed\n  if (opts.treatAsUTC === true) {\n    return local instanceof Date ? local : createUtcDateFromParts(buildLocalParts(local));\n  }\n\n  const parts = buildLocalParts(local);\n  const auto = opts.autoTimeZone !== false;\n\n  // 1) Explicit offset takes precedence\n  if (typeof opts.utcOffsetMinutes === \"number\" && Number.isFinite(opts.utcOffsetMinutes)) {\n    const utcMs = Date.UTC(\n      parts.year,\n      parts.month - 1,\n      parts.day,\n      parts.hour ?? 0,\n      parts.minute ?? 0,\n      parts.second ?? 0\n    );\n    return new Date(utcMs - opts.utcOffsetMinutes * 60_000);\n  }\n\n  // 2) IANA time zone provided\n  if (opts.timeZone) {\n    const naiveUtc = createUtcDateFromParts(parts);\n    const offsetMs = getTimeZoneOffsetMs(naiveUtc, opts.timeZone);\n    return new Date(naiveUtc.getTime() - offsetMs);\n  }\n\n  // 3) Custom resolver\n  if (\n    opts.resolveTimeZone &&\n    typeof latitude === \"number\" &&\n    typeof longitude === \"number\"\n  ) {\n    const tz = opts.resolveTimeZone(latitude, longitude, parts);\n    if (tz) {\n      const naiveUtc = createUtcDateFromParts(parts);\n      const offsetMs = getTimeZoneOffsetMs(naiveUtc, tz);\n      return new Date(naiveUtc.getTime() - offsetMs);\n    }\n  }\n\n  // 4) Auto resolve with tz-lookup if allowed and coords available\n  if (\n    auto &&\n    typeof latitude === \"number\" &&\n    typeof longitude === \"number\"\n  ) {\n\n    const mod = await import(\"tz-lookup\");\n    const lookup = mod.default ?? mod;\n    const tz = lookup(latitude, longitude);\n    if (tz) {\n      const naiveUtc = createUtcDateFromParts(parts);\n      const offsetMs = getTimeZoneOffsetMs(naiveUtc, tz);\n      return new Date(naiveUtc.getTime() - offsetMs);\n    }\n  }\n\n  throw new Error(\n    \"Time zone information is required. Provide 'utcOffsetMinutes', 'timeZone', 'resolveTimeZone', or enable autoTimeZone with latitude/longitude.\"\n  );\n}\n\n/**\n * Public helper to convert a local civil date-time to a UTC Date using the same\n * logic as house calculations.\n */\nexport async function toUtcDate(\n  local: Date | LocalDateTimeParts,\n  latitude?: number,\n  longitude?: number,\n  options: TimeZoneOptions = {}\n): Promise<Date> {\n  return localToUtcDate(local, latitude, longitude, options);\n}\n","/**\n * Astro*Carto*Graphy (ACG) — locational astrology.\n *\n * Computes where each planet falls on the four angles (MC, IC, AC, DC)\n * across the globe, and queries a specific location for nearby lines\n * and paran crossings.\n *\n * MC/IC lines are pure math (GMST − RA). AC/DC lines require a latitude\n * sweep solving cos(H) = −tan(φ)·tan(δ).\n */\n\nimport {\n  calculateEquatorialPosition,\n  type EquatorialPosition,\n  getJulianDay,\n  normalizeAngle,\n  Planet,\n  PLANET_AND_NODE_NAMES,\n} from \"./swisseph\";\n\n// ─── Types ──────────────────────────────────────────────────────────────\n\nexport type AngleType = \"MC\" | \"IC\" | \"AC\" | \"DC\";\n\nexport interface AstrocartographyLineProximity {\n  planet: string;\n  angle: AngleType;\n  /** Degrees of longitude separation (always positive, 0-180). */\n  distance: number;\n  /** True when distance ≤ orb. */\n  active: boolean;\n  /** The line's geographic longitude at the query latitude (-180..180). */\n  longitude: number;\n}\n\nexport interface AstrocartographyParan {\n  latitude: number;\n  planetA: string;\n  angleA: AngleType;\n  longitudeA: number;\n  planetB: string;\n  angleB: AngleType;\n  longitudeB: number;\n}\n\nexport interface AstrocartographyQueryResult {\n  queryLatitude: number;\n  queryLongitude: number;\n  orb: number;\n  lines: AstrocartographyLineProximity[];\n  activeLines: AstrocartographyLineProximity[];\n  parans: AstrocartographyParan[];\n}\n\nexport interface AstrocartographyMeridianLine {\n  planet: string;\n  angle: \"MC\" | \"IC\";\n  /** Geographic longitude (-180..180). */\n  longitude: number;\n}\n\nexport interface AstrocartographyHorizonPoint {\n  latitude: number;\n  longitude: number;\n}\n\nexport interface AstrocartographyHorizonLine {\n  planet: string;\n  angle: \"AC\" | \"DC\";\n  points: AstrocartographyHorizonPoint[];\n}\n\nexport interface AstrocartographyMap {\n  meridianLines: AstrocartographyMeridianLine[];\n  horizonLines: AstrocartographyHorizonLine[];\n}\n\nexport interface AstrocartographyMapOptions {\n  /** Degrees between latitude sample points (default 1). */\n  latitudeStep?: number;\n  /** Maximum latitude to sweep (default 66.5). */\n  latitudeRange?: number;\n  /** Planets to include (default: ASTROCARTOGRAPHY_DEFAULT_PLANETS). */\n  planets?: Planet[];\n}\n\nexport interface AstrocartographyQueryOptions {\n  latitude: number;\n  longitude: number;\n  /** Orb in degrees (default 2). */\n  orb?: number;\n  /** Planets to include (default: ASTROCARTOGRAPHY_DEFAULT_PLANETS). */\n  planets?: Planet[];\n  /** Paran orb in degrees (default 1). */\n  paranOrb?: number;\n}\n\n// ─── Constants ──────────────────────────────────────────────────────────\n\n/** Default planet set for ACG (traditional + modern, no Lilith). */\nexport const ASTROCARTOGRAPHY_DEFAULT_PLANETS: Planet[] = [\n  Planet.SUN,\n  Planet.MOON,\n  Planet.MERCURY,\n  Planet.VENUS,\n  Planet.MARS,\n  Planet.JUPITER,\n  Planet.SATURN,\n  Planet.URANUS,\n  Planet.NEPTUNE,\n  Planet.PLUTO,\n  Planet.CHIRON,\n  Planet.TRUE_NODE,\n];\n\nconst DEG = Math.PI / 180;\n\n// ─── Pure math ──────────────────────────────────────────────────────────\n\n/**\n * Greenwich Mean Sidereal Time from Julian Day (degrees, 0-360).\n */\nexport function computeGMST(julianDay: number): number {\n  return normalizeAngle(\n    280.46061837 + 360.98564736629 * (julianDay - 2451545.0)\n  );\n}\n\n/**\n * Geographic longitude where a planet's MC line falls.\n * Returns value in -180..180.\n */\nexport function computeMCLongitude(gmst: number, ra: number): number {\n  return toGeoLon(normalizeAngle(gmst - ra));\n}\n\n/**\n * Geographic longitude where a planet's IC line falls (opposite MC).\n */\nexport function computeICLongitude(gmst: number, ra: number): number {\n  return toGeoLon(normalizeAngle(gmst - ra + 180));\n}\n\n/**\n * Geographic longitude where a planet rises (AC) or sets (DC)\n * at a given geographic latitude.\n *\n * Returns null if the planet is circumpolar or never rises at this latitude.\n */\nexport function computeHorizonLongitude(\n  gmst: number,\n  ra: number,\n  dec: number,\n  latitude: number,\n  angle: \"AC\" | \"DC\"\n): number | null {\n  const tanPhi = Math.tan(latitude * DEG);\n  const tanDelta = Math.tan(dec * DEG);\n  const cosH = -(tanPhi * tanDelta);\n\n  // Circumpolar or never visible\n  if (Math.abs(cosH) > 1) return null;\n\n  const H = Math.acos(cosH) / DEG; // hour angle in degrees\n\n  // AC (rising) = east of meridian = negative hour angle\n  // DC (setting) = west of meridian = positive hour angle\n  const lon =\n    angle === \"AC\"\n      ? normalizeAngle(gmst - ra - H)\n      : normalizeAngle(gmst - ra + H);\n\n  return toGeoLon(lon);\n}\n\n/**\n * Shortest angular distance between two geographic longitudes.\n * Returns 0..180.\n */\nexport function geographicAngularDifference(a: number, b: number): number {\n  const d = normalizeAngle(a - b);\n  return d > 180 ? 360 - d : d;\n}\n\n/**\n * Convert 0..360 ecliptic-style longitude to -180..180 geographic longitude.\n * 0-180 → 0 to 180 (east), 180-360 → -180 to 0 (west).\n */\nfunction toGeoLon(deg360: number): number {\n  const n = normalizeAngle(deg360);\n  return n > 180 ? n - 360 : n;\n}\n\n// ─── Equatorial position helpers ────────────────────────────────────────\n\nexport interface PlanetEquatorial {\n  ra: number;\n  dec: number;\n  planetId: Planet;\n}\n\n/**\n * Compute equatorial positions (RA/Dec) for a set of planets at a UTC date.\n */\nexport function computeEquatorialPositions(\n  date: Date,\n  planets: Planet[] = ASTROCARTOGRAPHY_DEFAULT_PLANETS\n): Record<string, PlanetEquatorial> {\n  const result: Record<string, PlanetEquatorial> = {};\n  for (const p of planets) {\n    const name = PLANET_AND_NODE_NAMES[p];\n    const eq = calculateEquatorialPosition(date, p);\n    result[name] = {\n      ra: eq.rightAscension,\n      dec: eq.declination,\n      planetId: p,\n    };\n  }\n  return result;\n}\n\n// ─── Paran detection ────────────────────────────────────────────────────\n\n/**\n * Find paran crossings at a given latitude.\n *\n * A paran exists when two different planet's angle-lines\n * pass through the same latitude within `paranOrb` degrees of longitude.\n */\nexport function findParansAtLatitude(\n  equatorialPositions: Record<string, PlanetEquatorial>,\n  gmst: number,\n  latitude: number,\n  paranOrb = 1\n): AstrocartographyParan[] {\n  const ANGLES: AngleType[] = [\"MC\", \"IC\", \"AC\", \"DC\"];\n\n  // Build all lines at this latitude\n  interface LineAt {\n    planet: string;\n    angle: AngleType;\n    longitude: number;\n  }\n  const lines: LineAt[] = [];\n\n  for (const [name, eq] of Object.entries(equatorialPositions)) {\n    for (const angle of ANGLES) {\n      let lon: number | null;\n      if (angle === \"MC\") lon = computeMCLongitude(gmst, eq.ra);\n      else if (angle === \"IC\") lon = computeICLongitude(gmst, eq.ra);\n      else lon = computeHorizonLongitude(gmst, eq.ra, eq.dec, latitude, angle);\n\n      if (lon !== null) {\n        lines.push({ planet: name, angle, longitude: lon });\n      }\n    }\n  }\n\n  // Compare all pairs from different planets\n  const parans: AstrocartographyParan[] = [];\n  for (let i = 0; i < lines.length; i++) {\n    for (let j = i + 1; j < lines.length; j++) {\n      const a = lines[i];\n      const b = lines[j];\n      if (a.planet === b.planet) continue; // same planet, skip\n      if (a.angle === b.angle) continue; // same angle type, skip (not a crossing)\n\n      const dist = geographicAngularDifference(a.longitude, b.longitude);\n      if (dist <= paranOrb) {\n        parans.push({\n          latitude,\n          planetA: a.planet,\n          angleA: a.angle,\n          longitudeA: a.longitude,\n          planetB: b.planet,\n          angleB: b.angle,\n          longitudeB: b.longitude,\n        });\n      }\n    }\n  }\n  return parans;\n}\n\n// ─── Query function (primary API) ───────────────────────────────────────\n\n/**\n * Query a specific location against a birth chart's ACG lines.\n *\n * Returns how close each planet's angle line is to the query location,\n * which lines are \"active\" (within orb), and paran crossings at the\n * query latitude.\n */\nexport function queryAstrocartographyLocation(\n  date: Date,\n  options: AstrocartographyQueryOptions\n): AstrocartographyQueryResult {\n  const {\n    latitude,\n    longitude,\n    orb = 2,\n    planets = ASTROCARTOGRAPHY_DEFAULT_PLANETS,\n    paranOrb = 1,\n  } = options;\n\n  const jd = getJulianDay(date);\n  const gmst = computeGMST(jd);\n  const positions = computeEquatorialPositions(date, planets);\n\n  const lines: AstrocartographyLineProximity[] = [];\n  const ANGLES: AngleType[] = [\"MC\", \"IC\", \"AC\", \"DC\"];\n\n  for (const [name, eq] of Object.entries(positions)) {\n    for (const angle of ANGLES) {\n      let lineLon: number | null;\n      if (angle === \"MC\") lineLon = computeMCLongitude(gmst, eq.ra);\n      else if (angle === \"IC\") lineLon = computeICLongitude(gmst, eq.ra);\n      else\n        lineLon = computeHorizonLongitude(\n          gmst,\n          eq.ra,\n          eq.dec,\n          latitude,\n          angle\n        );\n\n      if (lineLon === null) continue; // circumpolar, no line at this latitude\n\n      const dist = geographicAngularDifference(longitude, lineLon);\n      lines.push({\n        planet: name,\n        angle,\n        distance: Math.round(dist * 1000) / 1000,\n        active: dist <= orb,\n        longitude: Math.round(lineLon * 1000) / 1000,\n      });\n    }\n  }\n\n  // Sort by distance ascending\n  lines.sort((a, b) => a.distance - b.distance);\n\n  const activeLines = lines.filter((l) => l.active);\n  const parans = findParansAtLatitude(positions, gmst, latitude, paranOrb);\n\n  return { queryLatitude: latitude, queryLongitude: longitude, orb, lines, activeLines, parans };\n}\n\n// ─── Full map generation ────────────────────────────────────────────────\n\n/**\n * Generate the full ACG map: MC/IC lines (constant longitudes) and\n * AC/DC lines (arrays of lat/lon points from a latitude sweep).\n */\nexport function computeAstrocartographyMap(\n  date: Date,\n  options: AstrocartographyMapOptions = {}\n): AstrocartographyMap {\n  const {\n    latitudeStep = 1,\n    latitudeRange = 66.5,\n    planets = ASTROCARTOGRAPHY_DEFAULT_PLANETS,\n  } = options;\n\n  const jd = getJulianDay(date);\n  const gmst = computeGMST(jd);\n  const positions = computeEquatorialPositions(date, planets);\n\n  const meridianLines: AstrocartographyMeridianLine[] = [];\n  const horizonLines: AstrocartographyHorizonLine[] = [];\n\n  for (const [name, eq] of Object.entries(positions)) {\n    // MC / IC — constant longitude lines\n    meridianLines.push({\n      planet: name,\n      angle: \"MC\",\n      longitude: Math.round(computeMCLongitude(gmst, eq.ra) * 1000) / 1000,\n    });\n    meridianLines.push({\n      planet: name,\n      angle: \"IC\",\n      longitude: Math.round(computeICLongitude(gmst, eq.ra) * 1000) / 1000,\n    });\n\n    // AC / DC — sweep latitudes\n    for (const angle of [\"AC\", \"DC\"] as const) {\n      const points: AstrocartographyHorizonPoint[] = [];\n      for (\n        let lat = -latitudeRange;\n        lat <= latitudeRange;\n        lat += latitudeStep\n      ) {\n        const lon = computeHorizonLongitude(gmst, eq.ra, eq.dec, lat, angle);\n        if (lon !== null) {\n          points.push({\n            latitude: Math.round(lat * 1000) / 1000,\n            longitude: Math.round(lon * 1000) / 1000,\n          });\n        }\n      }\n      horizonLines.push({ planet: name, angle, points });\n    }\n  }\n\n  return { meridianLines, horizonLines };\n}\n","import { normalizeAngle } from \"./swisseph\";\n\nexport type AspectName =\n  | \"conjunction\"\n  | \"duodecile\"\n  | \"octile\"\n  | \"sextile\"\n  | \"square\"\n  | \"trine\"\n  | \"trioctile\"\n  | \"quincunx\"\n  | \"opposition\";\n\nexport interface AspectSpec {\n  name: AspectName;\n  angle: number;\n  orb: number;\n}\n\nexport const DEFAULT_ASPECT_SPECS: AspectSpec[] = [\n  { name: \"conjunction\", angle: 0, orb: 8 },\n  { name: \"duodecile\", angle: 30, orb: 2 },\n  { name: \"octile\", angle: 45, orb: 3 },\n  { name: \"sextile\", angle: 60, orb: 5 },\n  { name: \"square\", angle: 90, orb: 6 },\n  { name: \"trine\", angle: 120, orb: 7 },\n  { name: \"trioctile\", angle: 135, orb: 3 },\n  { name: \"quincunx\", angle: 150, orb: 3 },\n  { name: \"opposition\", angle: 180, orb: 8 },\n];\n\nexport interface AspectEdge {\n  planetA: string;\n  planetB: string;\n  longitudeA: number;\n  longitudeB: number;\n  aspect: AspectName;\n  aspectAngle: number;\n  delta: number;\n  orb: number;\n}\n\nexport function getAspectMatch(\n  lonA: number,\n  lonB: number,\n  specs: AspectSpec[] = DEFAULT_ASPECT_SPECS\n): { spec: AspectSpec; orb: number; delta: number } | null {\n  const a = normalizeAngle(lonA);\n  const b = normalizeAngle(lonB);\n  const delta = Math.min(\n    normalizeAngle(b - a),\n    normalizeAngle(a - b)\n  );\n  for (const spec of specs) {\n    const orb = Math.abs(delta - spec.angle);\n    if (orb <= spec.orb) {\n      return { spec, orb, delta };\n    }\n  }\n  return null;\n}\n\nexport function computeAspects(\n  planets: Record<string, { longitude: number }>,\n  specs: AspectSpec[] = DEFAULT_ASPECT_SPECS\n): AspectEdge[] {\n  const keys = Object.keys(planets);\n  const edges: AspectEdge[] = [];\n  for (let i = 0; i < keys.length; i++) {\n    for (let j = i + 1; j < keys.length; j++) {\n      const a = planets[keys[i]];\n      const b = planets[keys[j]];\n      const match = getAspectMatch(a.longitude, b.longitude, specs);\n      if (match) {\n        edges.push({\n          planetA: keys[i],\n          planetB: keys[j],\n          longitudeA: a.longitude,\n          longitudeB: b.longitude,\n          aspect: match.spec.name,\n          aspectAngle: match.spec.angle,\n          delta: match.delta,\n          orb: match.orb,\n        });\n      }\n    }\n  }\n  return edges;\n}\n\nexport function computeSynastryAspects(\n  planetsA: Record<string, { longitude: number }>,\n  planetsB: Record<string, { longitude: number }>,\n  specs: AspectSpec[] = DEFAULT_ASPECT_SPECS\n): AspectEdge[] {\n  const keysA = Object.keys(planetsA);\n  const keysB = Object.keys(planetsB);\n  const edges: AspectEdge[] = [];\n  for (const kA of keysA) {\n    for (const kB of keysB) {\n      const a = planetsA[kA];\n      const b = planetsB[kB];\n      const match = getAspectMatch(a.longitude, b.longitude, specs);\n      if (match) {\n        edges.push({\n          planetA: kA,\n          planetB: kB,\n          longitudeA: a.longitude,\n          longitudeB: b.longitude,\n          aspect: match.spec.name,\n          aspectAngle: match.spec.angle,\n          delta: match.delta,\n          orb: match.orb,\n        });\n      }\n    }\n  }\n  return edges;\n}\n\n/** Shorter-arc midpoint of two ecliptic longitudes. */\nexport function shorterArcMidpoint(a: number, b: number): number {\n  let diff = b - a;\n  if (diff > 180) diff -= 360;\n  if (diff < -180) diff += 360;\n  return normalizeAngle(a + diff / 2);\n}\n\nexport function computeMidpoints(\n  planetsA: Record<string, { longitude: number }>,\n  planetsB: Record<string, { longitude: number }>\n): Record<string, number> {\n  const result: Record<string, number> = {};\n  for (const key of Object.keys(planetsA)) {\n    if (!(key in planetsB)) continue;\n    result[key] = shorterArcMidpoint(planetsA[key].longitude, planetsB[key].longitude);\n  }\n  return result;\n}\n\n// ── Transit aspects ─────────────────────────────────────────────────────\n\nexport interface TransitAspectEdge extends AspectEdge {\n  applying: boolean;\n  retrograde: boolean;\n  category: \"slow\" | \"fast\";\n}\n\nexport interface TransitAspectPoint {\n  longitude: number;\n  longitudeSpeed?: number;\n}\n\nexport const SLOW_PLANETS = new Set([\n  \"pluto\", \"neptune\", \"uranus\", \"saturn\", \"jupiter\", \"chiron\",\n  \"mean node\", \"true node\", \"lilith true\", \"lilith mean\",\n]);\n\n// Deferred transit features (future releases):\n// - Theme tagging: planet-pair -> archetypal theme (Mars-Pluto = POWER, Neptune-Mercury = DECEPTION, etc.)\n// - Ingress detection: transit planet crossing natal house cusp boundaries\n// - Multi-pass tracking: 3-hit retrograde patterns (direct, retrograde, direct exact dates)\n// - Secondary progressions (--progressed flag)\n// - Arabic parts / fixed stars / eclipses as transit targets\n// - Batch mode: multiple natal charts in one invocation\n\n/**\n * Compute transit-to-natal aspects with applying/separating, retrograde, and speed category.\n *\n * planetA = transit planet, planetB = natal planet/point.\n */\nexport function computeTransitAspects(\n  transitPlanets: Record<string, TransitAspectPoint>,\n  natalPlanets: Record<string, TransitAspectPoint>,\n  specs: AspectSpec[] = DEFAULT_ASPECT_SPECS\n): TransitAspectEdge[] {\n  const keysT = Object.keys(transitPlanets);\n  const keysN = Object.keys(natalPlanets);\n  const edges: TransitAspectEdge[] = [];\n\n  for (const kT of keysT) {\n    const t = transitPlanets[kT];\n    for (const kN of keysN) {\n      const n = natalPlanets[kN];\n      const match = getAspectMatch(t.longitude, n.longitude, specs);\n      if (!match) continue;\n\n      const tSpeed = t.longitudeSpeed ?? 0;\n      const nSpeed = n.longitudeSpeed ?? 0;\n\n      // Epsilon projection: check if orb is decreasing (applying) or increasing (separating)\n      const dt = 0.01; // ~14 minutes\n      const tLonFuture = t.longitude + tSpeed * dt;\n      const nLonFuture = n.longitude + nSpeed * dt;\n      const futureMatch = getAspectMatch(tLonFuture, nLonFuture, [match.spec]);\n      const applying = futureMatch != null ? futureMatch.orb < match.orb : false;\n\n      edges.push({\n        planetA: kT,\n        planetB: kN,\n        longitudeA: t.longitude,\n        longitudeB: n.longitude,\n        aspect: match.spec.name,\n        aspectAngle: match.spec.angle,\n        delta: match.delta,\n        orb: match.orb,\n        applying,\n        retrograde: tSpeed < 0,\n        category: SLOW_PLANETS.has(kT) ? \"slow\" : \"fast\",\n      });\n    }\n  }\n  return edges;\n}\n","/**\n * Essential Dignity Table — Traditional Hellenistic rulership data.\n * Pure math, no WASM dependency.\n */\n\nimport { SIGNS } from \"./index\";\n\nexport type Sign = (typeof SIGNS)[number];\n\nexport type TraditionalPlanet =\n  | \"Sun\"\n  | \"Moon\"\n  | \"Mercury\"\n  | \"Venus\"\n  | \"Mars\"\n  | \"Jupiter\"\n  | \"Saturn\";\n\nexport interface EssentialDignityResult {\n  domicile: boolean;\n  exaltation: boolean;\n  detriment: boolean;\n  fall: boolean;\n  domicileRuler: TraditionalPlanet;\n  peregrine: boolean;\n}\n\nexport const DOMICILE_RULERS: Record<Sign, TraditionalPlanet> = {\n  Aries: \"Mars\",\n  Taurus: \"Venus\",\n  Gemini: \"Mercury\",\n  Cancer: \"Moon\",\n  Leo: \"Sun\",\n  Virgo: \"Mercury\",\n  Libra: \"Venus\",\n  Scorpio: \"Mars\",\n  Sagittarius: \"Jupiter\",\n  Capricorn: \"Saturn\",\n  Aquarius: \"Saturn\",\n  Pisces: \"Jupiter\",\n};\n\nexport const EXALTATIONS: Record<TraditionalPlanet, { sign: Sign; degree: number }> = {\n  Sun: { sign: \"Aries\", degree: 19 },\n  Moon: { sign: \"Taurus\", degree: 3 },\n  Mercury: { sign: \"Virgo\", degree: 15 },\n  Venus: { sign: \"Pisces\", degree: 27 },\n  Mars: { sign: \"Capricorn\", degree: 28 },\n  Jupiter: { sign: \"Cancer\", degree: 15 },\n  Saturn: { sign: \"Libra\", degree: 21 },\n};\n\nexport function getDomicileRuler(sign: Sign): TraditionalPlanet {\n  return DOMICILE_RULERS[sign];\n}\n\nexport function getExaltation(planet: TraditionalPlanet): { sign: Sign; degree: number } {\n  return EXALTATIONS[planet];\n}\n\nexport function getOppositeSign(sign: Sign): Sign {\n  const idx = SIGNS.indexOf(sign);\n  return SIGNS[(idx + 6) % 12];\n}\n\n/** Signs where the planet is in detriment (opposite of its domicile signs). */\nexport function getDetriment(planet: TraditionalPlanet): Sign[] {\n  const signs: Sign[] = [];\n  for (const [sign, ruler] of Object.entries(DOMICILE_RULERS)) {\n    if (ruler === planet) {\n      signs.push(getOppositeSign(sign as Sign));\n    }\n  }\n  return signs;\n}\n\n/** Sign where the planet is in fall (opposite of its exaltation sign). */\nexport function getFall(planet: TraditionalPlanet): Sign {\n  return getOppositeSign(EXALTATIONS[planet].sign);\n}\n\nexport function getEssentialDignity(planet: TraditionalPlanet, sign: Sign): EssentialDignityResult {\n  const domicile = DOMICILE_RULERS[sign] === planet;\n  const exaltation = EXALTATIONS[planet].sign === sign;\n  const detrimentSigns = getDetriment(planet);\n  const detriment = detrimentSigns.includes(sign);\n  const fallSign = getFall(planet);\n  const fall = fallSign === sign;\n  const domicileRuler = DOMICILE_RULERS[sign];\n  const peregrine = !domicile && !exaltation && !detriment && !fall;\n\n  return { domicile, exaltation, detriment, fall, domicileRuler, peregrine };\n}\n","/**\n * Decan (face) lookup — Chaldean rulers + Golden Dawn tarot correspondence.\n * Pure math, no WASM dependency.\n */\n\nimport { normalizeAngle } from \"./swisseph\";\nimport { SIGNS } from \"./index\";\nimport type { TraditionalPlanet } from \"./dignity\";\n\nexport interface DecanResult {\n  sign: string;\n  decanNumber: 1 | 2 | 3;\n  ruler: TraditionalPlanet;\n  tarotCard: string;\n  startDegree: number;\n  endDegree: number;\n  degreeWithinSign: number;\n}\n\n/** Chaldean descent starting from Mars (Aries decan 1). */\nconst CHALDEAN_RULERS: TraditionalPlanet[] = [\n  \"Mars\", \"Sun\", \"Venus\", \"Mercury\", \"Moon\", \"Saturn\", \"Jupiter\",\n];\n\n/** Element-to-suit mapping (Golden Dawn). */\nconst SIGN_SUITS: Record<string, string> = {\n  Aries: \"Wands\",\n  Taurus: \"Pentacles\",\n  Gemini: \"Swords\",\n  Cancer: \"Cups\",\n  Leo: \"Wands\",\n  Virgo: \"Pentacles\",\n  Libra: \"Swords\",\n  Scorpio: \"Cups\",\n  Sagittarius: \"Wands\",\n  Capricorn: \"Pentacles\",\n  Aquarius: \"Swords\",\n  Pisces: \"Cups\",\n};\n\nconst RANK_NAMES = [\"Two\", \"Three\", \"Four\", \"Five\", \"Six\", \"Seven\", \"Eight\", \"Nine\", \"Ten\"];\n\nexport function getDecan(longitude: number): DecanResult {\n  const L = normalizeAngle(longitude);\n  const signIndex = Math.floor(L / 30) % 12;\n  const degreeWithinSign = L - signIndex * 30;\n  const decanIndex = Math.min(Math.floor(degreeWithinSign / 10), 2);\n  const globalDecanIndex = signIndex * 3 + decanIndex;\n\n  const sign = SIGNS[signIndex];\n  const ruler = CHALDEAN_RULERS[globalDecanIndex % 7];\n  const suit = SIGN_SUITS[sign];\n  const rank = RANK_NAMES[globalDecanIndex % 9];\n  const tarotCard = `${rank} of ${suit}`;\n\n  return {\n    sign,\n    decanNumber: (decanIndex + 1) as 1 | 2 | 3,\n    ruler,\n    tarotCard,\n    startDegree: signIndex * 30 + decanIndex * 10,\n    endDegree: signIndex * 30 + (decanIndex + 1) * 10,\n    degreeWithinSign,\n  };\n}\n","/**\n * Dodecatemoria (12th parts) — traditional Hellenistic technique.\n * Pure math, no WASM dependency.\n */\n\nimport { normalizeAngle } from \"./swisseph\";\nimport { SIGNS } from \"./index\";\n\nexport interface DodecatemoriaResult {\n  originalSign: string;\n  originalDegree: number;\n  dodecatemoriaSign: string;\n  dodecatemoriaIndex: number;\n}\n\nexport function getDodecatemoria(longitude: number): DodecatemoriaResult {\n  const L = normalizeAngle(longitude);\n  const signIndex = Math.floor(L / 30) % 12;\n  const degreeWithinSign = L - signIndex * 30;\n  const index = Math.min(Math.floor(degreeWithinSign / 2.5), 11);\n  const dodecatemoriaSignIndex = (signIndex + index) % 12;\n\n  return {\n    originalSign: SIGNS[signIndex],\n    originalDegree: degreeWithinSign,\n    dodecatemoriaSign: SIGNS[dodecatemoriaSignIndex],\n    dodecatemoriaIndex: index,\n  };\n}\n","/**\n * Annual & Monthly Profections — traditional Hellenistic time-lord technique.\n * Pure math. Requires a whole-sign BirthChart for house sign lookup.\n */\n\nimport type { BirthChart } from \"./index\";\nimport { getDomicileRuler, type Sign, type TraditionalPlanet } from \"./dignity\";\nimport { SIGNS } from \"./index\";\n\nexport interface AnnualProfection {\n  age: number;\n  house: number;\n  sign: string;\n  ruler: TraditionalPlanet;\n  targetYear: number;\n}\n\nexport interface MonthlyProfection {\n  month: number;\n  startDate: Date;\n  sign: string;\n  ruler: TraditionalPlanet;\n}\n\nexport interface MonthlyProfectionsResult {\n  annualProfection: AnnualProfection;\n  months: MonthlyProfection[];\n}\n\nexport function getAnnualProfection(\n  natalChart: BirthChart,\n  birthDate: Date,\n  targetYear?: number\n): AnnualProfection {\n  const year = targetYear ?? new Date().getFullYear();\n  const birthYear = birthDate.getFullYear();\n  const age = year - birthYear;\n  if (age < 0) {\n    throw new Error(`Target year (${year}) is before birth year (${birthYear}).`);\n  }\n  const house = (age % 12) + 1;\n  const sign = natalChart.houses.houses[house - 1].sign as Sign;\n  const ruler = getDomicileRuler(sign);\n\n  return { age, house, sign, ruler, targetYear: year };\n}\n\nexport function getMonthlyProfections(\n  natalChart: BirthChart,\n  birthDate: Date,\n  targetYear?: number\n): MonthlyProfectionsResult {\n  const annualProfection = getAnnualProfection(natalChart, birthDate, targetYear);\n  const annualSignIndex = SIGNS.indexOf(annualProfection.sign as Sign);\n\n  const bdMonth = birthDate.getMonth();\n  const bdDay = birthDate.getDate();\n  const year = annualProfection.targetYear;\n\n  const months: MonthlyProfection[] = [];\n  for (let i = 0; i < 12; i++) {\n    const monthDate = new Date(year, bdMonth + i, bdDay);\n    // Handle day overflow (e.g. Feb 29 → Mar 1)\n    if (monthDate.getDate() !== bdDay) {\n      monthDate.setDate(0); // last day of previous month\n    }\n    const signIndex = (annualSignIndex + i) % 12;\n    const sign = SIGNS[signIndex] as Sign;\n\n    months.push({\n      month: i + 1,\n      startDate: monthDate,\n      sign,\n      ruler: getDomicileRuler(sign),\n    });\n  }\n\n  return { annualProfection, months };\n}\n","/**\n * Firdaria — traditional planetary period system.\n * Pure math, no WASM dependency.\n */\n\nexport type FirdariaPlanet =\n  | \"Sun\"\n  | \"Moon\"\n  | \"Mercury\"\n  | \"Venus\"\n  | \"Mars\"\n  | \"Jupiter\"\n  | \"Saturn\"\n  | \"NorthNode\"\n  | \"SouthNode\";\n\nexport interface FirdariaSubPeriod {\n  planet: FirdariaPlanet;\n  startDate: Date;\n  endDate: Date;\n}\n\nexport interface FirdariaMajorPeriod {\n  planet: FirdariaPlanet;\n  years: number;\n  startDate: Date;\n  endDate: Date;\n  subPeriods: FirdariaSubPeriod[];\n}\n\nexport interface FirdariaResult {\n  sect: \"diurnal\" | \"nocturnal\";\n  currentMajor: FirdariaMajorPeriod;\n  currentSub: FirdariaSubPeriod;\n  allPeriods: FirdariaMajorPeriod[];\n}\n\nexport interface FirdariaOptions {\n  nodeSubPeriodStart?: \"jupiter-saturn\" | \"sun-mars\";\n}\n\ninterface SequenceEntry {\n  planet: FirdariaPlanet;\n  years: number;\n}\n\nconst DAY_SEQUENCE: SequenceEntry[] = [\n  { planet: \"Sun\", years: 10 },\n  { planet: \"Venus\", years: 8 },\n  { planet: \"Mercury\", years: 13 },\n  { planet: \"Moon\", years: 9 },\n  { planet: \"Saturn\", years: 11 },\n  { planet: \"Jupiter\", years: 12 },\n  { planet: \"Mars\", years: 7 },\n  { planet: \"NorthNode\", years: 3 },\n  { planet: \"SouthNode\", years: 2 },\n];\n\nconst NIGHT_SEQUENCE: SequenceEntry[] = [\n  { planet: \"Moon\", years: 9 },\n  { planet: \"Saturn\", years: 11 },\n  { planet: \"Jupiter\", years: 12 },\n  { planet: \"Mars\", years: 7 },\n  { planet: \"NorthNode\", years: 3 },\n  { planet: \"SouthNode\", years: 2 },\n  { planet: \"Sun\", years: 10 },\n  { planet: \"Venus\", years: 8 },\n  { planet: \"Mercury\", years: 13 },\n];\n\nconst CHALDEAN_ORDER: FirdariaPlanet[] = [\n  \"Saturn\", \"Jupiter\", \"Mars\", \"Sun\", \"Venus\", \"Mercury\", \"Moon\",\n];\n\nfunction addYears(date: Date, years: number): Date {\n  const ms = years * 365.25 * 24 * 60 * 60 * 1000;\n  return new Date(date.getTime() + ms);\n}\n\nfunction getSubPeriodStart(\n  planet: FirdariaPlanet,\n  options?: FirdariaOptions\n): number {\n  const mode = options?.nodeSubPeriodStart ?? \"jupiter-saturn\";\n\n  if (planet === \"NorthNode\") {\n    if (mode === \"sun-mars\") {\n      return CHALDEAN_ORDER.indexOf(\"Sun\");\n    }\n    return CHALDEAN_ORDER.indexOf(\"Jupiter\");\n  }\n  if (planet === \"SouthNode\") {\n    if (mode === \"sun-mars\") {\n      return CHALDEAN_ORDER.indexOf(\"Mars\");\n    }\n    return CHALDEAN_ORDER.indexOf(\"Saturn\");\n  }\n\n  // For regular planets, find position in Chaldean order\n  return CHALDEAN_ORDER.indexOf(planet);\n}\n\nfunction buildSubPeriods(\n  major: SequenceEntry,\n  majorStart: Date,\n  majorEnd: Date,\n  options?: FirdariaOptions\n): FirdariaSubPeriod[] {\n  const startIdx = getSubPeriodStart(major.planet, options);\n  const totalMs = majorEnd.getTime() - majorStart.getTime();\n  const subMs = totalMs / 7;\n\n  const subs: FirdariaSubPeriod[] = [];\n  for (let i = 0; i < 7; i++) {\n    const subPlanet = CHALDEAN_ORDER[(startIdx + i) % 7];\n    const subStart = new Date(majorStart.getTime() + i * subMs);\n    const subEnd = new Date(majorStart.getTime() + (i + 1) * subMs);\n    subs.push({ planet: subPlanet, startDate: subStart, endDate: subEnd });\n  }\n  return subs;\n}\n\nexport function getFirdaria(\n  birthDate: Date,\n  isDiurnal: boolean,\n  targetDate?: Date,\n  options?: FirdariaOptions\n): FirdariaResult {\n  const target = targetDate ?? new Date();\n  const sequence = isDiurnal ? DAY_SEQUENCE : NIGHT_SEQUENCE;\n  const sect = isDiurnal ? \"diurnal\" : \"nocturnal\";\n\n  // Build periods, cycling the 75-year sequence\n  const allPeriods: FirdariaMajorPeriod[] = [];\n  let cursor = new Date(birthDate.getTime());\n  let foundCurrent = false;\n\n  // Generate enough cycles to cover target date (max 3 cycles = 225 years)\n  for (let cycle = 0; cycle < 3 && !foundCurrent; cycle++) {\n    for (const entry of sequence) {\n      const start = new Date(cursor.getTime());\n      const end = addYears(start, entry.years);\n      const subPeriods = buildSubPeriods(entry, start, end, options);\n      allPeriods.push({\n        planet: entry.planet,\n        years: entry.years,\n        startDate: start,\n        endDate: end,\n        subPeriods,\n      });\n      cursor = end;\n\n      if (target.getTime() >= start.getTime() && target.getTime() < end.getTime()) {\n        foundCurrent = true;\n      }\n    }\n  }\n\n  // Find current major and sub\n  const currentMajor = allPeriods.find(\n    (p) => target.getTime() >= p.startDate.getTime() && target.getTime() < p.endDate.getTime()\n  ) ?? allPeriods[0];\n\n  const currentSub = currentMajor.subPeriods.find(\n    (s) => target.getTime() >= s.startDate.getTime() && target.getTime() < s.endDate.getTime()\n  ) ?? currentMajor.subPeriods[0];\n\n  return { sect, currentMajor, currentSub, allPeriods };\n}\n","/**\n * Astrological calculations using Swiss Ephemeris\n */\n\nimport {\n  type AzaltResult,\n  CalcFlag,\n  calcParsFortunae,\n  calculateHouses,\n  calculatePlanetaryPositions,\n  calculateSinglePlanetPosition,\n  closeSwissEph,\n  getSwissEph,\n  resolveSwissEphRuntimeAssets,\n  HouseSystem,\n  normalizeAngle,\n  Planet,\n  PLANET_AND_NODE_NAMES,\n  PlanetPosition,\n  type LocalDateTimeParts,\n  type ResolveSwissEphRuntimeAssetsOptions,\n  RiseTransitFlag,\n  type SwissEphRuntimeAssetPaths,\n  TimeZoneOptions,\n  toUtcDate,\n  VirtualNodes,\n} from \"./swisseph\";\n\nexport {\n  type AzaltResult,\n  type LocalDateTimeParts,\n  CalcFlag,\n  closeSwissEph,\n  getSwissEph,\n  type ResolveSwissEphRuntimeAssetsOptions,\n  type SwissEphRuntimeAssetPaths,\n  resolveSwissEphRuntimeAssets,\n  HouseSystem,\n  normalizeAngle,\n  Planet,\n  PLANET_AND_NODE_NAMES,\n  RiseTransitFlag,\n  VirtualNodes\n};\n\nexport * from \"./astrocartography\";\nexport * from \"./aspects\";\nexport * from \"./dignity\";\nexport * from \"./decans\";\nexport * from \"./dodecatemoria\";\nexport * from \"./profections\";\nexport * from \"./firdaria\";\nimport {\n  computeAspects,\n  computeSynastryAspects,\n  computeTransitAspects,\n  computeMidpoints,\n  shorterArcMidpoint,\n  DEFAULT_ASPECT_SPECS,\n  SLOW_PLANETS,\n  type AspectEdge,\n  type AspectName,\n  type AspectSpec,\n  type TransitAspectEdge,\n  type TransitAspectPoint,\n} from \"./aspects\";\n\nexport interface BirthChartOptions {\n  /**\n   * Local civil date-time for the chart moment.\n   * Prefer `LocalDateTimeParts` when the source data comes from separate\n   * date/time inputs so callers do not have to encode wall-clock parts into a\n   * browser-local `Date`.\n   */\n  date: Date | LocalDateTimeParts;\n  latitude: number;\n  longitude: number;\n  houseSystem?: HouseSystem;\n  timeZoneSettings?: TimeZoneOptions;\n}\n\nexport type ZodiacPosition = {\n  sign: string;\n  decimalDegrees: number; // degrees within the sign (0–30)\n  traditionalFormat: string; // \"D°MM'\"\n  decimal: string; // \"D.dd°\"\n  longitude: number;\n  house: number;\n};\nexport type HydratedNode = ZodiacPosition & { id: VirtualNodes; name: string };\nexport type HydratedPlanet = PlanetPosition & {\n  id: Planet;\n  name: string;\n  zodiacPosition: ZodiacPosition;\n};\n\nexport interface BirthChart {\n  dateUtc: Date;\n  planets: Record<string, HydratedPlanet>;\n  nodes: Record<string, HydratedNode>;\n  houses: {\n    ascendant: ZodiacPosition;\n    mc: ZodiacPosition;\n    dc: ZodiacPosition;\n    ic: ZodiacPosition;\n    houses: ZodiacPosition[];\n    ascmc?: {\n      armc?: ZodiacPosition;\n      vertex?: ZodiacPosition;\n      equasc?: ZodiacPosition;\n      coasc1?: ZodiacPosition;\n      coasc2?: ZodiacPosition;\n      polasc?: ZodiacPosition;\n    };\n  };\n  aspects: AspectEdge[];\n  sect: \"diurnal\" | \"nocturnal\";\n}\n\nfunction isValidLocalDateTimeParts(date: LocalDateTimeParts): boolean {\n  const hour = date.hour ?? 0;\n  const minute = date.minute ?? 0;\n  const second = date.second ?? 0;\n\n  if (\n    !Number.isInteger(date.year) ||\n    !Number.isInteger(date.month) ||\n    !Number.isInteger(date.day) ||\n    !Number.isInteger(hour) ||\n    !Number.isInteger(minute) ||\n    !Number.isInteger(second)\n  ) {\n    return false;\n  }\n\n  if (\n    date.month < 1 || date.month > 12 ||\n    date.day < 1 || date.day > 31 ||\n    hour < 0 || hour > 23 ||\n    minute < 0 || minute > 59 ||\n    second < 0 || second > 59\n  ) {\n    return false;\n  }\n\n  const utcDate = new Date(Date.UTC(date.year, date.month - 1, date.day, hour, minute, second));\n  return (\n    !Number.isNaN(utcDate.getTime()) &&\n    utcDate.getUTCFullYear() === date.year &&\n    utcDate.getUTCMonth() === date.month - 1 &&\n    utcDate.getUTCDate() === date.day &&\n    utcDate.getUTCHours() === hour &&\n    utcDate.getUTCMinutes() === minute &&\n    utcDate.getUTCSeconds() === second\n  );\n}\n\nfunction getCivilMonthDay(date: Date | LocalDateTimeParts): { monthIndex: number; day: number } {\n  if (date instanceof Date) {\n    return {\n      monthIndex: date.getMonth(),\n      day: date.getDate(),\n    };\n  }\n\n  return {\n    monthIndex: date.month - 1,\n    day: date.day,\n  };\n}\n\nfunction validateInputs(options: BirthChartOptions): void {\n  const { date } = options;\n\n  if (date instanceof Date) {\n    if (Number.isNaN(date.getTime())) {\n      throw new Error(\"Invalid date provided\");\n    }\n  } else if (!isValidLocalDateTimeParts(date)) {\n    throw new Error(\"Invalid date provided\");\n  }\n\n  if (\n    typeof options.latitude !== \"number\" ||\n    options.latitude < -90 ||\n    options.latitude > 90\n  ) {\n    throw new Error(\"Invalid latitude: must be between -90 and 90 degrees\");\n  }\n\n  if (\n    typeof options.longitude !== \"number\" ||\n    options.longitude < -180 ||\n    options.longitude > 180\n  ) {\n    throw new Error(\"Invalid longitude: must be between -180 and 180 degrees\");\n  }\n}\n\nfunction hydratePlanet(\n  id: Planet,\n  position: PlanetPosition,\n  houseCusps: number[]\n): HydratedPlanet {\n  return {\n    ...position,\n    id,\n    name: PLANET_AND_NODE_NAMES[id],\n    zodiacPosition: getZodiacPosition(position.longitude, houseCusps),\n  };\n}\n\n/**\n * Calculate a birth chart using Swiss Ephemeris\n *\n * @param options Chart calculation options\n * @returns Birth chart data\n */\nexport async function getBirthChart(\n  options: BirthChartOptions\n): Promise<BirthChart> {\n  try {\n    // Validate inputs\n    validateInputs(options);\n\n    // Determine time zone strategy: default to auto from lat/lon\n    const tzOptions: TimeZoneOptions = options.timeZoneSettings ?? { autoTimeZone: true };\n    const utcDate = await toUtcDate(options.date, options.latitude, options.longitude, tzOptions);\n\n    // Calculate planetary positions\n    const planetPositions = await calculatePlanetaryPositions(utcDate);\n    if (!planetPositions) {\n      throw new Error(\"Failed to calculate planetary positions\");\n    }\n\n    // Calculate houses\n    const housesPositions = await calculateHouses(\n      utcDate,\n      options.latitude,\n      options.longitude,\n      options.houseSystem || HouseSystem.PLACIDUS,\n      { treatAsUTC: true }\n    );\n    if (!housesPositions) {\n      throw new Error(\"Failed to calculate houses\");\n    }\n\n    // skipping the first house since swisseph uses it as dummy 0deg aries\n    const houseCusps = housesPositions.houses.slice(1, 13).map(normalizeAngle);\n\n    const planets: Record<string, HydratedPlanet> = {};\n    for (const [planetId, position] of Object.entries(planetPositions)) {\n      const id = planetId as unknown as Planet;\n      const hydratedPlanet = hydratePlanet(id, position, houseCusps);\n      planets[hydratedPlanet.name.toLocaleLowerCase()] = hydratedPlanet;\n    }\n\n    const houseCuspsPositions = houseCusps.map((lon) =>\n      getZodiacPosition(lon, houseCusps)\n    );\n\n    const descendant = normalizeAngle(housesPositions.ascendant + 180);\n    const imumCoeli = normalizeAngle(housesPositions.mc + 180);\n\n    const ascendantSign = getZodiacPosition(\n      housesPositions.ascendant,\n      houseCusps\n    );\n    const midheavenSign = getZodiacPosition(housesPositions.mc, houseCusps);\n    const descendantSign = getZodiacPosition(descendant, houseCusps);\n    const imumCoeliSign = getZodiacPosition(imumCoeli, houseCusps);\n\n    const houses: BirthChart[\"houses\"] = {\n      ascendant: ascendantSign,\n      mc: midheavenSign,\n      dc: descendantSign,\n      ic: imumCoeliSign,\n      houses: houseCuspsPositions,\n      ascmc: {\n        armc: housesPositions.ascmc\n          ? getZodiacPosition(housesPositions.ascmc.armc, houseCusps)\n          : undefined,\n        vertex: housesPositions.ascmc\n          ? getZodiacPosition(housesPositions.ascmc.vertex, houseCusps)\n          : undefined,\n        equasc: housesPositions.ascmc\n          ? getZodiacPosition(housesPositions.ascmc.equasc, houseCusps)\n          : undefined,\n        coasc1: housesPositions.ascmc\n          ? getZodiacPosition(housesPositions.ascmc.coasc1, houseCusps)\n          : undefined,\n        coasc2: housesPositions.ascmc\n          ? getZodiacPosition(housesPositions.ascmc.coasc2, houseCusps)\n          : undefined,\n        polasc: housesPositions.ascmc\n          ? getZodiacPosition(housesPositions.ascmc.polasc, houseCusps)\n          : undefined,\n      },\n    };\n\n    const isDiurnal =\n      planets.sun.zodiacPosition.house >= 7 &&\n      planets.sun.zodiacPosition.house <= 12;\n    const wheelOfFortuneLongitude = calcParsFortunae(\n      houses.ascendant.longitude,\n      planets.sun.longitude,\n      planets.moon.longitude,\n      isDiurnal\n    );\n\n    const wheelOfFortune = getZodiacPosition(\n      wheelOfFortuneLongitude,\n      houseCusps\n    );\n\n    const nodes: Record<string, HydratedNode> = {\n      [VirtualNodes.PARS_FORTUNAE]: {\n        ...wheelOfFortune,\n        id: VirtualNodes.PARS_FORTUNAE,\n        name: PLANET_AND_NODE_NAMES[VirtualNodes.PARS_FORTUNAE],\n      },\n    };\n\n    const aspects = computeAspects(getAspectPoints(planets, houses.ascendant.longitude, houses.mc.longitude));\n\n    return {\n      dateUtc: utcDate,\n      planets,\n      houses,\n      nodes,\n      aspects,\n      sect: isDiurnal ? \"diurnal\" as const : \"nocturnal\" as const,\n    };\n  } catch (error) {\n    console.error(\"Error calculating birth chart:\", error);\n    throw error;\n  }\n}\n\nexport const SIGNS = [\n  \"Aries\",\n  \"Taurus\",\n  \"Gemini\",\n  \"Cancer\",\n  \"Leo\",\n  \"Virgo\",\n  \"Libra\",\n  \"Scorpio\",\n  \"Sagittarius\",\n  \"Capricorn\",\n  \"Aquarius\",\n  \"Pisces\",\n] as const;\n\n/**\n * Convert decimal degrees to degrees and minutes format\n *\n * @param decimalDegrees Decimal degrees (e.g., 9.8)\n * @returns Formatted string (e.g., \"9°48'\")\n */\nexport function formatDegreeMinutes(decimalDegrees: number): string {\n  let deg = Math.floor(decimalDegrees);\n  let min = Math.round((decimalDegrees - deg) * 60);\n  if (min === 60) {\n    min = 0;\n    deg += 1;\n  } // carry\n  return `${deg}°${String(min).padStart(2, \"0\")}'`;\n}\n\n/**\n * Convert decimal degrees to zodiac position (sign and degrees)\n *\n * @param longitude Longitude in decimal degrees (0-360)\n * @returns Formatted zodiac position with both decimal and traditional format\n */\nexport function getZodiacPosition(\n  longitude: number,\n  houseCusps: number[]\n): ZodiacPosition {\n  const L = normalizeAngle(longitude);\n  const signIndex = Math.floor(L / 30) % 12;\n  const within = L - signIndex * 30; // 0–<30\n  const house = findHouseOf(L, houseCusps);\n\n  return {\n    sign: SIGNS[signIndex],\n    decimalDegrees: within,\n    traditionalFormat: formatDegreeMinutes(within),\n    decimal: within.toFixed(2) + \"°\",\n    longitude: L,\n    house,\n  };\n}\n\n// Find the house of a longitude (0–360) given the array of cusps (0–360)\nexport function findHouseOf(\n  longitude: number,\n  housePositions: number[]\n): number {\n  const L = normalizeAngle(longitude);\n\n  if (!housePositions || housePositions.length === 0) {\n    throw new Error(\"House positions are required\");\n  }\n\n  const H = housePositions\n    .map((c, i) => ({ i: i + 1, L: normalizeAngle(c) }))\n    .sort((a, b) => a.L - b.L);\n  for (let k = 0; k < H.length; k++) {\n    const cur = H[k],\n      nxt = H[(k + 1) % H.length];\n    if (nxt.L < cur.L) {\n      // wrap 360->0\n      if (L >= cur.L || L < nxt.L) return cur.i;\n    } else {\n      if (L >= cur.L && L < nxt.L) return cur.i;\n    }\n  }\n  return 1;\n}\n\nfunction getAspectPoints(\n  planets: Record<string, { longitude: number }>,\n  ascLon: number,\n  mcLon: number\n): Record<string, { longitude: number }> {\n  return { ...planets, ascendant: { longitude: ascLon }, mc: { longitude: mcLon } };\n}\n\n// ── Two-chart (synastry / composite) ──────────────────────────────────\n\nexport interface TwoChartOptions {\n  chartA: BirthChartOptions;\n  chartB: BirthChartOptions;\n  aspectSpecs?: AspectSpec[];\n}\nexport type SynastryChartOptions = TwoChartOptions;\nexport type CompositeChartOptions = TwoChartOptions;\n\nexport interface SynastryChart {\n  chartA: BirthChart;\n  chartB: BirthChart;\n  aspects: AspectEdge[];\n}\n\nexport interface CompositeChart {\n  chartA: BirthChart;\n  chartB: BirthChart;\n  compositePlanets: Record<\n    string,\n    { name: string; longitude: number; zodiacPosition: ZodiacPosition }\n  >;\n  compositeHouses: ZodiacPosition[];\n  aspects: AspectEdge[];\n}\n\nexport async function getSynastryChart(\n  options: SynastryChartOptions\n): Promise<SynastryChart> {\n  const [chartA, chartB] = await Promise.all([\n    getBirthChart(options.chartA),\n    getBirthChart(options.chartB),\n  ]);\n  const aspects = computeSynastryAspects(\n    getAspectPoints(chartA.planets, chartA.houses.ascendant.longitude, chartA.houses.mc.longitude),\n    getAspectPoints(chartB.planets, chartB.houses.ascendant.longitude, chartB.houses.mc.longitude),\n    options.aspectSpecs\n  );\n  return { chartA, chartB, aspects };\n}\n\nexport async function getCompositeChart(\n  options: CompositeChartOptions\n): Promise<CompositeChart> {\n  const [chartA, chartB] = await Promise.all([\n    getBirthChart(options.chartA),\n    getBirthChart(options.chartB),\n  ]);\n\n  // Midpoint planets\n  const midpointLongitudes = computeMidpoints(chartA.planets, chartB.planets);\n\n  // Midpoint house cusps (shorter-arc midpoint of corresponding cusps)\n  const cuspsA = chartA.houses.houses.map((h) => h.longitude);\n  const cuspsB = chartB.houses.houses.map((h) => h.longitude);\n  const compositeCusps = cuspsA.map((a, i) =>\n    i < cuspsB.length ? shorterArcMidpoint(a, cuspsB[i]) : a\n  );\n\n  // Hydrate composite planets with zodiac positions using midpoint cusps\n  const compositePlanets: CompositeChart[\"compositePlanets\"] = {};\n  for (const [key, lon] of Object.entries(midpointLongitudes)) {\n    compositePlanets[key] = {\n      name: key,\n      longitude: lon,\n      zodiacPosition: getZodiacPosition(lon, compositeCusps),\n    };\n  }\n\n  const compositeHouses = compositeCusps.map((lon) =>\n    getZodiacPosition(lon, compositeCusps)\n  );\n\n  const aspects = computeAspects(compositePlanets, options.aspectSpecs);\n\n  return {\n    chartA,\n    chartB,\n    compositePlanets,\n    compositeHouses,\n    aspects,\n  };\n}\n\n// ── Transits ────────────────────────────────────────────────────────────\n\nexport interface TransitChartOptions {\n  natal: BirthChartOptions;\n  transitDate: Date;\n  transitLatitude?: number;\n  transitLongitude?: number;\n  transitTimeZoneSettings?: TimeZoneOptions;\n  aspectSpecs?: AspectSpec[];\n  maxOrb?: number;\n  transitPlanets?: string[];\n  natalPlanets?: string[];\n  aspectFilter?: AspectName[];\n}\n\nexport interface TransitPlanet extends HydratedPlanet {\n  retrograde: boolean;\n  natalHouse: number;\n}\n\nexport interface TransitChart {\n  natalChart: BirthChart;\n  transitDateUtc: Date;\n  transitPlanets: Record<string, TransitPlanet>;\n  aspects: TransitAspectEdge[];\n}\n\nexport interface TransitRangeOptions extends Omit<TransitChartOptions, \"transitDate\"> {\n  from: Date;\n  to: Date;\n  stepDays?: number;\n}\n\nexport interface AspectPerfection {\n  transitPlanet: string;\n  natalPlanet: string;\n  aspect: AspectName;\n  exactDate: Date;\n  exactOrb: number;\n  retrograde: boolean;\n  category: \"slow\" | \"fast\";\n}\n\nexport interface TransitRangeResult {\n  natalChart: BirthChart;\n  from: Date;\n  to: Date;\n  perfections: AspectPerfection[];\n}\n\nfunction getTransitAspectPoints(\n  planets: Record<string, HydratedPlanet>\n): Record<string, TransitAspectPoint> {\n  const points: Record<string, TransitAspectPoint> = {};\n  for (const [key, p] of Object.entries(planets)) {\n    points[key] = { longitude: p.longitude, longitudeSpeed: p.longitudeSpeed };\n  }\n  return points;\n}\n\nfunction getNatalAspectPoints(\n  planets: Record<string, HydratedPlanet>,\n  ascLon: number,\n  mcLon: number\n): Record<string, TransitAspectPoint> {\n  // Natal positions are fixed targets — zero out speeds so applying/separating\n  // is computed solely from transit planet motion.\n  const points: Record<string, TransitAspectPoint> = {};\n  for (const [key, p] of Object.entries(planets)) {\n    points[key] = { longitude: p.longitude, longitudeSpeed: 0 };\n  }\n  points.ascendant = { longitude: ascLon, longitudeSpeed: 0 };\n  points.mc = { longitude: mcLon, longitudeSpeed: 0 };\n  return points;\n}\n\nfunction filterByNames(\n  points: Record<string, TransitAspectPoint>,\n  names?: string[]\n): Record<string, TransitAspectPoint> {\n  if (!names || names.length === 0) return points;\n  const allowed = new Set(names.map((n) => n.toLowerCase()));\n  const result: Record<string, TransitAspectPoint> = {};\n  for (const [key, val] of Object.entries(points)) {\n    if (allowed.has(key)) result[key] = val;\n  }\n  return result;\n}\n\nexport async function getTransitChart(\n  options: TransitChartOptions\n): Promise<TransitChart> {\n  const natalChart = await getBirthChart(options.natal);\n\n  const transitChart = await getBirthChart({\n    date: options.transitDate,\n    latitude: options.transitLatitude ?? options.natal.latitude,\n    longitude: options.transitLongitude ?? options.natal.longitude,\n    houseSystem: options.natal.houseSystem,\n    timeZoneSettings: options.transitTimeZoneSettings ?? { autoTimeZone: true },\n  });\n\n  const natalCusps = natalChart.houses.houses.map((h) => h.longitude);\n\n  // Place transit planets in natal houses\n  const transitPlanets: Record<string, TransitPlanet> = {};\n  for (const [key, planet] of Object.entries(transitChart.planets)) {\n    const natalZodiac = getZodiacPosition(planet.longitude, natalCusps);\n    transitPlanets[key] = {\n      ...planet,\n      retrograde: (planet.longitudeSpeed ?? 0) < 0,\n      natalHouse: natalZodiac.house,\n      zodiacPosition: {\n        ...planet.zodiacPosition,\n        house: natalZodiac.house,\n      },\n    };\n  }\n\n  // Build aspect points with filters\n  let tPoints = getTransitAspectPoints(transitChart.planets);\n  let nPoints = getNatalAspectPoints(\n    natalChart.planets,\n    natalChart.houses.ascendant.longitude,\n    natalChart.houses.mc.longitude\n  );\n  tPoints = filterByNames(tPoints, options.transitPlanets);\n  nPoints = filterByNames(nPoints, options.natalPlanets);\n\n  let aspects = computeTransitAspects(tPoints, nPoints, options.aspectSpecs);\n\n  if (options.maxOrb != null) {\n    aspects = aspects.filter((a) => a.orb <= options.maxOrb!);\n  }\n  if (options.aspectFilter && options.aspectFilter.length > 0) {\n    const allowed = new Set(options.aspectFilter);\n    aspects = aspects.filter((a) => allowed.has(a.aspect));\n  }\n\n  return {\n    natalChart,\n    transitDateUtc: transitChart.dateUtc,\n    transitPlanets,\n    aspects,\n  };\n}\n\nexport async function getTransitRange(\n  options: TransitRangeOptions\n): Promise<TransitRangeResult> {\n  const natalChart = await getBirthChart(options.natal);\n  const natalCusps = natalChart.houses.houses.map((h) => h.longitude);\n\n  const nPoints = filterByNames(\n    getNatalAspectPoints(\n      natalChart.planets,\n      natalChart.houses.ascendant.longitude,\n      natalChart.houses.mc.longitude\n    ),\n    options.natalPlanets\n  );\n  const natalKeys = Object.keys(nPoints);\n\n  const rawStep = options.stepDays ?? 1;\n  if (rawStep <= 0) throw new Error(\"stepDays must be greater than 0\");\n  const fromMs = options.from.getTime();\n  const toMs = options.to.getTime();\n  const specs = options.aspectSpecs;\n\n  // Collect positions at each step\n  type StepData = {\n    time: number;\n    positions: Record<string, TransitAspectPoint>;\n  };\n  const steps: StepData[] = [];\n\n  const transitLat = options.transitLatitude ?? options.natal.latitude;\n  const transitLon = options.transitLongitude ?? options.natal.longitude;\n  const transitTz = options.transitTimeZoneSettings ?? { autoTimeZone: true };\n\n  // Auto-reduce step for fast planets (Moon moves ~13°/day, can enter and exit\n  // an aspect between daily samples). Cap at 0.25 days (~6h) when fast planets\n  // are in the transit set so we don't miss perfections.\n  const FAST_PLANET_MAX_STEP = 0.25; // days\n  let effectiveStepDays = rawStep;\n  // Check if any requested transit planet is fast (not in SLOW_PLANETS)\n  const requestedTransitPlanets = options.transitPlanets?.map((n) => n.toLowerCase());\n  const hasFastPlanets = requestedTransitPlanets\n    ? requestedTransitPlanets.some((n) => !SLOW_PLANETS.has(n))\n    : true; // if no filter, assume fast planets present\n  if (hasFastPlanets && effectiveStepDays > FAST_PLANET_MAX_STEP) {\n    effectiveStepDays = FAST_PLANET_MAX_STEP;\n  }\n  const stepMs = effectiveStepDays * 86400000;\n\n  // Scan one extra step beyond toMs so perfections near the boundary can be detected\n  // (binary search needs two consecutive steps to spot the orb increase after a minimum).\n  // Perfections are still filtered to [from, to] at the end.\n  const scanEndMs = toMs + stepMs;\n  for (let ms = fromMs; ms <= scanEndMs; ms += stepMs) {\n    const date = new Date(ms);\n    const utcDate = await toUtcDate(date, transitLat, transitLon, transitTz ?? { autoTimeZone: true });\n    const positions = await calculatePlanetaryPositions(utcDate);\n    if (!positions) continue;\n\n    const points: Record<string, TransitAspectPoint> = {};\n    for (const [planetId, pos] of Object.entries(positions)) {\n      const id = planetId as unknown as Planet;\n      const name = PLANET_AND_NODE_NAMES[id].toLowerCase();\n      points[name] = { longitude: pos.longitude, longitudeSpeed: pos.longitudeSpeed };\n    }\n    steps.push({ time: ms, positions: filterByNames(points, options.transitPlanets) });\n  }\n\n  // Track orbs across steps and find perfections via binary search\n  const perfections: AspectPerfection[] = [];\n  const transitKeys = steps.length > 0 ? Object.keys(steps[0].positions) : [];\n\n  for (const tKey of transitKeys) {\n    for (const nKey of natalKeys) {\n      let prevOrb: number | null = null;\n      let prevDecreasing = false;\n      let prevStep: StepData | null = null;\n\n      for (const step of steps) {\n        const tPos = step.positions[tKey];\n        const nPos = nPoints[nKey];\n        if (!tPos || !nPos) continue;\n\n        // Check all aspect specs for the closest match\n        const match = specs\n          ? findClosestAspectOrb(tPos.longitude, nPos.longitude, specs)\n          : findClosestAspectOrb(tPos.longitude, nPos.longitude);\n\n        if (!match) {\n          prevOrb = null;\n          prevStep = step;\n          continue;\n        }\n\n        const currentOrb = match.orb;\n        if (prevOrb != null && prevStep) {\n          const wasDecreasing = prevOrb > currentOrb;\n          // Perfection: orb was decreasing and is now increasing\n          if (prevDecreasing && !wasDecreasing && currentOrb <= (match.spec.orb)) {\n            const exactResult = await binarySearchPerfection(\n              tKey, nKey, match.spec,\n              prevStep.time, step.time,\n              nPos, transitLat, transitLon, transitTz\n            );\n            if (exactResult) perfections.push(exactResult);\n          }\n          prevDecreasing = wasDecreasing;\n        } else {\n          prevDecreasing = false;\n        }\n        prevOrb = currentOrb;\n        prevStep = step;\n      }\n    }\n  }\n\n  // Filter perfections to the requested [from, to] range (scan extends beyond for detection)\n  let filtered = perfections.filter((p) => {\n    const t = p.exactDate.getTime();\n    return t >= fromMs && t <= toMs;\n  });\n  if (options.maxOrb != null) {\n    filtered = filtered.filter((p) => p.exactOrb <= options.maxOrb!);\n  }\n  if (options.aspectFilter && options.aspectFilter.length > 0) {\n    const allowed = new Set(options.aspectFilter);\n    filtered = filtered.filter((p) => allowed.has(p.aspect));\n  }\n\n  // Sort by date\n  filtered.sort((a, b) => a.exactDate.getTime() - b.exactDate.getTime());\n\n  return {\n    natalChart,\n    from: options.from,\n    to: options.to,\n    perfections: filtered,\n  };\n}\n\nfunction findClosestAspectOrb(\n  lonA: number,\n  lonB: number,\n  specs: AspectSpec[] = DEFAULT_ASPECT_SPECS\n): { spec: AspectSpec; orb: number; delta: number } | null {\n  const a = normalizeAngle(lonA);\n  const b = normalizeAngle(lonB);\n  const delta = Math.min(normalizeAngle(b - a), normalizeAngle(a - b));\n\n  let best: { spec: AspectSpec; orb: number; delta: number } | null = null;\n  for (const spec of specs) {\n    const orb = Math.abs(delta - spec.angle);\n    // Use a generous search orb (spec.orb + 2) to catch approaching aspects\n    if (orb <= spec.orb + 2) {\n      if (!best || orb < best.orb) {\n        best = { spec, orb, delta };\n      }\n    }\n  }\n  return best;\n}\n\nfunction computeOrbForAspect(\n  transitLon: number,\n  natalLon: number,\n  aspectAngle: number\n): number {\n  const delta = Math.min(\n    normalizeAngle(transitLon - natalLon),\n    normalizeAngle(natalLon - transitLon)\n  );\n  return Math.abs(delta - aspectAngle);\n}\n\n// Reverse map: lowercase name → Planet enum, built once\nconst NAME_TO_PLANET: Record<string, Planet> = {};\nfor (const [id, name] of Object.entries(PLANET_AND_NODE_NAMES)) {\n  const numId = Number(id);\n  if (!isNaN(numId)) NAME_TO_PLANET[name.toLowerCase()] = numId as Planet;\n}\n\nasync function getTransitLongitudeAt(\n  ms: number,\n  transitKey: string,\n  transitLat: number,\n  transitLon: number,\n  transitTz: TimeZoneOptions\n): Promise<PlanetPosition | null> {\n  const date = new Date(ms);\n  const utc = await toUtcDate(date, transitLat, transitLon, transitTz);\n\n  // Use single-planet calculation when possible (much cheaper than full ephemeris)\n  const planetId = NAME_TO_PLANET[transitKey];\n  if (planetId != null) {\n    try {\n      return calculateSinglePlanetPosition(utc, planetId);\n    } catch {\n      return null;\n    }\n  }\n\n  // Fallback for non-standard names (shouldn't happen in practice)\n  const positions = await calculatePlanetaryPositions(utc);\n  if (!positions) return null;\n  return findPlanetByName(positions, transitKey) ?? null;\n}\n\nasync function binarySearchPerfection(\n  transitKey: string,\n  natalKey: string,\n  spec: AspectSpec,\n  startMs: number,\n  endMs: number,\n  natalPoint: TransitAspectPoint,\n  transitLat: number,\n  transitLon: number,\n  transitTz?: TimeZoneOptions\n): Promise<AspectPerfection | null> {\n  const tz = transitTz ?? { autoTimeZone: true };\n  const maxIterations = 30;\n\n  // Ternary search: find the time that minimizes the orb (unimodal function)\n  let lo = startMs;\n  let hi = endMs;\n\n  for (let i = 0; i < maxIterations; i++) {\n    if (hi - lo < 60000) break; // < 1 minute precision\n\n    const m1 = lo + Math.floor((hi - lo) / 3);\n    const m2 = hi - Math.floor((hi - lo) / 3);\n\n    const pos1 = await getTransitLongitudeAt(m1, transitKey, transitLat, transitLon, tz);\n    const pos2 = await getTransitLongitudeAt(m2, transitKey, transitLat, transitLon, tz);\n    if (!pos1 || !pos2) break;\n\n    const orb1 = computeOrbForAspect(pos1.longitude, natalPoint.longitude, spec.angle);\n    const orb2 = computeOrbForAspect(pos2.longitude, natalPoint.longitude, spec.angle);\n\n    if (orb1 < orb2) {\n      hi = m2;\n    } else {\n      lo = m1;\n    }\n  }\n\n  // Final evaluation at converged point\n  const finalMs = Math.floor((lo + hi) / 2);\n  const finalPos = await getTransitLongitudeAt(finalMs, transitKey, transitLat, transitLon, tz);\n  if (!finalPos) return null;\n\n  const finalOrb = computeOrbForAspect(finalPos.longitude, natalPoint.longitude, spec.angle);\n\n  // Reject near-miss local minima that never got close to exact\n  if (finalOrb > spec.orb) return null;\n\n  return {\n    transitPlanet: transitKey,\n    natalPlanet: natalKey,\n    aspect: spec.name,\n    exactDate: new Date(finalMs),\n    exactOrb: finalOrb,\n    retrograde: (finalPos.longitudeSpeed ?? 0) < 0,\n    category: SLOW_PLANETS.has(transitKey) ? \"slow\" : \"fast\",\n  };\n}\n\nfunction findPlanetByName(\n  positions: Record<string, PlanetPosition>,\n  name: string\n): PlanetPosition | undefined {\n  for (const [planetId, pos] of Object.entries(positions)) {\n    const id = planetId as unknown as Planet;\n    if (PLANET_AND_NODE_NAMES[id].toLowerCase() === name) return pos;\n  }\n  return undefined;\n}\n\n// ── Solar Return ─────────────────────────────────────────────────────────\n\nexport interface SolarReturnOptions {\n  natal: BirthChartOptions;\n  year: number;\n  solarReturnLatitude?: number;\n  solarReturnLongitude?: number;\n  solarReturnHouseSystem?: HouseSystem;\n}\n\nexport interface SolarReturnChart {\n  natalChart: BirthChart;\n  solarReturnChart: BirthChart;\n  exactReturnDate: Date;\n  natalSunLongitude: number;\n  year: number;\n}\n\n/**\n * Get the Sun's ecliptic longitude at a given UTC millisecond timestamp.\n */\nasync function getSunLongitudeAtMs(ms: number): Promise<number> {\n  const positions = await calculatePlanetaryPositions(new Date(ms));\n  const sun = findPlanetByName(positions, \"sun\");\n  if (!sun) throw new Error(\"Failed to compute Sun position\");\n  return sun.longitude;\n}\n\n/**\n * Signed angular delta in (-180, 180].\n * Positive means `current` is ahead of `target` (Sun has passed the return point).\n */\nfunction signedAngularDelta(current: number, target: number): number {\n  let d = normalizeAngle(current - target);\n  if (d > 180) d -= 360;\n  return d;\n}\n\n/**\n * Calculate a Solar Return chart — the moment the transiting Sun returns\n * to its natal longitude in the given year.\n */\nexport async function getSolarReturnChart(\n  options: SolarReturnOptions\n): Promise<SolarReturnChart> {\n  // 1. Compute natal chart to get natal Sun longitude\n  const natalChart = await getBirthChart(options.natal);\n  const natalSunLongitude = natalChart.planets.sun.longitude;\n\n  // 2. Build search window: natal birthday in target year ± 2 days\n  const natalDate = getCivilMonthDay(options.natal.date);\n  const approxReturn = new Date(Date.UTC(\n    options.year,\n    natalDate.monthIndex,\n    natalDate.day,\n    12, 0, 0\n  ));\n  let lo = approxReturn.getTime() - 2 * 86400000;\n  let hi = approxReturn.getTime() + 2 * 86400000;\n\n  // 3. Binary search (max 30 iterations, converge to < 60s)\n  for (let i = 0; i < 30; i++) {\n    if (hi - lo < 60000) break;\n\n    const mid = Math.floor((lo + hi) / 2);\n    const sunLon = await getSunLongitudeAtMs(mid);\n    const delta = signedAngularDelta(sunLon, natalSunLongitude);\n\n    if (delta < 0) {\n      // Sun hasn't arrived yet → search forward\n      lo = mid;\n    } else {\n      // Sun has passed → search backward\n      hi = mid;\n    }\n  }\n\n  const exactMs = Math.floor((lo + hi) / 2);\n  const exactReturnDate = new Date(exactMs);\n\n  // 4. Cast full BirthChart at converged timestamp using SR location\n  const solarReturnChart = await getBirthChart({\n    date: exactReturnDate,\n    latitude: options.solarReturnLatitude ?? options.natal.latitude,\n    longitude: options.solarReturnLongitude ?? options.natal.longitude,\n    houseSystem: options.solarReturnHouseSystem ?? options.natal.houseSystem,\n    // Always treatAsUTC: the binary search converged on a UTC millisecond timestamp.\n    // Passing a caller timezone here would re-interpret the already-UTC instant as local,\n    // shifting planetary positions by hours.\n    timeZoneSettings: { treatAsUTC: true },\n  });\n\n  return {\n    natalChart,\n    solarReturnChart,\n    exactReturnDate,\n    natalSunLongitude,\n    year: options.year,\n  };\n}\n"]}