/* automatically generated by rust-bindgen 0.72.1 */

pub const EMPYREAN_RADAR_KIND_DELAY: u32 = 0;
pub const EMPYREAN_RADAR_KIND_DOPPLER: u32 = 1;
pub const EMPYREAN_REJECTION_ACCEPTED: u32 = 0;
pub const EMPYREAN_REJECTION_CHI_SQUARED: u32 = 1;
pub const EMPYREAN_REJECTION_SIGMA_CLIP: u32 = 2;
pub const EMPYREAN_REJECTION_COOKS_DISTANCE: u32 = 3;
pub const EMPYREAN_REJECTION_ADAPTIVE: u32 = 4;
pub const EMPYREAN_REJECTION_UNSUPPORTED_OBSERVATORY: u32 = 5;
pub const EMPYREAN_REJECTION_CMC2003: u32 = 6;
pub const EMPYREAN_REJECTION_RADAR_UNSUPPORTED: u32 = 7;
pub const EMPYREAN_REJECTION_OCCULTATION_UNSUPPORTED: u32 = 8;
pub const EMPYREAN_REJECTION_OUTSIDE_ARC: u32 = 9;
pub const EMPYREAN_REJECTION_NOT_EVALUATED: i32 = -1;
pub const EMPYREAN_REJECTION_KIND_ADAPTIVE: u32 = 0;
pub const EMPYREAN_REJECTION_KIND_CMC2003: u32 = 1;
pub const EMPYREAN_WEIGHTING_PRESET_NONE: u32 = 0;
pub const EMPYREAN_WEIGHTING_PRESET_VFC17: u32 = 1;
pub const EMPYREAN_WEIGHTING_PRESET_NEODYS: u32 = 2;
pub const EMPYREAN_SIGMA_POLICY_DEFAULT_ONLY: u32 = 0;
pub const EMPYREAN_SIGMA_POLICY_FLOOR: u32 = 1;
pub const EMPYREAN_WEIGHTING_LAYER_OBSERVATORY_RULE: u32 = 0;
pub const EMPYREAN_WEIGHTING_LAYER_NIGHTLY_DEWEIGHTING: u32 = 1;
pub const EMPYREAN_DEBIASING_TABLE_EFCC2020: u32 = 0;
pub const EMPYREAN_DEBIASING_RESOLUTION_STANDARD: u32 = 0;
pub const EMPYREAN_DEBIASING_RESOLUTION_HIRES: u32 = 1;
pub const EMPYREAN_SOLVE_FOR_STATE_ONLY: u32 = 0;
pub const EMPYREAN_SOLVE_FOR_STATE_AND_NONGRAV: u32 = 1;
pub const EMPYREAN_SOLVE_FOR_AUTO: u32 = 2;
pub const EMPYREAN_ORIGIN_POLICY_AUTO: u32 = 0;
pub const EMPYREAN_ORIGIN_POLICY_EXPLICIT: u32 = 1;
pub const EMPYREAN_OUTPUT_EPOCH_MID_ARC: u32 = 0;
pub const EMPYREAN_OUTPUT_EPOCH_LAST_OBSERVATION: u32 = 1;
pub const EMPYREAN_OUTPUT_EPOCH_EXPLICIT: u32 = 2;
pub const EMPYREAN_OUTPUT_EPOCH_IOD_EPOCH: u32 = 3;
pub const EMPYREAN_REPRESENTATION_CARTESIAN: u32 = 0;
pub const EMPYREAN_REPRESENTATION_KEPLERIAN: u32 = 1;
pub const EMPYREAN_REPRESENTATION_COMETARY: u32 = 2;
pub const EMPYREAN_REPRESENTATION_SPHERICAL: u32 = 3;
pub const EMPYREAN_PHASE_FUNCTION_NONE: i32 = -1;
pub const EMPYREAN_PHASE_FUNCTION_HG: u32 = 0;
pub const EMPYREAN_PHASE_FUNCTION_HG1G2: u32 = 1;
pub const EMPYREAN_PHASE_FUNCTION_HG12: u32 = 2;
pub const EMPYREAN_INTEGRATOR_GR15: u32 = 0;
pub const EMPYREAN_INTEGRATOR_DOP853: u32 = 1;
pub const EMPYREAN_ORIGIN_SWITCHING_DEFAULT: u32 = 0;
pub const EMPYREAN_ORIGIN_SWITCHING_ON: u32 = 1;
pub const EMPYREAN_ORIGIN_SWITCHING_OFF: u32 = 2;
pub const EMPYREAN_UNCERTAINTY_FIRST: u32 = 0;
pub const EMPYREAN_UNCERTAINTY_SECOND: u32 = 1;
pub const EMPYREAN_UNCERTAINTY_SIGMA_POINT: u32 = 2;
pub const EMPYREAN_UNCERTAINTY_MONTE_CARLO: u32 = 3;
pub const EMPYREAN_UNCERTAINTY_AUTO: u32 = 4;
pub const EMPYREAN_COVARIANCE_KIND_LINEAR: u32 = 0;
pub const EMPYREAN_COVARIANCE_KIND_SECOND_ORDER: u32 = 1;
pub const EMPYREAN_COVARIANCE_KIND_THIRD_ORDER: u32 = 2;
pub const EMPYREAN_COVARIANCE_KIND_MIXTURE: u32 = 3;
pub const EMPYREAN_COVARIANCE_KIND_MONTE_CARLO: u32 = 4;
pub const EMPYREAN_COVARIANCE_QUALITY_POSITIVE_DEFINITE: u32 = 0;
pub const EMPYREAN_COVARIANCE_QUALITY_INDEFINITE: u32 = 1;
pub const EMPYREAN_COVARIANCE_QUALITY_REPAIRED: u32 = 2;
pub const EMPYREAN_TARGET_FUNCTIONAL_CARTESIAN_STATE: u32 = 0;
pub const EMPYREAN_TARGET_FUNCTIONAL_CLOSE_APPROACH_MISS_DISTANCE: u32 = 1;
pub const EMPYREAN_TAGGED_COV_OK: u32 = 0;
pub const EMPYREAN_TAGGED_COV_NULL_POINTER: i32 = -1;
pub const EMPYREAN_TAGGED_COV_ORBIT_INDEX_OUT_OF_RANGE: i32 = -2;
pub const EMPYREAN_TAGGED_COV_NO_INITIAL_COVARIANCE: i32 = -3;
pub const EMPYREAN_TAGGED_COV_NO_DENSE_TRAJECTORY: i32 = -4;
pub const EMPYREAN_TAGGED_COV_STATE_MISSING: i32 = -5;
pub const EMPYREAN_TAGGED_COV_TRANSFORM: i32 = -6;
pub const EMPYREAN_TAGGED_COV_UNCERTAINTY: i32 = -7;
pub const EMPYREAN_TAGGED_COV_EPOCH_INDEX_OUT_OF_RANGE: i32 = -8;
pub const EMPYREAN_TAGGED_COV_PANIC: i32 = -99;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Context {
    _unused: [u8; 0],
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Session {
    _unused: [u8; 0],
}
#[doc = " C FFI opaque handle. Internally an [`empyrean_core::Context`]; the\n C header forward-declares `struct EmpyreanContext` — callers only\n see the pointer."]
pub type EmpyreanContext = Context;
#[doc = " Per-crate version strings reported by the empyrean stack.\n\n Mirrors [`empyrean_core::Versions`]. Each pointer is a heap-allocated\n NUL-terminated UTF-8 string owned by [`EmpyreanVersions`]; release\n the whole struct with [`empyrean_versions_free`] (do not free the\n individual fields with [`empyrean_string_free`])."]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EmpyreanVersions {
    #[doc = " `empyrean-core` crate version (semver string from `Cargo.toml`)."]
    pub empyrean_core: *mut ::std::os::raw::c_char,
    #[doc = " `villeneuve` crate version (`<tag>+<sha>` git-populated)."]
    pub villeneuve: *mut ::std::os::raw::c_char,
    #[doc = " `scott` crate version (`<tag>+<sha>` git-populated)."]
    pub scott: *mut ::std::os::raw::c_char,
    #[doc = " `nolan` crate version (`<tag>+<sha>` git-populated)."]
    pub nolan: *mut ::std::os::raw::c_char,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanVersions"][::std::mem::size_of::<EmpyreanVersions>() - 32usize];
    ["Alignment of EmpyreanVersions"][::std::mem::align_of::<EmpyreanVersions>() - 8usize];
    ["Offset of field: EmpyreanVersions::empyrean_core"]
        [::std::mem::offset_of!(EmpyreanVersions, empyrean_core) - 0usize];
    ["Offset of field: EmpyreanVersions::villeneuve"]
        [::std::mem::offset_of!(EmpyreanVersions, villeneuve) - 8usize];
    ["Offset of field: EmpyreanVersions::scott"]
        [::std::mem::offset_of!(EmpyreanVersions, scott) - 16usize];
    ["Offset of field: EmpyreanVersions::nolan"]
        [::std::mem::offset_of!(EmpyreanVersions, nolan) - 24usize];
};
impl Default for EmpyreanVersions {
    fn default() -> Self {
        let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
#[doc = " Flat C-ABI compatible coordinate state.\n\n Field-identical to [`empyrean_core::convert::CoordinateState`]; the\n duplicate definition exists so cbindgen (which has `parse_deps =\n false`) can emit the matching C struct in `empyrean.h` without\n traversing into the empyrean-core crate."]
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct CoordinateState {
    pub epoch_mjd_tdb: f64,
    pub elements: [f64; 6usize],
    pub covariance: [[f64; 6usize]; 6usize],
    pub has_covariance: u8,
    pub representation: i32,
    pub frame: i32,
    pub origin: i32,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of CoordinateState"][::std::mem::size_of::<CoordinateState>() - 360usize];
    ["Alignment of CoordinateState"][::std::mem::align_of::<CoordinateState>() - 8usize];
    ["Offset of field: CoordinateState::epoch_mjd_tdb"]
        [::std::mem::offset_of!(CoordinateState, epoch_mjd_tdb) - 0usize];
    ["Offset of field: CoordinateState::elements"]
        [::std::mem::offset_of!(CoordinateState, elements) - 8usize];
    ["Offset of field: CoordinateState::covariance"]
        [::std::mem::offset_of!(CoordinateState, covariance) - 56usize];
    ["Offset of field: CoordinateState::has_covariance"]
        [::std::mem::offset_of!(CoordinateState, has_covariance) - 344usize];
    ["Offset of field: CoordinateState::representation"]
        [::std::mem::offset_of!(CoordinateState, representation) - 348usize];
    ["Offset of field: CoordinateState::frame"]
        [::std::mem::offset_of!(CoordinateState, frame) - 352usize];
    ["Offset of field: CoordinateState::origin"]
        [::std::mem::offset_of!(CoordinateState, origin) - 356usize];
};
#[doc = " An orbit with optional non-gravitational parameters and photometry.\n\n Thrust-arc support has been removed in v0.7.0; if `a1 == a2 == a3 ==\n 0.0` the orbit is treated as gravity-only.\n\n `a1/a2/a3` are the Marsden–Sekanina RTN coefficients (radial,\n transverse, normal) in AU/day². `ng_alpha … ng_k` parameterize the\n g(r) distance-dependent scaling:\n \\\\[ g(r) = \\alpha \\\\, (r/r_0)^{-m} \\\\, (1 + (r/r_0)^n)^{-k} \\\\].\n All-zeros for the g-function fields selects the inverse-square\n default (Yarkovsky / SRP asteroid case): \\\\(\\alpha = r_0 = 1\\\\),\n \\\\(m = 2\\\\), \\\\(n = k = 0\\\\). Comets typically pass SBDB's\n Marsden water-ice values\n (\\\\(\\alpha = 0.1113, r_0 = 2.808, m = 2.15, n = 5.093, k = 4.6142\\\\)).\n\n Photometry: when `phot_system` is one of the `EMPYREAN_PHASE_FUNCTION_*`\n non-`NONE` constants, ephemeris generation produces apparent magnitude\n using the (`H`, `slope1`, `slope2`) triple per the chosen phase function:\n\n | Model | `H` | `slope1` | `slope2` |\n |-------|-----|----------|----------|\n | `HG`     | absolute magnitude | G    | unused (0)  |\n | `HG1G2`  | absolute magnitude | G₁   | G₂          |\n | `HG12`   | absolute magnitude | G₁₂  | unused (0)  |"]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EmpyreanOrbit {
    pub state: CoordinateState,
    #[doc = " Caller-supplied orbit identifier — primary key for joining\n outputs (propagated states, events, ephemeris, B-planes, IP) to\n the input row. NUL-terminated UTF-8. A null pointer or empty\n string causes the C ABI to fabricate a positional `\"orbit_{i}\"`\n tag instead — set this whenever you want stable joins.\n\n **Ownership:** read-only borrow from the caller; the C ABI does\n not free it."]
    pub orbit_id: *const ::std::os::raw::c_char,
    #[doc = " Caller-supplied object identifier (e.g. SBDB designation).\n Distinct from `orbit_id` so multiple orbit hypotheses for the\n same object can share an `object_id`. NUL-terminated UTF-8.\n Empty string or null = no object identifier.\n\n **Ownership:** read-only borrow from the caller; the C ABI does\n not free it."]
    pub object_id: *const ::std::os::raw::c_char,
    #[doc = " Marsden-Sekanina A1 coefficient (radial). 0 ⇒ no non-grav."]
    pub a1: f64,
    #[doc = " Marsden-Sekanina A2 coefficient (transverse)."]
    pub a2: f64,
    #[doc = " Marsden-Sekanina A3 coefficient (normal)."]
    pub a3: f64,
    #[doc = " g(r) normalizing constant α. All-zero g-fields → inverse_square."]
    pub ng_alpha: f64,
    #[doc = " g(r) reference distance r₀ (AU)."]
    pub ng_r0: f64,
    #[doc = " g(r) inner power-law exponent m."]
    pub ng_m: f64,
    #[doc = " g(r) outer power-law exponent n."]
    pub ng_n: f64,
    #[doc = " g(r) outer damping exponent k."]
    pub ng_k: f64,
    #[doc = " SBDB non-grav time delay in days. Use NaN for no delay (the\n asteroid default and the Marsden water-ice default for comets\n SBDB doesn't fit a delay for). Set to a finite value (positive\n or negative) when SBDB's `model_pars[]` exposes a `DT` field —\n e.g. 67P (+45.7d), 46P/Wirtanen (−14.1d), 2I/Borisov (−65.1d)."]
    pub non_grav_dt: f64,
    #[doc = " 1 when `non_grav_covariance` carries a non-grav prior covariance; 0\n otherwise. Set by the OD output path (a fitted orbit) so it re-feeds\n into a StateAndNonGrav refine without losing its non-grav prior\n (empyrean-wo4n); leave 0 for hand-built / SBDB / propagate inputs."]
    pub has_non_grav_covariance: u8,
    #[doc = " Non-grav 3×3 covariance for (A1, A2, A3), row-major. Only read when\n `has_non_grav_covariance = 1`."]
    pub non_grav_covariance: [[f64; 3usize]; 3usize],
    #[doc = " Phase-function model. `EMPYREAN_PHASE_FUNCTION_NONE` disables\n magnitude computation; the other values map to villeneuve's\n `PhaseFunction` enum."]
    pub phot_system: i32,
    #[doc = " Absolute magnitude H. Ignored when `phot_system == NONE`."]
    pub h_mag: f64,
    #[doc = " Slope parameter slot 1 — G (HG), G₁ (HG1G2), or G₁₂ (HG12)."]
    pub slope1: f64,
    #[doc = " Slope parameter slot 2 — G₂ (HG1G2 only); unused (0) for HG / HG12."]
    pub slope2: f64,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanOrbit"][::std::mem::size_of::<EmpyreanOrbit>() - 560usize];
    ["Alignment of EmpyreanOrbit"][::std::mem::align_of::<EmpyreanOrbit>() - 8usize];
    ["Offset of field: EmpyreanOrbit::state"]
        [::std::mem::offset_of!(EmpyreanOrbit, state) - 0usize];
    ["Offset of field: EmpyreanOrbit::orbit_id"]
        [::std::mem::offset_of!(EmpyreanOrbit, orbit_id) - 360usize];
    ["Offset of field: EmpyreanOrbit::object_id"]
        [::std::mem::offset_of!(EmpyreanOrbit, object_id) - 368usize];
    ["Offset of field: EmpyreanOrbit::a1"][::std::mem::offset_of!(EmpyreanOrbit, a1) - 376usize];
    ["Offset of field: EmpyreanOrbit::a2"][::std::mem::offset_of!(EmpyreanOrbit, a2) - 384usize];
    ["Offset of field: EmpyreanOrbit::a3"][::std::mem::offset_of!(EmpyreanOrbit, a3) - 392usize];
    ["Offset of field: EmpyreanOrbit::ng_alpha"]
        [::std::mem::offset_of!(EmpyreanOrbit, ng_alpha) - 400usize];
    ["Offset of field: EmpyreanOrbit::ng_r0"]
        [::std::mem::offset_of!(EmpyreanOrbit, ng_r0) - 408usize];
    ["Offset of field: EmpyreanOrbit::ng_m"]
        [::std::mem::offset_of!(EmpyreanOrbit, ng_m) - 416usize];
    ["Offset of field: EmpyreanOrbit::ng_n"]
        [::std::mem::offset_of!(EmpyreanOrbit, ng_n) - 424usize];
    ["Offset of field: EmpyreanOrbit::ng_k"]
        [::std::mem::offset_of!(EmpyreanOrbit, ng_k) - 432usize];
    ["Offset of field: EmpyreanOrbit::non_grav_dt"]
        [::std::mem::offset_of!(EmpyreanOrbit, non_grav_dt) - 440usize];
    ["Offset of field: EmpyreanOrbit::has_non_grav_covariance"]
        [::std::mem::offset_of!(EmpyreanOrbit, has_non_grav_covariance) - 448usize];
    ["Offset of field: EmpyreanOrbit::non_grav_covariance"]
        [::std::mem::offset_of!(EmpyreanOrbit, non_grav_covariance) - 456usize];
    ["Offset of field: EmpyreanOrbit::phot_system"]
        [::std::mem::offset_of!(EmpyreanOrbit, phot_system) - 528usize];
    ["Offset of field: EmpyreanOrbit::h_mag"]
        [::std::mem::offset_of!(EmpyreanOrbit, h_mag) - 536usize];
    ["Offset of field: EmpyreanOrbit::slope1"]
        [::std::mem::offset_of!(EmpyreanOrbit, slope1) - 544usize];
    ["Offset of field: EmpyreanOrbit::slope2"]
        [::std::mem::offset_of!(EmpyreanOrbit, slope2) - 552usize];
};
impl Default for EmpyreanOrbit {
    fn default() -> Self {
        let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
#[doc = " A single observer state for the C API."]
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct EmpyreanObserver {
    #[doc = " MPC 3-character code, null-terminated (4 bytes)."]
    pub obs_code: [u8; 4usize],
    #[doc = " Epoch as MJD TDB."]
    pub epoch_mjd_tdb: f64,
    #[doc = " Position in ICRF relative to SSB (AU)."]
    pub x: f64,
    pub y: f64,
    pub z: f64,
    #[doc = " Velocity in ICRF relative to SSB (AU/day)."]
    pub vx: f64,
    pub vy: f64,
    pub vz: f64,
    #[doc = " Observing night as YYYYMMDD integer, or -1 if unavailable."]
    pub observing_night: i32,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanObserver"][::std::mem::size_of::<EmpyreanObserver>() - 72usize];
    ["Alignment of EmpyreanObserver"][::std::mem::align_of::<EmpyreanObserver>() - 8usize];
    ["Offset of field: EmpyreanObserver::obs_code"]
        [::std::mem::offset_of!(EmpyreanObserver, obs_code) - 0usize];
    ["Offset of field: EmpyreanObserver::epoch_mjd_tdb"]
        [::std::mem::offset_of!(EmpyreanObserver, epoch_mjd_tdb) - 8usize];
    ["Offset of field: EmpyreanObserver::x"][::std::mem::offset_of!(EmpyreanObserver, x) - 16usize];
    ["Offset of field: EmpyreanObserver::y"][::std::mem::offset_of!(EmpyreanObserver, y) - 24usize];
    ["Offset of field: EmpyreanObserver::z"][::std::mem::offset_of!(EmpyreanObserver, z) - 32usize];
    ["Offset of field: EmpyreanObserver::vx"]
        [::std::mem::offset_of!(EmpyreanObserver, vx) - 40usize];
    ["Offset of field: EmpyreanObserver::vy"]
        [::std::mem::offset_of!(EmpyreanObserver, vy) - 48usize];
    ["Offset of field: EmpyreanObserver::vz"]
        [::std::mem::offset_of!(EmpyreanObserver, vz) - 56usize];
    ["Offset of field: EmpyreanObserver::observing_night"]
        [::std::mem::offset_of!(EmpyreanObserver, observing_night) - 64usize];
};
#[doc = " Uncertainty-propagation method, mirroring\n [`empyrean_core::propagation::UncertaintyMethod`] as a flat C struct.\n Fields outside the active variant are ignored — set them to zero /\n NaN.\n\n | tag | Variant | Active fields |\n |-----|---------|---------------|\n | 0   | First       | (none) |\n | 1   | Second      | (none) |\n | 2   | SigmaPoint  | `sp_n_sigma`, `sp_samples_per_plane` |\n | 3   | MonteCarlo  | `mc_n_samples`, `mc_seed_some` (1 = use `mc_seed`) |\n | 4   | Auto        | `auto_threshold_first`, `auto_threshold_mixture`, `auto_threshold_ip_skip`, `auto_gmm_max_depth`, `auto_gmm_components_per_split` |"]
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct EmpyreanUncertaintyMethod {
    #[doc = " Variant tag — see `EMPYREAN_UNCERTAINTY_*` constants."]
    pub tag: u8,
    #[doc = " SigmaPoint: number of sigma deviations (default 1.0)."]
    pub sp_n_sigma: f64,
    #[doc = " SigmaPoint: points per coordinate-plane pair (default 8 → 120 total)."]
    pub sp_samples_per_plane: u64,
    #[doc = " MonteCarlo: number of random samples."]
    pub mc_n_samples: u64,
    #[doc = " MonteCarlo: 1 if `mc_seed` is set, 0 to draw from `thread_rng`."]
    pub mc_seed_some: u8,
    #[doc = " MonteCarlo: RNG seed when `mc_seed_some == 1`."]
    pub mc_seed: u64,
    #[doc = " Auto-method tuning parameter; selected automatically."]
    pub auto_threshold_first: f64,
    #[doc = " Auto-method tuning parameter; selected automatically."]
    pub auto_threshold_mixture: f64,
    #[doc = " Auto-method tuning parameter; selected automatically."]
    pub auto_threshold_ip_skip: f64,
    #[doc = " Auto: adaptive-Gaussian-mixture maximum recursion depth."]
    pub auto_gmm_max_depth: u64,
    #[doc = " Auto: adaptive-Gaussian-mixture components per split (odd)."]
    pub auto_gmm_components_per_split: u64,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanUncertaintyMethod"]
        [::std::mem::size_of::<EmpyreanUncertaintyMethod>() - 88usize];
    ["Alignment of EmpyreanUncertaintyMethod"]
        [::std::mem::align_of::<EmpyreanUncertaintyMethod>() - 8usize];
    ["Offset of field: EmpyreanUncertaintyMethod::tag"]
        [::std::mem::offset_of!(EmpyreanUncertaintyMethod, tag) - 0usize];
    ["Offset of field: EmpyreanUncertaintyMethod::sp_n_sigma"]
        [::std::mem::offset_of!(EmpyreanUncertaintyMethod, sp_n_sigma) - 8usize];
    ["Offset of field: EmpyreanUncertaintyMethod::sp_samples_per_plane"]
        [::std::mem::offset_of!(EmpyreanUncertaintyMethod, sp_samples_per_plane) - 16usize];
    ["Offset of field: EmpyreanUncertaintyMethod::mc_n_samples"]
        [::std::mem::offset_of!(EmpyreanUncertaintyMethod, mc_n_samples) - 24usize];
    ["Offset of field: EmpyreanUncertaintyMethod::mc_seed_some"]
        [::std::mem::offset_of!(EmpyreanUncertaintyMethod, mc_seed_some) - 32usize];
    ["Offset of field: EmpyreanUncertaintyMethod::mc_seed"]
        [::std::mem::offset_of!(EmpyreanUncertaintyMethod, mc_seed) - 40usize];
    ["Offset of field: EmpyreanUncertaintyMethod::auto_threshold_first"]
        [::std::mem::offset_of!(EmpyreanUncertaintyMethod, auto_threshold_first) - 48usize];
    ["Offset of field: EmpyreanUncertaintyMethod::auto_threshold_mixture"]
        [::std::mem::offset_of!(EmpyreanUncertaintyMethod, auto_threshold_mixture) - 56usize];
    ["Offset of field: EmpyreanUncertaintyMethod::auto_threshold_ip_skip"]
        [::std::mem::offset_of!(EmpyreanUncertaintyMethod, auto_threshold_ip_skip) - 64usize];
    ["Offset of field: EmpyreanUncertaintyMethod::auto_gmm_max_depth"]
        [::std::mem::offset_of!(EmpyreanUncertaintyMethod, auto_gmm_max_depth) - 72usize];
    ["Offset of field: EmpyreanUncertaintyMethod::auto_gmm_components_per_split"][::std::mem::offset_of!(
        EmpyreanUncertaintyMethod,
        auto_gmm_components_per_split
    ) - 80usize];
};
#[doc = " Event-detection configuration. Mirrors\n [`villeneuve::events::EventConfig`] (less the `enrichment` sub-config,\n which carries internal nested data that doesn't translate cleanly\n through C — it always uses upstream defaults).\n\n `body_filter_naif` is non-owning: caller must keep the array alive\n for the duration of the propagation call. Pass `null` /\n `num_body_filter = 0` to monitor all bodies."]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EmpyreanEventConfig {
    pub close_approaches: u8,
    pub impacts: u8,
    pub atmospheric: u8,
    pub possible_impacts: u8,
    pub shadow_events: u8,
    #[doc = " Number of NAIF IDs in [`body_filter_naif`]; 0 = monitor all bodies."]
    pub num_body_filter: usize,
    #[doc = " Pointer to `num_body_filter` NAIF IDs to restrict event monitoring."]
    pub body_filter_naif: *const i32,
    #[doc = " Insert dense output points around close approaches. 1 = on (auto-enables\n `cache_integrator_steps`), 0 = off (default)."]
    pub dense_output: u8,
    #[doc = " Cadence (days) of dense output. 0.0 → upstream default (5 minutes)."]
    pub dense_output_cadence_days: f64,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanEventConfig"][::std::mem::size_of::<EmpyreanEventConfig>() - 40usize];
    ["Alignment of EmpyreanEventConfig"][::std::mem::align_of::<EmpyreanEventConfig>() - 8usize];
    ["Offset of field: EmpyreanEventConfig::close_approaches"]
        [::std::mem::offset_of!(EmpyreanEventConfig, close_approaches) - 0usize];
    ["Offset of field: EmpyreanEventConfig::impacts"]
        [::std::mem::offset_of!(EmpyreanEventConfig, impacts) - 1usize];
    ["Offset of field: EmpyreanEventConfig::atmospheric"]
        [::std::mem::offset_of!(EmpyreanEventConfig, atmospheric) - 2usize];
    ["Offset of field: EmpyreanEventConfig::possible_impacts"]
        [::std::mem::offset_of!(EmpyreanEventConfig, possible_impacts) - 3usize];
    ["Offset of field: EmpyreanEventConfig::shadow_events"]
        [::std::mem::offset_of!(EmpyreanEventConfig, shadow_events) - 4usize];
    ["Offset of field: EmpyreanEventConfig::num_body_filter"]
        [::std::mem::offset_of!(EmpyreanEventConfig, num_body_filter) - 8usize];
    ["Offset of field: EmpyreanEventConfig::body_filter_naif"]
        [::std::mem::offset_of!(EmpyreanEventConfig, body_filter_naif) - 16usize];
    ["Offset of field: EmpyreanEventConfig::dense_output"]
        [::std::mem::offset_of!(EmpyreanEventConfig, dense_output) - 24usize];
    ["Offset of field: EmpyreanEventConfig::dense_output_cadence_days"]
        [::std::mem::offset_of!(EmpyreanEventConfig, dense_output_cadence_days) - 32usize];
};
impl Default for EmpyreanEventConfig {
    fn default() -> Self {
        let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
#[doc = " Per-trajectory diagnostic outputs (sensitivity, nonlinearity, …).\n Mirrors [`villeneuve::diagnostics::DiagnosticsConfig`].\n\n All metrics default to off. Sentinel: `0` for `sample_stride` →\n upstream default (1); a NaN threshold means \"no event emission for\n that metric\"."]
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct EmpyreanDiagnosticsConfig {
    #[doc = " Frobenius norm of position-STM block. 1 = on, 0 = off."]
    pub sensitivity: u8,
    #[doc = " Hessian/gradient ratio (Jet2 only). 1 = on, 0 = off."]
    pub nonlinearity: u8,
    #[doc = " Finite-time Lyapunov exponent. 1 = on, 0 = off."]
    pub lyapunov: u8,
    #[doc = " Keyhole detection at close approaches (Jet1+). 1 = on, 0 = off."]
    pub keyholes: u8,
    #[doc = " Bifurcation detection at close approaches (Jet2 only). 1 = on, 0 = off."]
    pub bifurcations: u8,
    #[doc = " Timeseries sampling stride: every Nth integration step. 0 → upstream default (1)."]
    pub sample_stride: usize,
    #[doc = " Threshold for `HighSensitivity` events. NaN → no emission."]
    pub sensitivity_threshold: f64,
    #[doc = " Threshold for `ChaoticRegion` events. NaN → no emission."]
    pub lyapunov_threshold: f64,
    #[doc = " Threshold for `HighNonlinearity` events (Jet2 only). NaN → no emission."]
    pub nonlinearity_threshold: f64,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanDiagnosticsConfig"]
        [::std::mem::size_of::<EmpyreanDiagnosticsConfig>() - 40usize];
    ["Alignment of EmpyreanDiagnosticsConfig"]
        [::std::mem::align_of::<EmpyreanDiagnosticsConfig>() - 8usize];
    ["Offset of field: EmpyreanDiagnosticsConfig::sensitivity"]
        [::std::mem::offset_of!(EmpyreanDiagnosticsConfig, sensitivity) - 0usize];
    ["Offset of field: EmpyreanDiagnosticsConfig::nonlinearity"]
        [::std::mem::offset_of!(EmpyreanDiagnosticsConfig, nonlinearity) - 1usize];
    ["Offset of field: EmpyreanDiagnosticsConfig::lyapunov"]
        [::std::mem::offset_of!(EmpyreanDiagnosticsConfig, lyapunov) - 2usize];
    ["Offset of field: EmpyreanDiagnosticsConfig::keyholes"]
        [::std::mem::offset_of!(EmpyreanDiagnosticsConfig, keyholes) - 3usize];
    ["Offset of field: EmpyreanDiagnosticsConfig::bifurcations"]
        [::std::mem::offset_of!(EmpyreanDiagnosticsConfig, bifurcations) - 4usize];
    ["Offset of field: EmpyreanDiagnosticsConfig::sample_stride"]
        [::std::mem::offset_of!(EmpyreanDiagnosticsConfig, sample_stride) - 8usize];
    ["Offset of field: EmpyreanDiagnosticsConfig::sensitivity_threshold"]
        [::std::mem::offset_of!(EmpyreanDiagnosticsConfig, sensitivity_threshold) - 16usize];
    ["Offset of field: EmpyreanDiagnosticsConfig::lyapunov_threshold"]
        [::std::mem::offset_of!(EmpyreanDiagnosticsConfig, lyapunov_threshold) - 24usize];
    ["Offset of field: EmpyreanDiagnosticsConfig::nonlinearity_threshold"]
        [::std::mem::offset_of!(EmpyreanDiagnosticsConfig, nonlinearity_threshold) - 32usize];
};
#[doc = " Origin-switching configuration for trajectory splitting at body\n Laplace spheres of influence (Amato/Baù/Bombardelli 2017 §6).\n\n Default disabled (`enabled = 0`). When enabled, integration\n switches to a body-centric frame inside the SOI of each eligible\n body and back to SSB on exit.\n\n At the C-ABI surface, the per-body opt-in list (`bodies` in\n villeneuve) is not yet exposed — `EMPYREAN_ORIGIN_SWITCHING_ON`\n selects all monitored bodies. File a request if per-body scoping\n is needed from the C-ABI surface."]
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct EmpyreanOriginSwitchingConfig {
    #[doc = " Trajectory-splitting policy. Tri-state, see\n `EMPYREAN_ORIGIN_SWITCHING_*` constants:\n - `0 = DEFAULT` — use the upstream default (currently `ON`).\n   This is what `memset(0)` gives, matching the same sentinel\n   convention used for `dt_min` / `dt_initial` / `epsilon` /\n   `hysteresis` etc. — external C consumers can zero-init the\n   config struct and get the right behavior automatically.\n - `1 = ON`  — force trajectory-splitting on (matches the prior\n   semantic for `enabled = 1`, backward-compatible).\n - `2 = OFF` — force trajectory-splitting off. (The prior\n   semantic for `enabled = 0` is now reachable only via this\n   explicit value, since 0 now means DEFAULT.)\n\n Unknown values fall back to the upstream default."]
    pub enabled: u8,
    #[doc = " Fractional band around the acceleration-ratio crossover used\n to suppress chatter (default 0.2 = ±20 %). 0.0 → upstream\n default."]
    pub hysteresis: f64,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanOriginSwitchingConfig"]
        [::std::mem::size_of::<EmpyreanOriginSwitchingConfig>() - 16usize];
    ["Alignment of EmpyreanOriginSwitchingConfig"]
        [::std::mem::align_of::<EmpyreanOriginSwitchingConfig>() - 8usize];
    ["Offset of field: EmpyreanOriginSwitchingConfig::enabled"]
        [::std::mem::offset_of!(EmpyreanOriginSwitchingConfig, enabled) - 0usize];
    ["Offset of field: EmpyreanOriginSwitchingConfig::hysteresis"]
        [::std::mem::offset_of!(EmpyreanOriginSwitchingConfig, hysteresis) - 8usize];
};
#[doc = " Integrator tuning. Mirrors\n [`villeneuve::propagation::AdvancedIntegratorConfig`]. The default\n integrator backend is Gauss-Radau 15 (GR15), derived solely from the\n published papers; `epsilon` is interpreted as the relative b₆\n truncation tolerance.\n\n Sentinel rule: `0.0` requests the upstream default for `epsilon` /\n `encounter_timescale_divisor`; `dt_initial` / `dt_min` use NaN to\n mean \"auto-compute\"; `0` requests the upstream defaults for\n `max_steps` and `max_dense_steps`."]
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct EmpyreanAdvancedIntegratorConfig {
    #[doc = " Integrator backend (0 = GR15 default, 1 = DOP853). See\n `EMPYREAN_INTEGRATOR_*` constants."]
    pub integrator: i32,
    #[doc = " Truncation-error tolerance (relative b₆ for GR15, rtol for\n DOP853 paired with a fixed atol = 1e-14). 0.0 → upstream\n default (1e-9)."]
    pub epsilon: f64,
    #[doc = " Initial step size in days. NaN → auto from orbital timescale."]
    pub dt_initial: f64,
    #[doc = " Minimum allowed step size in days. NaN → auto."]
    pub dt_min: f64,
    #[doc = " Encounter dynamical-timescale step floor divisor. 0.0 → upstream default (1000.0)."]
    pub encounter_timescale_divisor: f64,
    #[doc = " Maximum integration steps before aborting. 0 → upstream default (10_000_000)."]
    pub max_steps: usize,
    #[doc = " Memory cap on the per-step b-coefficient cache. 0 → upstream default (100_000)."]
    pub max_dense_steps: usize,
    #[doc = " Cache the integrator's per-step b-coefficients for fast\n interpolation (light-time iteration, dense output around close\n approaches, arbitrary-epoch state queries). 1 = on, 0 = off\n (default)."]
    pub cache_integrator_steps: u8,
    #[doc = " Origin-switching trajectory-splitting configuration. Default\n disabled."]
    pub origin_switching: EmpyreanOriginSwitchingConfig,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanAdvancedIntegratorConfig"]
        [::std::mem::size_of::<EmpyreanAdvancedIntegratorConfig>() - 80usize];
    ["Alignment of EmpyreanAdvancedIntegratorConfig"]
        [::std::mem::align_of::<EmpyreanAdvancedIntegratorConfig>() - 8usize];
    ["Offset of field: EmpyreanAdvancedIntegratorConfig::integrator"]
        [::std::mem::offset_of!(EmpyreanAdvancedIntegratorConfig, integrator) - 0usize];
    ["Offset of field: EmpyreanAdvancedIntegratorConfig::epsilon"]
        [::std::mem::offset_of!(EmpyreanAdvancedIntegratorConfig, epsilon) - 8usize];
    ["Offset of field: EmpyreanAdvancedIntegratorConfig::dt_initial"]
        [::std::mem::offset_of!(EmpyreanAdvancedIntegratorConfig, dt_initial) - 16usize];
    ["Offset of field: EmpyreanAdvancedIntegratorConfig::dt_min"]
        [::std::mem::offset_of!(EmpyreanAdvancedIntegratorConfig, dt_min) - 24usize];
    ["Offset of field: EmpyreanAdvancedIntegratorConfig::encounter_timescale_divisor"][::std::mem::offset_of!(
        EmpyreanAdvancedIntegratorConfig,
        encounter_timescale_divisor
    ) - 32usize];
    ["Offset of field: EmpyreanAdvancedIntegratorConfig::max_steps"]
        [::std::mem::offset_of!(EmpyreanAdvancedIntegratorConfig, max_steps) - 40usize];
    ["Offset of field: EmpyreanAdvancedIntegratorConfig::max_dense_steps"]
        [::std::mem::offset_of!(EmpyreanAdvancedIntegratorConfig, max_dense_steps) - 48usize];
    ["Offset of field: EmpyreanAdvancedIntegratorConfig::cache_integrator_steps"][::std::mem::offset_of!(
        EmpyreanAdvancedIntegratorConfig,
        cache_integrator_steps
    ) - 56usize];
    ["Offset of field: EmpyreanAdvancedIntegratorConfig::origin_switching"]
        [::std::mem::offset_of!(EmpyreanAdvancedIntegratorConfig, origin_switching) - 64usize];
};
#[doc = " Propagation configuration.\n\n Mirrors [`villeneuve::propagation::PropagationConfig`] structurally:\n shared scalar fields at the top, nested config bundles for events,\n diagnostics, and integrator tuning. Sentinel rule for primitive\n fields: `0` / `0.0` requests the upstream default; documented\n negative-value sentinels retain their special meanings.\n\n `stop_condition` and `events.enrichment` are not exposed at this\n surface — both carry internal nested data that doesn't translate\n cleanly. They use upstream defaults; reach for empyrean-core's\n Rust API when they need to be overridden."]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EmpyreanPropagationConfig {
    #[doc = " Force-model tier: 0=Approximate, 1=Basic, 2=Standard."]
    pub force_model: i32,
    #[doc = " Number of `excluded_perturbers` in [`excluded_perturbers_naif`]; 0 = none."]
    pub num_excluded_perturbers: usize,
    #[doc = " NAIF IDs to exclude (self-perturbation avoidance for SB441-N16\n bodies). Non-owning. Pass `null` / count 0 to use the full\n perturber set."]
    pub excluded_perturbers_naif: *const i32,
    #[doc = " Uncertainty-propagation method (tag + per-variant params)."]
    pub uncertainty_method: EmpyreanUncertaintyMethod,
    #[doc = " Force `Jet1<6>` integration even without input covariance.\n 1 = on, 0 = off (default)."]
    pub compute_stm: u8,
    #[doc = " Output reference frame: 0=ICRF, 1=EclipticJ2000."]
    pub frame: i32,
    pub events: EmpyreanEventConfig,
    pub diagnostics: EmpyreanDiagnosticsConfig,
    #[doc = " Threads for multi-orbit propagation. 0 = use all cores\n (Rayon default); positive N = exactly N cores."]
    pub num_threads: usize,
    pub advanced: EmpyreanAdvancedIntegratorConfig,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanPropagationConfig"]
        [::std::mem::size_of::<EmpyreanPropagationConfig>() - 288usize];
    ["Alignment of EmpyreanPropagationConfig"]
        [::std::mem::align_of::<EmpyreanPropagationConfig>() - 8usize];
    ["Offset of field: EmpyreanPropagationConfig::force_model"]
        [::std::mem::offset_of!(EmpyreanPropagationConfig, force_model) - 0usize];
    ["Offset of field: EmpyreanPropagationConfig::num_excluded_perturbers"]
        [::std::mem::offset_of!(EmpyreanPropagationConfig, num_excluded_perturbers) - 8usize];
    ["Offset of field: EmpyreanPropagationConfig::excluded_perturbers_naif"]
        [::std::mem::offset_of!(EmpyreanPropagationConfig, excluded_perturbers_naif) - 16usize];
    ["Offset of field: EmpyreanPropagationConfig::uncertainty_method"]
        [::std::mem::offset_of!(EmpyreanPropagationConfig, uncertainty_method) - 24usize];
    ["Offset of field: EmpyreanPropagationConfig::compute_stm"]
        [::std::mem::offset_of!(EmpyreanPropagationConfig, compute_stm) - 112usize];
    ["Offset of field: EmpyreanPropagationConfig::frame"]
        [::std::mem::offset_of!(EmpyreanPropagationConfig, frame) - 116usize];
    ["Offset of field: EmpyreanPropagationConfig::events"]
        [::std::mem::offset_of!(EmpyreanPropagationConfig, events) - 120usize];
    ["Offset of field: EmpyreanPropagationConfig::diagnostics"]
        [::std::mem::offset_of!(EmpyreanPropagationConfig, diagnostics) - 160usize];
    ["Offset of field: EmpyreanPropagationConfig::num_threads"]
        [::std::mem::offset_of!(EmpyreanPropagationConfig, num_threads) - 200usize];
    ["Offset of field: EmpyreanPropagationConfig::advanced"]
        [::std::mem::offset_of!(EmpyreanPropagationConfig, advanced) - 208usize];
};
impl Default for EmpyreanPropagationConfig {
    fn default() -> Self {
        let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
#[doc = " Ephemeris-generation configuration.\n\n Wraps the inner [`EmpyreanPropagationConfig`] (force model,\n uncertainty method, output frame) plus the light-time iteration\n controls and a diagnostics toggle. The propagation runs internally\n to bring each orbit to its observation epoch, so every\n propagation-level knob applies here too."]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EmpyreanEphemerisConfig {
    #[doc = " Inner propagation configuration applied to the trajectory that\n brings each orbit to its observation epoch."]
    pub propagation: EmpyreanPropagationConfig,
    #[doc = " Maximum iterations for light-time convergence. 0 → use the\n upstream default (3)."]
    pub max_light_time_iterations: usize,
    #[doc = " Tolerance (days) for light-time convergence. 0.0 → upstream\n default (1e-10)."]
    pub light_time_tolerance_days: f64,
    #[doc = " 1 = compute phase angle / elongation / heliocentric distance /\n apparent magnitude. 0 = skip (faster; appropriate for OD inner\n loops that only need RA/Dec)."]
    pub compute_diagnostics: u8,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanEphemerisConfig"]
        [::std::mem::size_of::<EmpyreanEphemerisConfig>() - 312usize];
    ["Alignment of EmpyreanEphemerisConfig"]
        [::std::mem::align_of::<EmpyreanEphemerisConfig>() - 8usize];
    ["Offset of field: EmpyreanEphemerisConfig::propagation"]
        [::std::mem::offset_of!(EmpyreanEphemerisConfig, propagation) - 0usize];
    ["Offset of field: EmpyreanEphemerisConfig::max_light_time_iterations"]
        [::std::mem::offset_of!(EmpyreanEphemerisConfig, max_light_time_iterations) - 288usize];
    ["Offset of field: EmpyreanEphemerisConfig::light_time_tolerance_days"]
        [::std::mem::offset_of!(EmpyreanEphemerisConfig, light_time_tolerance_days) - 296usize];
    ["Offset of field: EmpyreanEphemerisConfig::compute_diagnostics"]
        [::std::mem::offset_of!(EmpyreanEphemerisConfig, compute_diagnostics) - 304usize];
};
impl Default for EmpyreanEphemerisConfig {
    fn default() -> Self {
        let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
#[doc = " A single predicted ephemeris entry."]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EmpyreanEphemerisEntry {
    #[doc = " Orbit identifier (heap-allocated, freed by empyrean_ephemeris_result_free)."]
    pub orbit_id: *mut ::std::os::raw::c_char,
    #[doc = " Epoch as MJD TDB."]
    pub epoch_mjd_tdb: f64,
    #[doc = " Right ascension (degrees)."]
    pub ra_deg: f64,
    #[doc = " Declination (degrees)."]
    pub dec_deg: f64,
    #[doc = " Topocentric distance (AU)."]
    pub rho_au: f64,
    #[doc = " Radial velocity (AU/day)."]
    pub vrho_au_day: f64,
    #[doc = " RA rate (deg/day)."]
    pub vra_deg_day: f64,
    #[doc = " Dec rate (deg/day)."]
    pub vdec_deg_day: f64,
    #[doc = " One-way light time (days). NaN if unavailable."]
    pub light_time_days: f64,
    #[doc = " Phase angle (degrees). NaN if unavailable."]
    pub phase_angle_deg: f64,
    #[doc = " Solar elongation (degrees). NaN if unavailable."]
    pub elongation_deg: f64,
    #[doc = " Heliocentric distance (AU). NaN if unavailable."]
    pub heliocentric_distance_au: f64,
    #[doc = " Predicted apparent magnitude. NaN if unavailable."]
    pub mag: f64,
    #[doc = " Magnitude uncertainty. NaN if unavailable."]
    pub mag_sigma: f64,
    #[doc = " Topocentric zenith angle (degrees). NaN if unavailable (e.g. no\n observer geodetic position)."]
    pub zenith_angle_deg: f64,
    #[doc = " Topocentric azimuth, East of North (degrees). NaN if unavailable."]
    pub azimuth_deg: f64,
    #[doc = " Local hour angle (degrees). NaN if unavailable."]
    pub hour_angle_deg: f64,
    #[doc = " Angular separation from the Moon (degrees). NaN if unavailable."]
    pub lunar_elongation_deg: f64,
    #[doc = " Position angle of motion, East of North (degrees). NaN if unavailable."]
    pub position_angle_deg: f64,
    #[doc = " Total apparent sky-plane rate of motion (degrees/day). NaN if\n unavailable."]
    pub sky_rate_deg_day: f64,
    #[doc = " Observer code, null-terminated (4 bytes)."]
    pub obs_code: [u8; 4usize],
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanEphemerisEntry"][::std::mem::size_of::<EmpyreanEphemerisEntry>() - 168usize];
    ["Alignment of EmpyreanEphemerisEntry"]
        [::std::mem::align_of::<EmpyreanEphemerisEntry>() - 8usize];
    ["Offset of field: EmpyreanEphemerisEntry::orbit_id"]
        [::std::mem::offset_of!(EmpyreanEphemerisEntry, orbit_id) - 0usize];
    ["Offset of field: EmpyreanEphemerisEntry::epoch_mjd_tdb"]
        [::std::mem::offset_of!(EmpyreanEphemerisEntry, epoch_mjd_tdb) - 8usize];
    ["Offset of field: EmpyreanEphemerisEntry::ra_deg"]
        [::std::mem::offset_of!(EmpyreanEphemerisEntry, ra_deg) - 16usize];
    ["Offset of field: EmpyreanEphemerisEntry::dec_deg"]
        [::std::mem::offset_of!(EmpyreanEphemerisEntry, dec_deg) - 24usize];
    ["Offset of field: EmpyreanEphemerisEntry::rho_au"]
        [::std::mem::offset_of!(EmpyreanEphemerisEntry, rho_au) - 32usize];
    ["Offset of field: EmpyreanEphemerisEntry::vrho_au_day"]
        [::std::mem::offset_of!(EmpyreanEphemerisEntry, vrho_au_day) - 40usize];
    ["Offset of field: EmpyreanEphemerisEntry::vra_deg_day"]
        [::std::mem::offset_of!(EmpyreanEphemerisEntry, vra_deg_day) - 48usize];
    ["Offset of field: EmpyreanEphemerisEntry::vdec_deg_day"]
        [::std::mem::offset_of!(EmpyreanEphemerisEntry, vdec_deg_day) - 56usize];
    ["Offset of field: EmpyreanEphemerisEntry::light_time_days"]
        [::std::mem::offset_of!(EmpyreanEphemerisEntry, light_time_days) - 64usize];
    ["Offset of field: EmpyreanEphemerisEntry::phase_angle_deg"]
        [::std::mem::offset_of!(EmpyreanEphemerisEntry, phase_angle_deg) - 72usize];
    ["Offset of field: EmpyreanEphemerisEntry::elongation_deg"]
        [::std::mem::offset_of!(EmpyreanEphemerisEntry, elongation_deg) - 80usize];
    ["Offset of field: EmpyreanEphemerisEntry::heliocentric_distance_au"]
        [::std::mem::offset_of!(EmpyreanEphemerisEntry, heliocentric_distance_au) - 88usize];
    ["Offset of field: EmpyreanEphemerisEntry::mag"]
        [::std::mem::offset_of!(EmpyreanEphemerisEntry, mag) - 96usize];
    ["Offset of field: EmpyreanEphemerisEntry::mag_sigma"]
        [::std::mem::offset_of!(EmpyreanEphemerisEntry, mag_sigma) - 104usize];
    ["Offset of field: EmpyreanEphemerisEntry::zenith_angle_deg"]
        [::std::mem::offset_of!(EmpyreanEphemerisEntry, zenith_angle_deg) - 112usize];
    ["Offset of field: EmpyreanEphemerisEntry::azimuth_deg"]
        [::std::mem::offset_of!(EmpyreanEphemerisEntry, azimuth_deg) - 120usize];
    ["Offset of field: EmpyreanEphemerisEntry::hour_angle_deg"]
        [::std::mem::offset_of!(EmpyreanEphemerisEntry, hour_angle_deg) - 128usize];
    ["Offset of field: EmpyreanEphemerisEntry::lunar_elongation_deg"]
        [::std::mem::offset_of!(EmpyreanEphemerisEntry, lunar_elongation_deg) - 136usize];
    ["Offset of field: EmpyreanEphemerisEntry::position_angle_deg"]
        [::std::mem::offset_of!(EmpyreanEphemerisEntry, position_angle_deg) - 144usize];
    ["Offset of field: EmpyreanEphemerisEntry::sky_rate_deg_day"]
        [::std::mem::offset_of!(EmpyreanEphemerisEntry, sky_rate_deg_day) - 152usize];
    ["Offset of field: EmpyreanEphemerisEntry::obs_code"]
        [::std::mem::offset_of!(EmpyreanEphemerisEntry, obs_code) - 160usize];
};
impl Default for EmpyreanEphemerisEntry {
    fn default() -> Self {
        let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
#[doc = " One observation-sensitivity row — the partial derivatives of the\n sky-plane observable w.r.t. the input state, for a single\n `(orbit, observer, epoch)`. One row per observation epoch within each\n `(orbit_id, obs_code)` chain (bd empyrean-14cz.4). Owning struct: free\n the whole result with [`empyrean_ephemeris_result_free`]."]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EmpyreanObservationSensitivity {
    #[doc = " Orbit identifier. Owning C string."]
    pub orbit_id: *mut ::std::os::raw::c_char,
    #[doc = " Object identifier (owning C string) or null when absent."]
    pub object_id: *mut ::std::os::raw::c_char,
    #[doc = " MPC observatory code, null-terminated (4 bytes)."]
    pub obs_code: [u8; 4usize],
    #[doc = " Observation epoch (MJD TDB)."]
    pub epoch_mjd_tdb: f64,
    #[doc = " Solved-parameter dimension: 6 (state) or 9 (state + non-grav)."]
    pub n_params: u8,
    #[doc = " Jacobian ∂(observable)/∂(input), row-major `[6][n_params]` flattened\n (length `6 * n_params`). Null when this epoch carries no Jacobian."]
    pub jacobian: *mut f64,
    #[doc = " Length of `jacobian` (`6 * n_params`), 0 when null."]
    pub jacobian_len: usize,
    #[doc = " Hessian ∂²(observable)/∂(input)², row-major `[6][n_params][n_params]`\n flattened (length `6 * n_params * n_params`). Null unless a\n second-order method (Jet2) ran."]
    pub hessian: *mut f64,
    #[doc = " Length of `hessian` (`6 * n_params²`), 0 when null."]
    pub hessian_len: usize,
    #[doc = " Frame of the input axis (Frame enum as int)."]
    pub frame: i32,
    #[doc = " Origin of the input axis (NAIF id)."]
    pub origin: i32,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanObservationSensitivity"]
        [::std::mem::size_of::<EmpyreanObservationSensitivity>() - 80usize];
    ["Alignment of EmpyreanObservationSensitivity"]
        [::std::mem::align_of::<EmpyreanObservationSensitivity>() - 8usize];
    ["Offset of field: EmpyreanObservationSensitivity::orbit_id"]
        [::std::mem::offset_of!(EmpyreanObservationSensitivity, orbit_id) - 0usize];
    ["Offset of field: EmpyreanObservationSensitivity::object_id"]
        [::std::mem::offset_of!(EmpyreanObservationSensitivity, object_id) - 8usize];
    ["Offset of field: EmpyreanObservationSensitivity::obs_code"]
        [::std::mem::offset_of!(EmpyreanObservationSensitivity, obs_code) - 16usize];
    ["Offset of field: EmpyreanObservationSensitivity::epoch_mjd_tdb"]
        [::std::mem::offset_of!(EmpyreanObservationSensitivity, epoch_mjd_tdb) - 24usize];
    ["Offset of field: EmpyreanObservationSensitivity::n_params"]
        [::std::mem::offset_of!(EmpyreanObservationSensitivity, n_params) - 32usize];
    ["Offset of field: EmpyreanObservationSensitivity::jacobian"]
        [::std::mem::offset_of!(EmpyreanObservationSensitivity, jacobian) - 40usize];
    ["Offset of field: EmpyreanObservationSensitivity::jacobian_len"]
        [::std::mem::offset_of!(EmpyreanObservationSensitivity, jacobian_len) - 48usize];
    ["Offset of field: EmpyreanObservationSensitivity::hessian"]
        [::std::mem::offset_of!(EmpyreanObservationSensitivity, hessian) - 56usize];
    ["Offset of field: EmpyreanObservationSensitivity::hessian_len"]
        [::std::mem::offset_of!(EmpyreanObservationSensitivity, hessian_len) - 64usize];
    ["Offset of field: EmpyreanObservationSensitivity::frame"]
        [::std::mem::offset_of!(EmpyreanObservationSensitivity, frame) - 72usize];
    ["Offset of field: EmpyreanObservationSensitivity::origin"]
        [::std::mem::offset_of!(EmpyreanObservationSensitivity, origin) - 76usize];
};
impl Default for EmpyreanObservationSensitivity {
    fn default() -> Self {
        let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
#[doc = " Result containing an array of ephemeris entries and, when an\n uncertainty method traced the STM, the observation-sensitivity chains."]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EmpyreanEphemerisResult {
    pub entries: *mut EmpyreanEphemerisEntry,
    pub num_entries: usize,
    #[doc = " Per-`(orbit, observer, epoch)` sensitivity rows. Null / 0 when no\n STM was traced (e.g. an f64-only path)."]
    pub sensitivity: *mut EmpyreanObservationSensitivity,
    pub num_sensitivity: usize,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanEphemerisResult"][::std::mem::size_of::<EmpyreanEphemerisResult>() - 32usize];
    ["Alignment of EmpyreanEphemerisResult"]
        [::std::mem::align_of::<EmpyreanEphemerisResult>() - 8usize];
    ["Offset of field: EmpyreanEphemerisResult::entries"]
        [::std::mem::offset_of!(EmpyreanEphemerisResult, entries) - 0usize];
    ["Offset of field: EmpyreanEphemerisResult::num_entries"]
        [::std::mem::offset_of!(EmpyreanEphemerisResult, num_entries) - 8usize];
    ["Offset of field: EmpyreanEphemerisResult::sensitivity"]
        [::std::mem::offset_of!(EmpyreanEphemerisResult, sensitivity) - 16usize];
    ["Offset of field: EmpyreanEphemerisResult::num_sensitivity"]
        [::std::mem::offset_of!(EmpyreanEphemerisResult, num_sensitivity) - 24usize];
};
impl Default for EmpyreanEphemerisResult {
    fn default() -> Self {
        let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
#[doc = " One impact-probability record emitted by\n [`empyrean_compute_impact_probabilities`]. Mirrors\n [`empyrean_core::impact::ImpactProbability`] flattened to primitives;\n nullable fields use NaN sentinels (Option<f64>) or 0 / null\n (Option<usize>).\n\n `method_tag` matches the `EMPYREAN_UNCERTAINTY_*` constants in\n `propagate.rs` and identifies which propagation produced this row."]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EmpyreanImpactProbability {
    #[doc = " Variant tag of the [`UncertaintyMethod`] that produced this row."]
    pub method_tag: u8,
    #[doc = " Owning C string — caller frees via `*_result_free`."]
    pub orbit_id: *mut ::std::os::raw::c_char,
    pub object_id: *mut ::std::os::raw::c_char,
    pub body: *mut ::std::os::raw::c_char,
    pub body_naif_id: i32,
    pub epoch_mjd_tdb: f64,
    pub miss_distance_au: f64,
    pub miss_distance_km: f64,
    pub effective_radius_au: f64,
    pub effective_radius_km: f64,
    pub sigma_distance_au: f64,
    pub sigma_distance_km: f64,
    pub ip_linear: f64,
    pub relative_velocity_au_day: f64,
    #[doc = " `ip_second_order`, NaN when not available."]
    pub ip_second_order: f64,
    #[doc = " Jet2 nonlinearity κ, NaN when not available."]
    pub nonlinearity: f64,
    #[doc = " AGM-mixed IP, NaN when not available."]
    pub ip_agm: f64,
    #[doc = " MC-sampled IP, NaN when not available."]
    pub ip_mc: f64,
    #[doc = " Number of MC samples drawn (0 when MC was not used)."]
    pub mc_n_samples: u64,
    #[doc = " Number of MC samples that impacted (0 when MC was not used)."]
    pub mc_n_impacts: u64,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanImpactProbability"]
        [::std::mem::size_of::<EmpyreanImpactProbability>() - 160usize];
    ["Alignment of EmpyreanImpactProbability"]
        [::std::mem::align_of::<EmpyreanImpactProbability>() - 8usize];
    ["Offset of field: EmpyreanImpactProbability::method_tag"]
        [::std::mem::offset_of!(EmpyreanImpactProbability, method_tag) - 0usize];
    ["Offset of field: EmpyreanImpactProbability::orbit_id"]
        [::std::mem::offset_of!(EmpyreanImpactProbability, orbit_id) - 8usize];
    ["Offset of field: EmpyreanImpactProbability::object_id"]
        [::std::mem::offset_of!(EmpyreanImpactProbability, object_id) - 16usize];
    ["Offset of field: EmpyreanImpactProbability::body"]
        [::std::mem::offset_of!(EmpyreanImpactProbability, body) - 24usize];
    ["Offset of field: EmpyreanImpactProbability::body_naif_id"]
        [::std::mem::offset_of!(EmpyreanImpactProbability, body_naif_id) - 32usize];
    ["Offset of field: EmpyreanImpactProbability::epoch_mjd_tdb"]
        [::std::mem::offset_of!(EmpyreanImpactProbability, epoch_mjd_tdb) - 40usize];
    ["Offset of field: EmpyreanImpactProbability::miss_distance_au"]
        [::std::mem::offset_of!(EmpyreanImpactProbability, miss_distance_au) - 48usize];
    ["Offset of field: EmpyreanImpactProbability::miss_distance_km"]
        [::std::mem::offset_of!(EmpyreanImpactProbability, miss_distance_km) - 56usize];
    ["Offset of field: EmpyreanImpactProbability::effective_radius_au"]
        [::std::mem::offset_of!(EmpyreanImpactProbability, effective_radius_au) - 64usize];
    ["Offset of field: EmpyreanImpactProbability::effective_radius_km"]
        [::std::mem::offset_of!(EmpyreanImpactProbability, effective_radius_km) - 72usize];
    ["Offset of field: EmpyreanImpactProbability::sigma_distance_au"]
        [::std::mem::offset_of!(EmpyreanImpactProbability, sigma_distance_au) - 80usize];
    ["Offset of field: EmpyreanImpactProbability::sigma_distance_km"]
        [::std::mem::offset_of!(EmpyreanImpactProbability, sigma_distance_km) - 88usize];
    ["Offset of field: EmpyreanImpactProbability::ip_linear"]
        [::std::mem::offset_of!(EmpyreanImpactProbability, ip_linear) - 96usize];
    ["Offset of field: EmpyreanImpactProbability::relative_velocity_au_day"]
        [::std::mem::offset_of!(EmpyreanImpactProbability, relative_velocity_au_day) - 104usize];
    ["Offset of field: EmpyreanImpactProbability::ip_second_order"]
        [::std::mem::offset_of!(EmpyreanImpactProbability, ip_second_order) - 112usize];
    ["Offset of field: EmpyreanImpactProbability::nonlinearity"]
        [::std::mem::offset_of!(EmpyreanImpactProbability, nonlinearity) - 120usize];
    ["Offset of field: EmpyreanImpactProbability::ip_agm"]
        [::std::mem::offset_of!(EmpyreanImpactProbability, ip_agm) - 128usize];
    ["Offset of field: EmpyreanImpactProbability::ip_mc"]
        [::std::mem::offset_of!(EmpyreanImpactProbability, ip_mc) - 136usize];
    ["Offset of field: EmpyreanImpactProbability::mc_n_samples"]
        [::std::mem::offset_of!(EmpyreanImpactProbability, mc_n_samples) - 144usize];
    ["Offset of field: EmpyreanImpactProbability::mc_n_impacts"]
        [::std::mem::offset_of!(EmpyreanImpactProbability, mc_n_impacts) - 152usize];
};
impl Default for EmpyreanImpactProbability {
    fn default() -> Self {
        let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EmpyreanImpactProbabilitiesResult {
    pub records: *mut EmpyreanImpactProbability,
    pub num_records: usize,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanImpactProbabilitiesResult"]
        [::std::mem::size_of::<EmpyreanImpactProbabilitiesResult>() - 16usize];
    ["Alignment of EmpyreanImpactProbabilitiesResult"]
        [::std::mem::align_of::<EmpyreanImpactProbabilitiesResult>() - 8usize];
    ["Offset of field: EmpyreanImpactProbabilitiesResult::records"]
        [::std::mem::offset_of!(EmpyreanImpactProbabilitiesResult, records) - 0usize];
    ["Offset of field: EmpyreanImpactProbabilitiesResult::num_records"]
        [::std::mem::offset_of!(EmpyreanImpactProbabilitiesResult, num_records) - 8usize];
};
impl Default for EmpyreanImpactProbabilitiesResult {
    fn default() -> Self {
        let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
#[doc = " One B-plane breakdown emitted by [`empyrean_compute_b_planes`].\n Mirrors [`empyrean_core::impact::BPlaneData`] flattened to primitives.\n Nullable f64 fields use NaN sentinels."]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EmpyreanBPlane {
    #[doc = " Variant tag of the [`UncertaintyMethod`] that produced this row."]
    pub method_tag: u8,
    #[doc = " Owning C string — caller frees via `*_result_free`."]
    pub body: *mut ::std::os::raw::c_char,
    pub epoch_mjd_tdb: f64,
    pub b_dot_t_km: f64,
    pub b_dot_r_km: f64,
    pub b_mag_km: f64,
    pub v_inf_km_s: f64,
    pub effective_radius_km: f64,
    pub body_radius_km: f64,
    #[doc = " `[σ_TT, σ_TR, σ_RR]` covariance elements (km²); NaN when no\n projected covariance is available."]
    pub cov_b_plane: [f64; 3usize],
    pub semi_major_3sig_km: f64,
    pub semi_minor_3sig_km: f64,
    pub ellipse_angle_rad: f64,
    pub ip_linear: f64,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanBPlane"][::std::mem::size_of::<EmpyreanBPlane>() - 128usize];
    ["Alignment of EmpyreanBPlane"][::std::mem::align_of::<EmpyreanBPlane>() - 8usize];
    ["Offset of field: EmpyreanBPlane::method_tag"]
        [::std::mem::offset_of!(EmpyreanBPlane, method_tag) - 0usize];
    ["Offset of field: EmpyreanBPlane::body"]
        [::std::mem::offset_of!(EmpyreanBPlane, body) - 8usize];
    ["Offset of field: EmpyreanBPlane::epoch_mjd_tdb"]
        [::std::mem::offset_of!(EmpyreanBPlane, epoch_mjd_tdb) - 16usize];
    ["Offset of field: EmpyreanBPlane::b_dot_t_km"]
        [::std::mem::offset_of!(EmpyreanBPlane, b_dot_t_km) - 24usize];
    ["Offset of field: EmpyreanBPlane::b_dot_r_km"]
        [::std::mem::offset_of!(EmpyreanBPlane, b_dot_r_km) - 32usize];
    ["Offset of field: EmpyreanBPlane::b_mag_km"]
        [::std::mem::offset_of!(EmpyreanBPlane, b_mag_km) - 40usize];
    ["Offset of field: EmpyreanBPlane::v_inf_km_s"]
        [::std::mem::offset_of!(EmpyreanBPlane, v_inf_km_s) - 48usize];
    ["Offset of field: EmpyreanBPlane::effective_radius_km"]
        [::std::mem::offset_of!(EmpyreanBPlane, effective_radius_km) - 56usize];
    ["Offset of field: EmpyreanBPlane::body_radius_km"]
        [::std::mem::offset_of!(EmpyreanBPlane, body_radius_km) - 64usize];
    ["Offset of field: EmpyreanBPlane::cov_b_plane"]
        [::std::mem::offset_of!(EmpyreanBPlane, cov_b_plane) - 72usize];
    ["Offset of field: EmpyreanBPlane::semi_major_3sig_km"]
        [::std::mem::offset_of!(EmpyreanBPlane, semi_major_3sig_km) - 96usize];
    ["Offset of field: EmpyreanBPlane::semi_minor_3sig_km"]
        [::std::mem::offset_of!(EmpyreanBPlane, semi_minor_3sig_km) - 104usize];
    ["Offset of field: EmpyreanBPlane::ellipse_angle_rad"]
        [::std::mem::offset_of!(EmpyreanBPlane, ellipse_angle_rad) - 112usize];
    ["Offset of field: EmpyreanBPlane::ip_linear"]
        [::std::mem::offset_of!(EmpyreanBPlane, ip_linear) - 120usize];
};
impl Default for EmpyreanBPlane {
    fn default() -> Self {
        let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EmpyreanBPlanesResult {
    pub records: *mut EmpyreanBPlane,
    pub num_records: usize,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanBPlanesResult"][::std::mem::size_of::<EmpyreanBPlanesResult>() - 16usize];
    ["Alignment of EmpyreanBPlanesResult"]
        [::std::mem::align_of::<EmpyreanBPlanesResult>() - 8usize];
    ["Offset of field: EmpyreanBPlanesResult::records"]
        [::std::mem::offset_of!(EmpyreanBPlanesResult, records) - 0usize];
    ["Offset of field: EmpyreanBPlanesResult::num_records"]
        [::std::mem::offset_of!(EmpyreanBPlanesResult, num_records) - 8usize];
};
impl Default for EmpyreanBPlanesResult {
    fn default() -> Self {
        let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
#[doc = " A batch of orbits with their identifiers.\n\n Returned by every `empyrean_orbits_read_*` and consumed by every\n `empyrean_orbits_write_*`. `orbit_ids` and `object_ids` are parallel\n to `orbits` (same length); each `object_ids[i]` may be null when the\n underlying orbit had no object designation.\n\n Free with [`empyrean_orbits_batch_free`] when done."]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EmpyreanOrbitBatch {
    #[doc = " Heap-allocated array of `EmpyreanOrbit`. Null when `num_orbits == 0`."]
    pub orbits: *mut EmpyreanOrbit,
    #[doc = " Heap-allocated array of orbit identifiers (null-terminated UTF-8).\n Each `orbit_ids[i]` is non-null when `i < num_orbits`."]
    pub orbit_ids: *mut *mut ::std::os::raw::c_char,
    #[doc = " Heap-allocated array of optional object identifiers\n (null-terminated UTF-8 or null pointer when absent)."]
    pub object_ids: *mut *mut ::std::os::raw::c_char,
    #[doc = " Number of orbits in the batch."]
    pub num_orbits: usize,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanOrbitBatch"][::std::mem::size_of::<EmpyreanOrbitBatch>() - 32usize];
    ["Alignment of EmpyreanOrbitBatch"][::std::mem::align_of::<EmpyreanOrbitBatch>() - 8usize];
    ["Offset of field: EmpyreanOrbitBatch::orbits"]
        [::std::mem::offset_of!(EmpyreanOrbitBatch, orbits) - 0usize];
    ["Offset of field: EmpyreanOrbitBatch::orbit_ids"]
        [::std::mem::offset_of!(EmpyreanOrbitBatch, orbit_ids) - 8usize];
    ["Offset of field: EmpyreanOrbitBatch::object_ids"]
        [::std::mem::offset_of!(EmpyreanOrbitBatch, object_ids) - 16usize];
    ["Offset of field: EmpyreanOrbitBatch::num_orbits"]
        [::std::mem::offset_of!(EmpyreanOrbitBatch, num_orbits) - 24usize];
};
impl Default for EmpyreanOrbitBatch {
    fn default() -> Self {
        let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
#[doc = " A detected dynamical event from propagation.\n\n For `event_type = \"covariance_regime_change\"` the audit-trail\n fields (`previous_kind`, `resolved_kind`, `kappa`,\n `threshold_below`, `threshold_above`) carry the\n [`CovarianceRegimeChange`](empyrean_core::propagation::events::DynamicalEvent::CovarianceRegimeChange)\n payload and the body / distance / velocity fields are zeroed\n (regime changes don't carry a body or geometry — they're audit\n markers from\n [`UncertaintyMethod::Auto`](empyrean_core::propagation::UncertaintyMethod::Auto)).\n For all other events these fields are sentinel-filled\n (`0xFF` / NaN).\n\n Field names mirror empyrean-core's variant fields for the\n regime-change payload — no per-variant prefix."]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EmpyreanEvent {
    pub event_type: *mut ::std::os::raw::c_char,
    pub orbit_id: *mut ::std::os::raw::c_char,
    #[doc = " Object identifier looked up by `orbit_id` from the input batch.\n Empty string when the input had no `object_id`. Owning C string —\n caller frees via `*_result_free`."]
    pub object_id: *mut ::std::os::raw::c_char,
    pub body: *mut ::std::os::raw::c_char,
    pub body_naif_id: i32,
    pub epoch_mjd_tdb: f64,
    pub distance_au: f64,
    pub distance_km: f64,
    pub relative_velocity_au_day: f64,
    #[doc = " `CovarianceRegimeChange` payload: previous resolved kind.\n Sentinel `0xFF` for non-regime events."]
    pub previous_kind: u8,
    #[doc = " `CovarianceRegimeChange` payload: new resolved kind.\n Sentinel `0xFF` for non-regime events."]
    pub resolved_kind: u8,
    #[doc = " `CovarianceRegimeChange` payload: local nonlinearity κ\n recorded at the CA. NaN for non-regime events."]
    pub kappa: f64,
    #[doc = " `CovarianceRegimeChange` payload: audit field for this resolved\n regime. NaN for non-regime events."]
    pub threshold_below: f64,
    #[doc = " `CovarianceRegimeChange` payload: audit field for this resolved\n regime. NaN for non-regime events."]
    pub threshold_above: f64,
    #[doc = " `CaptureStart` / `CaptureEnd` payload: two-body energy w.r.t. the\n capturing body (AU²/day²). NaN for non-capture events."]
    pub two_body_energy: f64,
    #[doc = " `CaptureStart` / `CaptureEnd` payload: Jacobi constant in the\n CR3BP. NaN for non-capture events or when unavailable."]
    pub jacobi_constant: f64,
    #[doc = " `CaptureStart` / `CaptureEnd` payload: 1σ uncertainty on the\n Jacobi constant. NaN when unavailable."]
    pub jacobi_constant_sigma: f64,
    #[doc = " `CaptureStart` / `CaptureEnd` payload: Jacobi constant at the L1\n gateway. NaN when unavailable."]
    pub jacobi_constant_l1: f64,
    #[doc = " `CaptureStart` / `CaptureEnd` payload: Jacobi constant at the L2\n gateway. NaN when unavailable."]
    pub jacobi_constant_l2: f64,
    #[doc = " `CaptureEnd` payload: number of periapsis passages during the\n temporary capture. `-1` sentinel for non-`CaptureEnd` events."]
    pub n_periapses: i32,
    #[doc = " `Impact` payload: planetodetic latitude of the surface intercept\n (degrees). NaN for non-impact events or when unresolved."]
    pub impact_latitude_deg: f64,
    #[doc = " `Impact` payload: planetodetic longitude of the surface intercept\n (degrees). NaN for non-impact events or when unresolved."]
    pub impact_longitude_deg: f64,
    #[doc = " `Impact` payload: altitude of the surface intercept above the\n reference ellipsoid (km). NaN for non-impact events or when\n unresolved."]
    pub impact_altitude_km: f64,
    #[doc = " `ShadowEntry` / `ShadowExit` payload: fraction of the Sun's disk\n occulted by the body (0 = none, 1 = full umbra). NaN for\n non-shadow events."]
    pub shadow_fraction: f64,
    #[doc = " `ShadowEntry` / `ShadowExit` payload: fraction of incident\n sunlight reaching the particle (1 = full sun, 0 = total eclipse).\n NaN for non-shadow events."]
    pub illumination: f64,
    #[doc = " `Periapsis` payload: relative position w.r.t. the approached body\n (AU), components x/y/z. NaN for non-periapsis events."]
    pub relative_x: f64,
    pub relative_y: f64,
    pub relative_z: f64,
    #[doc = " `Periapsis` payload: relative velocity w.r.t. the approached body\n (AU/day), components vx/vy/vz. NaN for non-periapsis events."]
    pub relative_vx: f64,
    pub relative_vy: f64,
    pub relative_vz: f64,
    #[doc = " `PossibleImpact` payload: effective capture radius with\n gravitational focusing (AU / km). NaN for non-possible-impact events."]
    pub effective_radius_au: f64,
    pub effective_radius_km: f64,
    #[doc = " `PossibleImpact` payload: 1σ uncertainty along the miss direction\n (AU). NaN for non-possible-impact events."]
    pub sigma_distance_au: f64,
    #[doc = " `PossibleImpact` payload: linear (STM-mapped) impact probability.\n NaN for non-possible-impact events."]
    pub ip_linear: f64,
    #[doc = " `PossibleImpact` payload: second-order (Edgeworth) impact\n probability. NaN for non-possible-impact / first-order runs."]
    pub ip_second_order: f64,
    #[doc = " `PossibleImpact` payload: local nonlinearity κ at the encounter.\n NaN when unavailable."]
    pub nonlinearity: f64,
    #[doc = " `PossibleImpact` payload: adaptive-Gaussian-mixture impact\n probability. NaN when not an AGM run."]
    pub ip_agm: f64,
    #[doc = " `PossibleImpact` payload: Monte-Carlo impact probability. NaN when\n not a Monte-Carlo run."]
    pub ip_mc: f64,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanEvent"][::std::mem::size_of::<EmpyreanEvent>() - 304usize];
    ["Alignment of EmpyreanEvent"][::std::mem::align_of::<EmpyreanEvent>() - 8usize];
    ["Offset of field: EmpyreanEvent::event_type"]
        [::std::mem::offset_of!(EmpyreanEvent, event_type) - 0usize];
    ["Offset of field: EmpyreanEvent::orbit_id"]
        [::std::mem::offset_of!(EmpyreanEvent, orbit_id) - 8usize];
    ["Offset of field: EmpyreanEvent::object_id"]
        [::std::mem::offset_of!(EmpyreanEvent, object_id) - 16usize];
    ["Offset of field: EmpyreanEvent::body"][::std::mem::offset_of!(EmpyreanEvent, body) - 24usize];
    ["Offset of field: EmpyreanEvent::body_naif_id"]
        [::std::mem::offset_of!(EmpyreanEvent, body_naif_id) - 32usize];
    ["Offset of field: EmpyreanEvent::epoch_mjd_tdb"]
        [::std::mem::offset_of!(EmpyreanEvent, epoch_mjd_tdb) - 40usize];
    ["Offset of field: EmpyreanEvent::distance_au"]
        [::std::mem::offset_of!(EmpyreanEvent, distance_au) - 48usize];
    ["Offset of field: EmpyreanEvent::distance_km"]
        [::std::mem::offset_of!(EmpyreanEvent, distance_km) - 56usize];
    ["Offset of field: EmpyreanEvent::relative_velocity_au_day"]
        [::std::mem::offset_of!(EmpyreanEvent, relative_velocity_au_day) - 64usize];
    ["Offset of field: EmpyreanEvent::previous_kind"]
        [::std::mem::offset_of!(EmpyreanEvent, previous_kind) - 72usize];
    ["Offset of field: EmpyreanEvent::resolved_kind"]
        [::std::mem::offset_of!(EmpyreanEvent, resolved_kind) - 73usize];
    ["Offset of field: EmpyreanEvent::kappa"]
        [::std::mem::offset_of!(EmpyreanEvent, kappa) - 80usize];
    ["Offset of field: EmpyreanEvent::threshold_below"]
        [::std::mem::offset_of!(EmpyreanEvent, threshold_below) - 88usize];
    ["Offset of field: EmpyreanEvent::threshold_above"]
        [::std::mem::offset_of!(EmpyreanEvent, threshold_above) - 96usize];
    ["Offset of field: EmpyreanEvent::two_body_energy"]
        [::std::mem::offset_of!(EmpyreanEvent, two_body_energy) - 104usize];
    ["Offset of field: EmpyreanEvent::jacobi_constant"]
        [::std::mem::offset_of!(EmpyreanEvent, jacobi_constant) - 112usize];
    ["Offset of field: EmpyreanEvent::jacobi_constant_sigma"]
        [::std::mem::offset_of!(EmpyreanEvent, jacobi_constant_sigma) - 120usize];
    ["Offset of field: EmpyreanEvent::jacobi_constant_l1"]
        [::std::mem::offset_of!(EmpyreanEvent, jacobi_constant_l1) - 128usize];
    ["Offset of field: EmpyreanEvent::jacobi_constant_l2"]
        [::std::mem::offset_of!(EmpyreanEvent, jacobi_constant_l2) - 136usize];
    ["Offset of field: EmpyreanEvent::n_periapses"]
        [::std::mem::offset_of!(EmpyreanEvent, n_periapses) - 144usize];
    ["Offset of field: EmpyreanEvent::impact_latitude_deg"]
        [::std::mem::offset_of!(EmpyreanEvent, impact_latitude_deg) - 152usize];
    ["Offset of field: EmpyreanEvent::impact_longitude_deg"]
        [::std::mem::offset_of!(EmpyreanEvent, impact_longitude_deg) - 160usize];
    ["Offset of field: EmpyreanEvent::impact_altitude_km"]
        [::std::mem::offset_of!(EmpyreanEvent, impact_altitude_km) - 168usize];
    ["Offset of field: EmpyreanEvent::shadow_fraction"]
        [::std::mem::offset_of!(EmpyreanEvent, shadow_fraction) - 176usize];
    ["Offset of field: EmpyreanEvent::illumination"]
        [::std::mem::offset_of!(EmpyreanEvent, illumination) - 184usize];
    ["Offset of field: EmpyreanEvent::relative_x"]
        [::std::mem::offset_of!(EmpyreanEvent, relative_x) - 192usize];
    ["Offset of field: EmpyreanEvent::relative_y"]
        [::std::mem::offset_of!(EmpyreanEvent, relative_y) - 200usize];
    ["Offset of field: EmpyreanEvent::relative_z"]
        [::std::mem::offset_of!(EmpyreanEvent, relative_z) - 208usize];
    ["Offset of field: EmpyreanEvent::relative_vx"]
        [::std::mem::offset_of!(EmpyreanEvent, relative_vx) - 216usize];
    ["Offset of field: EmpyreanEvent::relative_vy"]
        [::std::mem::offset_of!(EmpyreanEvent, relative_vy) - 224usize];
    ["Offset of field: EmpyreanEvent::relative_vz"]
        [::std::mem::offset_of!(EmpyreanEvent, relative_vz) - 232usize];
    ["Offset of field: EmpyreanEvent::effective_radius_au"]
        [::std::mem::offset_of!(EmpyreanEvent, effective_radius_au) - 240usize];
    ["Offset of field: EmpyreanEvent::effective_radius_km"]
        [::std::mem::offset_of!(EmpyreanEvent, effective_radius_km) - 248usize];
    ["Offset of field: EmpyreanEvent::sigma_distance_au"]
        [::std::mem::offset_of!(EmpyreanEvent, sigma_distance_au) - 256usize];
    ["Offset of field: EmpyreanEvent::ip_linear"]
        [::std::mem::offset_of!(EmpyreanEvent, ip_linear) - 264usize];
    ["Offset of field: EmpyreanEvent::ip_second_order"]
        [::std::mem::offset_of!(EmpyreanEvent, ip_second_order) - 272usize];
    ["Offset of field: EmpyreanEvent::nonlinearity"]
        [::std::mem::offset_of!(EmpyreanEvent, nonlinearity) - 280usize];
    ["Offset of field: EmpyreanEvent::ip_agm"]
        [::std::mem::offset_of!(EmpyreanEvent, ip_agm) - 288usize];
    ["Offset of field: EmpyreanEvent::ip_mc"]
        [::std::mem::offset_of!(EmpyreanEvent, ip_mc) - 296usize];
};
impl Default for EmpyreanEvent {
    fn default() -> Self {
        let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
#[doc = " Per-observation result from orbit determination or evaluation.\n\n Mirrors scott's [`ObservationResult`](scott::results::ObservationResult)\n — every field upstream produces is carried across the C ABI. NaN /\n `EMPYREAN_REJECTION_NOT_EVALUATED` mark fields that aren't populated\n for the call type (e.g. evaluate doesn't compute rejection or\n influence diagnostics).\n\n `obs_id` is a heap-allocated NUL-terminated UTF-8 string; the\n pointer is freed by [`empyrean_od_result_free`] /\n [`empyrean_evaluate_result_free`] when the parent array is freed.\n Do NOT free it manually."]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EmpyreanObservationResult {
    #[doc = " ADES `obsID` (or scott auto-assigned). Owned by the parent array\n — freed by the matching `*_result_free` call."]
    pub obs_id: *mut ::std::os::raw::c_char,
    #[doc = " MPC observatory code (3-byte + NUL)."]
    pub obs_code: [u8; 4usize],
    #[doc = " Star catalog used for astrometric reduction (ADES `astCat`).\n Heap-allocated; null when ADES did not carry one. Freed with the array."]
    pub ast_cat: *mut ::std::os::raw::c_char,
    #[doc = " Observation epoch (MJD TDB)."]
    pub epoch_mjd_tdb: f64,
    #[doc = " RA·cosδ residual (observed - predicted), arcsec."]
    pub ra_residual_arcsec: f64,
    #[doc = " Dec residual, arcsec."]
    pub dec_residual_arcsec: f64,
    #[doc = " Mahalanobis χ² of this observation. NaN if covariance unavailable."]
    pub chi2: f64,
    #[doc = " Degrees of freedom (number of non-NaN residual dimensions)."]
    pub dof: u32,
    #[doc = " χ² survival probability."]
    pub probability: f64,
    #[doc = " Whether this observation was used in the fit (1 = yes, 0 = no)."]
    pub selected: u8,
    #[doc = " Combined obs+predicted RA covariance (arcsec²). NaN if absent."]
    pub residual_cov_ra: f64,
    #[doc = " Combined obs+predicted Dec covariance (arcsec²). NaN if absent."]
    pub residual_cov_dec: f64,
    #[doc = " Off-diagonal correlation coefficient (dimensionless, [-1, 1]). NaN if absent."]
    pub residual_cov_corr: f64,
    #[doc = " Reason this observation was kept / rejected. One of the\n `EMPYREAN_REJECTION_*` codes; `EMPYREAN_REJECTION_NOT_EVALUATED`\n when the call did not run rejection (e.g. `empyrean_evaluate`)."]
    pub rejection_reason: i32,
    #[doc = " Criterion value (chi², Cook's D, …) tested against the threshold. NaN if not evaluated."]
    pub rejection_criterion: f64,
    #[doc = " Static threshold the criterion was compared against. NaN if not evaluated."]
    pub rejection_threshold: f64,
    #[doc = " Effective threshold for adaptive rejection (Layer 3). NaN otherwise."]
    pub rejection_effective_threshold: f64,
    #[doc = " D-optimality information loss from removing this observation. NaN if not computed."]
    pub rejection_information_loss: f64,
    #[doc = " Cook's distance. NaN if no influence pass was run."]
    pub cooks_distance: f64,
    #[doc = " Scalar leverage h_ii ∈ [0, 2]. NaN if no influence pass."]
    pub leverage: f64,
    #[doc = " D-optimality fractional information contribution\n `f_i = tr(N⁻¹ I_i)`. NaN if no influence pass."]
    pub fractional_information: f64,
    #[doc = " Along-track residual (arcsec). NaN if no sky-motion rates."]
    pub along_track_arcsec: f64,
    #[doc = " Cross-track residual (arcsec). NaN if no sky-motion rates."]
    pub cross_track_arcsec: f64,
    #[doc = " Along-track 1σ (arcsec). NaN if unavailable."]
    pub along_track_error_arcsec: f64,
    #[doc = " Cross-track 1σ (arcsec). NaN if unavailable."]
    pub cross_track_error_arcsec: f64,
    #[doc = " Position angle of sky motion (degrees, East of North). NaN if unavailable."]
    pub track_position_angle_deg: f64,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanObservationResult"]
        [::std::mem::size_of::<EmpyreanObservationResult>() - 208usize];
    ["Alignment of EmpyreanObservationResult"]
        [::std::mem::align_of::<EmpyreanObservationResult>() - 8usize];
    ["Offset of field: EmpyreanObservationResult::obs_id"]
        [::std::mem::offset_of!(EmpyreanObservationResult, obs_id) - 0usize];
    ["Offset of field: EmpyreanObservationResult::obs_code"]
        [::std::mem::offset_of!(EmpyreanObservationResult, obs_code) - 8usize];
    ["Offset of field: EmpyreanObservationResult::ast_cat"]
        [::std::mem::offset_of!(EmpyreanObservationResult, ast_cat) - 16usize];
    ["Offset of field: EmpyreanObservationResult::epoch_mjd_tdb"]
        [::std::mem::offset_of!(EmpyreanObservationResult, epoch_mjd_tdb) - 24usize];
    ["Offset of field: EmpyreanObservationResult::ra_residual_arcsec"]
        [::std::mem::offset_of!(EmpyreanObservationResult, ra_residual_arcsec) - 32usize];
    ["Offset of field: EmpyreanObservationResult::dec_residual_arcsec"]
        [::std::mem::offset_of!(EmpyreanObservationResult, dec_residual_arcsec) - 40usize];
    ["Offset of field: EmpyreanObservationResult::chi2"]
        [::std::mem::offset_of!(EmpyreanObservationResult, chi2) - 48usize];
    ["Offset of field: EmpyreanObservationResult::dof"]
        [::std::mem::offset_of!(EmpyreanObservationResult, dof) - 56usize];
    ["Offset of field: EmpyreanObservationResult::probability"]
        [::std::mem::offset_of!(EmpyreanObservationResult, probability) - 64usize];
    ["Offset of field: EmpyreanObservationResult::selected"]
        [::std::mem::offset_of!(EmpyreanObservationResult, selected) - 72usize];
    ["Offset of field: EmpyreanObservationResult::residual_cov_ra"]
        [::std::mem::offset_of!(EmpyreanObservationResult, residual_cov_ra) - 80usize];
    ["Offset of field: EmpyreanObservationResult::residual_cov_dec"]
        [::std::mem::offset_of!(EmpyreanObservationResult, residual_cov_dec) - 88usize];
    ["Offset of field: EmpyreanObservationResult::residual_cov_corr"]
        [::std::mem::offset_of!(EmpyreanObservationResult, residual_cov_corr) - 96usize];
    ["Offset of field: EmpyreanObservationResult::rejection_reason"]
        [::std::mem::offset_of!(EmpyreanObservationResult, rejection_reason) - 104usize];
    ["Offset of field: EmpyreanObservationResult::rejection_criterion"]
        [::std::mem::offset_of!(EmpyreanObservationResult, rejection_criterion) - 112usize];
    ["Offset of field: EmpyreanObservationResult::rejection_threshold"]
        [::std::mem::offset_of!(EmpyreanObservationResult, rejection_threshold) - 120usize];
    ["Offset of field: EmpyreanObservationResult::rejection_effective_threshold"][::std::mem::offset_of!(
        EmpyreanObservationResult,
        rejection_effective_threshold
    ) - 128usize];
    ["Offset of field: EmpyreanObservationResult::rejection_information_loss"]
        [::std::mem::offset_of!(EmpyreanObservationResult, rejection_information_loss) - 136usize];
    ["Offset of field: EmpyreanObservationResult::cooks_distance"]
        [::std::mem::offset_of!(EmpyreanObservationResult, cooks_distance) - 144usize];
    ["Offset of field: EmpyreanObservationResult::leverage"]
        [::std::mem::offset_of!(EmpyreanObservationResult, leverage) - 152usize];
    ["Offset of field: EmpyreanObservationResult::fractional_information"]
        [::std::mem::offset_of!(EmpyreanObservationResult, fractional_information) - 160usize];
    ["Offset of field: EmpyreanObservationResult::along_track_arcsec"]
        [::std::mem::offset_of!(EmpyreanObservationResult, along_track_arcsec) - 168usize];
    ["Offset of field: EmpyreanObservationResult::cross_track_arcsec"]
        [::std::mem::offset_of!(EmpyreanObservationResult, cross_track_arcsec) - 176usize];
    ["Offset of field: EmpyreanObservationResult::along_track_error_arcsec"]
        [::std::mem::offset_of!(EmpyreanObservationResult, along_track_error_arcsec) - 184usize];
    ["Offset of field: EmpyreanObservationResult::cross_track_error_arcsec"]
        [::std::mem::offset_of!(EmpyreanObservationResult, cross_track_error_arcsec) - 192usize];
    ["Offset of field: EmpyreanObservationResult::track_position_angle_deg"]
        [::std::mem::offset_of!(EmpyreanObservationResult, track_position_angle_deg) - 200usize];
};
impl Default for EmpyreanObservationResult {
    fn default() -> Self {
        let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
#[doc = " Result containing an array of observer states."]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EmpyreanObserverResult {
    pub observers: *mut EmpyreanObserver,
    pub num_observers: usize,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanObserverResult"][::std::mem::size_of::<EmpyreanObserverResult>() - 16usize];
    ["Alignment of EmpyreanObserverResult"]
        [::std::mem::align_of::<EmpyreanObserverResult>() - 8usize];
    ["Offset of field: EmpyreanObserverResult::observers"]
        [::std::mem::offset_of!(EmpyreanObserverResult, observers) - 0usize];
    ["Offset of field: EmpyreanObserverResult::num_observers"]
        [::std::mem::offset_of!(EmpyreanObserverResult, num_observers) - 8usize];
};
impl Default for EmpyreanObserverResult {
    fn default() -> Self {
        let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
#[doc = " A single optical observation for orbit determination — full ADES schema.\n\n String fields are nullable (`null` pointer = absent). Float fields\n use NaN as the absent sentinel. The `n_stars` integer uses `-1` as\n the absent sentinel (since `u32::MAX` is a valid count). The\n `obs_code` is fixed-size 4-byte null-padded to keep the common case\n allocation-free.\n\n Mirrors scott's `OpticalObservation` field-for-field — every named\n PSV column round-trips losslessly except for ADES extension fields\n not yet in the upstream schema."]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EmpyreanObservation {
    #[doc = " IAU permanent designation (nullable)."]
    pub perm_id: *mut ::std::os::raw::c_char,
    #[doc = " MPC provisional designation (nullable)."]
    pub prov_id: *mut ::std::os::raw::c_char,
    #[doc = " Observer-assigned tracklet identifier (nullable)."]
    pub trk_sub: *mut ::std::os::raw::c_char,
    #[doc = " MPC-assigned observation identifier (`obsid`, nullable)."]
    pub obs_id: *mut ::std::os::raw::c_char,
    #[doc = " Observer-assigned sub-identifier (`obsSubID`, nullable)."]
    pub obs_sub_id: *mut ::std::os::raw::c_char,
    #[doc = " Track identifier (`trkID`, nullable)."]
    pub trk_id: *mut ::std::os::raw::c_char,
    #[doc = " MPC observatory code, null-padded to 4 bytes."]
    pub obs_code: [u8; 4usize],
    #[doc = " Observation mode (CCD, CMOS, etc.) (nullable)."]
    pub mode: *mut ::std::os::raw::c_char,
    #[doc = " MPC program code (nullable)."]
    pub prog: *mut ::std::os::raw::c_char,
    #[doc = " Coordinate system for observer position (nullable)."]
    pub sys: *mut ::std::os::raw::c_char,
    #[doc = " Center body NAIF ID. NaN if unset."]
    pub ctr: f64,
    #[doc = " Position component 1 (lon for WGS84, X for ICRF_KM). NaN if unset."]
    pub pos1: f64,
    #[doc = " Position component 2 (lat for WGS84, Y for ICRF_KM). NaN if unset."]
    pub pos2: f64,
    #[doc = " Position component 3 (alt for WGS84, Z for ICRF_KM). NaN if unset."]
    pub pos3: f64,
    #[doc = " Observation time as ISO 8601 UTC string."]
    pub obs_time: *mut ::std::os::raw::c_char,
    #[doc = " Right ascension (degrees)."]
    pub ra_deg: f64,
    #[doc = " Declination (degrees)."]
    pub dec_deg: f64,
    #[doc = " RA·cos(Dec) uncertainty (arcseconds). NaN if unavailable."]
    pub rms_ra_arcsec: f64,
    #[doc = " Dec uncertainty (arcseconds). NaN if unavailable."]
    pub rms_dec_arcsec: f64,
    #[doc = " RA-Dec correlation coefficient [-1, 1]. NaN if unavailable."]
    pub rms_corr: f64,
    #[doc = " Star catalog used for astrometric reduction (nullable)."]
    pub ast_cat: *mut ::std::os::raw::c_char,
    #[doc = " Apparent magnitude. NaN if unavailable."]
    pub mag: f64,
    #[doc = " Magnitude uncertainty. NaN if unavailable."]
    pub rms_mag: f64,
    #[doc = " Photometric passband (nullable)."]
    pub band: *mut ::std::os::raw::c_char,
    #[doc = " Photometric catalog (nullable)."]
    pub phot_cat: *mut ::std::os::raw::c_char,
    #[doc = " Photometric aperture (arcseconds). NaN if unavailable."]
    pub phot_ap: f64,
    #[doc = " log10(SNR) of the detection. NaN if unavailable."]
    pub log_snr: f64,
    #[doc = " Seeing FWHM (arcseconds). NaN if unavailable."]
    pub seeing: f64,
    #[doc = " Exposure time (seconds). NaN if unavailable."]
    pub exp: f64,
    #[doc = " RMS of astrometric fit (arcseconds). NaN if unavailable."]
    pub rms_fit: f64,
    #[doc = " Number of reference stars in astrometric fit. -1 if unavailable."]
    pub n_stars: i32,
    #[doc = " MPC note flags (nullable)."]
    pub notes: *mut ::std::os::raw::c_char,
    #[doc = " Free-text observer remarks (nullable)."]
    pub remarks: *mut ::std::os::raw::c_char,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanObservation"][::std::mem::size_of::<EmpyreanObservation>() - 264usize];
    ["Alignment of EmpyreanObservation"][::std::mem::align_of::<EmpyreanObservation>() - 8usize];
    ["Offset of field: EmpyreanObservation::perm_id"]
        [::std::mem::offset_of!(EmpyreanObservation, perm_id) - 0usize];
    ["Offset of field: EmpyreanObservation::prov_id"]
        [::std::mem::offset_of!(EmpyreanObservation, prov_id) - 8usize];
    ["Offset of field: EmpyreanObservation::trk_sub"]
        [::std::mem::offset_of!(EmpyreanObservation, trk_sub) - 16usize];
    ["Offset of field: EmpyreanObservation::obs_id"]
        [::std::mem::offset_of!(EmpyreanObservation, obs_id) - 24usize];
    ["Offset of field: EmpyreanObservation::obs_sub_id"]
        [::std::mem::offset_of!(EmpyreanObservation, obs_sub_id) - 32usize];
    ["Offset of field: EmpyreanObservation::trk_id"]
        [::std::mem::offset_of!(EmpyreanObservation, trk_id) - 40usize];
    ["Offset of field: EmpyreanObservation::obs_code"]
        [::std::mem::offset_of!(EmpyreanObservation, obs_code) - 48usize];
    ["Offset of field: EmpyreanObservation::mode"]
        [::std::mem::offset_of!(EmpyreanObservation, mode) - 56usize];
    ["Offset of field: EmpyreanObservation::prog"]
        [::std::mem::offset_of!(EmpyreanObservation, prog) - 64usize];
    ["Offset of field: EmpyreanObservation::sys"]
        [::std::mem::offset_of!(EmpyreanObservation, sys) - 72usize];
    ["Offset of field: EmpyreanObservation::ctr"]
        [::std::mem::offset_of!(EmpyreanObservation, ctr) - 80usize];
    ["Offset of field: EmpyreanObservation::pos1"]
        [::std::mem::offset_of!(EmpyreanObservation, pos1) - 88usize];
    ["Offset of field: EmpyreanObservation::pos2"]
        [::std::mem::offset_of!(EmpyreanObservation, pos2) - 96usize];
    ["Offset of field: EmpyreanObservation::pos3"]
        [::std::mem::offset_of!(EmpyreanObservation, pos3) - 104usize];
    ["Offset of field: EmpyreanObservation::obs_time"]
        [::std::mem::offset_of!(EmpyreanObservation, obs_time) - 112usize];
    ["Offset of field: EmpyreanObservation::ra_deg"]
        [::std::mem::offset_of!(EmpyreanObservation, ra_deg) - 120usize];
    ["Offset of field: EmpyreanObservation::dec_deg"]
        [::std::mem::offset_of!(EmpyreanObservation, dec_deg) - 128usize];
    ["Offset of field: EmpyreanObservation::rms_ra_arcsec"]
        [::std::mem::offset_of!(EmpyreanObservation, rms_ra_arcsec) - 136usize];
    ["Offset of field: EmpyreanObservation::rms_dec_arcsec"]
        [::std::mem::offset_of!(EmpyreanObservation, rms_dec_arcsec) - 144usize];
    ["Offset of field: EmpyreanObservation::rms_corr"]
        [::std::mem::offset_of!(EmpyreanObservation, rms_corr) - 152usize];
    ["Offset of field: EmpyreanObservation::ast_cat"]
        [::std::mem::offset_of!(EmpyreanObservation, ast_cat) - 160usize];
    ["Offset of field: EmpyreanObservation::mag"]
        [::std::mem::offset_of!(EmpyreanObservation, mag) - 168usize];
    ["Offset of field: EmpyreanObservation::rms_mag"]
        [::std::mem::offset_of!(EmpyreanObservation, rms_mag) - 176usize];
    ["Offset of field: EmpyreanObservation::band"]
        [::std::mem::offset_of!(EmpyreanObservation, band) - 184usize];
    ["Offset of field: EmpyreanObservation::phot_cat"]
        [::std::mem::offset_of!(EmpyreanObservation, phot_cat) - 192usize];
    ["Offset of field: EmpyreanObservation::phot_ap"]
        [::std::mem::offset_of!(EmpyreanObservation, phot_ap) - 200usize];
    ["Offset of field: EmpyreanObservation::log_snr"]
        [::std::mem::offset_of!(EmpyreanObservation, log_snr) - 208usize];
    ["Offset of field: EmpyreanObservation::seeing"]
        [::std::mem::offset_of!(EmpyreanObservation, seeing) - 216usize];
    ["Offset of field: EmpyreanObservation::exp"]
        [::std::mem::offset_of!(EmpyreanObservation, exp) - 224usize];
    ["Offset of field: EmpyreanObservation::rms_fit"]
        [::std::mem::offset_of!(EmpyreanObservation, rms_fit) - 232usize];
    ["Offset of field: EmpyreanObservation::n_stars"]
        [::std::mem::offset_of!(EmpyreanObservation, n_stars) - 240usize];
    ["Offset of field: EmpyreanObservation::notes"]
        [::std::mem::offset_of!(EmpyreanObservation, notes) - 248usize];
    ["Offset of field: EmpyreanObservation::remarks"]
        [::std::mem::offset_of!(EmpyreanObservation, remarks) - 256usize];
};
impl Default for EmpyreanObservation {
    fn default() -> Self {
        let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
#[doc = " A single radar (delay or Doppler) observation for orbit determination —\n the ADES `<radar>` schema.\n\n ADES models radar astrometry as its own top-level table, parallel to\n `<optical>` (not as an optical `mode`). A record carries a round-trip\n time **delay** *or* a **Doppler** shift (the ADES `RadarValue` is an\n XSD `<choice>`), referred to a transmitting (`trx`) and receiving\n (`rcv`) station — equal for a monostatic observation, distinct for a\n bistatic one.\n\n **Units are ADES-native through this FFI — the C ABI performs ZERO unit\n conversion.** The delay *value* is in **seconds** while its uncertainty\n `rms_delay_microseconds` is in **microseconds** (this asymmetry is\n intentional in the ADES schema, verified against the IAU-ADES\n `a4179_radar` reference data and the JPL SSD radar API); Doppler value\n and uncertainty are both in **Hz**; `frq_mhz` is in **MHz**. The single\n SI normalisation happens once downstream in scott's\n `Observation::from_radar`, never here.\n\n String fields are nullable (`null` pointer = absent). The `trx`/`rcv`\n station codes are fixed-size 4-byte null-padded (like `obs_code`).\n Absent f64 fields use `f64::NAN`. The `com` flag is a tri-state `i8`.\n No field is silently zeroed or defaulted.\n\n Mirrors scott's `RadarObservation` field-for-field."]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EmpyreanRadarObservation {
    #[doc = " IAU permanent designation (nullable)."]
    pub perm_id: *mut ::std::os::raw::c_char,
    #[doc = " MPC provisional designation (nullable)."]
    pub prov_id: *mut ::std::os::raw::c_char,
    #[doc = " Observer-assigned tracklet identifier (nullable)."]
    pub trk_sub: *mut ::std::os::raw::c_char,
    #[doc = " MPC station code of the **transmitting** antenna (ADES `trx`),\n null-padded to 4 bytes."]
    pub trx: [u8; 4usize],
    #[doc = " MPC station code of the **receiving** antenna (ADES `rcv`),\n null-padded to 4 bytes. Equal to `trx` for a monostatic\n observation; differs for a bistatic one."]
    pub rcv: [u8; 4usize],
    #[doc = " Observation epoch as an ISO 8601 UTC string. For radar this is the\n **receive** epoch (the time the returned signal is recorded).\n Required, non-null."]
    pub obs_time: *mut ::std::os::raw::c_char,
    #[doc = " Measurement kind: `EMPYREAN_RADAR_KIND_DELAY` (0) or\n `EMPYREAN_RADAR_KIND_DOPPLER` (1). Selects which value pair is live."]
    pub kind: u8,
    #[doc = " Round-trip time delay in **seconds** (ADES-native). Valid iff\n `kind == EMPYREAN_RADAR_KIND_DELAY`, else `f64::NAN`."]
    pub delay_seconds: f64,
    #[doc = " 1σ uncertainty of the delay in **microseconds** (ADES-native; the\n asymmetry vs `delay_seconds` is intentional). Valid iff\n `kind == EMPYREAN_RADAR_KIND_DELAY`, else `f64::NAN`."]
    pub rms_delay_microseconds: f64,
    #[doc = " Doppler shift in **Hz** (ADES-native, signed). Valid iff\n `kind == EMPYREAN_RADAR_KIND_DOPPLER`, else `f64::NAN`."]
    pub doppler_hz: f64,
    #[doc = " 1σ uncertainty of the Doppler shift in **Hz** (ADES-native). Valid\n iff `kind == EMPYREAN_RADAR_KIND_DOPPLER`, else `f64::NAN`."]
    pub rms_doppler_hz: f64,
    #[doc = " Transmit carrier reference frequency in **MHz** (ADES `frq`).\n Required; relates a Doppler shift to a range rate."]
    pub frq_mhz: f64,
    #[doc = " Center-of-mass flag (ADES `com`), tri-state: `-1` = absent,\n `0` = false (peak-power / leading-edge reduction), `1` = true\n (reduced to target center of mass). Mirrors `Option<bool>`; a\n missing flag MUST map to `-1` (never `0`) — the ADES center-of-mass\n default is applied explicitly downstream, not silently here."]
    pub com: i8,
    #[doc = " log10(SNR) of the echo, if reported. `f64::NAN` if absent."]
    pub log_snr: f64,
    #[doc = " Free-text observer remarks (nullable)."]
    pub remarks: *mut ::std::os::raw::c_char,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanRadarObservation"]
        [::std::mem::size_of::<EmpyreanRadarObservation>() - 112usize];
    ["Alignment of EmpyreanRadarObservation"]
        [::std::mem::align_of::<EmpyreanRadarObservation>() - 8usize];
    ["Offset of field: EmpyreanRadarObservation::perm_id"]
        [::std::mem::offset_of!(EmpyreanRadarObservation, perm_id) - 0usize];
    ["Offset of field: EmpyreanRadarObservation::prov_id"]
        [::std::mem::offset_of!(EmpyreanRadarObservation, prov_id) - 8usize];
    ["Offset of field: EmpyreanRadarObservation::trk_sub"]
        [::std::mem::offset_of!(EmpyreanRadarObservation, trk_sub) - 16usize];
    ["Offset of field: EmpyreanRadarObservation::trx"]
        [::std::mem::offset_of!(EmpyreanRadarObservation, trx) - 24usize];
    ["Offset of field: EmpyreanRadarObservation::rcv"]
        [::std::mem::offset_of!(EmpyreanRadarObservation, rcv) - 28usize];
    ["Offset of field: EmpyreanRadarObservation::obs_time"]
        [::std::mem::offset_of!(EmpyreanRadarObservation, obs_time) - 32usize];
    ["Offset of field: EmpyreanRadarObservation::kind"]
        [::std::mem::offset_of!(EmpyreanRadarObservation, kind) - 40usize];
    ["Offset of field: EmpyreanRadarObservation::delay_seconds"]
        [::std::mem::offset_of!(EmpyreanRadarObservation, delay_seconds) - 48usize];
    ["Offset of field: EmpyreanRadarObservation::rms_delay_microseconds"]
        [::std::mem::offset_of!(EmpyreanRadarObservation, rms_delay_microseconds) - 56usize];
    ["Offset of field: EmpyreanRadarObservation::doppler_hz"]
        [::std::mem::offset_of!(EmpyreanRadarObservation, doppler_hz) - 64usize];
    ["Offset of field: EmpyreanRadarObservation::rms_doppler_hz"]
        [::std::mem::offset_of!(EmpyreanRadarObservation, rms_doppler_hz) - 72usize];
    ["Offset of field: EmpyreanRadarObservation::frq_mhz"]
        [::std::mem::offset_of!(EmpyreanRadarObservation, frq_mhz) - 80usize];
    ["Offset of field: EmpyreanRadarObservation::com"]
        [::std::mem::offset_of!(EmpyreanRadarObservation, com) - 88usize];
    ["Offset of field: EmpyreanRadarObservation::log_snr"]
        [::std::mem::offset_of!(EmpyreanRadarObservation, log_snr) - 96usize];
    ["Offset of field: EmpyreanRadarObservation::remarks"]
        [::std::mem::offset_of!(EmpyreanRadarObservation, remarks) - 104usize];
};
impl Default for EmpyreanRadarObservation {
    fn default() -> Self {
        let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
#[doc = " One element of [`EmpyreanWeightingConfig::additional_layers`].\n Tagged-union shape: the active fields depend on `kind`."]
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct EmpyreanWeightingLayer {
    #[doc = " Layer kind discriminator — one of\n `EMPYREAN_WEIGHTING_LAYER_*`."]
    pub kind: i32,
    #[doc = " MPC observatory code, null-padded to 4 bytes."]
    pub obs_code: [u8; 4usize],
    #[doc = " 1σ RA·cos(δ) in arcsec."]
    pub sigma_ra_arcsec: f64,
    #[doc = " 1σ Dec in arcsec."]
    pub sigma_dec_arcsec: f64,
    #[doc = " Start of applicable time range (MJD TDB). NaN = unbounded."]
    pub start_epoch_mjd_tdb: f64,
    #[doc = " End of applicable time range (MJD TDB). NaN = unbounded."]
    pub end_epoch_mjd_tdb: f64,
    #[doc = " Scale factor on the resulting weight. 0.0 → upstream default (1.0)."]
    pub scale: f64,
    #[doc = " Maximum gap between observations to count as the same night\n (days). 0.0 → upstream default (0.5)."]
    pub max_gap_days: f64,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanWeightingLayer"][::std::mem::size_of::<EmpyreanWeightingLayer>() - 56usize];
    ["Alignment of EmpyreanWeightingLayer"]
        [::std::mem::align_of::<EmpyreanWeightingLayer>() - 8usize];
    ["Offset of field: EmpyreanWeightingLayer::kind"]
        [::std::mem::offset_of!(EmpyreanWeightingLayer, kind) - 0usize];
    ["Offset of field: EmpyreanWeightingLayer::obs_code"]
        [::std::mem::offset_of!(EmpyreanWeightingLayer, obs_code) - 4usize];
    ["Offset of field: EmpyreanWeightingLayer::sigma_ra_arcsec"]
        [::std::mem::offset_of!(EmpyreanWeightingLayer, sigma_ra_arcsec) - 8usize];
    ["Offset of field: EmpyreanWeightingLayer::sigma_dec_arcsec"]
        [::std::mem::offset_of!(EmpyreanWeightingLayer, sigma_dec_arcsec) - 16usize];
    ["Offset of field: EmpyreanWeightingLayer::start_epoch_mjd_tdb"]
        [::std::mem::offset_of!(EmpyreanWeightingLayer, start_epoch_mjd_tdb) - 24usize];
    ["Offset of field: EmpyreanWeightingLayer::end_epoch_mjd_tdb"]
        [::std::mem::offset_of!(EmpyreanWeightingLayer, end_epoch_mjd_tdb) - 32usize];
    ["Offset of field: EmpyreanWeightingLayer::scale"]
        [::std::mem::offset_of!(EmpyreanWeightingLayer, scale) - 40usize];
    ["Offset of field: EmpyreanWeightingLayer::max_gap_days"]
        [::std::mem::offset_of!(EmpyreanWeightingLayer, max_gap_days) - 48usize];
};
#[doc = " Weighting configuration. Mirrors\n [`scott::weighting::WeightingConfig`] structurally; extends it\n with an `enabled` toggle and a preset selector for the common\n case of \"use the production preset\" without constructing layers\n by hand.\n\n `enabled = 0` runs OD with uniform 1″ weighting (the old\n `use_weighting = 0` behavior). `enabled = 1` activates the\n pipeline; the resulting layer chain is the preset's layers\n followed by `additional_layers` (allows e.g. VFC17 + per-survey\n override)."]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EmpyreanWeightingConfig {
    #[doc = " 1 = enabled (default), 0 = uniform 1″ weighting."]
    pub enabled: u8,
    #[doc = " Preset selector. One of `EMPYREAN_WEIGHTING_PRESET_*`.\n Default `0` (NONE) means \"use additional_layers only\";\n when `enabled = 1` and zero-init, the conversion code\n substitutes `VFC17` so default-zero structs keep the\n production behavior."]
    pub preset: u8,
    #[doc = " Default 1σ used when no rule applies (arcsec). 0.0 →\n upstream default (1.0). Ignored when preset != NONE."]
    pub default_sigma_arcsec: f64,
    #[doc = " Sigma combination policy. -1 = use the preset's policy;\n otherwise one of `EMPYREAN_SIGMA_POLICY_*`."]
    pub sigma_policy: i32,
    #[doc = " Pointer to additional layers appended to the preset's chain.\n Non-owning — caller keeps the array alive for the OD call."]
    pub additional_layers: *const EmpyreanWeightingLayer,
    pub num_additional_layers: usize,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanWeightingConfig"][::std::mem::size_of::<EmpyreanWeightingConfig>() - 40usize];
    ["Alignment of EmpyreanWeightingConfig"]
        [::std::mem::align_of::<EmpyreanWeightingConfig>() - 8usize];
    ["Offset of field: EmpyreanWeightingConfig::enabled"]
        [::std::mem::offset_of!(EmpyreanWeightingConfig, enabled) - 0usize];
    ["Offset of field: EmpyreanWeightingConfig::preset"]
        [::std::mem::offset_of!(EmpyreanWeightingConfig, preset) - 1usize];
    ["Offset of field: EmpyreanWeightingConfig::default_sigma_arcsec"]
        [::std::mem::offset_of!(EmpyreanWeightingConfig, default_sigma_arcsec) - 8usize];
    ["Offset of field: EmpyreanWeightingConfig::sigma_policy"]
        [::std::mem::offset_of!(EmpyreanWeightingConfig, sigma_policy) - 16usize];
    ["Offset of field: EmpyreanWeightingConfig::additional_layers"]
        [::std::mem::offset_of!(EmpyreanWeightingConfig, additional_layers) - 24usize];
    ["Offset of field: EmpyreanWeightingConfig::num_additional_layers"]
        [::std::mem::offset_of!(EmpyreanWeightingConfig, num_additional_layers) - 32usize];
};
impl Default for EmpyreanWeightingConfig {
    fn default() -> Self {
        let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
#[doc = " Catalog-bias-correction configuration. Mirrors scott's\n `Option<Arc<DebiasingTable>>` field on `ODConfig`.\n\n `enabled = 0` runs OD with no catalog debiasing (matches the old\n `use_debiasing = 0` behavior). `enabled = 1` activates the\n EFCC2020 pipeline; the table is loaded from `bias_dat_path` if\n non-NULL, otherwise from the DataManager-default location at the\n requested `resolution`."]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EmpyreanDebiasingConfig {
    #[doc = " 1 = on (default), 0 = no debiasing."]
    pub enabled: u8,
    #[doc = " Table identity. Currently `EFCC2020` only."]
    pub table_id: i32,
    #[doc = " `EMPYREAN_DEBIASING_RESOLUTION_*` — Standard (~35 MB) or Hires (~567 MB)."]
    pub resolution: i32,
    #[doc = " Optional path to the bias.dat file. NULL = DataManager default.\n Non-owning."]
    pub bias_dat_path: *const ::std::os::raw::c_char,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanDebiasingConfig"][::std::mem::size_of::<EmpyreanDebiasingConfig>() - 24usize];
    ["Alignment of EmpyreanDebiasingConfig"]
        [::std::mem::align_of::<EmpyreanDebiasingConfig>() - 8usize];
    ["Offset of field: EmpyreanDebiasingConfig::enabled"]
        [::std::mem::offset_of!(EmpyreanDebiasingConfig, enabled) - 0usize];
    ["Offset of field: EmpyreanDebiasingConfig::table_id"]
        [::std::mem::offset_of!(EmpyreanDebiasingConfig, table_id) - 4usize];
    ["Offset of field: EmpyreanDebiasingConfig::resolution"]
        [::std::mem::offset_of!(EmpyreanDebiasingConfig, resolution) - 8usize];
    ["Offset of field: EmpyreanDebiasingConfig::bias_dat_path"]
        [::std::mem::offset_of!(EmpyreanDebiasingConfig, bias_dat_path) - 16usize];
};
impl Default for EmpyreanDebiasingConfig {
    fn default() -> Self {
        let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
#[doc = " Origin-policy selector for the OD pipeline (mirrors\n [`OriginPolicy`]).\n\n `policy = EMPYREAN_ORIGIN_POLICY_AUTO` ignores `explicit_naif`;\n `_EXPLICIT` interprets the field as the NAIF body ID of the central\n body to pin to (e.g. 10 = Sun, 399 = Earth, 4 = Mars-barycenter)."]
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct EmpyreanOriginPolicy {
    pub policy: i32,
    pub explicit_naif: i32,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanOriginPolicy"][::std::mem::size_of::<EmpyreanOriginPolicy>() - 8usize];
    ["Alignment of EmpyreanOriginPolicy"][::std::mem::align_of::<EmpyreanOriginPolicy>() - 4usize];
    ["Offset of field: EmpyreanOriginPolicy::policy"]
        [::std::mem::offset_of!(EmpyreanOriginPolicy, policy) - 0usize];
    ["Offset of field: EmpyreanOriginPolicy::explicit_naif"]
        [::std::mem::offset_of!(EmpyreanOriginPolicy, explicit_naif) - 4usize];
};
#[doc = " IOD ranging tuning (mirrors the IOD section of [`scott::od::ODConfig`]).\n\n Nested rather than flattened so callers can pass the bundle around\n as a single value and zero-init pulls the upstream defaults\n uniformly. Sentinel rule: `0` / `0.0` requests the upstream default;\n `opposition_gap_days < 0` disables opposition splitting."]
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct EmpyreanIODConfig {
    pub max_triplet_attempts: u32,
    pub max_triplet_span_days: f64,
    #[doc = " `-1.0` disables opposition splitting; `0.0` uses upstream default (90)."]
    pub opposition_gap_days: f64,
    pub max_iod_arc_days: f64,
    pub curvature_snr_threshold: f64,
    pub max_iod_fractional_sigma_a: f64,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanIODConfig"][::std::mem::size_of::<EmpyreanIODConfig>() - 48usize];
    ["Alignment of EmpyreanIODConfig"][::std::mem::align_of::<EmpyreanIODConfig>() - 8usize];
    ["Offset of field: EmpyreanIODConfig::max_triplet_attempts"]
        [::std::mem::offset_of!(EmpyreanIODConfig, max_triplet_attempts) - 0usize];
    ["Offset of field: EmpyreanIODConfig::max_triplet_span_days"]
        [::std::mem::offset_of!(EmpyreanIODConfig, max_triplet_span_days) - 8usize];
    ["Offset of field: EmpyreanIODConfig::opposition_gap_days"]
        [::std::mem::offset_of!(EmpyreanIODConfig, opposition_gap_days) - 16usize];
    ["Offset of field: EmpyreanIODConfig::max_iod_arc_days"]
        [::std::mem::offset_of!(EmpyreanIODConfig, max_iod_arc_days) - 24usize];
    ["Offset of field: EmpyreanIODConfig::curvature_snr_threshold"]
        [::std::mem::offset_of!(EmpyreanIODConfig, curvature_snr_threshold) - 32usize];
    ["Offset of field: EmpyreanIODConfig::max_iod_fractional_sigma_a"]
        [::std::mem::offset_of!(EmpyreanIODConfig, max_iod_fractional_sigma_a) - 40usize];
};
#[doc = " Output epoch specification (mirrors [`OutputEpoch`]).\n\n The `mode` field determines which variant is active:\n `EMPYREAN_OUTPUT_EPOCH_MID_ARC` / `_LAST_OBSERVATION` / `_IOD_EPOCH`\n ignore `explicit_mjd_tdb`; `_EXPLICIT` reads the field as MJD TDB."]
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct EmpyreanOutputEpoch {
    pub mode: i32,
    pub explicit_mjd_tdb: f64,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanOutputEpoch"][::std::mem::size_of::<EmpyreanOutputEpoch>() - 16usize];
    ["Alignment of EmpyreanOutputEpoch"][::std::mem::align_of::<EmpyreanOutputEpoch>() - 8usize];
    ["Offset of field: EmpyreanOutputEpoch::mode"]
        [::std::mem::offset_of!(EmpyreanOutputEpoch, mode) - 0usize];
    ["Offset of field: EmpyreanOutputEpoch::explicit_mjd_tdb"]
        [::std::mem::offset_of!(EmpyreanOutputEpoch, explicit_mjd_tdb) - 8usize];
};
#[doc = " Auto-escalation policy for [`SolveForParams::Auto`]\n (mirrors [`scott::od::AutoEscalationPolicy`]). Sentinel: `0` /\n `0.0` → upstream default."]
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct EmpyreanAutoEscalationPolicy {
    pub reduced_chi2: f64,
    pub at_ct_ratio: f64,
    pub min_arc_days: f64,
    pub min_n_obs: u32,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanAutoEscalationPolicy"]
        [::std::mem::size_of::<EmpyreanAutoEscalationPolicy>() - 32usize];
    ["Alignment of EmpyreanAutoEscalationPolicy"]
        [::std::mem::align_of::<EmpyreanAutoEscalationPolicy>() - 8usize];
    ["Offset of field: EmpyreanAutoEscalationPolicy::reduced_chi2"]
        [::std::mem::offset_of!(EmpyreanAutoEscalationPolicy, reduced_chi2) - 0usize];
    ["Offset of field: EmpyreanAutoEscalationPolicy::at_ct_ratio"]
        [::std::mem::offset_of!(EmpyreanAutoEscalationPolicy, at_ct_ratio) - 8usize];
    ["Offset of field: EmpyreanAutoEscalationPolicy::min_arc_days"]
        [::std::mem::offset_of!(EmpyreanAutoEscalationPolicy, min_arc_days) - 16usize];
    ["Offset of field: EmpyreanAutoEscalationPolicy::min_n_obs"]
        [::std::mem::offset_of!(EmpyreanAutoEscalationPolicy, min_n_obs) - 24usize];
};
#[doc = " Acceptability thresholds for the post-DC fit-quality checks\n (mirrors [`scott::od::AcceptabilityThresholds`]). Sentinel: `0.0` →\n upstream default."]
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct EmpyreanAcceptabilityThresholds {
    pub reduced_chi2: f64,
    pub rms_arcsec: f64,
    pub at_ct_ratio: f64,
    pub min_arc_days: f64,
    pub fractional_sigma_a: f64,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanAcceptabilityThresholds"]
        [::std::mem::size_of::<EmpyreanAcceptabilityThresholds>() - 40usize];
    ["Alignment of EmpyreanAcceptabilityThresholds"]
        [::std::mem::align_of::<EmpyreanAcceptabilityThresholds>() - 8usize];
    ["Offset of field: EmpyreanAcceptabilityThresholds::reduced_chi2"]
        [::std::mem::offset_of!(EmpyreanAcceptabilityThresholds, reduced_chi2) - 0usize];
    ["Offset of field: EmpyreanAcceptabilityThresholds::rms_arcsec"]
        [::std::mem::offset_of!(EmpyreanAcceptabilityThresholds, rms_arcsec) - 8usize];
    ["Offset of field: EmpyreanAcceptabilityThresholds::at_ct_ratio"]
        [::std::mem::offset_of!(EmpyreanAcceptabilityThresholds, at_ct_ratio) - 16usize];
    ["Offset of field: EmpyreanAcceptabilityThresholds::min_arc_days"]
        [::std::mem::offset_of!(EmpyreanAcceptabilityThresholds, min_arc_days) - 24usize];
    ["Offset of field: EmpyreanAcceptabilityThresholds::fractional_sigma_a"]
        [::std::mem::offset_of!(EmpyreanAcceptabilityThresholds, fractional_sigma_a) - 32usize];
};
#[doc = " Per-station RA/Dec bias-fit configuration (mirrors\n [`scott::nuisance::BiasKind::StationRaDec`]).\n\n Activated by [`EmpyreanODConfig::fit_station_biases`]. Per-station\n sigma overrides and `BiasScope` filtering aren't carried across the\n C ABI yet — every active station uses `sigma_prior_arcsec` and the\n scope is always [`BiasScope::AllStations`]. Reach for the\n empyrean-core Rust API when you need finer control."]
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct EmpyreanStationRaDecConfig {
    #[doc = " Default 1-sigma prior on the RA / Dec offset (arcsec). Default = 0.3."]
    pub sigma_prior_arcsec: f64,
    #[doc = " Minimum observations per station for a bias parameter to be\n allocated. Stations below this threshold contribute observations\n at face value. 0 → upstream default (5)."]
    pub min_obs_per_station: usize,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanStationRaDecConfig"]
        [::std::mem::size_of::<EmpyreanStationRaDecConfig>() - 16usize];
    ["Alignment of EmpyreanStationRaDecConfig"]
        [::std::mem::align_of::<EmpyreanStationRaDecConfig>() - 8usize];
    ["Offset of field: EmpyreanStationRaDecConfig::sigma_prior_arcsec"]
        [::std::mem::offset_of!(EmpyreanStationRaDecConfig, sigma_prior_arcsec) - 0usize];
    ["Offset of field: EmpyreanStationRaDecConfig::min_obs_per_station"]
        [::std::mem::offset_of!(EmpyreanStationRaDecConfig, min_obs_per_station) - 8usize];
};
#[doc = " Outlier rejection configuration. Selects between two strategies via\n the [`kind`](Self::kind) discriminator:\n\n - `kind = EMPYREAN_REJECTION_KIND_ADAPTIVE` (default): mirrors\n   [`scott::rejection::AdaptiveRejectionConfig`]. Reads\n   `chi2_base` / `lambda` / `max_threshold`. Sentinels:\n   `chi2_base = 0.0` → 9.21, `lambda < 0` → 1.0,\n   `max_threshold = 0.0` → 100.0.\n - `kind = EMPYREAN_REJECTION_KIND_CMC2003`: mirrors\n   [`scott::rejection::CMC2003Config`]. Reads `chi2_rej` / `chi2_rec`\n   (the upper / lower hysteresis thresholds). Sentinels:\n   `chi2_rej = 0.0` → 8.0, `chi2_rec = 0.0` → 7.0.\n\n `enabled = 0` runs OD without any rejection pass — the strategy\n fields are ignored. `enabled = 1` activates rejection."]
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct EmpyreanRejectionConfig {
    #[doc = " 1 = run rejection (default), 0 = skip."]
    pub enabled: u8,
    #[doc = " Strategy selector — one of the `EMPYREAN_REJECTION_KIND_*`\n constants. Default `0` (Adaptive) keeps existing C callers\n working without code changes."]
    pub kind: u8,
    pub chi2_base: f64,
    #[doc = " `-1.0` selects the upstream default (1.0); negative values are\n otherwise valid and disable adaptation when 0.0."]
    pub lambda: f64,
    pub max_threshold: f64,
    #[doc = " CMC2003 upper threshold (reject when χ² > chi2_rej). 0.0 →\n upstream default (8.0). Ignored unless `kind ==\n EMPYREAN_REJECTION_KIND_CMC2003`."]
    pub chi2_rej: f64,
    #[doc = " CMC2003 lower threshold (recover when χ² < chi2_rec). 0.0 →\n upstream default (7.0). Must be strictly less than `chi2_rej`\n for hysteresis to break cycles. Ignored unless `kind ==\n EMPYREAN_REJECTION_KIND_CMC2003`."]
    pub chi2_rec: f64,
    #[doc = " Maximum rejection-refit passes. 0 → upstream default (3)."]
    pub max_passes: u32,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanRejectionConfig"][::std::mem::size_of::<EmpyreanRejectionConfig>() - 56usize];
    ["Alignment of EmpyreanRejectionConfig"]
        [::std::mem::align_of::<EmpyreanRejectionConfig>() - 8usize];
    ["Offset of field: EmpyreanRejectionConfig::enabled"]
        [::std::mem::offset_of!(EmpyreanRejectionConfig, enabled) - 0usize];
    ["Offset of field: EmpyreanRejectionConfig::kind"]
        [::std::mem::offset_of!(EmpyreanRejectionConfig, kind) - 1usize];
    ["Offset of field: EmpyreanRejectionConfig::chi2_base"]
        [::std::mem::offset_of!(EmpyreanRejectionConfig, chi2_base) - 8usize];
    ["Offset of field: EmpyreanRejectionConfig::lambda"]
        [::std::mem::offset_of!(EmpyreanRejectionConfig, lambda) - 16usize];
    ["Offset of field: EmpyreanRejectionConfig::max_threshold"]
        [::std::mem::offset_of!(EmpyreanRejectionConfig, max_threshold) - 24usize];
    ["Offset of field: EmpyreanRejectionConfig::chi2_rej"]
        [::std::mem::offset_of!(EmpyreanRejectionConfig, chi2_rej) - 32usize];
    ["Offset of field: EmpyreanRejectionConfig::chi2_rec"]
        [::std::mem::offset_of!(EmpyreanRejectionConfig, chi2_rec) - 40usize];
    ["Offset of field: EmpyreanRejectionConfig::max_passes"]
        [::std::mem::offset_of!(EmpyreanRejectionConfig, max_passes) - 48usize];
};
#[doc = " Orbit-determination configuration.\n\n Drives `empyrean_determine`, `empyrean_evaluate`, and `empyrean_refine`.\n Mirrors [`scott::od::ODConfig`](scott::od::ODConfig) **structurally** —\n where scott has a nested config (e.g. `auto_escalation`,\n `acceptability`), this surface keeps the same nesting via\n [`EmpyreanAutoEscalationPolicy`], [`EmpyreanAcceptabilityThresholds`],\n etc., so the C-side caller's mental model matches the upstream Rust\n type. Sentinel rule for primitive fields: `0` / `0.0` requests the\n upstream default; only the few fields documented inline (e.g.\n `opposition_gap_days < 0`, `lambda < 0`) carry their own special\n values.\n\n IOD strategy configs (Gauss / Herget / SystematicRanging /\n Refinement) are not exposed here — those are tens of internal\n tuning fields that don't translate cleanly. They always run with\n their upstream defaults; reach for the empyrean-core Rust API when\n you need to override them."]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EmpyreanODConfig {
    #[doc = " Force-model tier: 0=Approximate, 1=Basic, 2=Standard."]
    pub force_model: i32,
    #[doc = " Integrator truncation-error tolerance (interpreted by the\n active integrator backend — for the default GR15 this is the\n relative b₆ truncation tolerance). 0.0 → upstream default\n (1e-9)."]
    pub epsilon: f64,
    #[doc = " Maximum light-time iterations. 0 → upstream default (3)."]
    pub max_light_time_iterations: usize,
    #[doc = " Threads for batch operations. 0 → all available cores."]
    pub num_threads: usize,
    #[doc = " Output reference frame: 0=ICRF, 1=EclipticJ2000."]
    pub frame: i32,
    #[doc = " Observation weighting pipeline configuration. Zero-init = the\n production default (VFC17 + nightly de-weighting at floor-σ\n policy). See [`EmpyreanWeightingConfig`]."]
    pub weighting: EmpyreanWeightingConfig,
    #[doc = " Catalog-bias-correction configuration. Zero-init = the\n production default (EFCC2020 standard resolution, loaded from\n the DataManager default path). See [`EmpyreanDebiasingConfig`]."]
    pub debiasing: EmpyreanDebiasingConfig,
    #[doc = " Number of `excluded_perturbers` in [`excluded_perturbers_naif`]; 0 = none."]
    pub num_excluded_perturbers: usize,
    #[doc = " Pointer to `num_excluded_perturbers` NAIF body IDs to exclude\n from the perturber set (for self-determination of SB441-N16\n bodies). Non-owning — caller must keep the array alive for the\n duration of the OD call."]
    pub excluded_perturbers_naif: *const i32,
    #[doc = " Origin-policy selector. Zero-init = `Auto` (heliocentric → geo-\n centric Earth cascade). See [`EmpyreanOriginPolicy`]."]
    pub origin: EmpyreanOriginPolicy,
    pub iod: EmpyreanIODConfig,
    pub output_epoch: EmpyreanOutputEpoch,
    #[doc = " Maximum DC iterations. 0 → upstream default (100)."]
    pub max_iterations: u32,
    #[doc = " DC convergence tolerance on Δx^T N Δx. 0.0 → upstream default (0.1)."]
    pub convergence_tol: f64,
    #[doc = " Use STM-cached ephemeris updates for iterations 2+. 1 = on (default)."]
    pub use_stm_cache: u8,
    #[doc = " Solve-for parameter set (`EMPYREAN_SOLVE_FOR_*`). Default = Auto."]
    pub solve_for: i32,
    pub auto_escalation: EmpyreanAutoEscalationPolicy,
    pub acceptability: EmpyreanAcceptabilityThresholds,
    #[doc = " Schur-eliminate per-station RA/Dec biases. 1 = enable, 0 = off (default)."]
    pub fit_station_biases: u8,
    #[doc = " Per-station RA/Dec bias config. Honored only when\n [`fit_station_biases`] is non-zero."]
    pub station_radec: EmpyreanStationRaDecConfig,
    #[doc = " Use span-grouped Jacobian reuse on cache iterations. 0 = off (default)."]
    pub use_span_grouping: u8,
    pub rejection: EmpyreanRejectionConfig,
    #[doc = " Auto-select force-model tier from IOD elements. 0 = off (default)."]
    pub auto_force_model: u8,
    #[doc = " Output coordinate representation for the fitted orbit + covariance\n (`EMPYREAN_REPRESENTATION_*`). Default = Cartesian."]
    pub output_representation: i32,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanODConfig"][::std::mem::size_of::<EmpyreanODConfig>() - 384usize];
    ["Alignment of EmpyreanODConfig"][::std::mem::align_of::<EmpyreanODConfig>() - 8usize];
    ["Offset of field: EmpyreanODConfig::force_model"]
        [::std::mem::offset_of!(EmpyreanODConfig, force_model) - 0usize];
    ["Offset of field: EmpyreanODConfig::epsilon"]
        [::std::mem::offset_of!(EmpyreanODConfig, epsilon) - 8usize];
    ["Offset of field: EmpyreanODConfig::max_light_time_iterations"]
        [::std::mem::offset_of!(EmpyreanODConfig, max_light_time_iterations) - 16usize];
    ["Offset of field: EmpyreanODConfig::num_threads"]
        [::std::mem::offset_of!(EmpyreanODConfig, num_threads) - 24usize];
    ["Offset of field: EmpyreanODConfig::frame"]
        [::std::mem::offset_of!(EmpyreanODConfig, frame) - 32usize];
    ["Offset of field: EmpyreanODConfig::weighting"]
        [::std::mem::offset_of!(EmpyreanODConfig, weighting) - 40usize];
    ["Offset of field: EmpyreanODConfig::debiasing"]
        [::std::mem::offset_of!(EmpyreanODConfig, debiasing) - 80usize];
    ["Offset of field: EmpyreanODConfig::num_excluded_perturbers"]
        [::std::mem::offset_of!(EmpyreanODConfig, num_excluded_perturbers) - 104usize];
    ["Offset of field: EmpyreanODConfig::excluded_perturbers_naif"]
        [::std::mem::offset_of!(EmpyreanODConfig, excluded_perturbers_naif) - 112usize];
    ["Offset of field: EmpyreanODConfig::origin"]
        [::std::mem::offset_of!(EmpyreanODConfig, origin) - 120usize];
    ["Offset of field: EmpyreanODConfig::iod"]
        [::std::mem::offset_of!(EmpyreanODConfig, iod) - 128usize];
    ["Offset of field: EmpyreanODConfig::output_epoch"]
        [::std::mem::offset_of!(EmpyreanODConfig, output_epoch) - 176usize];
    ["Offset of field: EmpyreanODConfig::max_iterations"]
        [::std::mem::offset_of!(EmpyreanODConfig, max_iterations) - 192usize];
    ["Offset of field: EmpyreanODConfig::convergence_tol"]
        [::std::mem::offset_of!(EmpyreanODConfig, convergence_tol) - 200usize];
    ["Offset of field: EmpyreanODConfig::use_stm_cache"]
        [::std::mem::offset_of!(EmpyreanODConfig, use_stm_cache) - 208usize];
    ["Offset of field: EmpyreanODConfig::solve_for"]
        [::std::mem::offset_of!(EmpyreanODConfig, solve_for) - 212usize];
    ["Offset of field: EmpyreanODConfig::auto_escalation"]
        [::std::mem::offset_of!(EmpyreanODConfig, auto_escalation) - 216usize];
    ["Offset of field: EmpyreanODConfig::acceptability"]
        [::std::mem::offset_of!(EmpyreanODConfig, acceptability) - 248usize];
    ["Offset of field: EmpyreanODConfig::fit_station_biases"]
        [::std::mem::offset_of!(EmpyreanODConfig, fit_station_biases) - 288usize];
    ["Offset of field: EmpyreanODConfig::station_radec"]
        [::std::mem::offset_of!(EmpyreanODConfig, station_radec) - 296usize];
    ["Offset of field: EmpyreanODConfig::use_span_grouping"]
        [::std::mem::offset_of!(EmpyreanODConfig, use_span_grouping) - 312usize];
    ["Offset of field: EmpyreanODConfig::rejection"]
        [::std::mem::offset_of!(EmpyreanODConfig, rejection) - 320usize];
    ["Offset of field: EmpyreanODConfig::auto_force_model"]
        [::std::mem::offset_of!(EmpyreanODConfig, auto_force_model) - 376usize];
    ["Offset of field: EmpyreanODConfig::output_representation"]
        [::std::mem::offset_of!(EmpyreanODConfig, output_representation) - 380usize];
};
impl Default for EmpyreanODConfig {
    fn default() -> Self {
        let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
#[doc = " A single propagated Cartesian state."]
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct EmpyreanPropagatedState {
    pub epoch_mjd_tdb: f64,
    pub x: f64,
    pub y: f64,
    pub z: f64,
    pub vx: f64,
    pub vy: f64,
    pub vz: f64,
    pub origin: i32,
    pub frame: i32,
    pub covariance: [[f64; 6usize]; 6usize],
    pub has_covariance: u8,
    #[doc = " State Transition Matrix Φ(t, t₀). Zero-filled when `has_stm` is 0."]
    pub stm: [[f64; 6usize]; 6usize],
    pub has_stm: u8,
    #[doc = " State Transition Tensor Ψ(t, t₀). Zero-filled when `has_stt` is 0."]
    pub stt: [[[f64; 6usize]; 6usize]; 6usize],
    pub has_stt: u8,
    #[doc = " Resolved [`CovarianceKind`](empyrean_core::propagation::CovarianceKind)\n at this output epoch — see `EMPYREAN_COVARIANCE_KIND_*`.\n Defaults to `LINEAR` for non-Auto methods and for Auto epochs\n outside CA windows."]
    pub resolved_kind: u8,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanPropagatedState"]
        [::std::mem::size_of::<EmpyreanPropagatedState>() - 2392usize];
    ["Alignment of EmpyreanPropagatedState"]
        [::std::mem::align_of::<EmpyreanPropagatedState>() - 8usize];
    ["Offset of field: EmpyreanPropagatedState::epoch_mjd_tdb"]
        [::std::mem::offset_of!(EmpyreanPropagatedState, epoch_mjd_tdb) - 0usize];
    ["Offset of field: EmpyreanPropagatedState::x"]
        [::std::mem::offset_of!(EmpyreanPropagatedState, x) - 8usize];
    ["Offset of field: EmpyreanPropagatedState::y"]
        [::std::mem::offset_of!(EmpyreanPropagatedState, y) - 16usize];
    ["Offset of field: EmpyreanPropagatedState::z"]
        [::std::mem::offset_of!(EmpyreanPropagatedState, z) - 24usize];
    ["Offset of field: EmpyreanPropagatedState::vx"]
        [::std::mem::offset_of!(EmpyreanPropagatedState, vx) - 32usize];
    ["Offset of field: EmpyreanPropagatedState::vy"]
        [::std::mem::offset_of!(EmpyreanPropagatedState, vy) - 40usize];
    ["Offset of field: EmpyreanPropagatedState::vz"]
        [::std::mem::offset_of!(EmpyreanPropagatedState, vz) - 48usize];
    ["Offset of field: EmpyreanPropagatedState::origin"]
        [::std::mem::offset_of!(EmpyreanPropagatedState, origin) - 56usize];
    ["Offset of field: EmpyreanPropagatedState::frame"]
        [::std::mem::offset_of!(EmpyreanPropagatedState, frame) - 60usize];
    ["Offset of field: EmpyreanPropagatedState::covariance"]
        [::std::mem::offset_of!(EmpyreanPropagatedState, covariance) - 64usize];
    ["Offset of field: EmpyreanPropagatedState::has_covariance"]
        [::std::mem::offset_of!(EmpyreanPropagatedState, has_covariance) - 352usize];
    ["Offset of field: EmpyreanPropagatedState::stm"]
        [::std::mem::offset_of!(EmpyreanPropagatedState, stm) - 360usize];
    ["Offset of field: EmpyreanPropagatedState::has_stm"]
        [::std::mem::offset_of!(EmpyreanPropagatedState, has_stm) - 648usize];
    ["Offset of field: EmpyreanPropagatedState::stt"]
        [::std::mem::offset_of!(EmpyreanPropagatedState, stt) - 656usize];
    ["Offset of field: EmpyreanPropagatedState::has_stt"]
        [::std::mem::offset_of!(EmpyreanPropagatedState, has_stt) - 2384usize];
    ["Offset of field: EmpyreanPropagatedState::resolved_kind"]
        [::std::mem::offset_of!(EmpyreanPropagatedState, resolved_kind) - 2385usize];
};
#[doc = " Aggregate residual statistics.\n\n All angular quantities in arcseconds. NaN entries indicate the stat\n could not be computed (e.g. AT/CT RMS when no sky-motion rates were\n available, or weighted RMS when no weighting layer was active)."]
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct EmpyreanResidualSummary {
    pub num_obs: usize,
    pub num_selected: usize,
    pub num_rejected: usize,
    #[doc = " Total χ² over selected observations."]
    pub chi2: f64,
    #[doc = " Effective degrees of freedom (after subtracting solve-for params)."]
    pub dof: usize,
    #[doc = " Reduced χ² = chi2 / dof. NaN when dof ≤ 0."]
    pub reduced_chi2: f64,
    pub rms_ra_arcsec: f64,
    pub rms_dec_arcsec: f64,
    #[doc = " Combined RA·cosδ + Dec residual RMS (arcsec). Matches the\n find_orb / OrbFit `rms` reporting convention — a single\n number directly comparable across tools."]
    pub rms_combined_arcsec: f64,
    #[doc = " RMS weighted by the per-observation σ (matches scott's `weighted_rms`)."]
    pub weighted_rms_ra_arcsec: f64,
    pub weighted_rms_dec_arcsec: f64,
    #[doc = " Combined weighted RA·cosδ + Dec residual RMS (arcsec)."]
    pub weighted_rms_combined_arcsec: f64,
    pub mean_ra_arcsec: f64,
    pub mean_dec_arcsec: f64,
    pub std_ra_arcsec: f64,
    pub std_dec_arcsec: f64,
    #[doc = " RMS along-track residual (arcsec). NaN if no AT/CT data."]
    pub rms_along_track_arcsec: f64,
    #[doc = " RMS cross-track residual (arcsec). NaN if no AT/CT data."]
    pub rms_cross_track_arcsec: f64,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanResidualSummary"]
        [::std::mem::size_of::<EmpyreanResidualSummary>() - 144usize];
    ["Alignment of EmpyreanResidualSummary"]
        [::std::mem::align_of::<EmpyreanResidualSummary>() - 8usize];
    ["Offset of field: EmpyreanResidualSummary::num_obs"]
        [::std::mem::offset_of!(EmpyreanResidualSummary, num_obs) - 0usize];
    ["Offset of field: EmpyreanResidualSummary::num_selected"]
        [::std::mem::offset_of!(EmpyreanResidualSummary, num_selected) - 8usize];
    ["Offset of field: EmpyreanResidualSummary::num_rejected"]
        [::std::mem::offset_of!(EmpyreanResidualSummary, num_rejected) - 16usize];
    ["Offset of field: EmpyreanResidualSummary::chi2"]
        [::std::mem::offset_of!(EmpyreanResidualSummary, chi2) - 24usize];
    ["Offset of field: EmpyreanResidualSummary::dof"]
        [::std::mem::offset_of!(EmpyreanResidualSummary, dof) - 32usize];
    ["Offset of field: EmpyreanResidualSummary::reduced_chi2"]
        [::std::mem::offset_of!(EmpyreanResidualSummary, reduced_chi2) - 40usize];
    ["Offset of field: EmpyreanResidualSummary::rms_ra_arcsec"]
        [::std::mem::offset_of!(EmpyreanResidualSummary, rms_ra_arcsec) - 48usize];
    ["Offset of field: EmpyreanResidualSummary::rms_dec_arcsec"]
        [::std::mem::offset_of!(EmpyreanResidualSummary, rms_dec_arcsec) - 56usize];
    ["Offset of field: EmpyreanResidualSummary::rms_combined_arcsec"]
        [::std::mem::offset_of!(EmpyreanResidualSummary, rms_combined_arcsec) - 64usize];
    ["Offset of field: EmpyreanResidualSummary::weighted_rms_ra_arcsec"]
        [::std::mem::offset_of!(EmpyreanResidualSummary, weighted_rms_ra_arcsec) - 72usize];
    ["Offset of field: EmpyreanResidualSummary::weighted_rms_dec_arcsec"]
        [::std::mem::offset_of!(EmpyreanResidualSummary, weighted_rms_dec_arcsec) - 80usize];
    ["Offset of field: EmpyreanResidualSummary::weighted_rms_combined_arcsec"]
        [::std::mem::offset_of!(EmpyreanResidualSummary, weighted_rms_combined_arcsec) - 88usize];
    ["Offset of field: EmpyreanResidualSummary::mean_ra_arcsec"]
        [::std::mem::offset_of!(EmpyreanResidualSummary, mean_ra_arcsec) - 96usize];
    ["Offset of field: EmpyreanResidualSummary::mean_dec_arcsec"]
        [::std::mem::offset_of!(EmpyreanResidualSummary, mean_dec_arcsec) - 104usize];
    ["Offset of field: EmpyreanResidualSummary::std_ra_arcsec"]
        [::std::mem::offset_of!(EmpyreanResidualSummary, std_ra_arcsec) - 112usize];
    ["Offset of field: EmpyreanResidualSummary::std_dec_arcsec"]
        [::std::mem::offset_of!(EmpyreanResidualSummary, std_dec_arcsec) - 120usize];
    ["Offset of field: EmpyreanResidualSummary::rms_along_track_arcsec"]
        [::std::mem::offset_of!(EmpyreanResidualSummary, rms_along_track_arcsec) - 128usize];
    ["Offset of field: EmpyreanResidualSummary::rms_cross_track_arcsec"]
        [::std::mem::offset_of!(EmpyreanResidualSummary, rms_cross_track_arcsec) - 136usize];
};
#[doc = " A complete non-gravitational acceleration model, flattened for the C ABI.\n\n Mirrors the fields the input [`EmpyreanOrbit`] carries, so a fitted orbit's\n non-grav can be read back off [`EmpyreanODResult::non_grav`] and re-applied\n to an `EmpyreanOrbit` with no loss: the radial/transverse/normal\n coefficients (A1/A2/A3, AU/day²), the Marsden–Sekanina g(r) exponents\n (`ng_alpha`..`ng_k`; all-zero = inverse-square default), and the optional\n thermal-lag delay `non_grav_dt` (days, valid only when `has_dt = 1`)."]
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct EmpyreanNonGravParams {
    pub a1: f64,
    pub a2: f64,
    pub a3: f64,
    pub ng_alpha: f64,
    pub ng_r0: f64,
    pub ng_m: f64,
    pub ng_n: f64,
    pub ng_k: f64,
    #[doc = " 1 when `non_grav_dt` carries a thermal-lag delay; 0 otherwise."]
    pub has_dt: u8,
    #[doc = " g(r) evaluation time delay (days); only meaningful when `has_dt = 1`."]
    pub non_grav_dt: f64,
    #[doc = " 1 when `covariance` carries the fitted non-grav covariance; 0 otherwise."]
    pub has_covariance: u8,
    #[doc = " Fitted non-grav 3×3 covariance for (A1, A2, A3), row-major. Only\n meaningful when `has_covariance = 1`. Re-feeding it onto an input\n orbit lets a fitted orbit flow into a StateAndNonGrav refine without\n losing its non-grav prior (empyrean-wo4n)."]
    pub covariance: [[f64; 3usize]; 3usize],
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanNonGravParams"][::std::mem::size_of::<EmpyreanNonGravParams>() - 160usize];
    ["Alignment of EmpyreanNonGravParams"]
        [::std::mem::align_of::<EmpyreanNonGravParams>() - 8usize];
    ["Offset of field: EmpyreanNonGravParams::a1"]
        [::std::mem::offset_of!(EmpyreanNonGravParams, a1) - 0usize];
    ["Offset of field: EmpyreanNonGravParams::a2"]
        [::std::mem::offset_of!(EmpyreanNonGravParams, a2) - 8usize];
    ["Offset of field: EmpyreanNonGravParams::a3"]
        [::std::mem::offset_of!(EmpyreanNonGravParams, a3) - 16usize];
    ["Offset of field: EmpyreanNonGravParams::ng_alpha"]
        [::std::mem::offset_of!(EmpyreanNonGravParams, ng_alpha) - 24usize];
    ["Offset of field: EmpyreanNonGravParams::ng_r0"]
        [::std::mem::offset_of!(EmpyreanNonGravParams, ng_r0) - 32usize];
    ["Offset of field: EmpyreanNonGravParams::ng_m"]
        [::std::mem::offset_of!(EmpyreanNonGravParams, ng_m) - 40usize];
    ["Offset of field: EmpyreanNonGravParams::ng_n"]
        [::std::mem::offset_of!(EmpyreanNonGravParams, ng_n) - 48usize];
    ["Offset of field: EmpyreanNonGravParams::ng_k"]
        [::std::mem::offset_of!(EmpyreanNonGravParams, ng_k) - 56usize];
    ["Offset of field: EmpyreanNonGravParams::has_dt"]
        [::std::mem::offset_of!(EmpyreanNonGravParams, has_dt) - 64usize];
    ["Offset of field: EmpyreanNonGravParams::non_grav_dt"]
        [::std::mem::offset_of!(EmpyreanNonGravParams, non_grav_dt) - 72usize];
    ["Offset of field: EmpyreanNonGravParams::has_covariance"]
        [::std::mem::offset_of!(EmpyreanNonGravParams, has_covariance) - 80usize];
    ["Offset of field: EmpyreanNonGravParams::covariance"]
        [::std::mem::offset_of!(EmpyreanNonGravParams, covariance) - 88usize];
};
#[doc = " Acceptability sub-checks computed post-DC.\n\n Mirrors scott's [`AcceptabilityReport`](scott::od::AcceptabilityReport).\n Boolean fields are encoded as `u8` (0/1). When a value is unavailable\n (e.g. AT/CT ratio with no sky-motion rates), the `_value` is NaN and\n the corresponding `_ok` flag is 0. Always populated on\n [`EmpyreanODResult`]; on [`EmpyreanEvaluateResult`] the report is\n filled with NaN/0 because evaluate does not produce a fitted orbit."]
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct EmpyreanAcceptabilityReport {
    pub fit_acceptable: u8,
    pub extrapolation_acceptable: u8,
    pub converged_ok: u8,
    pub reduced_chi2_ok: u8,
    pub reduced_chi2_value: f64,
    pub reduced_chi2_threshold: f64,
    pub rms_ok: u8,
    pub rms_value_arcsec: f64,
    pub rms_threshold_arcsec: f64,
    pub residual_isotropy_ok: u8,
    pub at_ct_ratio_value: f64,
    pub at_ct_ratio_threshold: f64,
    pub covariance_ok: u8,
    pub arc_coverage_ok: u8,
    pub arc_days_value: f64,
    pub arc_days_threshold: f64,
    pub fractional_sigma_a_ok: u8,
    pub fractional_sigma_a_value: f64,
    pub fractional_sigma_a_threshold: f64,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanAcceptabilityReport"]
        [::std::mem::size_of::<EmpyreanAcceptabilityReport>() - 120usize];
    ["Alignment of EmpyreanAcceptabilityReport"]
        [::std::mem::align_of::<EmpyreanAcceptabilityReport>() - 8usize];
    ["Offset of field: EmpyreanAcceptabilityReport::fit_acceptable"]
        [::std::mem::offset_of!(EmpyreanAcceptabilityReport, fit_acceptable) - 0usize];
    ["Offset of field: EmpyreanAcceptabilityReport::extrapolation_acceptable"]
        [::std::mem::offset_of!(EmpyreanAcceptabilityReport, extrapolation_acceptable) - 1usize];
    ["Offset of field: EmpyreanAcceptabilityReport::converged_ok"]
        [::std::mem::offset_of!(EmpyreanAcceptabilityReport, converged_ok) - 2usize];
    ["Offset of field: EmpyreanAcceptabilityReport::reduced_chi2_ok"]
        [::std::mem::offset_of!(EmpyreanAcceptabilityReport, reduced_chi2_ok) - 3usize];
    ["Offset of field: EmpyreanAcceptabilityReport::reduced_chi2_value"]
        [::std::mem::offset_of!(EmpyreanAcceptabilityReport, reduced_chi2_value) - 8usize];
    ["Offset of field: EmpyreanAcceptabilityReport::reduced_chi2_threshold"]
        [::std::mem::offset_of!(EmpyreanAcceptabilityReport, reduced_chi2_threshold) - 16usize];
    ["Offset of field: EmpyreanAcceptabilityReport::rms_ok"]
        [::std::mem::offset_of!(EmpyreanAcceptabilityReport, rms_ok) - 24usize];
    ["Offset of field: EmpyreanAcceptabilityReport::rms_value_arcsec"]
        [::std::mem::offset_of!(EmpyreanAcceptabilityReport, rms_value_arcsec) - 32usize];
    ["Offset of field: EmpyreanAcceptabilityReport::rms_threshold_arcsec"]
        [::std::mem::offset_of!(EmpyreanAcceptabilityReport, rms_threshold_arcsec) - 40usize];
    ["Offset of field: EmpyreanAcceptabilityReport::residual_isotropy_ok"]
        [::std::mem::offset_of!(EmpyreanAcceptabilityReport, residual_isotropy_ok) - 48usize];
    ["Offset of field: EmpyreanAcceptabilityReport::at_ct_ratio_value"]
        [::std::mem::offset_of!(EmpyreanAcceptabilityReport, at_ct_ratio_value) - 56usize];
    ["Offset of field: EmpyreanAcceptabilityReport::at_ct_ratio_threshold"]
        [::std::mem::offset_of!(EmpyreanAcceptabilityReport, at_ct_ratio_threshold) - 64usize];
    ["Offset of field: EmpyreanAcceptabilityReport::covariance_ok"]
        [::std::mem::offset_of!(EmpyreanAcceptabilityReport, covariance_ok) - 72usize];
    ["Offset of field: EmpyreanAcceptabilityReport::arc_coverage_ok"]
        [::std::mem::offset_of!(EmpyreanAcceptabilityReport, arc_coverage_ok) - 73usize];
    ["Offset of field: EmpyreanAcceptabilityReport::arc_days_value"]
        [::std::mem::offset_of!(EmpyreanAcceptabilityReport, arc_days_value) - 80usize];
    ["Offset of field: EmpyreanAcceptabilityReport::arc_days_threshold"]
        [::std::mem::offset_of!(EmpyreanAcceptabilityReport, arc_days_threshold) - 88usize];
    ["Offset of field: EmpyreanAcceptabilityReport::fractional_sigma_a_ok"]
        [::std::mem::offset_of!(EmpyreanAcceptabilityReport, fractional_sigma_a_ok) - 96usize];
    ["Offset of field: EmpyreanAcceptabilityReport::fractional_sigma_a_value"]
        [::std::mem::offset_of!(EmpyreanAcceptabilityReport, fractional_sigma_a_value) - 104usize];
    ["Offset of field: EmpyreanAcceptabilityReport::fractional_sigma_a_threshold"][::std::mem::offset_of!(
        EmpyreanAcceptabilityReport,
        fractional_sigma_a_threshold
    ) - 112usize];
};
#[doc = " One per-station bias estimate from a Schur-eliminated nuisance fit.\n\n Mirrors [`scott::results::StationBias`]. Populated rows in the\n returned array correspond to stations that met the\n `min_obs_per_station` threshold; under-observed stations are absent.\n Timing fields are populated only when a `BiasKind::StationTiming`\n nuisance was active (currently no surface to enable it from the C\n ABI; reserved for the upcoming `empyrean-96r` follow-up).\n\n `obs_code` is heap-allocated and owned by the parent array — freed\n by [`empyrean_od_result_free`] when the result is freed. Don't free\n it manually."]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EmpyreanStationBias {
    pub obs_code: *mut ::std::os::raw::c_char,
    #[doc = " Pre-rejection observation count from this station."]
    pub n_obs: usize,
    pub bias_ra_arcsec: f64,
    pub sigma_ra_arcsec: f64,
    pub bias_dec_arcsec: f64,
    pub sigma_dec_arcsec: f64,
    #[doc = " 1 when the timing bias is populated; 0 otherwise. Reserved for\n the post-empyrean-96r `BiasKind::StationTiming` epic."]
    pub has_timing: u8,
    pub bias_timing_sec: f64,
    pub sigma_timing_sec: f64,
    #[doc = " Scalar significance: max of |bᵢ|/σᵢ across populated components."]
    pub significance: f64,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanStationBias"][::std::mem::size_of::<EmpyreanStationBias>() - 80usize];
    ["Alignment of EmpyreanStationBias"][::std::mem::align_of::<EmpyreanStationBias>() - 8usize];
    ["Offset of field: EmpyreanStationBias::obs_code"]
        [::std::mem::offset_of!(EmpyreanStationBias, obs_code) - 0usize];
    ["Offset of field: EmpyreanStationBias::n_obs"]
        [::std::mem::offset_of!(EmpyreanStationBias, n_obs) - 8usize];
    ["Offset of field: EmpyreanStationBias::bias_ra_arcsec"]
        [::std::mem::offset_of!(EmpyreanStationBias, bias_ra_arcsec) - 16usize];
    ["Offset of field: EmpyreanStationBias::sigma_ra_arcsec"]
        [::std::mem::offset_of!(EmpyreanStationBias, sigma_ra_arcsec) - 24usize];
    ["Offset of field: EmpyreanStationBias::bias_dec_arcsec"]
        [::std::mem::offset_of!(EmpyreanStationBias, bias_dec_arcsec) - 32usize];
    ["Offset of field: EmpyreanStationBias::sigma_dec_arcsec"]
        [::std::mem::offset_of!(EmpyreanStationBias, sigma_dec_arcsec) - 40usize];
    ["Offset of field: EmpyreanStationBias::has_timing"]
        [::std::mem::offset_of!(EmpyreanStationBias, has_timing) - 48usize];
    ["Offset of field: EmpyreanStationBias::bias_timing_sec"]
        [::std::mem::offset_of!(EmpyreanStationBias, bias_timing_sec) - 56usize];
    ["Offset of field: EmpyreanStationBias::sigma_timing_sec"]
        [::std::mem::offset_of!(EmpyreanStationBias, sigma_timing_sec) - 64usize];
    ["Offset of field: EmpyreanStationBias::significance"]
        [::std::mem::offset_of!(EmpyreanStationBias, significance) - 72usize];
};
impl Default for EmpyreanStationBias {
    fn default() -> Self {
        let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
#[doc = " Result of orbit determination (determine or refine).\n\n Mirrors scott's [`ODResult`](scott::od::ODResult). Carries the fitted\n orbit, the 6×6 (or 9×9 when non-grav was solved) formal covariance,\n the per-observation result array, the summary, the structured\n acceptability report, and the per-station nuisance-bias array\n when `fit_station_biases` was active.\n\n The fitted **absolute** non-gravitational model (when one was solved\n or carried) is exposed via [`has_non_grav`](EmpyreanODResult::has_non_grav)\n / [`non_grav`](EmpyreanODResult::non_grav) so the orbit can be re-fed into\n propagation / evaluate / refine without losing the force model. This is\n distinct from [`non_grav_delta`](EmpyreanODResult::non_grav_delta), which\n is the *cumulative correction* the fit applied and is kept for inspection."]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EmpyreanODResult {
    pub orbit: EmpyreanPropagatedState,
    pub observations: *mut EmpyreanObservationResult,
    pub num_observations: usize,
    pub summary: EmpyreanResidualSummary,
    pub iterations: u32,
    #[doc = " Convergence metric at the final DC iteration (Δx^T N Δx)."]
    pub update_norm: f64,
    #[doc = " Solver reached its stopping criterion (1 = yes).\n Equivalent to `acceptability.converged_ok`; kept for backwards\n compatibility with the v0.7.0 surface that pre-dated the\n structured acceptability report."]
    pub converged: u8,
    #[doc = " Fitted 6×6 state covariance in [`covariance_representation`]."]
    pub covariance: [[f64; 6usize]; 6usize],
    #[doc = " Coordinate basis the 6×6 / 9×9 covariance is reported in\n (`EMPYREAN_REPRESENTATION_*`)."]
    pub covariance_representation: i32,
    #[doc = " 1 when [`covariance_9x9`] is populated (non-grav was solved)."]
    pub has_covariance_9x9: u8,
    #[doc = " Full 9×9 covariance over (state, A1, A2, A3) when solving for non-grav."]
    pub covariance_9x9: [[f64; 9usize]; 9usize],
    #[doc = " 1 when [`non_grav_delta`] is populated."]
    pub has_non_grav_delta: u8,
    #[doc = " Cumulative non-grav parameter corrections (ΔA1, ΔA2, ΔA3) when solving for non-grav."]
    pub non_grav_delta: [f64; 3usize],
    #[doc = " 1 when [`non_grav`] carries a fitted/absolute non-gravitational model."]
    pub has_non_grav: u8,
    #[doc = " The fitted orbit's **absolute** non-gravitational model (A1/A2/A3 +\n g(r) exponents + optional thermal-lag `dt`). Re-feed this onto the\n orbit for propagation / evaluate / refine. Zeroed when the orbit is\n gravity-only (`has_non_grav = 0`)."]
    pub non_grav: EmpyreanNonGravParams,
    #[doc = " Number of rejection/refit passes performed."]
    pub rejection_passes: u32,
    #[doc = " Number of oppositions successfully fit."]
    pub num_oppositions_fit: u32,
    #[doc = " Force model tier actually used (0=Approximate, 1=Basic, 2=Standard)."]
    pub force_model_used: i32,
    #[doc = " Solve-for parameter set requested on the driving config\n (`EMPYREAN_SOLVE_FOR_*`). Together with `has_covariance_9x9`\n disambiguates Auto outcomes."]
    pub solve_for_used: i32,
    #[doc = " Structured fit-quality verdict. The `acceptable` flags can be\n checked directly; per-check values + thresholds are exposed for\n reporting and downstream sub-classification."]
    pub acceptability: EmpyreanAcceptabilityReport,
    #[doc = " Per-station fitted nuisance biases when [`EmpyreanODConfig::fit_station_biases`]\n was set. Owned heap allocation; freed by [`empyrean_od_result_free`].\n Null + `num_station_biases = 0` when no bias fit was configured."]
    pub station_biases: *mut EmpyreanStationBias,
    pub num_station_biases: usize,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanODResult"][::std::mem::size_of::<EmpyreanODResult>() - 3872usize];
    ["Alignment of EmpyreanODResult"][::std::mem::align_of::<EmpyreanODResult>() - 8usize];
    ["Offset of field: EmpyreanODResult::orbit"]
        [::std::mem::offset_of!(EmpyreanODResult, orbit) - 0usize];
    ["Offset of field: EmpyreanODResult::observations"]
        [::std::mem::offset_of!(EmpyreanODResult, observations) - 2392usize];
    ["Offset of field: EmpyreanODResult::num_observations"]
        [::std::mem::offset_of!(EmpyreanODResult, num_observations) - 2400usize];
    ["Offset of field: EmpyreanODResult::summary"]
        [::std::mem::offset_of!(EmpyreanODResult, summary) - 2408usize];
    ["Offset of field: EmpyreanODResult::iterations"]
        [::std::mem::offset_of!(EmpyreanODResult, iterations) - 2552usize];
    ["Offset of field: EmpyreanODResult::update_norm"]
        [::std::mem::offset_of!(EmpyreanODResult, update_norm) - 2560usize];
    ["Offset of field: EmpyreanODResult::converged"]
        [::std::mem::offset_of!(EmpyreanODResult, converged) - 2568usize];
    ["Offset of field: EmpyreanODResult::covariance"]
        [::std::mem::offset_of!(EmpyreanODResult, covariance) - 2576usize];
    ["Offset of field: EmpyreanODResult::covariance_representation"]
        [::std::mem::offset_of!(EmpyreanODResult, covariance_representation) - 2864usize];
    ["Offset of field: EmpyreanODResult::has_covariance_9x9"]
        [::std::mem::offset_of!(EmpyreanODResult, has_covariance_9x9) - 2868usize];
    ["Offset of field: EmpyreanODResult::covariance_9x9"]
        [::std::mem::offset_of!(EmpyreanODResult, covariance_9x9) - 2872usize];
    ["Offset of field: EmpyreanODResult::has_non_grav_delta"]
        [::std::mem::offset_of!(EmpyreanODResult, has_non_grav_delta) - 3520usize];
    ["Offset of field: EmpyreanODResult::non_grav_delta"]
        [::std::mem::offset_of!(EmpyreanODResult, non_grav_delta) - 3528usize];
    ["Offset of field: EmpyreanODResult::has_non_grav"]
        [::std::mem::offset_of!(EmpyreanODResult, has_non_grav) - 3552usize];
    ["Offset of field: EmpyreanODResult::non_grav"]
        [::std::mem::offset_of!(EmpyreanODResult, non_grav) - 3560usize];
    ["Offset of field: EmpyreanODResult::rejection_passes"]
        [::std::mem::offset_of!(EmpyreanODResult, rejection_passes) - 3720usize];
    ["Offset of field: EmpyreanODResult::num_oppositions_fit"]
        [::std::mem::offset_of!(EmpyreanODResult, num_oppositions_fit) - 3724usize];
    ["Offset of field: EmpyreanODResult::force_model_used"]
        [::std::mem::offset_of!(EmpyreanODResult, force_model_used) - 3728usize];
    ["Offset of field: EmpyreanODResult::solve_for_used"]
        [::std::mem::offset_of!(EmpyreanODResult, solve_for_used) - 3732usize];
    ["Offset of field: EmpyreanODResult::acceptability"]
        [::std::mem::offset_of!(EmpyreanODResult, acceptability) - 3736usize];
    ["Offset of field: EmpyreanODResult::station_biases"]
        [::std::mem::offset_of!(EmpyreanODResult, station_biases) - 3856usize];
    ["Offset of field: EmpyreanODResult::num_station_biases"]
        [::std::mem::offset_of!(EmpyreanODResult, num_station_biases) - 3864usize];
};
impl Default for EmpyreanODResult {
    fn default() -> Self {
        let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
#[doc = " Result of orbit evaluation (residuals without fitting).\n\n Same per-observation surface as [`EmpyreanODResult`] (rejection +\n influence fields are NaN / `NOT_EVALUATED` because evaluate does\n not run rejection or influence passes), but no fitted orbit or\n acceptability report."]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EmpyreanEvaluateResult {
    pub observations: *mut EmpyreanObservationResult,
    pub num_observations: usize,
    pub summary: EmpyreanResidualSummary,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanEvaluateResult"][::std::mem::size_of::<EmpyreanEvaluateResult>() - 160usize];
    ["Alignment of EmpyreanEvaluateResult"]
        [::std::mem::align_of::<EmpyreanEvaluateResult>() - 8usize];
    ["Offset of field: EmpyreanEvaluateResult::observations"]
        [::std::mem::offset_of!(EmpyreanEvaluateResult, observations) - 0usize];
    ["Offset of field: EmpyreanEvaluateResult::num_observations"]
        [::std::mem::offset_of!(EmpyreanEvaluateResult, num_observations) - 8usize];
    ["Offset of field: EmpyreanEvaluateResult::summary"]
        [::std::mem::offset_of!(EmpyreanEvaluateResult, summary) - 16usize];
};
impl Default for EmpyreanEvaluateResult {
    fn default() -> Self {
        let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
#[doc = " A single planned (candidate) observation: an epoch plus either an optical or\n a radar measurement spec. Optical fields are read when `kind == 0`, radar\n fields when `kind == 1`; absent optional radar target properties use NaN\n (the link budget refuses, rather than silently defaults, a missing value)."]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EmpyreanPlannedObservation {
    #[doc = " Planned (receive, for radar) epoch — MJD, TDB."]
    pub epoch_mjd_tdb: f64,
    #[doc = " 0 = optical, 1 = radar."]
    pub kind: u8,
    #[doc = " Optical: registered MPC station code (null-terminated UTF-8)."]
    pub optical_code: *const ::std::os::raw::c_char,
    #[doc = " Optical 1σ (RA·cosδ) uncertainty (arcsec)."]
    pub optical_sigma_ra_arcsec: f64,
    #[doc = " Optical 1σ Dec uncertainty (arcsec)."]
    pub optical_sigma_dec_arcsec: f64,
    #[doc = " Radar transmit dish preset: 0 = Goldstone DSS-14, 1 = Green Bank\n (receive-only), 2 = Arecibo (defunct — rejected loudly, never scheduled)."]
    pub radar_transmit_station: u8,
    #[doc = " Radar receive dish preset (same encoding; equal to transmit = monostatic)."]
    pub radar_receive_station: u8,
    #[doc = " Radar mode: 0 = Delay, 1 = Doppler, 2 = Both."]
    pub radar_mode: u8,
    #[doc = " Waveform bandwidth (Hz) — sets the delay (range) σ."]
    pub radar_bandwidth_hz: f64,
    #[doc = " Doppler frequency resolution (Hz) — sets the Doppler (range-rate) σ."]
    pub radar_freq_resolution_hz: f64,
    #[doc = " Supplied effective SNR (linear, not dB). NaN → compute from the link\n budget using the target properties + integration time below."]
    pub radar_snr: f64,
    #[doc = " Link-budget target absolute magnitude H (mag). NaN = absent."]
    pub radar_target_h_mag: f64,
    #[doc = " Link-budget target visual geometric albedo. NaN = absent."]
    pub radar_target_visual_albedo: f64,
    #[doc = " Link-budget target radar (OC) albedo. NaN = absent."]
    pub radar_target_radar_albedo: f64,
    #[doc = " Link-budget target effective diameter (km). NaN = absent."]
    pub radar_target_diameter_km: f64,
    #[doc = " Link-budget target rotation period (hours), caps coherent integration.\n NaN = absent."]
    pub radar_target_spin_period_hours: f64,
    #[doc = " Coherent integration time (s) for the link-budget SNR."]
    pub radar_integration_s: f64,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanPlannedObservation"]
        [::std::mem::size_of::<EmpyreanPlannedObservation>() - 120usize];
    ["Alignment of EmpyreanPlannedObservation"]
        [::std::mem::align_of::<EmpyreanPlannedObservation>() - 8usize];
    ["Offset of field: EmpyreanPlannedObservation::epoch_mjd_tdb"]
        [::std::mem::offset_of!(EmpyreanPlannedObservation, epoch_mjd_tdb) - 0usize];
    ["Offset of field: EmpyreanPlannedObservation::kind"]
        [::std::mem::offset_of!(EmpyreanPlannedObservation, kind) - 8usize];
    ["Offset of field: EmpyreanPlannedObservation::optical_code"]
        [::std::mem::offset_of!(EmpyreanPlannedObservation, optical_code) - 16usize];
    ["Offset of field: EmpyreanPlannedObservation::optical_sigma_ra_arcsec"]
        [::std::mem::offset_of!(EmpyreanPlannedObservation, optical_sigma_ra_arcsec) - 24usize];
    ["Offset of field: EmpyreanPlannedObservation::optical_sigma_dec_arcsec"]
        [::std::mem::offset_of!(EmpyreanPlannedObservation, optical_sigma_dec_arcsec) - 32usize];
    ["Offset of field: EmpyreanPlannedObservation::radar_transmit_station"]
        [::std::mem::offset_of!(EmpyreanPlannedObservation, radar_transmit_station) - 40usize];
    ["Offset of field: EmpyreanPlannedObservation::radar_receive_station"]
        [::std::mem::offset_of!(EmpyreanPlannedObservation, radar_receive_station) - 41usize];
    ["Offset of field: EmpyreanPlannedObservation::radar_mode"]
        [::std::mem::offset_of!(EmpyreanPlannedObservation, radar_mode) - 42usize];
    ["Offset of field: EmpyreanPlannedObservation::radar_bandwidth_hz"]
        [::std::mem::offset_of!(EmpyreanPlannedObservation, radar_bandwidth_hz) - 48usize];
    ["Offset of field: EmpyreanPlannedObservation::radar_freq_resolution_hz"]
        [::std::mem::offset_of!(EmpyreanPlannedObservation, radar_freq_resolution_hz) - 56usize];
    ["Offset of field: EmpyreanPlannedObservation::radar_snr"]
        [::std::mem::offset_of!(EmpyreanPlannedObservation, radar_snr) - 64usize];
    ["Offset of field: EmpyreanPlannedObservation::radar_target_h_mag"]
        [::std::mem::offset_of!(EmpyreanPlannedObservation, radar_target_h_mag) - 72usize];
    ["Offset of field: EmpyreanPlannedObservation::radar_target_visual_albedo"]
        [::std::mem::offset_of!(EmpyreanPlannedObservation, radar_target_visual_albedo) - 80usize];
    ["Offset of field: EmpyreanPlannedObservation::radar_target_radar_albedo"]
        [::std::mem::offset_of!(EmpyreanPlannedObservation, radar_target_radar_albedo) - 88usize];
    ["Offset of field: EmpyreanPlannedObservation::radar_target_diameter_km"]
        [::std::mem::offset_of!(EmpyreanPlannedObservation, radar_target_diameter_km) - 96usize];
    ["Offset of field: EmpyreanPlannedObservation::radar_target_spin_period_hours"][::std::mem::offset_of!(
        EmpyreanPlannedObservation,
        radar_target_spin_period_hours
    ) - 104usize];
    ["Offset of field: EmpyreanPlannedObservation::radar_integration_s"]
        [::std::mem::offset_of!(EmpyreanPlannedObservation, radar_integration_s) - 112usize];
};
impl Default for EmpyreanPlannedObservation {
    fn default() -> Self {
        let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
#[doc = " Per-observatory assumptions: astrometric σ + observability filters."]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EmpyreanObservatoryConfig {
    #[doc = " MPC observatory code (null-terminated UTF-8)."]
    pub obs_code: *const ::std::os::raw::c_char,
    #[doc = " 1σ (RA·cosδ) astrometric uncertainty (arcsec)."]
    pub sigma_ra_arcsec: f64,
    #[doc = " 1σ Dec astrometric uncertainty (arcsec)."]
    pub sigma_dec_arcsec: f64,
    #[doc = " Limiting apparent magnitude."]
    pub max_apparent_mag: f64,
    #[doc = " Minimum solar elongation (degrees)."]
    pub min_elongation_deg: f64,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanObservatoryConfig"]
        [::std::mem::size_of::<EmpyreanObservatoryConfig>() - 40usize];
    ["Alignment of EmpyreanObservatoryConfig"]
        [::std::mem::align_of::<EmpyreanObservatoryConfig>() - 8usize];
    ["Offset of field: EmpyreanObservatoryConfig::obs_code"]
        [::std::mem::offset_of!(EmpyreanObservatoryConfig, obs_code) - 0usize];
    ["Offset of field: EmpyreanObservatoryConfig::sigma_ra_arcsec"]
        [::std::mem::offset_of!(EmpyreanObservatoryConfig, sigma_ra_arcsec) - 8usize];
    ["Offset of field: EmpyreanObservatoryConfig::sigma_dec_arcsec"]
        [::std::mem::offset_of!(EmpyreanObservatoryConfig, sigma_dec_arcsec) - 16usize];
    ["Offset of field: EmpyreanObservatoryConfig::max_apparent_mag"]
        [::std::mem::offset_of!(EmpyreanObservatoryConfig, max_apparent_mag) - 24usize];
    ["Offset of field: EmpyreanObservatoryConfig::min_elongation_deg"]
        [::std::mem::offset_of!(EmpyreanObservatoryConfig, min_elongation_deg) - 32usize];
};
impl Default for EmpyreanObservatoryConfig {
    fn default() -> Self {
        let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
#[doc = " Planning configuration: force model, integration tolerance, the\n per-observatory astrometric assumptions, and threading."]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EmpyreanPlanningConfig {
    #[doc = " Force-model tier: 0 = Approximate, 1 = Basic, 2 = Standard."]
    pub force_model: i32,
    #[doc = " GR15 / IAS15 integration tolerance."]
    pub epsilon: f64,
    #[doc = " Per-observatory config array."]
    pub observatories: *const EmpyreanObservatoryConfig,
    #[doc = " Number of entries in `observatories`."]
    pub num_observatories: usize,
    #[doc = " Threads for batch operations; -1 = all CPUs."]
    pub num_threads: i32,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanPlanningConfig"][::std::mem::size_of::<EmpyreanPlanningConfig>() - 40usize];
    ["Alignment of EmpyreanPlanningConfig"]
        [::std::mem::align_of::<EmpyreanPlanningConfig>() - 8usize];
    ["Offset of field: EmpyreanPlanningConfig::force_model"]
        [::std::mem::offset_of!(EmpyreanPlanningConfig, force_model) - 0usize];
    ["Offset of field: EmpyreanPlanningConfig::epsilon"]
        [::std::mem::offset_of!(EmpyreanPlanningConfig, epsilon) - 8usize];
    ["Offset of field: EmpyreanPlanningConfig::observatories"]
        [::std::mem::offset_of!(EmpyreanPlanningConfig, observatories) - 16usize];
    ["Offset of field: EmpyreanPlanningConfig::num_observatories"]
        [::std::mem::offset_of!(EmpyreanPlanningConfig, num_observatories) - 24usize];
    ["Offset of field: EmpyreanPlanningConfig::num_threads"]
        [::std::mem::offset_of!(EmpyreanPlanningConfig, num_threads) - 32usize];
};
impl Default for EmpyreanPlanningConfig {
    fn default() -> Self {
        let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
#[doc = " Covariance summary metrics (prior, posterior, or per-candidate cumulative)."]
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct EmpyreanCovarianceMetrics {
    #[doc = " RSS position 1σ (km)."]
    pub position_sigma_km: f64,
    #[doc = " RSS velocity 1σ (m/s) — the rendezvous-Δv-knowledge term."]
    pub velocity_sigma_m_s: f64,
    #[doc = " Semi-major axis of the 1σ position ellipsoid (km)."]
    pub semi_major_km: f64,
    #[doc = " Semi-minor axis of the 1σ position ellipsoid (km)."]
    pub semi_minor_km: f64,
    #[doc = " ln(det(Σ)) — D-optimality criterion."]
    pub log_det: f64,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanCovarianceMetrics"]
        [::std::mem::size_of::<EmpyreanCovarianceMetrics>() - 40usize];
    ["Alignment of EmpyreanCovarianceMetrics"]
        [::std::mem::align_of::<EmpyreanCovarianceMetrics>() - 8usize];
    ["Offset of field: EmpyreanCovarianceMetrics::position_sigma_km"]
        [::std::mem::offset_of!(EmpyreanCovarianceMetrics, position_sigma_km) - 0usize];
    ["Offset of field: EmpyreanCovarianceMetrics::velocity_sigma_m_s"]
        [::std::mem::offset_of!(EmpyreanCovarianceMetrics, velocity_sigma_m_s) - 8usize];
    ["Offset of field: EmpyreanCovarianceMetrics::semi_major_km"]
        [::std::mem::offset_of!(EmpyreanCovarianceMetrics, semi_major_km) - 16usize];
    ["Offset of field: EmpyreanCovarianceMetrics::semi_minor_km"]
        [::std::mem::offset_of!(EmpyreanCovarianceMetrics, semi_minor_km) - 24usize];
    ["Offset of field: EmpyreanCovarianceMetrics::log_det"]
        [::std::mem::offset_of!(EmpyreanCovarianceMetrics, log_det) - 32usize];
};
#[doc = " Per-candidate information-gain analysis."]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EmpyreanPlanCandidate {
    #[doc = " Index into the planned-observation list."]
    pub index: usize,
    #[doc = " Observatory / receive-station code (owned; freed by\n `empyrean_plan_result_free`)."]
    pub obs_code: *mut ::std::os::raw::c_char,
    #[doc = " 0 = optical, 1 = radar."]
    pub kind: u8,
    #[doc = " 1 if observable at this epoch (passes the filters / has positive SNR)."]
    pub observable: u8,
    #[doc = " Sky-plane along-track 1σ (arcsec) — optical geometry (NaN for radar)."]
    pub along_track_sigma_arcsec: f64,
    #[doc = " Sky-plane cross-track 1σ (arcsec)."]
    pub cross_track_sigma_arcsec: f64,
    #[doc = " Predicted RA·cosδ 1σ (arcsec)."]
    pub ra_sigma_arcsec: f64,
    #[doc = " Predicted Dec 1σ (arcsec)."]
    pub dec_sigma_arcsec: f64,
    #[doc = " Position angle of the sky-plane uncertainty ellipse (degrees)."]
    pub position_angle_deg: f64,
    #[doc = " Marginal covariance-volume reduction factor from this observation (≤ 1)."]
    pub marginal_volume_reduction: f64,
    #[doc = " Fractional position-σ improvement from this observation (∈ [0, 1])."]
    pub marginal_position_improvement: f64,
    #[doc = " Post-observation along-track 1σ (arcsec)."]
    pub post_along_track_sigma_arcsec: f64,
    #[doc = " Post-observation cross-track 1σ (arcsec)."]
    pub post_cross_track_sigma_arcsec: f64,
    #[doc = " Covariance metrics after folding this observation and all prior ones."]
    pub cumulative: EmpyreanCovarianceMetrics,
    #[doc = " Active solve-for width (6 = state-only)."]
    pub active_width: usize,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanPlanCandidate"][::std::mem::size_of::<EmpyreanPlanCandidate>() - 144usize];
    ["Alignment of EmpyreanPlanCandidate"]
        [::std::mem::align_of::<EmpyreanPlanCandidate>() - 8usize];
    ["Offset of field: EmpyreanPlanCandidate::index"]
        [::std::mem::offset_of!(EmpyreanPlanCandidate, index) - 0usize];
    ["Offset of field: EmpyreanPlanCandidate::obs_code"]
        [::std::mem::offset_of!(EmpyreanPlanCandidate, obs_code) - 8usize];
    ["Offset of field: EmpyreanPlanCandidate::kind"]
        [::std::mem::offset_of!(EmpyreanPlanCandidate, kind) - 16usize];
    ["Offset of field: EmpyreanPlanCandidate::observable"]
        [::std::mem::offset_of!(EmpyreanPlanCandidate, observable) - 17usize];
    ["Offset of field: EmpyreanPlanCandidate::along_track_sigma_arcsec"]
        [::std::mem::offset_of!(EmpyreanPlanCandidate, along_track_sigma_arcsec) - 24usize];
    ["Offset of field: EmpyreanPlanCandidate::cross_track_sigma_arcsec"]
        [::std::mem::offset_of!(EmpyreanPlanCandidate, cross_track_sigma_arcsec) - 32usize];
    ["Offset of field: EmpyreanPlanCandidate::ra_sigma_arcsec"]
        [::std::mem::offset_of!(EmpyreanPlanCandidate, ra_sigma_arcsec) - 40usize];
    ["Offset of field: EmpyreanPlanCandidate::dec_sigma_arcsec"]
        [::std::mem::offset_of!(EmpyreanPlanCandidate, dec_sigma_arcsec) - 48usize];
    ["Offset of field: EmpyreanPlanCandidate::position_angle_deg"]
        [::std::mem::offset_of!(EmpyreanPlanCandidate, position_angle_deg) - 56usize];
    ["Offset of field: EmpyreanPlanCandidate::marginal_volume_reduction"]
        [::std::mem::offset_of!(EmpyreanPlanCandidate, marginal_volume_reduction) - 64usize];
    ["Offset of field: EmpyreanPlanCandidate::marginal_position_improvement"]
        [::std::mem::offset_of!(EmpyreanPlanCandidate, marginal_position_improvement) - 72usize];
    ["Offset of field: EmpyreanPlanCandidate::post_along_track_sigma_arcsec"]
        [::std::mem::offset_of!(EmpyreanPlanCandidate, post_along_track_sigma_arcsec) - 80usize];
    ["Offset of field: EmpyreanPlanCandidate::post_cross_track_sigma_arcsec"]
        [::std::mem::offset_of!(EmpyreanPlanCandidate, post_cross_track_sigma_arcsec) - 88usize];
    ["Offset of field: EmpyreanPlanCandidate::cumulative"]
        [::std::mem::offset_of!(EmpyreanPlanCandidate, cumulative) - 96usize];
    ["Offset of field: EmpyreanPlanCandidate::active_width"]
        [::std::mem::offset_of!(EmpyreanPlanCandidate, active_width) - 136usize];
};
impl Default for EmpyreanPlanCandidate {
    fn default() -> Self {
        let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
#[doc = " Result of a plan evaluation. The caller allocates the struct; the\n `orbit_id` string and the `candidates` array (with their `obs_code`\n strings) are heap-allocated here and must be released with\n [`empyrean_plan_result_free`]."]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EmpyreanPlanResult {
    #[doc = " Orbit identifier (owned)."]
    pub orbit_id: *mut ::std::os::raw::c_char,
    #[doc = " Prior (pre-observation) covariance metrics."]
    pub prior: EmpyreanCovarianceMetrics,
    #[doc = " Posterior (all candidates folded) covariance metrics."]
    pub posterior: EmpyreanCovarianceMetrics,
    #[doc = " Per-candidate analysis array (owned)."]
    pub candidates: *mut EmpyreanPlanCandidate,
    #[doc = " Number of entries in `candidates`."]
    pub num_candidates: usize,
    #[doc = " Active solve-for width (6 = state-only)."]
    pub active_width: usize,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanPlanResult"][::std::mem::size_of::<EmpyreanPlanResult>() - 112usize];
    ["Alignment of EmpyreanPlanResult"][::std::mem::align_of::<EmpyreanPlanResult>() - 8usize];
    ["Offset of field: EmpyreanPlanResult::orbit_id"]
        [::std::mem::offset_of!(EmpyreanPlanResult, orbit_id) - 0usize];
    ["Offset of field: EmpyreanPlanResult::prior"]
        [::std::mem::offset_of!(EmpyreanPlanResult, prior) - 8usize];
    ["Offset of field: EmpyreanPlanResult::posterior"]
        [::std::mem::offset_of!(EmpyreanPlanResult, posterior) - 48usize];
    ["Offset of field: EmpyreanPlanResult::candidates"]
        [::std::mem::offset_of!(EmpyreanPlanResult, candidates) - 88usize];
    ["Offset of field: EmpyreanPlanResult::num_candidates"]
        [::std::mem::offset_of!(EmpyreanPlanResult, num_candidates) - 96usize];
    ["Offset of field: EmpyreanPlanResult::active_width"]
        [::std::mem::offset_of!(EmpyreanPlanResult, active_width) - 104usize];
};
impl Default for EmpyreanPlanResult {
    fn default() -> Self {
        let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
#[doc = " One Gaussian sub-component of an AGM mixture decomposition.\n\n Mirrors\n [`empyrean_core::propagation::MixtureComponent`]. The mean carries\n the *propagated* sub-Gaussian centroid at the CA epoch (f64 from\n the Jet2 integrator); the covariance is the linearly-mapped\n \\\\(\\Phi \\, \\Sigma_k \\, \\Phi^\\top\\\\) over the same propagation\n segment. A consumer can evaluate\n \\\\(\\sum_k w_k \\\\, \\mathcal{N}(x \\mid \\mu_k, \\Sigma_k)\\\\) directly\n at the CA epoch."]
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct EmpyreanMixtureComponent {
    pub weight: f64,
    pub mean: [f64; 6usize],
    pub covariance: [[f64; 6usize]; 6usize],
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanMixtureComponent"]
        [::std::mem::size_of::<EmpyreanMixtureComponent>() - 344usize];
    ["Alignment of EmpyreanMixtureComponent"]
        [::std::mem::align_of::<EmpyreanMixtureComponent>() - 8usize];
    ["Offset of field: EmpyreanMixtureComponent::weight"]
        [::std::mem::offset_of!(EmpyreanMixtureComponent, weight) - 0usize];
    ["Offset of field: EmpyreanMixtureComponent::mean"]
        [::std::mem::offset_of!(EmpyreanMixtureComponent, mean) - 8usize];
    ["Offset of field: EmpyreanMixtureComponent::covariance"]
        [::std::mem::offset_of!(EmpyreanMixtureComponent, covariance) - 56usize];
};
#[doc = " Per-orbit AGM mixture decomposition retained by Auto / Mixture.\n\n Mirrors [`empyrean_core::propagation::MixtureChain`] in flat form.\n `ca_epochs_mjd_tdb` and `components_per_epoch` are\n `num_ca_epochs`-length parallel arrays. Components are flattened\n into a single `components` array — for CA index `k`, the slice is\n `components[components_offset[k] .. components_offset[k] +\n components_per_epoch[k]]`. `components_offset[k]` is the\n prefix-sum of `components_per_epoch[0..k]` (so\n `components_offset[0] == 0`).\n\n Only orbits whose AGM splits actually fired carry a chain;\n non-mixture orbits get one entry whose `num_ca_epochs == 0` and\n whose pointers are null."]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EmpyreanMixtureChain {
    #[doc = " Owning C string — caller frees via `*_result_free`."]
    pub orbit_id: *mut ::std::os::raw::c_char,
    #[doc = " `num_ca_epochs`-length array of CA epochs (mjd_tdb)."]
    pub ca_epochs_mjd_tdb: *mut f64,
    pub num_ca_epochs: usize,
    #[doc = " `num_ca_epochs`-length array of per-epoch component counts."]
    pub components_per_epoch: *mut usize,
    #[doc = " `num_ca_epochs`-length array of starting offsets into the\n flattened `components` array. `components_offset[k]` is the\n prefix-sum of `components_per_epoch[0..k]`."]
    pub components_offset: *mut usize,
    #[doc = " Flattened components — total length =\n sum(components_per_epoch)."]
    pub components: *mut EmpyreanMixtureComponent,
    pub num_components_total: usize,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanMixtureChain"][::std::mem::size_of::<EmpyreanMixtureChain>() - 56usize];
    ["Alignment of EmpyreanMixtureChain"][::std::mem::align_of::<EmpyreanMixtureChain>() - 8usize];
    ["Offset of field: EmpyreanMixtureChain::orbit_id"]
        [::std::mem::offset_of!(EmpyreanMixtureChain, orbit_id) - 0usize];
    ["Offset of field: EmpyreanMixtureChain::ca_epochs_mjd_tdb"]
        [::std::mem::offset_of!(EmpyreanMixtureChain, ca_epochs_mjd_tdb) - 8usize];
    ["Offset of field: EmpyreanMixtureChain::num_ca_epochs"]
        [::std::mem::offset_of!(EmpyreanMixtureChain, num_ca_epochs) - 16usize];
    ["Offset of field: EmpyreanMixtureChain::components_per_epoch"]
        [::std::mem::offset_of!(EmpyreanMixtureChain, components_per_epoch) - 24usize];
    ["Offset of field: EmpyreanMixtureChain::components_offset"]
        [::std::mem::offset_of!(EmpyreanMixtureChain, components_offset) - 32usize];
    ["Offset of field: EmpyreanMixtureChain::components"]
        [::std::mem::offset_of!(EmpyreanMixtureChain, components) - 40usize];
    ["Offset of field: EmpyreanMixtureChain::num_components_total"]
        [::std::mem::offset_of!(EmpyreanMixtureChain, num_components_total) - 48usize];
};
impl Default for EmpyreanMixtureChain {
    fn default() -> Self {
        let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
#[doc = " Propagation result containing states, events, and object identifiers.\n\n `mixtures` parallels `object_ids` only when populated — it is\n per-orbit (not per-state), so its length is the distinct orbit\n count, not `num_states`."]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EmpyreanPropagationResult {
    pub states: *mut EmpyreanPropagatedState,
    pub num_states: usize,
    pub object_ids: *mut *mut ::std::os::raw::c_char,
    pub events: *mut EmpyreanEvent,
    pub num_events: usize,
    #[doc = " One [`EmpyreanMixtureChain`] per input orbit (positional with\n the input orbit batch). Empty / null when no orbits produced\n mixtures (the typical case for FirstOrder / SecondOrder /\n SigmaPoint / MonteCarlo)."]
    pub mixtures: *mut EmpyreanMixtureChain,
    pub num_mixtures: usize,
    #[doc = " Opaque retained handle to the rich propagation result, enabling\n the on-demand tagged-covariance accessors\n (`empyrean_propagation_covariance_series_cartesian` /\n `_covariance_at_cartesian`). **Do not dereference from C** — it is\n freed by `empyrean_propagation_result_free`. Null when the\n propagation produced no retainable result."]
    pub lazy_handle: *mut ::std::os::raw::c_void,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanPropagationResult"]
        [::std::mem::size_of::<EmpyreanPropagationResult>() - 64usize];
    ["Alignment of EmpyreanPropagationResult"]
        [::std::mem::align_of::<EmpyreanPropagationResult>() - 8usize];
    ["Offset of field: EmpyreanPropagationResult::states"]
        [::std::mem::offset_of!(EmpyreanPropagationResult, states) - 0usize];
    ["Offset of field: EmpyreanPropagationResult::num_states"]
        [::std::mem::offset_of!(EmpyreanPropagationResult, num_states) - 8usize];
    ["Offset of field: EmpyreanPropagationResult::object_ids"]
        [::std::mem::offset_of!(EmpyreanPropagationResult, object_ids) - 16usize];
    ["Offset of field: EmpyreanPropagationResult::events"]
        [::std::mem::offset_of!(EmpyreanPropagationResult, events) - 24usize];
    ["Offset of field: EmpyreanPropagationResult::num_events"]
        [::std::mem::offset_of!(EmpyreanPropagationResult, num_events) - 32usize];
    ["Offset of field: EmpyreanPropagationResult::mixtures"]
        [::std::mem::offset_of!(EmpyreanPropagationResult, mixtures) - 40usize];
    ["Offset of field: EmpyreanPropagationResult::num_mixtures"]
        [::std::mem::offset_of!(EmpyreanPropagationResult, num_mixtures) - 48usize];
    ["Offset of field: EmpyreanPropagationResult::lazy_handle"]
        [::std::mem::offset_of!(EmpyreanPropagationResult, lazy_handle) - 56usize];
};
impl Default for EmpyreanPropagationResult {
    fn default() -> Self {
        let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
#[doc = " Flattened, owned form of `empyrean_core::propagation::TaggedCovariance`\n (villeneuve's provenance-tagged covariance). Self-describing: the 6×6\n matrix together with the co-located nominal state, how the covariance\n was derived, its definiteness, its basis, the solved-for parameters,\n and the functional it describes — so a consumer can never read a\n second-order CA ellipsoid as a linear one.\n\n NOTE on the `_cartesian` accessor's reachable range: that accessor\n classifies but never repairs (`quality` ∈ {POSITIVE_DEFINITE,\n INDEFINITE}), is always state-only (`solved_width == 6`,\n `target_functional == CARTESIAN_STATE`, `has_mean_shift_input == 0`),\n and resolves Monte-Carlo epochs to an error rather than a row. The\n constant fields are carried for the future element-space / off-grid /\n CA-window accessors that *do* vary them."]
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct EmpyreanTaggedCovariance {
    #[doc = " Epoch of this covariance (TDB)."]
    pub epoch_mjd_tdb: f64,
    #[doc = " Propagated nominal state [x, y, z, vx, vy, vz] (AU, AU/day),\n co-located engine-side. The CORRECTED mean is\n `state + (has_mean_shift_prop ? mean_shift_prop : 0)\n        + (has_mean_shift_input ? mean_shift_input : 0)`."]
    pub state: [f64; 6usize],
    #[doc = " The 6×6 covariance (AU², AU²/day, AU²/day² blocks)."]
    pub matrix: [[f64; 6usize]; 6usize],
    #[doc = " `EMPYREAN_COVARIANCE_KIND_*`."]
    pub kind: u8,
    #[doc = " RNG seed — valid iff `has_mc_seed == 1` (kind == MONTE_CARLO)."]
    pub mc_seed: u64,
    #[doc = " Disambiguates a real `mc_seed == 0` from \"no seed\". 0 on the\n `_cartesian` accessor (MC resolves to an error there)."]
    pub has_mc_seed: u8,
    #[doc = " Second-order propagation mean shift δμ_prop (zero at t₀).\n Zero-filled when `has_mean_shift_prop == 0`."]
    pub mean_shift_prop: [f64; 6usize],
    pub has_mean_shift_prop: u8,
    #[doc = " OD-estimator mean shift δμ₀ (nonzero at t₀). Zero-filled when\n `has_mean_shift_input == 0` (always 0 on the `_cartesian` accessor)."]
    pub mean_shift_input: [f64; 6usize],
    pub has_mean_shift_input: u8,
    #[doc = " `EMPYREAN_COVARIANCE_QUALITY_*`."]
    pub quality: u8,
    #[doc = " `min_eig` for INDEFINITE / REPAIRED; `f64::NAN` for\n POSITIVE_DEFINITE. **Read-only provenance** — `isnan`-guard before\n any arithmetic; never feed to a clamp."]
    pub quality_min_eig: f64,
    #[doc = " `EMPYREAN_REPRESENTATION_*` (always CARTESIAN=0 on this accessor)."]
    pub representation: i32,
    #[doc = " Frame, same encoding as `EmpyreanPropagatedState.frame`."]
    pub frame: i32,
    #[doc = " Origin NAIF id, same encoding as `EmpyreanPropagatedState.origin`."]
    pub origin: i32,
    #[doc = " [A1, A2, A3] non-grav solved flags (0/1). The returned 6×6 is the\n MARGINALIZED state block of a possibly-wider fit."]
    pub non_grav: [u8; 3usize],
    #[doc = " Thrust Δv segments solved for."]
    pub thrust_segments: u32,
    #[doc = " `TaggedCovariance::solved_width()` (6 / 9 / 12 / …) — the scalar\n IP consumers key on (6 on this accessor)."]
    pub solved_width: u32,
    #[doc = " `EMPYREAN_TARGET_FUNCTIONAL_*` (always CARTESIAN_STATE on this accessor)."]
    pub target_functional: u8,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanTaggedCovariance"]
        [::std::mem::size_of::<EmpyreanTaggedCovariance>() - 520usize];
    ["Alignment of EmpyreanTaggedCovariance"]
        [::std::mem::align_of::<EmpyreanTaggedCovariance>() - 8usize];
    ["Offset of field: EmpyreanTaggedCovariance::epoch_mjd_tdb"]
        [::std::mem::offset_of!(EmpyreanTaggedCovariance, epoch_mjd_tdb) - 0usize];
    ["Offset of field: EmpyreanTaggedCovariance::state"]
        [::std::mem::offset_of!(EmpyreanTaggedCovariance, state) - 8usize];
    ["Offset of field: EmpyreanTaggedCovariance::matrix"]
        [::std::mem::offset_of!(EmpyreanTaggedCovariance, matrix) - 56usize];
    ["Offset of field: EmpyreanTaggedCovariance::kind"]
        [::std::mem::offset_of!(EmpyreanTaggedCovariance, kind) - 344usize];
    ["Offset of field: EmpyreanTaggedCovariance::mc_seed"]
        [::std::mem::offset_of!(EmpyreanTaggedCovariance, mc_seed) - 352usize];
    ["Offset of field: EmpyreanTaggedCovariance::has_mc_seed"]
        [::std::mem::offset_of!(EmpyreanTaggedCovariance, has_mc_seed) - 360usize];
    ["Offset of field: EmpyreanTaggedCovariance::mean_shift_prop"]
        [::std::mem::offset_of!(EmpyreanTaggedCovariance, mean_shift_prop) - 368usize];
    ["Offset of field: EmpyreanTaggedCovariance::has_mean_shift_prop"]
        [::std::mem::offset_of!(EmpyreanTaggedCovariance, has_mean_shift_prop) - 416usize];
    ["Offset of field: EmpyreanTaggedCovariance::mean_shift_input"]
        [::std::mem::offset_of!(EmpyreanTaggedCovariance, mean_shift_input) - 424usize];
    ["Offset of field: EmpyreanTaggedCovariance::has_mean_shift_input"]
        [::std::mem::offset_of!(EmpyreanTaggedCovariance, has_mean_shift_input) - 472usize];
    ["Offset of field: EmpyreanTaggedCovariance::quality"]
        [::std::mem::offset_of!(EmpyreanTaggedCovariance, quality) - 473usize];
    ["Offset of field: EmpyreanTaggedCovariance::quality_min_eig"]
        [::std::mem::offset_of!(EmpyreanTaggedCovariance, quality_min_eig) - 480usize];
    ["Offset of field: EmpyreanTaggedCovariance::representation"]
        [::std::mem::offset_of!(EmpyreanTaggedCovariance, representation) - 488usize];
    ["Offset of field: EmpyreanTaggedCovariance::frame"]
        [::std::mem::offset_of!(EmpyreanTaggedCovariance, frame) - 492usize];
    ["Offset of field: EmpyreanTaggedCovariance::origin"]
        [::std::mem::offset_of!(EmpyreanTaggedCovariance, origin) - 496usize];
    ["Offset of field: EmpyreanTaggedCovariance::non_grav"]
        [::std::mem::offset_of!(EmpyreanTaggedCovariance, non_grav) - 500usize];
    ["Offset of field: EmpyreanTaggedCovariance::thrust_segments"]
        [::std::mem::offset_of!(EmpyreanTaggedCovariance, thrust_segments) - 504usize];
    ["Offset of field: EmpyreanTaggedCovariance::solved_width"]
        [::std::mem::offset_of!(EmpyreanTaggedCovariance, solved_width) - 508usize];
    ["Offset of field: EmpyreanTaggedCovariance::target_functional"]
        [::std::mem::offset_of!(EmpyreanTaggedCovariance, target_functional) - 512usize];
};
#[doc = " Owned series of [`EmpyreanTaggedCovariance`], one entry per output\n epoch. Free with [`empyrean_tagged_covariance_series_free`]."]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EmpyreanTaggedCovarianceSeries {
    pub entries: *mut EmpyreanTaggedCovariance,
    pub num_entries: usize,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanTaggedCovarianceSeries"]
        [::std::mem::size_of::<EmpyreanTaggedCovarianceSeries>() - 16usize];
    ["Alignment of EmpyreanTaggedCovarianceSeries"]
        [::std::mem::align_of::<EmpyreanTaggedCovarianceSeries>() - 8usize];
    ["Offset of field: EmpyreanTaggedCovarianceSeries::entries"]
        [::std::mem::offset_of!(EmpyreanTaggedCovarianceSeries, entries) - 0usize];
    ["Offset of field: EmpyreanTaggedCovarianceSeries::num_entries"]
        [::std::mem::offset_of!(EmpyreanTaggedCovarianceSeries, num_entries) - 8usize];
};
impl Default for EmpyreanTaggedCovarianceSeries {
    fn default() -> Self {
        let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
#[doc = " Opaque handle to an `empyrean_core::determination::Session`.\n\n Owns observations, the mask state, and the fit history. Construct\n with [`empyrean_session_new`]; release with\n [`empyrean_session_free`]. The handle is **not** thread-safe — do\n not share between threads without external synchronization."]
pub type EmpyreanSession = Session;
#[doc = " Pairwise diagnostic returned by [`empyrean_session_diff`]."]
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct EmpyreanSessionDiff {
    #[doc = " Δ reduced χ² (positive ⇒ current fit is worse than prior)."]
    pub reduced_chi2_delta: f64,
    #[doc = " Δ iteration count."]
    pub iterations_delta: i64,
    #[doc = " Δ number of observations used (negative ⇒ observations were\n masked between prior and current)."]
    pub n_observations_delta: i64,
    #[doc = " Final update-norm convergence metric on the current fit."]
    pub update_norm_current: f64,
    #[doc = " Final update-norm convergence metric on the prior fit."]
    pub update_norm_prior: f64,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanSessionDiff"][::std::mem::size_of::<EmpyreanSessionDiff>() - 40usize];
    ["Alignment of EmpyreanSessionDiff"][::std::mem::align_of::<EmpyreanSessionDiff>() - 8usize];
    ["Offset of field: EmpyreanSessionDiff::reduced_chi2_delta"]
        [::std::mem::offset_of!(EmpyreanSessionDiff, reduced_chi2_delta) - 0usize];
    ["Offset of field: EmpyreanSessionDiff::iterations_delta"]
        [::std::mem::offset_of!(EmpyreanSessionDiff, iterations_delta) - 8usize];
    ["Offset of field: EmpyreanSessionDiff::n_observations_delta"]
        [::std::mem::offset_of!(EmpyreanSessionDiff, n_observations_delta) - 16usize];
    ["Offset of field: EmpyreanSessionDiff::update_norm_current"]
        [::std::mem::offset_of!(EmpyreanSessionDiff, update_norm_current) - 24usize];
    ["Offset of field: EmpyreanSessionDiff::update_norm_prior"]
        [::std::mem::offset_of!(EmpyreanSessionDiff, update_norm_prior) - 32usize];
};
#[doc = " A single body state for the C API."]
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct EmpyreanState {
    #[doc = " Epoch as MJD TDB."]
    pub epoch_mjd_tdb: f64,
    #[doc = " Position (AU)."]
    pub x: f64,
    pub y: f64,
    pub z: f64,
    #[doc = " Velocity (AU/day)."]
    pub vx: f64,
    pub vy: f64,
    pub vz: f64,
    #[doc = " Reference frame (EMPYREAN_FRAME_*)."]
    pub frame: i32,
    #[doc = " Center body NAIF ID."]
    pub origin: i32,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanState"][::std::mem::size_of::<EmpyreanState>() - 64usize];
    ["Alignment of EmpyreanState"][::std::mem::align_of::<EmpyreanState>() - 8usize];
    ["Offset of field: EmpyreanState::epoch_mjd_tdb"]
        [::std::mem::offset_of!(EmpyreanState, epoch_mjd_tdb) - 0usize];
    ["Offset of field: EmpyreanState::x"][::std::mem::offset_of!(EmpyreanState, x) - 8usize];
    ["Offset of field: EmpyreanState::y"][::std::mem::offset_of!(EmpyreanState, y) - 16usize];
    ["Offset of field: EmpyreanState::z"][::std::mem::offset_of!(EmpyreanState, z) - 24usize];
    ["Offset of field: EmpyreanState::vx"][::std::mem::offset_of!(EmpyreanState, vx) - 32usize];
    ["Offset of field: EmpyreanState::vy"][::std::mem::offset_of!(EmpyreanState, vy) - 40usize];
    ["Offset of field: EmpyreanState::vz"][::std::mem::offset_of!(EmpyreanState, vz) - 48usize];
    ["Offset of field: EmpyreanState::frame"]
        [::std::mem::offset_of!(EmpyreanState, frame) - 56usize];
    ["Offset of field: EmpyreanState::origin"]
        [::std::mem::offset_of!(EmpyreanState, origin) - 60usize];
};
#[doc = " Result containing an array of body states."]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EmpyreanStateResult {
    pub states: *mut EmpyreanState,
    pub num_states: usize,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of EmpyreanStateResult"][::std::mem::size_of::<EmpyreanStateResult>() - 16usize];
    ["Alignment of EmpyreanStateResult"][::std::mem::align_of::<EmpyreanStateResult>() - 8usize];
    ["Offset of field: EmpyreanStateResult::states"]
        [::std::mem::offset_of!(EmpyreanStateResult, states) - 0usize];
    ["Offset of field: EmpyreanStateResult::num_states"]
        [::std::mem::offset_of!(EmpyreanStateResult, num_states) - 8usize];
};
impl Default for EmpyreanStateResult {
    fn default() -> Self {
        let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
pub struct EmpyreanLib {
    __library: ::libloading::Library,
    pub empyrean_last_error: unsafe extern "C" fn() -> *const ::std::os::raw::c_char,
    pub empyrean_context_new_minimal: unsafe extern "C" fn(
        de440_path: *const ::std::os::raw::c_char,
        gm_path: *const ::std::os::raw::c_char,
    ) -> *mut EmpyreanContext,
    pub empyrean_context_with_spk: unsafe extern "C" fn(
        ctx: *mut EmpyreanContext,
        spk_path: *const ::std::os::raw::c_char,
    ) -> i32,
    pub empyrean_context_from_data_dir:
        unsafe extern "C" fn(data_dir: *const ::std::os::raw::c_char) -> *mut EmpyreanContext,
    pub empyrean_context_free: unsafe extern "C" fn(ctx: *mut EmpyreanContext),
    pub empyrean_default_data_dir: unsafe extern "C" fn() -> *mut ::std::os::raw::c_char,
    pub empyrean_string_free: unsafe extern "C" fn(s: *mut ::std::os::raw::c_char),
    pub empyrean_version_string: unsafe extern "C" fn() -> *mut ::std::os::raw::c_char,
    pub empyrean_versions: unsafe extern "C" fn(out: *mut EmpyreanVersions) -> i32,
    pub empyrean_versions_free: unsafe extern "C" fn(versions: *mut EmpyreanVersions),
    pub empyrean_generate_ephemeris: unsafe extern "C" fn(
        ctx: *const EmpyreanContext,
        orbits_ptr: *const EmpyreanOrbit,
        num_orbits: usize,
        observers_ptr: *const EmpyreanObserver,
        num_observers: usize,
        config: *const EmpyreanEphemerisConfig,
        result_out: *mut EmpyreanEphemerisResult,
    ) -> i32,
    pub empyrean_ephemeris_result_free: unsafe extern "C" fn(result: *mut EmpyreanEphemerisResult),
    pub empyrean_compute_impact_probabilities: unsafe extern "C" fn(
        ctx: *const EmpyreanContext,
        orbits_ptr: *const EmpyreanOrbit,
        num_orbits: usize,
        end_mjd_tdb: f64,
        methods_ptr: *const EmpyreanUncertaintyMethod,
        num_methods: usize,
        body_filter_naif: *const i32,
        num_body_filter: usize,
        result_out: *mut EmpyreanImpactProbabilitiesResult,
    ) -> i32,
    pub empyrean_compute_impact_probabilities_result_free:
        unsafe extern "C" fn(result: *mut EmpyreanImpactProbabilitiesResult),
    pub empyrean_compute_b_planes: unsafe extern "C" fn(
        ctx: *const EmpyreanContext,
        orbits_ptr: *const EmpyreanOrbit,
        num_orbits: usize,
        end_mjd_tdb: f64,
        methods_ptr: *const EmpyreanUncertaintyMethod,
        num_methods: usize,
        body_filter_naif: *const i32,
        num_body_filter: usize,
        result_out: *mut EmpyreanBPlanesResult,
    ) -> i32,
    pub empyrean_compute_b_planes_result_free:
        unsafe extern "C" fn(result: *mut EmpyreanBPlanesResult),
    pub empyrean_orbits_batch_free: unsafe extern "C" fn(batch: *mut EmpyreanOrbitBatch),
    pub empyrean_orbits_read_parquet: unsafe extern "C" fn(
        path: *const ::std::os::raw::c_char,
        out: *mut EmpyreanOrbitBatch,
    ) -> i32,
    pub empyrean_orbits_write_parquet: unsafe extern "C" fn(
        path: *const ::std::os::raw::c_char,
        batch: *const EmpyreanOrbitBatch,
    ) -> i32,
    pub empyrean_orbits_read_json: unsafe extern "C" fn(
        path: *const ::std::os::raw::c_char,
        out: *mut EmpyreanOrbitBatch,
    ) -> i32,
    pub empyrean_orbits_write_json: unsafe extern "C" fn(
        path: *const ::std::os::raw::c_char,
        batch: *const EmpyreanOrbitBatch,
    ) -> i32,
    pub empyrean_orbits_read_csv: unsafe extern "C" fn(
        path: *const ::std::os::raw::c_char,
        out: *mut EmpyreanOrbitBatch,
    ) -> i32,
    pub empyrean_orbits_write_csv: unsafe extern "C" fn(
        path: *const ::std::os::raw::c_char,
        batch: *const EmpyreanOrbitBatch,
    ) -> i32,
    pub empyrean_ephemeris_write_parquet: unsafe extern "C" fn(
        path: *const ::std::os::raw::c_char,
        entries_ptr: *const EmpyreanEphemerisEntry,
        num_entries: usize,
    ) -> i32,
    pub empyrean_ephemeris_write_json: unsafe extern "C" fn(
        path: *const ::std::os::raw::c_char,
        entries_ptr: *const EmpyreanEphemerisEntry,
        num_entries: usize,
    ) -> i32,
    pub empyrean_ephemeris_write_csv: unsafe extern "C" fn(
        path: *const ::std::os::raw::c_char,
        entries_ptr: *const EmpyreanEphemerisEntry,
        num_entries: usize,
    ) -> i32,
    pub empyrean_events_write_parquet: unsafe extern "C" fn(
        path: *const ::std::os::raw::c_char,
        events_ptr: *const EmpyreanEvent,
        num_events: usize,
    ) -> i32,
    pub empyrean_events_write_json: unsafe extern "C" fn(
        path: *const ::std::os::raw::c_char,
        events_ptr: *const EmpyreanEvent,
        num_events: usize,
    ) -> i32,
    pub empyrean_events_write_csv: unsafe extern "C" fn(
        path: *const ::std::os::raw::c_char,
        events_ptr: *const EmpyreanEvent,
        num_events: usize,
    ) -> i32,
    pub empyrean_residuals_write_parquet: unsafe extern "C" fn(
        path: *const ::std::os::raw::c_char,
        obs_ptr: *const EmpyreanObservationResult,
        num_obs: usize,
    ) -> i32,
    pub empyrean_residuals_write_json: unsafe extern "C" fn(
        path: *const ::std::os::raw::c_char,
        obs_ptr: *const EmpyreanObservationResult,
        num_obs: usize,
    ) -> i32,
    pub empyrean_residuals_write_csv: unsafe extern "C" fn(
        path: *const ::std::os::raw::c_char,
        obs_ptr: *const EmpyreanObservationResult,
        num_obs: usize,
    ) -> i32,
    pub empyrean_eigenvector_max_6x6: unsafe extern "C" fn(
        matrix: *const [[f64; 6usize]; 6usize],
        eigenvalue_out: *mut f64,
        eigenvector_out: *mut [f64; 6usize],
    ) -> i32,
    pub empyrean_split_gaussian: unsafe extern "C" fn(
        mean: *const [f64; 6usize],
        covariance: *const [[f64; 6usize]; 6usize],
        k: usize,
        weights_out: *mut f64,
        means_out: *mut [f64; 6usize],
        covariances_out: *mut [[f64; 6usize]; 6usize],
    ) -> i32,
    pub empyrean_get_observers: unsafe extern "C" fn(
        ctx: *const EmpyreanContext,
        obs_codes: *const *const ::std::os::raw::c_char,
        num_codes: usize,
        epochs_mjd_tdb: *const f64,
        num_epochs: usize,
        result_out: *mut EmpyreanObserverResult,
    ) -> i32,
    pub empyrean_observer_result_free: unsafe extern "C" fn(result: *mut EmpyreanObserverResult),
    pub empyrean_read_ades: unsafe extern "C" fn(
        content: *const ::std::os::raw::c_char,
        observations_out: *mut *mut EmpyreanObservation,
        num_observations_out: *mut usize,
        radar_out: *mut *mut EmpyreanRadarObservation,
        num_radar_out: *mut usize,
    ) -> i32,
    pub empyrean_observations_from_array: unsafe extern "C" fn(
        input: *const EmpyreanObservation,
        num: usize,
        out_ptr: *mut *mut EmpyreanObservation,
        out_num: *mut usize,
    ) -> i32,
    pub empyrean_observations_free:
        unsafe extern "C" fn(observations: *mut EmpyreanObservation, num: usize),
    pub empyrean_radar_observations_from_array: unsafe extern "C" fn(
        input: *const EmpyreanRadarObservation,
        num: usize,
        out_ptr: *mut *mut EmpyreanRadarObservation,
        out_num: *mut usize,
    ) -> i32,
    pub empyrean_radar_observations_free:
        unsafe extern "C" fn(observations: *mut EmpyreanRadarObservation, num: usize),
    pub empyrean_determine: unsafe extern "C" fn(
        ctx: *const EmpyreanContext,
        observations: *const EmpyreanObservation,
        num_observations: usize,
        radar: *const EmpyreanRadarObservation,
        num_radar: usize,
        initial_orbits: *const EmpyreanOrbit,
        num_initial_orbits: usize,
        config: *const EmpyreanODConfig,
        result_out: *mut EmpyreanODResult,
    ) -> i32,
    pub empyrean_od_result_free: unsafe extern "C" fn(result: *mut EmpyreanODResult),
    pub empyrean_evaluate: unsafe extern "C" fn(
        ctx: *const EmpyreanContext,
        orbit: *const EmpyreanOrbit,
        observations: *const EmpyreanObservation,
        num_observations: usize,
        config: *const EmpyreanODConfig,
        result_out: *mut EmpyreanEvaluateResult,
    ) -> i32,
    pub empyrean_evaluate_result_free: unsafe extern "C" fn(result: *mut EmpyreanEvaluateResult),
    pub empyrean_refine: unsafe extern "C" fn(
        ctx: *const EmpyreanContext,
        orbit: *const EmpyreanOrbit,
        observations: *const EmpyreanObservation,
        num_observations: usize,
        config: *const EmpyreanODConfig,
        result_out: *mut EmpyreanODResult,
    ) -> i32,
    pub empyrean_evaluate_plan: unsafe extern "C" fn(
        ctx: *const EmpyreanContext,
        orbit: *const EmpyreanOrbit,
        orbit_id: *const ::std::os::raw::c_char,
        planned: *const EmpyreanPlannedObservation,
        num_planned: usize,
        config: *const EmpyreanPlanningConfig,
        result_out: *mut EmpyreanPlanResult,
    ) -> i32,
    pub empyrean_plan_result_free: unsafe extern "C" fn(result: *mut EmpyreanPlanResult),
    pub empyrean_propagate: unsafe extern "C" fn(
        ctx: *const EmpyreanContext,
        orbits_ptr: *const EmpyreanOrbit,
        num_orbits: usize,
        times_ptr: *const f64,
        num_times: usize,
        config: *const EmpyreanPropagationConfig,
        result_out: *mut EmpyreanPropagationResult,
    ) -> i32,
    pub empyrean_propagation_result_free:
        unsafe extern "C" fn(result: *mut EmpyreanPropagationResult),
    pub empyrean_propagation_covariance_series_cartesian: unsafe extern "C" fn(
        result: *const EmpyreanPropagationResult,
        orbit_index: usize,
        out_series: *mut *mut EmpyreanTaggedCovarianceSeries,
    ) -> i32,
    pub empyrean_propagation_covariance_at_cartesian: unsafe extern "C" fn(
        result: *const EmpyreanPropagationResult,
        orbit_index: usize,
        epoch_index: usize,
        out: *mut EmpyreanTaggedCovariance,
    ) -> i32,
    pub empyrean_tagged_covariance_series_free:
        unsafe extern "C" fn(series: *mut EmpyreanTaggedCovarianceSeries),
    pub empyrean_query_sbdb: unsafe extern "C" fn(
        object_ids: *const *const ::std::os::raw::c_char,
        num_object_ids: usize,
        cache_dir: *const ::std::os::raw::c_char,
        out: *mut EmpyreanOrbitBatch,
    ) -> i32,
    pub empyrean_query_horizons: unsafe extern "C" fn(
        object_ids: *const *const ::std::os::raw::c_char,
        num_object_ids: usize,
        obs_code: *const ::std::os::raw::c_char,
        times_mjd_tdb: *const f64,
        num_times: usize,
        cache_dir: *const ::std::os::raw::c_char,
        out: *mut EmpyreanEphemerisResult,
    ) -> i32,
    pub empyrean_query_horizons_vectors: unsafe extern "C" fn(
        command: *const ::std::os::raw::c_char,
        epoch_mjd_tdb: f64,
        cache_dir: *const ::std::os::raw::c_char,
        out_pos: *mut f64,
        out_vel: *mut f64,
    ) -> i32,
    pub empyrean_query_observations: unsafe extern "C" fn(
        designations: *const *const ::std::os::raw::c_char,
        num_designations: usize,
        cache_dir: *const ::std::os::raw::c_char,
        out_ptr: *mut *mut EmpyreanObservation,
        out_num: *mut usize,
    ) -> i32,
    pub empyrean_query_radar: unsafe extern "C" fn(
        designations: *const *const ::std::os::raw::c_char,
        num_designations: usize,
        cache_dir: *const ::std::os::raw::c_char,
        out_ptr: *mut *mut EmpyreanRadarObservation,
        out_num: *mut usize,
    ) -> i32,
    pub empyrean_session_new: unsafe extern "C" fn(
        observations: *const EmpyreanObservation,
        num_observations: usize,
        config: *const EmpyreanODConfig,
    ) -> *mut EmpyreanSession,
    pub empyrean_session_free: unsafe extern "C" fn(session: *mut EmpyreanSession),
    pub empyrean_session_n_observations:
        unsafe extern "C" fn(session: *const EmpyreanSession) -> usize,
    pub empyrean_session_n_masked: unsafe extern "C" fn(session: *const EmpyreanSession) -> usize,
    pub empyrean_session_n_active: unsafe extern "C" fn(session: *const EmpyreanSession) -> usize,
    pub empyrean_session_mask:
        unsafe extern "C" fn(session: *mut EmpyreanSession, idx: usize) -> i32,
    pub empyrean_session_unmask:
        unsafe extern "C" fn(session: *mut EmpyreanSession, idx: usize) -> i32,
    pub empyrean_session_unmask_all: unsafe extern "C" fn(session: *mut EmpyreanSession) -> i32,
    pub empyrean_session_is_masked:
        unsafe extern "C" fn(session: *const EmpyreanSession, idx: usize) -> u8,
    pub empyrean_session_refine: unsafe extern "C" fn(
        session: *mut EmpyreanSession,
        ctx: *const EmpyreanContext,
        result_out: *mut EmpyreanODResult,
    ) -> i32,
    pub empyrean_session_history_len:
        unsafe extern "C" fn(session: *const EmpyreanSession) -> usize,
    pub empyrean_session_get_history: unsafe extern "C" fn(
        session: *const EmpyreanSession,
        idx: usize,
        result_out: *mut EmpyreanODResult,
    ) -> i32,
    pub empyrean_session_diff: unsafe extern "C" fn(
        session: *const EmpyreanSession,
        prior_idx: usize,
        diff_out: *mut EmpyreanSessionDiff,
    ) -> i32,
    pub empyrean_get_states: unsafe extern "C" fn(
        ctx: *const EmpyreanContext,
        target_naif_id: i32,
        center_naif_id: i32,
        epochs_mjd_tdb: *const f64,
        num_epochs: usize,
        frame: i32,
        result_out: *mut EmpyreanStateResult,
    ) -> i32,
    pub empyrean_state_result_free: unsafe extern "C" fn(result: *mut EmpyreanStateResult),
    pub empyrean_iso_to_mjd: unsafe extern "C" fn(
        iso: *const ::std::os::raw::c_char,
        scale: i32,
        out_mjd: *mut f64,
    ) -> i32,
    pub empyrean_mjd_to_iso: unsafe extern "C" fn(
        mjd: f64,
        scale: i32,
        out_buf: *mut ::std::os::raw::c_char,
        buf_len: usize,
    ) -> i32,
    pub empyrean_transform_coordinates: unsafe extern "C" fn(
        ctx: *const EmpyreanContext,
        input: *const CoordinateState,
        target_representation: i32,
        target_frame: i32,
        target_origin: i32,
        output: *mut CoordinateState,
    ) -> i32,
}
impl EmpyreanLib {
    pub unsafe fn new<P>(path: P) -> Result<Self, ::libloading::Error>
    where
        P: AsRef<::std::ffi::OsStr>,
    {
        let library = ::libloading::Library::new(path)?;
        Self::from_library(library)
    }
    pub unsafe fn from_library<L>(library: L) -> Result<Self, ::libloading::Error>
    where
        L: Into<::libloading::Library>,
    {
        let __library = library.into();
        let empyrean_last_error = __library.get(b"empyrean_last_error\0").map(|sym| *sym)?;
        let empyrean_context_new_minimal = __library
            .get(b"empyrean_context_new_minimal\0")
            .map(|sym| *sym)?;
        let empyrean_context_with_spk = __library
            .get(b"empyrean_context_with_spk\0")
            .map(|sym| *sym)?;
        let empyrean_context_from_data_dir = __library
            .get(b"empyrean_context_from_data_dir\0")
            .map(|sym| *sym)?;
        let empyrean_context_free = __library.get(b"empyrean_context_free\0").map(|sym| *sym)?;
        let empyrean_default_data_dir = __library
            .get(b"empyrean_default_data_dir\0")
            .map(|sym| *sym)?;
        let empyrean_string_free = __library.get(b"empyrean_string_free\0").map(|sym| *sym)?;
        let empyrean_version_string = __library
            .get(b"empyrean_version_string\0")
            .map(|sym| *sym)?;
        let empyrean_versions = __library.get(b"empyrean_versions\0").map(|sym| *sym)?;
        let empyrean_versions_free = __library.get(b"empyrean_versions_free\0").map(|sym| *sym)?;
        let empyrean_generate_ephemeris = __library
            .get(b"empyrean_generate_ephemeris\0")
            .map(|sym| *sym)?;
        let empyrean_ephemeris_result_free = __library
            .get(b"empyrean_ephemeris_result_free\0")
            .map(|sym| *sym)?;
        let empyrean_compute_impact_probabilities = __library
            .get(b"empyrean_compute_impact_probabilities\0")
            .map(|sym| *sym)?;
        let empyrean_compute_impact_probabilities_result_free = __library
            .get(b"empyrean_compute_impact_probabilities_result_free\0")
            .map(|sym| *sym)?;
        let empyrean_compute_b_planes = __library
            .get(b"empyrean_compute_b_planes\0")
            .map(|sym| *sym)?;
        let empyrean_compute_b_planes_result_free = __library
            .get(b"empyrean_compute_b_planes_result_free\0")
            .map(|sym| *sym)?;
        let empyrean_orbits_batch_free = __library
            .get(b"empyrean_orbits_batch_free\0")
            .map(|sym| *sym)?;
        let empyrean_orbits_read_parquet = __library
            .get(b"empyrean_orbits_read_parquet\0")
            .map(|sym| *sym)?;
        let empyrean_orbits_write_parquet = __library
            .get(b"empyrean_orbits_write_parquet\0")
            .map(|sym| *sym)?;
        let empyrean_orbits_read_json = __library
            .get(b"empyrean_orbits_read_json\0")
            .map(|sym| *sym)?;
        let empyrean_orbits_write_json = __library
            .get(b"empyrean_orbits_write_json\0")
            .map(|sym| *sym)?;
        let empyrean_orbits_read_csv = __library
            .get(b"empyrean_orbits_read_csv\0")
            .map(|sym| *sym)?;
        let empyrean_orbits_write_csv = __library
            .get(b"empyrean_orbits_write_csv\0")
            .map(|sym| *sym)?;
        let empyrean_ephemeris_write_parquet = __library
            .get(b"empyrean_ephemeris_write_parquet\0")
            .map(|sym| *sym)?;
        let empyrean_ephemeris_write_json = __library
            .get(b"empyrean_ephemeris_write_json\0")
            .map(|sym| *sym)?;
        let empyrean_ephemeris_write_csv = __library
            .get(b"empyrean_ephemeris_write_csv\0")
            .map(|sym| *sym)?;
        let empyrean_events_write_parquet = __library
            .get(b"empyrean_events_write_parquet\0")
            .map(|sym| *sym)?;
        let empyrean_events_write_json = __library
            .get(b"empyrean_events_write_json\0")
            .map(|sym| *sym)?;
        let empyrean_events_write_csv = __library
            .get(b"empyrean_events_write_csv\0")
            .map(|sym| *sym)?;
        let empyrean_residuals_write_parquet = __library
            .get(b"empyrean_residuals_write_parquet\0")
            .map(|sym| *sym)?;
        let empyrean_residuals_write_json = __library
            .get(b"empyrean_residuals_write_json\0")
            .map(|sym| *sym)?;
        let empyrean_residuals_write_csv = __library
            .get(b"empyrean_residuals_write_csv\0")
            .map(|sym| *sym)?;
        let empyrean_eigenvector_max_6x6 = __library
            .get(b"empyrean_eigenvector_max_6x6\0")
            .map(|sym| *sym)?;
        let empyrean_split_gaussian = __library
            .get(b"empyrean_split_gaussian\0")
            .map(|sym| *sym)?;
        let empyrean_get_observers = __library.get(b"empyrean_get_observers\0").map(|sym| *sym)?;
        let empyrean_observer_result_free = __library
            .get(b"empyrean_observer_result_free\0")
            .map(|sym| *sym)?;
        let empyrean_read_ades = __library.get(b"empyrean_read_ades\0").map(|sym| *sym)?;
        let empyrean_observations_from_array = __library
            .get(b"empyrean_observations_from_array\0")
            .map(|sym| *sym)?;
        let empyrean_observations_free = __library
            .get(b"empyrean_observations_free\0")
            .map(|sym| *sym)?;
        let empyrean_radar_observations_from_array = __library
            .get(b"empyrean_radar_observations_from_array\0")
            .map(|sym| *sym)?;
        let empyrean_radar_observations_free = __library
            .get(b"empyrean_radar_observations_free\0")
            .map(|sym| *sym)?;
        let empyrean_determine = __library.get(b"empyrean_determine\0").map(|sym| *sym)?;
        let empyrean_od_result_free = __library
            .get(b"empyrean_od_result_free\0")
            .map(|sym| *sym)?;
        let empyrean_evaluate = __library.get(b"empyrean_evaluate\0").map(|sym| *sym)?;
        let empyrean_evaluate_result_free = __library
            .get(b"empyrean_evaluate_result_free\0")
            .map(|sym| *sym)?;
        let empyrean_refine = __library.get(b"empyrean_refine\0").map(|sym| *sym)?;
        let empyrean_evaluate_plan = __library.get(b"empyrean_evaluate_plan\0").map(|sym| *sym)?;
        let empyrean_plan_result_free = __library
            .get(b"empyrean_plan_result_free\0")
            .map(|sym| *sym)?;
        let empyrean_propagate = __library.get(b"empyrean_propagate\0").map(|sym| *sym)?;
        let empyrean_propagation_result_free = __library
            .get(b"empyrean_propagation_result_free\0")
            .map(|sym| *sym)?;
        let empyrean_propagation_covariance_series_cartesian = __library
            .get(b"empyrean_propagation_covariance_series_cartesian\0")
            .map(|sym| *sym)?;
        let empyrean_propagation_covariance_at_cartesian = __library
            .get(b"empyrean_propagation_covariance_at_cartesian\0")
            .map(|sym| *sym)?;
        let empyrean_tagged_covariance_series_free = __library
            .get(b"empyrean_tagged_covariance_series_free\0")
            .map(|sym| *sym)?;
        let empyrean_query_sbdb = __library.get(b"empyrean_query_sbdb\0").map(|sym| *sym)?;
        let empyrean_query_horizons = __library
            .get(b"empyrean_query_horizons\0")
            .map(|sym| *sym)?;
        let empyrean_query_horizons_vectors = __library
            .get(b"empyrean_query_horizons_vectors\0")
            .map(|sym| *sym)?;
        let empyrean_query_observations = __library
            .get(b"empyrean_query_observations\0")
            .map(|sym| *sym)?;
        let empyrean_query_radar = __library.get(b"empyrean_query_radar\0").map(|sym| *sym)?;
        let empyrean_session_new = __library.get(b"empyrean_session_new\0").map(|sym| *sym)?;
        let empyrean_session_free = __library.get(b"empyrean_session_free\0").map(|sym| *sym)?;
        let empyrean_session_n_observations = __library
            .get(b"empyrean_session_n_observations\0")
            .map(|sym| *sym)?;
        let empyrean_session_n_masked = __library
            .get(b"empyrean_session_n_masked\0")
            .map(|sym| *sym)?;
        let empyrean_session_n_active = __library
            .get(b"empyrean_session_n_active\0")
            .map(|sym| *sym)?;
        let empyrean_session_mask = __library.get(b"empyrean_session_mask\0").map(|sym| *sym)?;
        let empyrean_session_unmask = __library
            .get(b"empyrean_session_unmask\0")
            .map(|sym| *sym)?;
        let empyrean_session_unmask_all = __library
            .get(b"empyrean_session_unmask_all\0")
            .map(|sym| *sym)?;
        let empyrean_session_is_masked = __library
            .get(b"empyrean_session_is_masked\0")
            .map(|sym| *sym)?;
        let empyrean_session_refine = __library
            .get(b"empyrean_session_refine\0")
            .map(|sym| *sym)?;
        let empyrean_session_history_len = __library
            .get(b"empyrean_session_history_len\0")
            .map(|sym| *sym)?;
        let empyrean_session_get_history = __library
            .get(b"empyrean_session_get_history\0")
            .map(|sym| *sym)?;
        let empyrean_session_diff = __library.get(b"empyrean_session_diff\0").map(|sym| *sym)?;
        let empyrean_get_states = __library.get(b"empyrean_get_states\0").map(|sym| *sym)?;
        let empyrean_state_result_free = __library
            .get(b"empyrean_state_result_free\0")
            .map(|sym| *sym)?;
        let empyrean_iso_to_mjd = __library.get(b"empyrean_iso_to_mjd\0").map(|sym| *sym)?;
        let empyrean_mjd_to_iso = __library.get(b"empyrean_mjd_to_iso\0").map(|sym| *sym)?;
        let empyrean_transform_coordinates = __library
            .get(b"empyrean_transform_coordinates\0")
            .map(|sym| *sym)?;
        Ok(EmpyreanLib {
            __library,
            empyrean_last_error,
            empyrean_context_new_minimal,
            empyrean_context_with_spk,
            empyrean_context_from_data_dir,
            empyrean_context_free,
            empyrean_default_data_dir,
            empyrean_string_free,
            empyrean_version_string,
            empyrean_versions,
            empyrean_versions_free,
            empyrean_generate_ephemeris,
            empyrean_ephemeris_result_free,
            empyrean_compute_impact_probabilities,
            empyrean_compute_impact_probabilities_result_free,
            empyrean_compute_b_planes,
            empyrean_compute_b_planes_result_free,
            empyrean_orbits_batch_free,
            empyrean_orbits_read_parquet,
            empyrean_orbits_write_parquet,
            empyrean_orbits_read_json,
            empyrean_orbits_write_json,
            empyrean_orbits_read_csv,
            empyrean_orbits_write_csv,
            empyrean_ephemeris_write_parquet,
            empyrean_ephemeris_write_json,
            empyrean_ephemeris_write_csv,
            empyrean_events_write_parquet,
            empyrean_events_write_json,
            empyrean_events_write_csv,
            empyrean_residuals_write_parquet,
            empyrean_residuals_write_json,
            empyrean_residuals_write_csv,
            empyrean_eigenvector_max_6x6,
            empyrean_split_gaussian,
            empyrean_get_observers,
            empyrean_observer_result_free,
            empyrean_read_ades,
            empyrean_observations_from_array,
            empyrean_observations_free,
            empyrean_radar_observations_from_array,
            empyrean_radar_observations_free,
            empyrean_determine,
            empyrean_od_result_free,
            empyrean_evaluate,
            empyrean_evaluate_result_free,
            empyrean_refine,
            empyrean_evaluate_plan,
            empyrean_plan_result_free,
            empyrean_propagate,
            empyrean_propagation_result_free,
            empyrean_propagation_covariance_series_cartesian,
            empyrean_propagation_covariance_at_cartesian,
            empyrean_tagged_covariance_series_free,
            empyrean_query_sbdb,
            empyrean_query_horizons,
            empyrean_query_horizons_vectors,
            empyrean_query_observations,
            empyrean_query_radar,
            empyrean_session_new,
            empyrean_session_free,
            empyrean_session_n_observations,
            empyrean_session_n_masked,
            empyrean_session_n_active,
            empyrean_session_mask,
            empyrean_session_unmask,
            empyrean_session_unmask_all,
            empyrean_session_is_masked,
            empyrean_session_refine,
            empyrean_session_history_len,
            empyrean_session_get_history,
            empyrean_session_diff,
            empyrean_get_states,
            empyrean_state_result_free,
            empyrean_iso_to_mjd,
            empyrean_mjd_to_iso,
            empyrean_transform_coordinates,
        })
    }
    #[doc = " Return a pointer to the last error message (thread-local, null-terminated).\n\n The pointer is valid until the next call that sets an error on the same\n thread."]
    pub unsafe fn empyrean_last_error(&self) -> *const ::std::os::raw::c_char {
        (self.empyrean_last_error)()
    }
    #[doc = " Create a **minimal** `EmpyreanContext` from a DE440 SPK file and a\n GM TPC file.\n\n Loads ONLY the planetary ephemeris and gravitational parameters —\n no Earth/Moon BPC kernels, no SB441-N16 asteroid perturbers, no\n MPC observatory codes, no Earth gravity field. This is sufficient\n for coordinate transforms and basic propagation under the\n `Approximate` force model, but is **not** enough for production\n orbit propagation, orbit determination, or topocentric ephemeris\n generation. Most callers should use\n [`empyrean_context_from_data_dir`] instead, which loads the full\n Standard-tier kernel set (downloading any missing files).\n\n Use [`empyrean_context_with_spk`] to chain additional SPK kernels\n (e.g. SB441-N16) onto a context built by this function.\n\n Returns a heap-allocated pointer on success, or null on error.\n Call `empyrean_last_error()` to retrieve the error message when null is\n returned.  The caller owns the returned pointer and must free it with\n `empyrean_context_free()`."]
    pub unsafe fn empyrean_context_new_minimal(
        &self,
        de440_path: *const ::std::os::raw::c_char,
        gm_path: *const ::std::os::raw::c_char,
    ) -> *mut EmpyreanContext {
        (self.empyrean_context_new_minimal)(de440_path, gm_path)
    }
    #[doc = " Load an additional SPK kernel into an existing context, in place.\n\n Useful for layering SB441-N16 asteroid perturbers or spacecraft\n SPK kernels (JWST, Gaia, custom probes) on top of a context built\n by [`empyrean_context_new_minimal`] or [`empyrean_context_from_data_dir`].\n The merged context picks up the new kernel's body coverage on top\n of what was already loaded.\n\n Returns 0 on success; negative error code on failure. The context\n pointer remains valid and unchanged when this function returns\n non-zero — failure does not invalidate `ctx`."]
    pub unsafe fn empyrean_context_with_spk(
        &self,
        ctx: *mut EmpyreanContext,
        spk_path: *const ::std::os::raw::c_char,
    ) -> i32 {
        (self.empyrean_context_with_spk)(ctx, spk_path)
    }
    #[doc = " Create a new `EmpyreanContext` from a data directory.\n\n Loads the full Standard-tier kernel set (DE440, SB441-N16, Earth/Moon\n BPCs, GM, MPC observatory codes) from `data_dir`, downloading any\n missing files. Pass null for `data_dir` to use the platform XDG\n data directory (`~/.empyrean/data` on Linux/macOS).\n\n Returns a heap-allocated pointer on success, or null on error.\n Call `empyrean_last_error()` to retrieve the error message when null is\n returned. The caller owns the returned pointer and must free it with\n `empyrean_context_free()`."]
    pub unsafe fn empyrean_context_from_data_dir(
        &self,
        data_dir: *const ::std::os::raw::c_char,
    ) -> *mut EmpyreanContext {
        (self.empyrean_context_from_data_dir)(data_dir)
    }
    #[doc = " Free an `EmpyreanContext` previously returned by `empyrean_context_new()`.\n\n Passing null is a no-op."]
    pub unsafe fn empyrean_context_free(&self, ctx: *mut EmpyreanContext) {
        (self.empyrean_context_free)(ctx)
    }
    #[doc = " Return the platform XDG-compliant default data directory as a\n heap-allocated, NUL-terminated UTF-8 string.\n\n Mirrors villeneuve's [`DataManager::new`] resolution: honors\n `EMPYREAN_DATA_DIR` first, then falls back to `dirs::data_dir()` —\n `~/.local/share/empyrean/data/` on Linux, `~/Library/Application\n Support/empyrean/data/` on macOS, `%APPDATA%\\empyrean\\data\\` on\n Windows. Cheap (no filesystem I/O).\n\n Returns null on failure (non-UTF-8 path, NUL byte in path, panic).\n Call `empyrean_last_error()` for details.\n\n **The caller owns the returned pointer and must release it with\n [`empyrean_string_free`].**"]
    pub unsafe fn empyrean_default_data_dir(&self) -> *mut ::std::os::raw::c_char {
        (self.empyrean_default_data_dir)()
    }
    #[doc = " Free a string returned by an empyrean C API function (e.g.,\n [`empyrean_default_data_dir`], [`empyrean_version_string`]).\n\n Passing null is a no-op. Passing any pointer not obtained from an\n empyrean string-returning function is undefined behavior."]
    pub unsafe fn empyrean_string_free(&self, s: *mut ::std::os::raw::c_char) {
        (self.empyrean_string_free)(s)
    }
    #[doc = " Multi-line version report — `empyrean-core <ver>\\nvilleneuve <ver>\\n…`.\n\n Mirrors [`empyrean_core::version_string`]. Useful for `--version`-style\n output and for verifying the build provenance of a deployed cdylib.\n Returns null on allocation failure (extremely unlikely — the strings\n are short and `&'static` underneath); call `empyrean_last_error()` if\n it does.\n\n **The caller owns the returned pointer and must release it with\n [`empyrean_string_free`].**"]
    pub unsafe fn empyrean_version_string(&self) -> *mut ::std::os::raw::c_char {
        (self.empyrean_version_string)()
    }
    #[doc = " Populate `out` with the per-crate versions of the empyrean stack.\n\n Returns 0 on success, non-zero on failure (`empyrean_last_error()`\n has the details). On failure `out` is left zero-initialized — no\n allocation needs freeing.\n\n **The caller owns the strings inside `out` and must release the\n whole struct with [`empyrean_versions_free`] when done.**"]
    pub unsafe fn empyrean_versions(&self, out: *mut EmpyreanVersions) -> i32 {
        (self.empyrean_versions)(out)
    }
    #[doc = " Free the version strings inside `versions` (each was heap-allocated\n by a previous successful [`empyrean_versions`] call). After this\n returns, `versions` itself is zero-initialized — safe to drop on\n the caller's stack.\n\n Passing null is a no-op. Calling this twice on the same struct, or\n passing a struct that wasn't populated by [`empyrean_versions`], is\n undefined behavior."]
    pub unsafe fn empyrean_versions_free(&self, versions: *mut EmpyreanVersions) {
        (self.empyrean_versions_free)(versions)
    }
    #[doc = " Generate predicted ephemeris for orbits and observers.\n\n Returns 0 on success, negative error code on failure.\n On success, `result_out` is populated with ephemeris entries.\n The caller must free the result with `empyrean_ephemeris_result_free()`."]
    pub unsafe fn empyrean_generate_ephemeris(
        &self,
        ctx: *const EmpyreanContext,
        orbits_ptr: *const EmpyreanOrbit,
        num_orbits: usize,
        observers_ptr: *const EmpyreanObserver,
        num_observers: usize,
        config: *const EmpyreanEphemerisConfig,
        result_out: *mut EmpyreanEphemerisResult,
    ) -> i32 {
        (self.empyrean_generate_ephemeris)(
            ctx,
            orbits_ptr,
            num_orbits,
            observers_ptr,
            num_observers,
            config,
            result_out,
        )
    }
    #[doc = " Free an ephemeris result previously returned by `empyrean_generate_ephemeris()`."]
    pub unsafe fn empyrean_ephemeris_result_free(&self, result: *mut EmpyreanEphemerisResult) {
        (self.empyrean_ephemeris_result_free)(result)
    }
    #[doc = " Run [`empyrean_core::impact::compute_impact_probabilities`] over a\n caller-supplied set of [`UncertaintyMethod`] variants and return\n the flattened IP records tagged by method.\n\n Caller is responsible for freeing the result via\n [`empyrean_compute_impact_probabilities_result_free`].\n\n # Returns\n `0` on success, negative on failure (see [`crate::set_last_error`]).\n\n # Safety\n All non-null pointer arguments must point to valid arrays of the\n indicated length for the duration of the call. The output struct\n is allocated by the caller; pointer fields inside it are allocated\n here and owned by the result."]
    pub unsafe fn empyrean_compute_impact_probabilities(
        &self,
        ctx: *const EmpyreanContext,
        orbits_ptr: *const EmpyreanOrbit,
        num_orbits: usize,
        end_mjd_tdb: f64,
        methods_ptr: *const EmpyreanUncertaintyMethod,
        num_methods: usize,
        body_filter_naif: *const i32,
        num_body_filter: usize,
        result_out: *mut EmpyreanImpactProbabilitiesResult,
    ) -> i32 {
        (self.empyrean_compute_impact_probabilities)(
            ctx,
            orbits_ptr,
            num_orbits,
            end_mjd_tdb,
            methods_ptr,
            num_methods,
            body_filter_naif,
            num_body_filter,
            result_out,
        )
    }
    #[doc = " Free the records array allocated by\n [`empyrean_compute_impact_probabilities`]. After calling, the\n struct's `records` is reset to null and `num_records` to 0."]
    pub unsafe fn empyrean_compute_impact_probabilities_result_free(
        &self,
        result: *mut EmpyreanImpactProbabilitiesResult,
    ) {
        (self.empyrean_compute_impact_probabilities_result_free)(result)
    }
    #[doc = " Run [`empyrean_core::impact::compute_b_planes`] over a caller-\n supplied set of [`UncertaintyMethod`] variants and return the\n flattened B-plane records tagged by method.\n\n Caller is responsible for freeing the result via\n [`empyrean_compute_b_planes_result_free`].\n\n # Safety\n Same contract as\n [`empyrean_compute_impact_probabilities`]."]
    pub unsafe fn empyrean_compute_b_planes(
        &self,
        ctx: *const EmpyreanContext,
        orbits_ptr: *const EmpyreanOrbit,
        num_orbits: usize,
        end_mjd_tdb: f64,
        methods_ptr: *const EmpyreanUncertaintyMethod,
        num_methods: usize,
        body_filter_naif: *const i32,
        num_body_filter: usize,
        result_out: *mut EmpyreanBPlanesResult,
    ) -> i32 {
        (self.empyrean_compute_b_planes)(
            ctx,
            orbits_ptr,
            num_orbits,
            end_mjd_tdb,
            methods_ptr,
            num_methods,
            body_filter_naif,
            num_body_filter,
            result_out,
        )
    }
    #[doc = " Free the records array allocated by [`empyrean_compute_b_planes`]."]
    pub unsafe fn empyrean_compute_b_planes_result_free(&self, result: *mut EmpyreanBPlanesResult) {
        (self.empyrean_compute_b_planes_result_free)(result)
    }
    #[doc = " Free a batch previously returned by an `empyrean_orbits_read_*`\n function. Passing null is a no-op."]
    pub unsafe fn empyrean_orbits_batch_free(&self, batch: *mut EmpyreanOrbitBatch) {
        (self.empyrean_orbits_batch_free)(batch)
    }
    #[doc = " Read an orbits parquet file. Caller frees the result with\n [`empyrean_orbits_batch_free`]."]
    pub unsafe fn empyrean_orbits_read_parquet(
        &self,
        path: *const ::std::os::raw::c_char,
        out: *mut EmpyreanOrbitBatch,
    ) -> i32 {
        (self.empyrean_orbits_read_parquet)(path, out)
    }
    #[doc = " Write an orbit batch to a parquet file."]
    pub unsafe fn empyrean_orbits_write_parquet(
        &self,
        path: *const ::std::os::raw::c_char,
        batch: *const EmpyreanOrbitBatch,
    ) -> i32 {
        (self.empyrean_orbits_write_parquet)(path, batch)
    }
    #[doc = " Read an orbits JSON file (array of orbit-row objects). Caller frees\n with [`empyrean_orbits_batch_free`]."]
    pub unsafe fn empyrean_orbits_read_json(
        &self,
        path: *const ::std::os::raw::c_char,
        out: *mut EmpyreanOrbitBatch,
    ) -> i32 {
        (self.empyrean_orbits_read_json)(path, out)
    }
    #[doc = " Write an orbit batch to JSON."]
    pub unsafe fn empyrean_orbits_write_json(
        &self,
        path: *const ::std::os::raw::c_char,
        batch: *const EmpyreanOrbitBatch,
    ) -> i32 {
        (self.empyrean_orbits_write_json)(path, batch)
    }
    #[doc = " Read an orbits CSV file.\n\n CSV does not carry covariance (use parquet for covariance round-trip)."]
    pub unsafe fn empyrean_orbits_read_csv(
        &self,
        path: *const ::std::os::raw::c_char,
        out: *mut EmpyreanOrbitBatch,
    ) -> i32 {
        (self.empyrean_orbits_read_csv)(path, out)
    }
    #[doc = " Write an orbit batch to CSV."]
    pub unsafe fn empyrean_orbits_write_csv(
        &self,
        path: *const ::std::os::raw::c_char,
        batch: *const EmpyreanOrbitBatch,
    ) -> i32 {
        (self.empyrean_orbits_write_csv)(path, batch)
    }
    #[doc = " Write ephemeris entries to parquet using the villeneuve schema."]
    pub unsafe fn empyrean_ephemeris_write_parquet(
        &self,
        path: *const ::std::os::raw::c_char,
        entries_ptr: *const EmpyreanEphemerisEntry,
        num_entries: usize,
    ) -> i32 {
        (self.empyrean_ephemeris_write_parquet)(path, entries_ptr, num_entries)
    }
    #[doc = " Write ephemeris entries to JSON."]
    pub unsafe fn empyrean_ephemeris_write_json(
        &self,
        path: *const ::std::os::raw::c_char,
        entries_ptr: *const EmpyreanEphemerisEntry,
        num_entries: usize,
    ) -> i32 {
        (self.empyrean_ephemeris_write_json)(path, entries_ptr, num_entries)
    }
    #[doc = " Write ephemeris entries to CSV."]
    pub unsafe fn empyrean_ephemeris_write_csv(
        &self,
        path: *const ::std::os::raw::c_char,
        entries_ptr: *const EmpyreanEphemerisEntry,
        num_entries: usize,
    ) -> i32 {
        (self.empyrean_ephemeris_write_csv)(path, entries_ptr, num_entries)
    }
    #[doc = " Write events to parquet."]
    pub unsafe fn empyrean_events_write_parquet(
        &self,
        path: *const ::std::os::raw::c_char,
        events_ptr: *const EmpyreanEvent,
        num_events: usize,
    ) -> i32 {
        (self.empyrean_events_write_parquet)(path, events_ptr, num_events)
    }
    #[doc = " Write events to JSON."]
    pub unsafe fn empyrean_events_write_json(
        &self,
        path: *const ::std::os::raw::c_char,
        events_ptr: *const EmpyreanEvent,
        num_events: usize,
    ) -> i32 {
        (self.empyrean_events_write_json)(path, events_ptr, num_events)
    }
    #[doc = " Write events to CSV."]
    pub unsafe fn empyrean_events_write_csv(
        &self,
        path: *const ::std::os::raw::c_char,
        events_ptr: *const EmpyreanEvent,
        num_events: usize,
    ) -> i32 {
        (self.empyrean_events_write_csv)(path, events_ptr, num_events)
    }
    #[doc = " Write OD residuals to parquet."]
    pub unsafe fn empyrean_residuals_write_parquet(
        &self,
        path: *const ::std::os::raw::c_char,
        obs_ptr: *const EmpyreanObservationResult,
        num_obs: usize,
    ) -> i32 {
        (self.empyrean_residuals_write_parquet)(path, obs_ptr, num_obs)
    }
    #[doc = " Write OD residuals to JSON."]
    pub unsafe fn empyrean_residuals_write_json(
        &self,
        path: *const ::std::os::raw::c_char,
        obs_ptr: *const EmpyreanObservationResult,
        num_obs: usize,
    ) -> i32 {
        (self.empyrean_residuals_write_json)(path, obs_ptr, num_obs)
    }
    #[doc = " Write OD residuals to CSV."]
    pub unsafe fn empyrean_residuals_write_csv(
        &self,
        path: *const ::std::os::raw::c_char,
        obs_ptr: *const EmpyreanObservationResult,
        num_obs: usize,
    ) -> i32 {
        (self.empyrean_residuals_write_csv)(path, obs_ptr, num_obs)
    }
    #[doc = " Find the dominant eigenvalue and eigenvector of a 6x6 symmetric matrix.\n\n Returns 0 on success. `eigenvalue_out` receives the eigenvalue,\n `eigenvector_out` receives the 6-element eigenvector."]
    pub unsafe fn empyrean_eigenvector_max_6x6(
        &self,
        matrix: *const [[f64; 6usize]; 6usize],
        eigenvalue_out: *mut f64,
        eigenvector_out: *mut [f64; 6usize],
    ) -> i32 {
        (self.empyrean_eigenvector_max_6x6)(matrix, eigenvalue_out, eigenvector_out)
    }
    #[doc = " Split a 6D Gaussian into K weighted components along the dominant\n eigenvector of the covariance.\n\n `weights_out`, `means_out`, `covariances_out` must point to arrays\n of size K, K×6, and K×6×6 respectively. Returns 0 on success."]
    pub unsafe fn empyrean_split_gaussian(
        &self,
        mean: *const [f64; 6usize],
        covariance: *const [[f64; 6usize]; 6usize],
        k: usize,
        weights_out: *mut f64,
        means_out: *mut [f64; 6usize],
        covariances_out: *mut [[f64; 6usize]; 6usize],
    ) -> i32 {
        (self.empyrean_split_gaussian)(mean, covariance, k, weights_out, means_out, covariances_out)
    }
    #[doc = " Compute observer states for given observatory codes and epochs.\n\n Returns 0 on success, negative error code on failure.\n On success, `result_out` is populated with observer states.\n The caller must free the result with `empyrean_observer_result_free()`."]
    pub unsafe fn empyrean_get_observers(
        &self,
        ctx: *const EmpyreanContext,
        obs_codes: *const *const ::std::os::raw::c_char,
        num_codes: usize,
        epochs_mjd_tdb: *const f64,
        num_epochs: usize,
        result_out: *mut EmpyreanObserverResult,
    ) -> i32 {
        (self.empyrean_get_observers)(
            ctx,
            obs_codes,
            num_codes,
            epochs_mjd_tdb,
            num_epochs,
            result_out,
        )
    }
    #[doc = " Free an observer result previously returned by `empyrean_get_observers()`.\n\n Passing a zeroed/null result is a no-op."]
    pub unsafe fn empyrean_observer_result_free(&self, result: *mut EmpyreanObserverResult) {
        (self.empyrean_observer_result_free)(result)
    }
    #[doc = " Read ADES PSV / MPC80 data from a string and pack into the C array.\n\n `path_or_content` is a null-terminated UTF-8 string with the ADES\n content directly (not a file path)."]
    pub unsafe fn empyrean_read_ades(
        &self,
        content: *const ::std::os::raw::c_char,
        observations_out: *mut *mut EmpyreanObservation,
        num_observations_out: *mut usize,
        radar_out: *mut *mut EmpyreanRadarObservation,
        num_radar_out: *mut usize,
    ) -> i32 {
        (self.empyrean_read_ades)(
            content,
            observations_out,
            num_observations_out,
            radar_out,
            num_radar_out,
        )
    }
    #[doc = " Free an observation array previously returned by `empyrean_read_ades()`.\n Copy a caller-owned array of [`EmpyreanObservation`] into a fresh\n allocation that matches the layout produced by\n [`empyrean_read_ades`].\n\n The strings on the input observations (`perm_id` / `prov_id` /\n `obs_time`) are duplicated into freshly-allocated `CString`s so the\n returned array owns its own memory independent of the input.\n\n On success populates `*out_ptr` with the new array and `*out_num`\n with its length, both freeable with [`empyrean_observations_free`].\n\n Returns 0 on success; negative error code on failure."]
    pub unsafe fn empyrean_observations_from_array(
        &self,
        input: *const EmpyreanObservation,
        num: usize,
        out_ptr: *mut *mut EmpyreanObservation,
        out_num: *mut usize,
    ) -> i32 {
        (self.empyrean_observations_from_array)(input, num, out_ptr, out_num)
    }
    pub unsafe fn empyrean_observations_free(
        &self,
        observations: *mut EmpyreanObservation,
        num: usize,
    ) {
        (self.empyrean_observations_free)(observations, num)
    }
    #[doc = " Copy a caller-owned array of [`EmpyreanRadarObservation`] into a fresh\n allocation matching the layout produced by [`empyrean_read_ades`].\n\n The nullable `*mut c_char` fields (`perm_id` / `prov_id` / `trk_sub` /\n `obs_time` / `remarks`) are duplicated into freshly-allocated\n `CString`s so the returned array owns its own memory independent of the\n input. All scalar fields (including the ADES-native delay/Doppler\n values) are copied verbatim — no unit conversion, nothing zeroed.\n\n On success populates `*out_ptr` with the new array and `*out_num` with\n its length, both freeable with [`empyrean_radar_observations_free`].\n\n Returns 0 on success; negative error code on failure."]
    pub unsafe fn empyrean_radar_observations_from_array(
        &self,
        input: *const EmpyreanRadarObservation,
        num: usize,
        out_ptr: *mut *mut EmpyreanRadarObservation,
        out_num: *mut usize,
    ) -> i32 {
        (self.empyrean_radar_observations_from_array)(input, num, out_ptr, out_num)
    }
    #[doc = " Free a radar observation array previously returned by\n [`empyrean_read_ades`] or [`empyrean_radar_observations_from_array`]."]
    pub unsafe fn empyrean_radar_observations_free(
        &self,
        observations: *mut EmpyreanRadarObservation,
        num: usize,
    ) {
        (self.empyrean_radar_observations_free)(observations, num)
    }
    #[doc = " Run the full orbit determination pipeline.\n\n When `num_initial_orbits > 0`, the supplied orbits are used as DC\n seeds (one per ADES object_id encountered in `observations`,\n matched by orbit index). Pass `null, 0` to let the IOD pipeline\n produce its own seeds."]
    pub unsafe fn empyrean_determine(
        &self,
        ctx: *const EmpyreanContext,
        observations: *const EmpyreanObservation,
        num_observations: usize,
        radar: *const EmpyreanRadarObservation,
        num_radar: usize,
        initial_orbits: *const EmpyreanOrbit,
        num_initial_orbits: usize,
        config: *const EmpyreanODConfig,
        result_out: *mut EmpyreanODResult,
    ) -> i32 {
        (self.empyrean_determine)(
            ctx,
            observations,
            num_observations,
            radar,
            num_radar,
            initial_orbits,
            num_initial_orbits,
            config,
            result_out,
        )
    }
    #[doc = " Free an OD result previously returned by `empyrean_determine()` or `empyrean_refine()`."]
    pub unsafe fn empyrean_od_result_free(&self, result: *mut EmpyreanODResult) {
        (self.empyrean_od_result_free)(result)
    }
    #[doc = " Evaluate residuals for a single orbit against observations."]
    pub unsafe fn empyrean_evaluate(
        &self,
        ctx: *const EmpyreanContext,
        orbit: *const EmpyreanOrbit,
        observations: *const EmpyreanObservation,
        num_observations: usize,
        config: *const EmpyreanODConfig,
        result_out: *mut EmpyreanEvaluateResult,
    ) -> i32 {
        (self.empyrean_evaluate)(
            ctx,
            orbit,
            observations,
            num_observations,
            config,
            result_out,
        )
    }
    #[doc = " Free an evaluate result previously returned by `empyrean_evaluate()`."]
    pub unsafe fn empyrean_evaluate_result_free(&self, result: *mut EmpyreanEvaluateResult) {
        (self.empyrean_evaluate_result_free)(result)
    }
    #[doc = " Refine a single orbit estimate with new observations using a\n Bayesian prior."]
    pub unsafe fn empyrean_refine(
        &self,
        ctx: *const EmpyreanContext,
        orbit: *const EmpyreanOrbit,
        observations: *const EmpyreanObservation,
        num_observations: usize,
        config: *const EmpyreanODConfig,
        result_out: *mut EmpyreanODResult,
    ) -> i32 {
        (self.empyrean_refine)(
            ctx,
            orbit,
            observations,
            num_observations,
            config,
            result_out,
        )
    }
    #[doc = " Evaluate an observation plan: how much each candidate observation would\n tighten the prior orbit covariance.\n\n `orbit` must carry a 6×6 Cartesian covariance (e.g. a `determine` result).\n `planned` is an array of `num_planned` candidate observations. `orbit_id`\n may be null (defaults to `\"orbit_0\"`). On success populates `*result_out`\n (caller-allocated); free with [`empyrean_plan_result_free`].\n\n Returns 0 on success, -1 for a null/invalid argument, -3 if planning fails\n (missing/singular prior covariance, an infeasible or invalid candidate, an\n ephemeris-generation error), -99 on an internal panic. The error message is\n retrievable via `empyrean_last_error()`."]
    pub unsafe fn empyrean_evaluate_plan(
        &self,
        ctx: *const EmpyreanContext,
        orbit: *const EmpyreanOrbit,
        orbit_id: *const ::std::os::raw::c_char,
        planned: *const EmpyreanPlannedObservation,
        num_planned: usize,
        config: *const EmpyreanPlanningConfig,
        result_out: *mut EmpyreanPlanResult,
    ) -> i32 {
        (self.empyrean_evaluate_plan)(
            ctx,
            orbit,
            orbit_id,
            planned,
            num_planned,
            config,
            result_out,
        )
    }
    #[doc = " Free the heap allocations inside a plan result populated by\n [`empyrean_evaluate_plan`]. Does not free the caller-allocated struct."]
    pub unsafe fn empyrean_plan_result_free(&self, result: *mut EmpyreanPlanResult) {
        (self.empyrean_plan_result_free)(result)
    }
    #[doc = " Propagate orbits to the requested target times.\n\n Returns 0 on success, negative error code on failure.\n On success, `result_out` is populated with the propagated states.\n The caller must free the result with `empyrean_propagation_result_free()`."]
    pub unsafe fn empyrean_propagate(
        &self,
        ctx: *const EmpyreanContext,
        orbits_ptr: *const EmpyreanOrbit,
        num_orbits: usize,
        times_ptr: *const f64,
        num_times: usize,
        config: *const EmpyreanPropagationConfig,
        result_out: *mut EmpyreanPropagationResult,
    ) -> i32 {
        (self.empyrean_propagate)(
            ctx, orbits_ptr, num_orbits, times_ptr, num_times, config, result_out,
        )
    }
    #[doc = " Free a propagation result previously returned by `empyrean_propagate()`."]
    pub unsafe fn empyrean_propagation_result_free(&self, result: *mut EmpyreanPropagationResult) {
        (self.empyrean_propagation_result_free)(result)
    }
    #[doc = " Resolved-kind tagged covariance at every output epoch for one orbit,\n Cartesian basis. On success `out_series` owns the array; free with\n [`empyrean_tagged_covariance_series_free`]. On error `out_series` is\n left null and the detail is on `empyrean_last_error()`.\n\n # Safety\n `result` must be a valid pointer returned by `empyrean_propagate`;\n `out_series` must be a valid pointer to write the result into."]
    pub unsafe fn empyrean_propagation_covariance_series_cartesian(
        &self,
        result: *const EmpyreanPropagationResult,
        orbit_index: usize,
        out_series: *mut *mut EmpyreanTaggedCovarianceSeries,
    ) -> i32 {
        (self.empyrean_propagation_covariance_series_cartesian)(result, orbit_index, out_series)
    }
    #[doc = " Resolved-kind tagged covariance at a single `(orbit_index,\n epoch_index)`, Cartesian basis (the gm-free point query). `out` is\n written on success.\n\n # Safety\n `result` and `out` must be valid pointers; `result` from `empyrean_propagate`."]
    pub unsafe fn empyrean_propagation_covariance_at_cartesian(
        &self,
        result: *const EmpyreanPropagationResult,
        orbit_index: usize,
        epoch_index: usize,
        out: *mut EmpyreanTaggedCovariance,
    ) -> i32 {
        (self.empyrean_propagation_covariance_at_cartesian)(result, orbit_index, epoch_index, out)
    }
    #[doc = " Free a series returned by\n [`empyrean_propagation_covariance_series_cartesian`].\n\n # Safety\n `series` must be null or a pointer returned by that accessor, freed once."]
    pub unsafe fn empyrean_tagged_covariance_series_free(
        &self,
        series: *mut EmpyreanTaggedCovarianceSeries,
    ) {
        (self.empyrean_tagged_covariance_series_free)(series)
    }
    #[doc = " Query the JPL Small-Body Database for one or more orbits.\n\n `object_ids` is an array of `num_object_ids` null-terminated UTF-8\n designations / names / SPK IDs (e.g. `\"apophis\"`, `\"99942\"`,\n `\"2024 YR4\"`, `\"67P\"`). `cache_dir` may be null to skip caching, or\n a directory path where SBDB JSON responses are cached on disk.\n\n On success the populated [`EmpyreanOrbitBatch`] must be released with\n [`empyrean_orbits_batch_free`](crate::io::empyrean_orbits_batch_free)."]
    pub unsafe fn empyrean_query_sbdb(
        &self,
        object_ids: *const *const ::std::os::raw::c_char,
        num_object_ids: usize,
        cache_dir: *const ::std::os::raw::c_char,
        out: *mut EmpyreanOrbitBatch,
    ) -> i32 {
        (self.empyrean_query_sbdb)(object_ids, num_object_ids, cache_dir, out)
    }
    #[doc = " Query JPL Horizons for predicted ephemeris records.\n\n `object_ids` is an array of `num_object_ids` null-terminated UTF-8\n designations / names / SPK IDs. `obs_code` is the MPC observatory\n code as a null-terminated string. `times_mjd_tdb` carries\n `num_times` epochs in MJD TDB.\n\n On success populates an [`EmpyreanEphemerisResult`] with one entry\n per `(object_id × epoch)`. Free with\n [`empyrean_ephemeris_result_free`](crate::ephemeris::empyrean_ephemeris_result_free).\n\n All angular values are converted to **degrees** at the FFI boundary\n (Horizons natively returns radians)."]
    pub unsafe fn empyrean_query_horizons(
        &self,
        object_ids: *const *const ::std::os::raw::c_char,
        num_object_ids: usize,
        obs_code: *const ::std::os::raw::c_char,
        times_mjd_tdb: *const f64,
        num_times: usize,
        cache_dir: *const ::std::os::raw::c_char,
        out: *mut EmpyreanEphemerisResult,
    ) -> i32 {
        (self.empyrean_query_horizons)(
            object_ids,
            num_object_ids,
            obs_code,
            times_mjd_tdb,
            num_times,
            cache_dir,
            out,
        )
    }
    #[doc = " Query JPL Horizons for a Cartesian state vector at a single epoch.\n\n `command` is the Horizons COMMAND string as a null-terminated UTF-8\n string (e.g. `\"99942;\"`, `\"DES=C/2019 Q4;\"`). `epoch_mjd_tdb` is\n the epoch in MJD TDB. `cache_dir` may be null to skip caching, or\n a directory path where Horizons JSON responses are cached on disk.\n\n On success writes the position (AU) to `out_pos` (length 3) and the\n velocity (AU/day) to `out_vel` (length 3) — both solar-system\n barycenter (SSB) centered, ICRF."]
    pub unsafe fn empyrean_query_horizons_vectors(
        &self,
        command: *const ::std::os::raw::c_char,
        epoch_mjd_tdb: f64,
        cache_dir: *const ::std::os::raw::c_char,
        out_pos: *mut f64,
        out_vel: *mut f64,
    ) -> i32 {
        (self.empyrean_query_horizons_vectors)(command, epoch_mjd_tdb, cache_dir, out_pos, out_vel)
    }
    #[doc = " Query the MPC observations API for ADES records of one or more\n designations.\n\n `designations` is an array of `num_designations` null-terminated\n UTF-8 designations (e.g. `\"99942\"`, `\"2024 YR4\"`, `\"67P\"`). The\n MPC API returns ADES_DF JSON; this function parses each row into\n the C-ABI [`EmpyreanObservation`] struct, filling the full ADES\n schema (perm_id / prov_id / trk_sub / mode / sys / ctr / pos1-3 /\n rms_corr / mag / rms_mag / band / ast_cat / phot_cat / phot_ap /\n log_snr / seeing / exp / rms_fit / n_stars / notes / remarks) when\n present in the JSON.\n\n On success `*out_ptr` carries a heap-allocated array of length\n `*out_num`. Free with\n [`empyrean_observations_free`](crate::od::empyrean_observations_free)."]
    pub unsafe fn empyrean_query_observations(
        &self,
        designations: *const *const ::std::os::raw::c_char,
        num_designations: usize,
        cache_dir: *const ::std::os::raw::c_char,
        out_ptr: *mut *mut EmpyreanObservation,
        out_num: *mut usize,
    ) -> i32 {
        (self.empyrean_query_observations)(
            designations,
            num_designations,
            cache_dir,
            out_ptr,
            out_num,
        )
    }
    #[doc = " Query the JPL `sb_radar` API for delay/Doppler radar astrometry of one\n or more designations.\n\n `designations` is an array of `num_designations` null-terminated UTF-8\n designations (e.g. `\"99942\"`, `\"2024 YR4\"`). Asteroid radar astrometry\n is a JPL SSD product — it is **not** served by the MPC observations API\n (`empyrean_query_observations` returns only optical / occultation\n records), so radar ships as its own live-query entry point. JPL\n `sb_radar` JSON records are converted to ADES-native scott\n `RadarObservation`s and packed into the C-ABI\n [`EmpyreanRadarObservation`] struct (the same layout\n [`empyrean_read_ades`](crate::od::empyrean_read_ades) emits): the delay\n value is in seconds, its σ in microseconds, Doppler in Hz, frequency in\n MHz, and the `com` flag is a tri-state i8. `cache_dir` may be null to\n skip caching, or a directory path where `sb_radar` JSON responses are\n cached on disk.\n\n An object with no radar astrometry contributes no records (it is not an\n error). A JPL record that fails to parse (missing required field, or an\n unrecognised DSN station code) is rejected loudly rather than silently\n dropped — the whole call fails so no radar quietly goes missing.\n\n On success `*out_ptr` carries a heap-allocated array of length\n `*out_num`. Free with\n [`empyrean_radar_observations_free`](crate::od::empyrean_radar_observations_free)."]
    pub unsafe fn empyrean_query_radar(
        &self,
        designations: *const *const ::std::os::raw::c_char,
        num_designations: usize,
        cache_dir: *const ::std::os::raw::c_char,
        out_ptr: *mut *mut EmpyreanRadarObservation,
        out_num: *mut usize,
    ) -> i32 {
        (self.empyrean_query_radar)(designations, num_designations, cache_dir, out_ptr, out_num)
    }
    #[doc = " Construct a new orbit-determination session over a fixed\n observation set.\n\n Returns a heap-allocated handle on success, or null on error.\n The caller owns the returned pointer and must free it with\n [`empyrean_session_free`]."]
    pub unsafe fn empyrean_session_new(
        &self,
        observations: *const EmpyreanObservation,
        num_observations: usize,
        config: *const EmpyreanODConfig,
    ) -> *mut EmpyreanSession {
        (self.empyrean_session_new)(observations, num_observations, config)
    }
    #[doc = " Free a session previously returned by [`empyrean_session_new`].\n Passing null is a no-op."]
    pub unsafe fn empyrean_session_free(&self, session: *mut EmpyreanSession) {
        (self.empyrean_session_free)(session)
    }
    #[doc = " Total number of observations in the session (masked or not).\n Returns 0 if `session` is null."]
    pub unsafe fn empyrean_session_n_observations(&self, session: *const EmpyreanSession) -> usize {
        (self.empyrean_session_n_observations)(session)
    }
    #[doc = " Number of observations currently masked."]
    pub unsafe fn empyrean_session_n_masked(&self, session: *const EmpyreanSession) -> usize {
        (self.empyrean_session_n_masked)(session)
    }
    #[doc = " Number of observations active (not masked) in the next refine."]
    pub unsafe fn empyrean_session_n_active(&self, session: *const EmpyreanSession) -> usize {
        (self.empyrean_session_n_active)(session)
    }
    #[doc = " Mask the observation at `idx`. Returns 0 on success, -1 on null\n or out-of-bounds."]
    pub unsafe fn empyrean_session_mask(&self, session: *mut EmpyreanSession, idx: usize) -> i32 {
        (self.empyrean_session_mask)(session, idx)
    }
    #[doc = " Unmask the observation at `idx`. Returns 0 on success, -1 on null\n or out-of-bounds."]
    pub unsafe fn empyrean_session_unmask(&self, session: *mut EmpyreanSession, idx: usize) -> i32 {
        (self.empyrean_session_unmask)(session, idx)
    }
    #[doc = " Clear all masks. Returns 0 on success, -1 on null."]
    pub unsafe fn empyrean_session_unmask_all(&self, session: *mut EmpyreanSession) -> i32 {
        (self.empyrean_session_unmask_all)(session)
    }
    #[doc = " Whether the observation at `idx` is masked. Returns 1 = masked,\n 0 = active, 255 (-1 cast) on null/out-of-bounds."]
    pub unsafe fn empyrean_session_is_masked(
        &self,
        session: *const EmpyreanSession,
        idx: usize,
    ) -> u8 {
        (self.empyrean_session_is_masked)(session, idx)
    }
    #[doc = " Run an OD refine using the current mask state.\n\n On the first call, runs the full IOD → DC pipeline. On subsequent\n calls, uses the previously-fit orbit as the IOD seed (skipping the\n IOD step). Pushes the new fit onto the session's history.\n\n On success populates `result_out` with the latest fit. The caller\n must free `result_out` with [`empyrean_od_result_free`](crate::od::empyrean_od_result_free)."]
    pub unsafe fn empyrean_session_refine(
        &self,
        session: *mut EmpyreanSession,
        ctx: *const EmpyreanContext,
        result_out: *mut EmpyreanODResult,
    ) -> i32 {
        (self.empyrean_session_refine)(session, ctx, result_out)
    }
    #[doc = " Number of fits in the session history."]
    pub unsafe fn empyrean_session_history_len(&self, session: *const EmpyreanSession) -> usize {
        (self.empyrean_session_history_len)(session)
    }
    #[doc = " Copy the i-th history entry into `result_out`. Returns 0 on\n success, -1 on null/out-of-bounds. Caller frees `result_out` with\n [`empyrean_od_result_free`](crate::od::empyrean_od_result_free)."]
    pub unsafe fn empyrean_session_get_history(
        &self,
        session: *const EmpyreanSession,
        idx: usize,
        result_out: *mut EmpyreanODResult,
    ) -> i32 {
        (self.empyrean_session_get_history)(session, idx, result_out)
    }
    #[doc = " Diff the current fit against an earlier history entry. Returns 0\n on success, -1 if there is no current fit or `prior_idx` is out\n of bounds."]
    pub unsafe fn empyrean_session_diff(
        &self,
        session: *const EmpyreanSession,
        prior_idx: usize,
        diff_out: *mut EmpyreanSessionDiff,
    ) -> i32 {
        (self.empyrean_session_diff)(session, prior_idx, diff_out)
    }
    #[doc = " Query body states relative to a center body at given epochs.\n\n Returns 0 on success, negative error code on failure.\n On success, `result_out` is populated with body states.\n The caller must free the result with `empyrean_state_result_free()`."]
    pub unsafe fn empyrean_get_states(
        &self,
        ctx: *const EmpyreanContext,
        target_naif_id: i32,
        center_naif_id: i32,
        epochs_mjd_tdb: *const f64,
        num_epochs: usize,
        frame: i32,
        result_out: *mut EmpyreanStateResult,
    ) -> i32 {
        (self.empyrean_get_states)(
            ctx,
            target_naif_id,
            center_naif_id,
            epochs_mjd_tdb,
            num_epochs,
            frame,
            result_out,
        )
    }
    #[doc = " Free a state result previously returned by `empyrean_get_states()`.\n\n Passing a zeroed/null result is a no-op."]
    pub unsafe fn empyrean_state_result_free(&self, result: *mut EmpyreanStateResult) {
        (self.empyrean_state_result_free)(result)
    }
    #[doc = " Parse an ISO 8601 UTC string (e.g. ``\"2024-08-01T00:00:00.000Z\"``)\n to MJD in the requested target scale.\n\n `scale` is `0` for UTC, `1` for TDB.\n\n On success writes the MJD value to `*out_mjd` and returns 0.\n On failure returns a negative code; consult\n [`empyrean_last_error`](crate::empyrean_last_error)."]
    pub unsafe fn empyrean_iso_to_mjd(
        &self,
        iso: *const ::std::os::raw::c_char,
        scale: i32,
        out_mjd: *mut f64,
    ) -> i32 {
        (self.empyrean_iso_to_mjd)(iso, scale, out_mjd)
    }
    #[doc = " Format an MJD value (in the given scale) as an ISO 8601 UTC string.\n\n `scale` is `0` for UTC, `1` for TDB. Writes a null-terminated\n string of length ≤ `buf_len-1` into `out_buf`. A 32-byte buffer is\n always sufficient (typical output is 24 bytes:\n ``\"2024-08-01T00:00:00.000Z\"``).\n\n Returns 0 on success; negative on failure."]
    pub unsafe fn empyrean_mjd_to_iso(
        &self,
        mjd: f64,
        scale: i32,
        out_buf: *mut ::std::os::raw::c_char,
        buf_len: usize,
    ) -> i32 {
        (self.empyrean_mjd_to_iso)(mjd, scale, out_buf, buf_len)
    }
    #[doc = " Transform a coordinate state to a new representation, frame, and/or origin.\n\n Returns 0 on success or a negative error code on failure.\n Call `empyrean_last_error()` to retrieve the error message on failure."]
    pub unsafe fn empyrean_transform_coordinates(
        &self,
        ctx: *const EmpyreanContext,
        input: *const CoordinateState,
        target_representation: i32,
        target_frame: i32,
        target_origin: i32,
        output: *mut CoordinateState,
    ) -> i32 {
        (self.empyrean_transform_coordinates)(
            ctx,
            input,
            target_representation,
            target_frame,
            target_origin,
            output,
        )
    }
}
