@neilberkman/sidereon 0.12.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -305,6 +305,25 @@ export class BroadcastEphemeris {
305
305
  * J2000 seconds. Returns `undefined` when no usable record covers the query.
306
306
  */
307
307
  evaluate(satellite: string, t_j2000_s: number): BroadcastStoreEvaluation | undefined;
308
+ /**
309
+ * Query ECEF position and clock for parallel satellite and epoch arrays
310
+ * against this parsed broadcast ephemeris store.
311
+ *
312
+ * `satellites[i]` is evaluated at `epochsJ2000S[i]`, where epochs are
313
+ * seconds since J2000 in GPST for GNSS broadcast records. The returned
314
+ * plain object has aligned `positionsEcefM`, `clocksS`, `statuses`, and
315
+ * `elementResults` arrays.
316
+ */
317
+ observableStatesAtJ2000S(satellites: any, epochs_j2000_s: any): any;
318
+ /**
319
+ * Query ECEF position and clock for many satellites at one epoch against
320
+ * this parsed broadcast ephemeris store.
321
+ *
322
+ * `epochJ2000S` is seconds since J2000 in GPST. The returned object follows
323
+ * the same contract as
324
+ * [`observableStatesAtJ2000S`](Self::observable_states_at_j2000_s).
325
+ */
326
+ observableStatesAtSharedJ2000S(satellites: any, epoch_j2000_s: number): any;
308
327
  /**
309
328
  * Solve a receiver position from broadcast ephemeris ALONE: the supported
310
329
  * real-time / offline single-point-positioning mode. `request` is the same
@@ -1845,6 +1864,43 @@ export class GeoidGrid {
1845
1864
  undulationsRad(points_rad: Float64Array): Float64Array;
1846
1865
  }
1847
1866
 
1867
+ /**
1868
+ * Geometry observability and covariance-validation diagnostics.
1869
+ */
1870
+ export class GeometryQuality {
1871
+ private constructor();
1872
+ free(): void;
1873
+ [Symbol.dispose](): void;
1874
+ /**
1875
+ * Singular-value condition number of the design matrix.
1876
+ */
1877
+ readonly conditionNumber: number;
1878
+ /**
1879
+ * Whether residuals or a propagated prior validated the covariance bound.
1880
+ */
1881
+ readonly covarianceValidated: boolean;
1882
+ /**
1883
+ * Geometric dilution of precision for the solved state.
1884
+ */
1885
+ readonly gdop: number;
1886
+ /**
1887
+ * Whether residual-based RAIM can test the solve.
1888
+ */
1889
+ readonly raimCheckable: boolean;
1890
+ /**
1891
+ * Rank of the design matrix used by the solve.
1892
+ */
1893
+ readonly rank: number;
1894
+ /**
1895
+ * Observation redundancy, `nObs - nParams`.
1896
+ */
1897
+ readonly redundancy: number;
1898
+ /**
1899
+ * Observability and validation tier.
1900
+ */
1901
+ readonly tier: ObservabilityTier;
1902
+ }
1903
+
1848
1904
  /**
1849
1905
  * One GLONASS broadcast state-vector record. `toeUtcJ2000S` is UTC seconds past
1850
1906
  * J2000; position is PZ-90.11 ECEF metres, velocity m/s, acceleration m/s^2.
@@ -3257,6 +3313,34 @@ export class ObsPhaseShift {
3257
3313
  readonly system: GnssSystem;
3258
3314
  }
3259
3315
 
3316
+ /**
3317
+ * Observability and validation tier for an estimation design.
3318
+ *
3319
+ * `ZeroRedundancy` means the design is full rank but has no residual degrees of
3320
+ * freedom, so snapshot-solve covariance bounds are unvalidated unless a
3321
+ * propagated prior is present. `Weak` means the design exceeded the configured
3322
+ * condition-number or GDOP cutoff; the returned bounds are reported as computed
3323
+ * and are not clamped.
3324
+ */
3325
+ export enum ObservabilityTier {
3326
+ /**
3327
+ * At least one estimated parameter is not observable.
3328
+ */
3329
+ RankDeficient = 0,
3330
+ /**
3331
+ * Full rank with no residual degrees of freedom.
3332
+ */
3333
+ ZeroRedundancy = 1,
3334
+ /**
3335
+ * Full rank with residual degrees of freedom, but above a cutoff.
3336
+ */
3337
+ Weak = 2,
3338
+ /**
3339
+ * Full rank and within the configured cutoffs.
3340
+ */
3341
+ Nominal = 3,
3342
+ }
3343
+
3260
3344
  /**
3261
3345
  * Optional observation-code allow-list for raw and carrier-phase rows. Build
3262
3346
  * with `new ObservationFilter()` then chain `.withSystem(system, codes)`.
@@ -4179,6 +4263,80 @@ export class PppFloatSolution {
4179
4263
  readonly ztdResidualM: number | undefined;
4180
4264
  }
4181
4265
 
4266
+ /**
4267
+ * A reusable precise-ephemeris interpolant with cached per-satellite nodes.
4268
+ *
4269
+ * Build this handle once from a parsed [`Sp3`] product, raw precise samples, or
4270
+ * a [`PreciseEphemerisSampleSource`], then reuse it for many state or range
4271
+ * queries. The handle delegates to
4272
+ * `sidereon_core::ephemeris::PreciseEphemerisInterpolant`; ECEF positions are
4273
+ * metres, clocks are seconds, and query epochs are seconds since J2000 in the
4274
+ * source time scale.
4275
+ */
4276
+ export class PreciseEphemerisInterpolant {
4277
+ private constructor();
4278
+ free(): void;
4279
+ [Symbol.dispose](): void;
4280
+ /**
4281
+ * Build a cached interpolant from an existing sample-backed precise source.
4282
+ */
4283
+ static fromPreciseEphemerisSamples(source: PreciseEphemerisSampleSource): PreciseEphemerisInterpolant;
4284
+ /**
4285
+ * Build a cached interpolant directly from precise samples.
4286
+ *
4287
+ * `samples` is the same array accepted by
4288
+ * [`preciseEphemerisSamplesFromSamples`]: each item has `{ sat, epoch,
4289
+ * positionEcefM, clockS?, clockEvent? }`, with epochs in seconds since
4290
+ * J2000 and positions in ECEF metres. Throws a `TypeError` for malformed
4291
+ * JS input and a `RangeError` for sample validation failures.
4292
+ */
4293
+ static fromSamples(samples: any): PreciseEphemerisInterpolant;
4294
+ /**
4295
+ * Build a cached interpolant from a parsed SP3 precise product.
4296
+ *
4297
+ * Nodes are copied from the product's native SP3 records. Query epochs are
4298
+ * seconds since J2000 in the SP3 product time scale.
4299
+ */
4300
+ static fromSp3(sp3: Sp3): PreciseEphemerisInterpolant;
4301
+ /**
4302
+ * Query ECEF position and optional clock for parallel satellite and epoch
4303
+ * arrays using this cached interpolant.
4304
+ *
4305
+ * `satellites[i]` is evaluated at `epochsJ2000S[i]`, where epochs are
4306
+ * seconds since J2000 on this handle's time scale. The returned plain
4307
+ * object has aligned `positionsEcefM`, `clocksS`, `statuses`, and
4308
+ * `elementResults` arrays.
4309
+ */
4310
+ observableStatesAtJ2000S(satellites: any, epochs_j2000_s: any): any;
4311
+ /**
4312
+ * Query ECEF position and optional clock for many satellites at one epoch
4313
+ * using this cached interpolant.
4314
+ *
4315
+ * `epochJ2000S` is seconds since J2000 on this handle's time scale. The
4316
+ * returned object follows the same contract as
4317
+ * [`observableStatesAtJ2000S`](Self::observable_states_at_j2000_s).
4318
+ */
4319
+ observableStatesAtSharedJ2000S(satellites: any, epoch_j2000_s: number): any;
4320
+ /**
4321
+ * Predict geometric ranges for many `(satellite, receiver, epoch)`
4322
+ * requests using this cached interpolant.
4323
+ *
4324
+ * `requests` is an array of `{ sat, receiverEcefM, tRxJ2000S }` objects.
4325
+ * Positions are ECEF metres and epochs are seconds since J2000 on this
4326
+ * handle's time scale. The output matches [`Sp3.predictRanges`].
4327
+ */
4328
+ predictRanges(requests: any, options: any): any;
4329
+ /**
4330
+ * Satellite tokens this handle can interpolate, ascending.
4331
+ */
4332
+ readonly satellites: string[];
4333
+ /**
4334
+ * Source time-scale abbreviation used by this handle's J2000-second axis,
4335
+ * such as `"GPST"`.
4336
+ */
4337
+ readonly timeScale: string;
4338
+ }
4339
+
4182
4340
  /**
4183
4341
  * A precise-ephemeris source built from samples rather than parsed SP3 text.
4184
4342
  *
@@ -4190,6 +4348,26 @@ export class PreciseEphemerisSampleSource {
4190
4348
  private constructor();
4191
4349
  free(): void;
4192
4350
  [Symbol.dispose](): void;
4351
+ /**
4352
+ * Query ECEF position and optional clock for parallel satellite and epoch
4353
+ * arrays against this sample-backed precise source.
4354
+ *
4355
+ * `satellites[i]` is evaluated at `epochsJ2000S[i]`, where epochs are
4356
+ * seconds since J2000 on the source time scale. The returned plain object
4357
+ * has aligned `positionsEcefM`, `clocksS`, `statuses`, and
4358
+ * `elementResults` arrays. Failed elements use the core missing-position
4359
+ * sentinel and carry the scalar engine error in `elementResults[i].error`.
4360
+ */
4361
+ observableStatesAtJ2000S(satellites: any, epochs_j2000_s: any): any;
4362
+ /**
4363
+ * Query ECEF position and optional clock for many satellites at one epoch
4364
+ * against this sample-backed precise source.
4365
+ *
4366
+ * `epochJ2000S` is seconds since J2000 on the source time scale. The
4367
+ * returned plain object follows the same contract as
4368
+ * [`observableStatesAtJ2000S`](Self::observable_states_at_j2000_s).
4369
+ */
4370
+ observableStatesAtSharedJ2000S(satellites: any, epoch_j2000_s: number): any;
4193
4371
  /**
4194
4372
  * Predict geometric ranges for many requests in one call. See the shared
4195
4373
  * [`predictRanges`](crate::precise_samples::predict_ranges_over) contract;
@@ -4657,6 +4835,11 @@ export class RtkFixedSolution {
4657
4835
  * The underlying float baseline as a `Float64Array` `[dx, dy, dz]`, metres.
4658
4836
  */
4659
4837
  readonly floatBaselineM: Float64Array;
4838
+ /**
4839
+ * Geometry observability and covariance-validation diagnostics for the
4840
+ * float design used by the integer-fixed solve.
4841
+ */
4842
+ readonly geometryQuality: GeometryQuality;
4660
4843
  readonly integerCandidates: number;
4661
4844
  /**
4662
4845
  * Integer ambiguity ratio, or `undefined` when no ratio was computed.
@@ -4666,6 +4849,16 @@ export class RtkFixedSolution {
4666
4849
  * Integer ambiguity-fix status: `"Fixed"` or `"NotFixed"`.
4667
4850
  */
4668
4851
  readonly integerStatus: string;
4852
+ /**
4853
+ * Whether residual-based RAIM can test the float design used by the
4854
+ * integer-fixed solve.
4855
+ */
4856
+ readonly raimCheckable: boolean;
4857
+ /**
4858
+ * Observation redundancy, `nObs - nParams`, for the float design used by
4859
+ * the integer-fixed solve.
4860
+ */
4861
+ readonly redundancy: number;
4669
4862
  }
4670
4863
 
4671
4864
  /**
@@ -4685,9 +4878,24 @@ export class RtkFloatSolution {
4685
4878
  readonly baselineM: Float64Array;
4686
4879
  readonly codeRmsM: number;
4687
4880
  readonly converged: boolean;
4881
+ /**
4882
+ * Geometry observability and covariance-validation diagnostics for the
4883
+ * final double-difference design. `ZeroRedundancy` bounds are unvalidated
4884
+ * for snapshot solves, `Weak` bounds are unclamped, and rank-deficient
4885
+ * designs are returned as a singular-geometry `Error`.
4886
+ */
4887
+ readonly geometryQuality: GeometryQuality;
4688
4888
  readonly iterations: number;
4689
4889
  readonly nObservations: number;
4690
4890
  readonly phaseRmsM: number;
4891
+ /**
4892
+ * Whether residual-based RAIM can test the float design.
4893
+ */
4894
+ readonly raimCheckable: boolean;
4895
+ /**
4896
+ * Observation redundancy, `nObs - nParams`, for the float design.
4897
+ */
4898
+ readonly redundancy: number;
4691
4899
  readonly weightedRmsM: number;
4692
4900
  }
4693
4901
 
@@ -4994,6 +5202,26 @@ export class Sp3 {
4994
5202
  * coverage gap (the engine refuses to extrapolate).
4995
5203
  */
4996
5204
  interpolate(satellite: string, j2000_seconds: Float64Array): Sp3Interpolation;
5205
+ /**
5206
+ * Query ECEF position and optional clock for parallel satellite and epoch
5207
+ * arrays against this parsed SP3 product.
5208
+ *
5209
+ * `satellites[i]` is evaluated at `epochsJ2000S[i]`, where epochs are
5210
+ * seconds since J2000 in the product time scale. The returned plain object
5211
+ * has aligned `positionsEcefM`, `clocksS`, `statuses`, and
5212
+ * `elementResults` arrays. Failed elements use the core missing-position
5213
+ * sentinel and carry the scalar engine error in `elementResults[i].error`.
5214
+ */
5215
+ observableStatesAtJ2000S(satellites: any, epochs_j2000_s: any): any;
5216
+ /**
5217
+ * Query ECEF position and optional clock for many satellites at one epoch
5218
+ * against this parsed SP3 product.
5219
+ *
5220
+ * `epochJ2000S` is seconds since J2000 in the product time scale. The
5221
+ * returned object follows the same contract as
5222
+ * [`observableStatesAtJ2000S`](Self::observable_states_at_j2000_s).
5223
+ */
5224
+ observableStatesAtSharedJ2000S(satellites: any, epoch_j2000_s: number): any;
4997
5225
  /**
4998
5226
  * Predict geometric ranges for many `(satellite, receiver, epoch)` requests
4999
5227
  * against this ephemeris in one call. `requests` is an array of
@@ -5494,10 +5722,25 @@ export class SppSolution {
5494
5722
  * for geodetic output, otherwise `undefined`.
5495
5723
  */
5496
5724
  readonly geodetic: Float64Array | undefined;
5725
+ /**
5726
+ * Geometry observability and covariance-validation diagnostics for this
5727
+ * solved design. `ZeroRedundancy` marks unvalidated snapshot covariance
5728
+ * bounds, `Weak` leaves large bounds unclamped, and rank-deficient designs
5729
+ * are returned as a singular-geometry `Error` rather than a solution.
5730
+ */
5731
+ readonly geometryQuality: GeometryQuality;
5497
5732
  /**
5498
5733
  * ECEF position as a `Float64Array` `[x, y, z]`, metres.
5499
5734
  */
5500
5735
  readonly positionM: Float64Array;
5736
+ /**
5737
+ * Whether residual-based RAIM can test the accepted solve.
5738
+ */
5739
+ readonly raimCheckable: boolean;
5740
+ /**
5741
+ * Degrees of freedom in the accepted solve: `usedCount - (3 + clocks)`.
5742
+ */
5743
+ readonly redundancy: number;
5501
5744
  /**
5502
5745
  * Post-fit residuals, metres, index-aligned to `usedSats`.
5503
5746
  */
@@ -6120,6 +6363,39 @@ export function acquire(samples: Float64Array, prn: bigint, options: any): Acqui
6120
6363
  */
6121
6364
  export function allanDeviation(series: any, tau0_s: number, averaging_factors: any): any;
6122
6365
 
6366
+ /**
6367
+ * Alpha-beta measurement update applied to a predicted scalar state.
6368
+ *
6369
+ * `predicted` is `{ level, rate }`, `measurement` has the same unit as
6370
+ * `level`, `dt` is seconds, and `gains` is `{ alpha, beta }`.
6371
+ */
6372
+ export function alphaBetaApplyMeasurement(predicted: any, measurement: number, dt: number, gains: any): any;
6373
+
6374
+ /**
6375
+ * Run one alpha-beta predict and measurement update.
6376
+ *
6377
+ * `state` is `{ level, rate }`, `measurement` has the same unit as `level`,
6378
+ * `dt` is seconds, and `gains` is `{ alpha, beta }`. Returns `{ predicted,
6379
+ * updated, innovation }`.
6380
+ */
6381
+ export function alphaBetaFilterStep(state: any, measurement: number, dt: number, gains: any): any;
6382
+
6383
+ /**
6384
+ * Alpha-beta constant-rate prediction.
6385
+ *
6386
+ * `state` is `{ level, rate }` and `dt` is the positive propagation interval in
6387
+ * seconds. Returns the predicted `{ level, rate }`.
6388
+ */
6389
+ export function alphaBetaPredict(state: any, dt: number): any;
6390
+
6391
+ /**
6392
+ * Steady-state alpha-beta gains from a positive tracking index.
6393
+ *
6394
+ * Returns `{ alpha, beta }`, where `alpha` is the level gain and `beta` maps
6395
+ * innovation to rate through `beta * innovation / dt`.
6396
+ */
6397
+ export function alphaBetaSteadyStateGains(tracking_index: number): any;
6398
+
6123
6399
  /**
6124
6400
  * On-sky angle in degrees between two direction vectors.
6125
6401
  */
@@ -6226,6 +6502,38 @@ export function carrierBandName(band: CarrierBand): string;
6226
6502
  */
6227
6503
  export function carrierFrequencyHz(system: GnssSystem, band: CarrierBand): number | undefined;
6228
6504
 
6505
+ /**
6506
+ * CA-CFAR false alarm probability from searched-cell count, absolute
6507
+ * threshold, and mean noise level.
6508
+ */
6509
+ export function cfarCaFalseAlarmProbability(searched_cells: number, threshold: number, noise_level: number): number;
6510
+
6511
+ /**
6512
+ * CA-CFAR threshold multiplier from searched-cell count and target false alarm
6513
+ * probability.
6514
+ */
6515
+ export function cfarCaMultiplierFromPfa(searched_cells: number, false_alarm_probability: number): number;
6516
+
6517
+ /**
6518
+ * CA-CFAR false alarm probability from searched-cell count and multiplier.
6519
+ */
6520
+ export function cfarCaPfaFromMultiplier(searched_cells: number, multiplier: number): number;
6521
+
6522
+ /**
6523
+ * CA-CFAR absolute threshold from searched-cell count, target false alarm
6524
+ * probability, and mean noise level.
6525
+ */
6526
+ export function cfarCaThreshold(searched_cells: number, false_alarm_probability: number, noise_level: number): number;
6527
+
6528
+ /**
6529
+ * Compute the closed-form Chan-Ho seed used by [`locateSource`].
6530
+ *
6531
+ * `mode` is `"toa"`, `"tdoa"`, or `{ mode: "tdoa", referenceSensor }`.
6532
+ * Per-sensor speed overrides are not used by the closed-form equations, but
6533
+ * they are used by [`locateSource`] during iterative refinement.
6534
+ */
6535
+ export function chanHoInitialGuess(sensors: any, arrival_times_s: any, propagation_speed_m_s: number, mode: any): any;
6536
+
6229
6537
  /**
6230
6538
  * Returns `true` when a diff has any findings.
6231
6539
  */
@@ -6633,6 +6941,19 @@ export function estimateDecay(drag: DragForce, request: any): any;
6633
6941
  */
6634
6942
  export function estimateDecayWithSpaceWeather(drag: DragForce, table: SpaceWeatherTable, request: any): any;
6635
6943
 
6944
+ /**
6945
+ * Exponentially weighted moving-average update.
6946
+ *
6947
+ * `alpha` must be in `[0, 1]`; the returned value is
6948
+ * `previous + alpha * (sample - previous)`.
6949
+ */
6950
+ export function ewmaUpdate(previous: number, sample: number, alpha: number): number;
6951
+
6952
+ /**
6953
+ * EWMA update with `alpha = 1 / 2^shift`.
6954
+ */
6955
+ export function ewmaUpdatePowerOfTwo(previous: number, sample: number, shift: number): number;
6956
+
6636
6957
  /**
6637
6958
  * Find Moon elevation threshold crossings (moonrise / moonset) over a UTC
6638
6959
  * window.
@@ -7074,6 +7395,15 @@ export function j2000SecondsToCivil(seconds: bigint): CivilDateTime;
7074
7395
  */
7075
7396
  export function jarqueBera(x: Float64Array): any;
7076
7397
 
7398
+ /**
7399
+ * Steady-state gains for a scalar constant-velocity Kalman filter.
7400
+ *
7401
+ * `trackingIndex`, `dt`, and `measurementVariance` must be positive. Returns
7402
+ * `{ positionGain, rateGain }`; `rateGain * dt` equals the alpha-beta `beta`
7403
+ * gain for the same tracking index.
7404
+ */
7405
+ export function kalmanCvSteadyStateGains(tracking_index: number, dt: number, measurement_variance: number): any;
7406
+
7077
7407
  /**
7078
7408
  * GPS broadcast Klobuchar ionospheric group delay in the model's native units
7079
7409
  * (positive metres).
@@ -7286,12 +7616,38 @@ export function loadRinexObs(bytes: Uint8Array): RinexObs;
7286
7616
  */
7287
7617
  export function loadSp3(bytes: Uint8Array): Sp3;
7288
7618
 
7619
+ /**
7620
+ * Locate a source from sensor arrival times.
7621
+ *
7622
+ * `sensors` is an array of `{ positionM, propagationSpeedMS? }`; each
7623
+ * `positionM` is a 2D or 3D Cartesian metre vector and all sensors must share
7624
+ * the same dimension. `arrivalTimesS` is an aligned seconds array,
7625
+ * `propagationSpeedMS` is the call-level speed in metres per second, and
7626
+ * `options` may include `mode`, `referenceSensor`, `timingSigmaS`, `loss`,
7627
+ * `fScaleS`, `ftol`, `xtol`, `gtol`, and `maxNfev`.
7628
+ */
7629
+ export function locateSource(sensors: any, arrival_times_s: any, propagation_speed_m_s: number, options: any): any;
7630
+
7289
7631
  export function lunarSolarEclipses(start_unix_us: bigint, end_unix_us: bigint, step_s: number, tolerance_s: number): any;
7290
7632
 
7291
7633
  export function lunarSolarEclipsesSpk(spk: Spk, start_unix_us: bigint, end_unix_us: bigint, step_s: number, tolerance_s: number): any;
7292
7634
 
7293
7635
  export function lvlhRotation(position_km: Float64Array, velocity_km_s: Float64Array): Float64Array;
7294
7636
 
7637
+ /**
7638
+ * Gaussian consistency factor applied by [`madSpread`].
7639
+ */
7640
+ export function madGaussianConsistency(): number;
7641
+
7642
+ /**
7643
+ * Median absolute deviation spread estimate.
7644
+ *
7645
+ * `values` is a JS number array. The returned spread is
7646
+ * `MAD_GAUSSIAN_CONSISTENCY * median(abs(value - median(values)))`, floored by
7647
+ * `scaleFloor`.
7648
+ */
7649
+ export function madSpread(values: any, scale_floor: number): number;
7650
+
7295
7651
  export function meanMotionCircular(radius_km: number): number;
7296
7652
 
7297
7653
  export function meanMotionFromState(position_km: Float64Array, velocity_km_s: Float64Array): number;
@@ -7425,6 +7781,28 @@ export function nequickGDelayM(_eval: any, frequency_hz: number): number;
7425
7781
  */
7426
7782
  export function nequickGStecTecu(_eval: any): number;
7427
7783
 
7784
+ /**
7785
+ * Scalar normalized innovation squared statistic.
7786
+ */
7787
+ export function nis(innovation: number, innovation_variance: number): number;
7788
+
7789
+ /**
7790
+ * Bar-Shalom expected NIS value for `dof` measurement degrees of freedom.
7791
+ */
7792
+ export function nisExpectedValue(dof: number): number;
7793
+
7794
+ /**
7795
+ * Test a scalar innovation against a chi-square NIS gate.
7796
+ *
7797
+ * Returns `{ nis, threshold, inGate, dof }`, with `confidence` in `(0, 1)`.
7798
+ */
7799
+ export function nisGate(innovation: number, innovation_variance: number, dof: number, confidence: number): any;
7800
+
7801
+ /**
7802
+ * Chi-square NIS gate threshold for `dof` and confidence probability.
7803
+ */
7804
+ export function nisGateThreshold(dof: number, confidence: number): number;
7805
+
7428
7806
  /**
7429
7807
  * Parse bytes and return grouped epoch snapshots directly.
7430
7808
  */
@@ -7455,11 +7833,31 @@ export function noiseAmplification(f1_hz: number, f2_hz: number): number;
7455
7833
  */
7456
7834
  export function normalCovariance(jacobian: Float64Array, m: number, n: number, variance_scale: number): Float64Array;
7457
7835
 
7836
+ /**
7837
+ * Scalar normalized innovation `innovation / sqrt(innovationVariance)`.
7838
+ */
7839
+ export function normalizedInnovation(innovation: number, innovation_variance: number): number;
7840
+
7458
7841
  /**
7459
7842
  * Build the NTRIP connection request bytes for a config object.
7460
7843
  */
7461
7844
  export function ntripRequestBytes(config: any): Uint8Array;
7462
7845
 
7846
+ /**
7847
+ * Stable string label for an [`ObservabilityTier`] enum value.
7848
+ */
7849
+ export function observabilityTierLabel(tier: ObservabilityTier): string;
7850
+
7851
+ /**
7852
+ * Missing-position sentinel used in failed observable-state batch elements.
7853
+ *
7854
+ * The returned JS value is `[NaN, NaN, NaN]`, matching
7855
+ * `sidereon_core::ephemeris::OBSERVABLE_STATE_MISSING_POSITION_ECEF_M`. Always
7856
+ * check `elementResults[i].ok` or `statuses[i]` before using
7857
+ * `positionsEcefM[i]`.
7858
+ */
7859
+ export function observableStateMissingPositionEcefM(): any;
7860
+
7463
7861
  /**
7464
7862
  * Predict observables for one satellite from a broadcast ephemeris store.
7465
7863
  * Delegates to `sidereon_core::observables::predict`.
@@ -8209,6 +8607,33 @@ export function solveVelocityBroadcast(broadcast: BroadcastEphemeris, observatio
8209
8607
  */
8210
8608
  export function solveWithFallback(precise: Sp3[], broadcast: BroadcastEphemeris, request: any, policy: any): SourcedSolution;
8211
8609
 
8610
+ /**
8611
+ * Compute the timing Cramer-Rao lower bound for a proposed source position.
8612
+ *
8613
+ * The covariance is `(H^T H)^-1 * timingSigmaS^2`; position blocks are square
8614
+ * metres and origin-time variance is square seconds.
8615
+ */
8616
+ export function sourceCrlb(sensors: any, source_position_m: any, propagation_speed_m_s: number, timing_sigma_s: number): any;
8617
+
8618
+ /**
8619
+ * Compute timing DOP for a proposed source position.
8620
+ *
8621
+ * `sourcePositionM` is a 2D or 3D Cartesian metre vector in the same frame as
8622
+ * the sensors. The returned DOP values multiply timing sigma in seconds to
8623
+ * produce metres in the caller's Cartesian axes.
8624
+ */
8625
+ export function sourceDop(sensors: any, source_position_m: any, propagation_speed_m_s: number): any;
8626
+
8627
+ /**
8628
+ * Return the plain mode object for TDOA solves against `referenceSensor`.
8629
+ */
8630
+ export function sourceSolveModeTdoa(reference_sensor: number): any;
8631
+
8632
+ /**
8633
+ * Return the plain mode value for absolute time-of-arrival solves.
8634
+ */
8635
+ export function sourceSolveModeToa(): string;
8636
+
8212
8637
  /**
8213
8638
  * Extract a parsed SP3 product as the canonical precise-ephemeris samples, one
8214
8639
  * per real position record in ascending epoch order.