gnss-js 1.39.0 → 1.41.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.
@@ -1,3 +1,7 @@
1
+ import {
2
+ getGpsLeap
3
+ } from "./chunk-HVXYFUCB.js";
4
+
1
5
  // src/trimble/frame.ts
2
6
  var STX = 2;
3
7
  var ETX = 3;
@@ -40,68 +44,139 @@ function* trimbleFrames(data, stats) {
40
44
 
41
45
  // src/trimble/nav.ts
42
46
  var GPS_EPOCH_MS = Date.UTC(1980, 0, 6);
47
+ var BDT_EPOCH_MS = Date.UTC(2006, 0, 1);
43
48
  var SEC_PER_WEEK = 7 * 86400;
44
49
  var MS_PER_WEEK = SEC_PER_WEEK * 1e3;
45
50
  var GPS_PI = 3.1415926535898;
51
+ var BDS_WEEK_OFFSET = 1356;
52
+ var BDS_LEAP_SEC = 14;
46
53
  var gpsMs = (week, sec) => GPS_EPOCH_MS + week * MS_PER_WEEK + sec * 1e3;
47
54
  var sowOf = (dateMs) => dateMs / 1e3 % SEC_PER_WEEK;
48
55
  var SUB_GPS_EPHEMERIS = 1;
49
56
  var SUB_ION_UTC = 3;
50
- function decodeGpsEphemeris(data, view, base) {
51
- const prn = data[base + 5];
52
- if (prn < 1 || prn > 32) return null;
53
- const week = view.getUint16(base + 6, false);
54
- const iode = data[base + 11];
55
- const toc = view.getInt32(base + 16, false);
56
- const toe = view.getUint32(base + 20, false);
57
- const tgd = view.getFloat64(base + 24, false);
58
- const af2 = view.getFloat64(base + 32, false);
59
- const af1 = view.getFloat64(base + 40, false);
60
- const af0 = view.getFloat64(base + 48, false);
61
- const crs = view.getFloat64(base + 56, false);
62
- const deltaN = view.getFloat64(base + 64, false) * GPS_PI;
63
- const m0 = view.getFloat64(base + 72, false) * GPS_PI;
64
- const cuc = view.getFloat64(base + 80, false) * GPS_PI;
65
- const e = view.getFloat64(base + 88, false);
66
- const cus = view.getFloat64(base + 96, false) * GPS_PI;
67
- const sqrtA = view.getFloat64(base + 104, false);
68
- const cic = view.getFloat64(base + 112, false) * GPS_PI;
69
- const omega0 = view.getFloat64(base + 120, false) * GPS_PI;
70
- const cis = view.getFloat64(base + 128, false) * GPS_PI;
71
- const i0 = view.getFloat64(base + 136, false) * GPS_PI;
72
- const crc = view.getFloat64(base + 144, false);
73
- const omega = view.getFloat64(base + 152, false) * GPS_PI;
74
- const omegaDot = view.getFloat64(base + 160, false) * GPS_PI;
75
- const idot = view.getFloat64(base + 168, false) * GPS_PI;
76
- const flags = view.getUint32(base + 176, false);
57
+ var SUB_GLO_EPHEMERIS = 9;
58
+ var SUB_BDS_EPHEMERIS = 21;
59
+ function readKepler(view, base) {
60
+ return {
61
+ svid: view.getUint8(base + 5),
62
+ week: view.getUint16(base + 6, false),
63
+ iode: view.getUint8(base + 11),
64
+ tocSec: view.getInt32(base + 16, false),
65
+ toeSec: view.getUint32(base + 20, false),
66
+ tgd: view.getFloat64(base + 24, false),
67
+ af2: view.getFloat64(base + 32, false),
68
+ af1: view.getFloat64(base + 40, false),
69
+ af0: view.getFloat64(base + 48, false),
70
+ crs: view.getFloat64(base + 56, false),
71
+ deltaN: view.getFloat64(base + 64, false) * GPS_PI,
72
+ m0: view.getFloat64(base + 72, false) * GPS_PI,
73
+ cuc: view.getFloat64(base + 80, false) * GPS_PI,
74
+ e: view.getFloat64(base + 88, false),
75
+ cus: view.getFloat64(base + 96, false) * GPS_PI,
76
+ sqrtA: view.getFloat64(base + 104, false),
77
+ cic: view.getFloat64(base + 112, false) * GPS_PI,
78
+ omega0: view.getFloat64(base + 120, false) * GPS_PI,
79
+ cis: view.getFloat64(base + 128, false) * GPS_PI,
80
+ i0: view.getFloat64(base + 136, false) * GPS_PI,
81
+ crc: view.getFloat64(base + 144, false),
82
+ omega: view.getFloat64(base + 152, false) * GPS_PI,
83
+ omegaDot: view.getFloat64(base + 160, false) * GPS_PI,
84
+ idot: view.getFloat64(base + 168, false) * GPS_PI,
85
+ flags: view.getUint32(base + 176, false)
86
+ };
87
+ }
88
+ function keplerCommon(r) {
89
+ return {
90
+ af0: r.af0,
91
+ af1: r.af1,
92
+ af2: r.af2,
93
+ iode: r.iode,
94
+ crs: r.crs,
95
+ deltaN: r.deltaN,
96
+ m0: r.m0,
97
+ cuc: r.cuc,
98
+ e: r.e,
99
+ cus: r.cus,
100
+ sqrtA: r.sqrtA,
101
+ cic: r.cic,
102
+ omega0: r.omega0,
103
+ cis: r.cis,
104
+ i0: r.i0,
105
+ crc: r.crc,
106
+ omega: r.omega,
107
+ omegaDot: r.omegaDot,
108
+ idot: r.idot,
109
+ tgd: r.tgd
110
+ };
111
+ }
112
+ function decodeGpsEphemeris(view, base) {
113
+ const r = readKepler(view, base);
114
+ if (r.svid < 1 || r.svid > 32) return null;
115
+ const tocMs = gpsMs(r.week, r.tocSec);
77
116
  return {
78
117
  system: "G",
79
- prn: `G${String(prn).padStart(2, "0")}`,
80
- toc: sowOf(gpsMs(week, toc)),
81
- tocDate: new Date(gpsMs(week, toc)),
82
- af0,
83
- af1,
84
- af2,
85
- iode,
86
- crs,
87
- deltaN,
88
- m0,
89
- cuc,
90
- e,
91
- cus,
92
- sqrtA,
93
- toe,
94
- cic,
95
- omega0,
96
- cis,
97
- i0,
98
- crc,
99
- omega,
100
- omegaDot,
101
- idot,
102
- week,
103
- svHealth: flags >>> 4 & 127,
104
- tgd
118
+ prn: `G${String(r.svid).padStart(2, "0")}`,
119
+ toc: sowOf(tocMs),
120
+ tocDate: new Date(tocMs),
121
+ toe: r.toeSec,
122
+ week: r.week,
123
+ svHealth: r.flags >>> 4 & 127,
124
+ ...keplerCommon(r)
125
+ };
126
+ }
127
+ function decodeBdsEphemeris(view, base) {
128
+ const r = readKepler(view, base);
129
+ if (r.svid < 1 || r.svid > 63) return null;
130
+ const bdsWeek = r.week - BDS_WEEK_OFFSET;
131
+ const tocSec = r.tocSec - BDS_LEAP_SEC;
132
+ const toeSec = r.toeSec - BDS_LEAP_SEC;
133
+ const tocDate = new Date(
134
+ BDT_EPOCH_MS + bdsWeek * MS_PER_WEEK + tocSec * 1e3
135
+ );
136
+ return {
137
+ system: "C",
138
+ prn: `C${String(r.svid).padStart(2, "0")}`,
139
+ toc: sowOf(tocDate.getTime()),
140
+ tocDate,
141
+ toe: toeSec,
142
+ week: bdsWeek,
143
+ // Health from the same flags nibble as GPS (0 = healthy for the observed
144
+ // operational BeiDou sats); flags bit 0 is a set-on-all format marker,
145
+ // not SatH1, so it must not be used here.
146
+ svHealth: r.flags >>> 4 & 127,
147
+ ...keplerCommon(r)
148
+ };
149
+ }
150
+ function decodeGloEphemeris(view, base) {
151
+ const slot = view.getUint8(base + 5);
152
+ if (slot < 1 || slot > 24) return null;
153
+ const week = view.getUint16(base + 6, false);
154
+ const tow = view.getUint32(base + 8, false);
155
+ const gpsTimeMs = gpsMs(week, tow);
156
+ const leapMs = getGpsLeap(new Date(gpsTimeMs)) * 1e3;
157
+ const tocMs = gpsTimeMs - leapMs;
158
+ return {
159
+ system: "R",
160
+ prn: `R${String(slot).padStart(2, "0")}`,
161
+ tocDate: new Date(tocMs),
162
+ // RINEX stores −τn as the clock bias; the record carries τn (ICD sign).
163
+ tauN: -view.getFloat64(base + 113, false),
164
+ gammaN: view.getFloat64(base + 121, false),
165
+ messageFrameTime: (tocMs - GPS_EPOCH_MS) / 1e3 % SEC_PER_WEEK,
166
+ // State vector: metres / m·s⁻¹ / m·s⁻² → km / km·s⁻¹ / km·s⁻².
167
+ x: view.getFloat64(base + 33, false) / 1e3,
168
+ xDot: view.getFloat64(base + 41, false) / 1e3,
169
+ xAcc: view.getFloat64(base + 49, false) / 1e3,
170
+ y: view.getFloat64(base + 57, false) / 1e3,
171
+ yDot: view.getFloat64(base + 65, false) / 1e3,
172
+ yAcc: view.getFloat64(base + 73, false) / 1e3,
173
+ z: view.getFloat64(base + 81, false) / 1e3,
174
+ zDot: view.getFloat64(base + 89, false) / 1e3,
175
+ zAcc: view.getFloat64(base + 97, false) / 1e3,
176
+ health: 0,
177
+ // Bn health bit not located; observed sats are operational
178
+ freqNum: view.getInt8(base + 29)
179
+ // FCN, signed byte (−7…+6)
105
180
  };
106
181
  }
107
182
  function parseTrimbleNav(data) {
@@ -116,8 +191,8 @@ function parseTrimbleNav(data) {
116
191
  if (f.type !== RETSVDATA) continue;
117
192
  const sub = data[f.payload];
118
193
  retsvCounts[sub] = (retsvCounts[sub] ?? 0) + 1;
119
- if (sub === SUB_GPS_EPHEMERIS && f.len >= 176) {
120
- const eph = decodeGpsEphemeris(data, view, f.start);
194
+ if ((sub === SUB_GPS_EPHEMERIS || sub === SUB_BDS_EPHEMERIS) && f.len >= 176) {
195
+ const eph = sub === SUB_GPS_EPHEMERIS ? decodeGpsEphemeris(view, f.start) : decodeBdsEphemeris(view, f.start);
121
196
  if (!eph) continue;
122
197
  if (lastIode.get(eph.prn) === eph.iode) continue;
123
198
  lastIode.set(eph.prn, eph.iode);
@@ -133,6 +208,13 @@ function parseTrimbleNav(data) {
133
208
  ionoCorrections["GPSA"] = alpha;
134
209
  ionoCorrections["GPSB"] = beta;
135
210
  leapSeconds = Math.trunc(view.getFloat64(p + 94, false));
211
+ } else if (sub === SUB_GLO_EPHEMERIS && f.len >= 125) {
212
+ const eph = decodeGloEphemeris(view, f.start);
213
+ if (!eph) continue;
214
+ const key = eph.tocDate.getTime();
215
+ if (lastIode.get(eph.prn) === key) continue;
216
+ lastIode.set(eph.prn, key);
217
+ ephemerides.push(eph);
136
218
  }
137
219
  }
138
220
  return {
package/dist/index.cjs CHANGED
@@ -9590,68 +9590,139 @@ function* trimbleFrames(data, stats) {
9590
9590
 
9591
9591
  // src/trimble/nav.ts
9592
9592
  var GPS_EPOCH_MS14 = Date.UTC(1980, 0, 6);
9593
+ var BDT_EPOCH_MS4 = Date.UTC(2006, 0, 1);
9593
9594
  var SEC_PER_WEEK10 = 7 * 86400;
9594
9595
  var MS_PER_WEEK9 = SEC_PER_WEEK10 * 1e3;
9595
9596
  var GPS_PI2 = 3.1415926535898;
9597
+ var BDS_WEEK_OFFSET = 1356;
9598
+ var BDS_LEAP_SEC = 14;
9596
9599
  var gpsMs3 = (week, sec) => GPS_EPOCH_MS14 + week * MS_PER_WEEK9 + sec * 1e3;
9597
9600
  var sowOf4 = (dateMs) => dateMs / 1e3 % SEC_PER_WEEK10;
9598
9601
  var SUB_GPS_EPHEMERIS = 1;
9599
9602
  var SUB_ION_UTC = 3;
9600
- function decodeGpsEphemeris2(data, view, base) {
9601
- const prn = data[base + 5];
9602
- if (prn < 1 || prn > 32) return null;
9603
- const week = view.getUint16(base + 6, false);
9604
- const iode = data[base + 11];
9605
- const toc = view.getInt32(base + 16, false);
9606
- const toe = view.getUint32(base + 20, false);
9607
- const tgd = view.getFloat64(base + 24, false);
9608
- const af2 = view.getFloat64(base + 32, false);
9609
- const af1 = view.getFloat64(base + 40, false);
9610
- const af0 = view.getFloat64(base + 48, false);
9611
- const crs = view.getFloat64(base + 56, false);
9612
- const deltaN = view.getFloat64(base + 64, false) * GPS_PI2;
9613
- const m0 = view.getFloat64(base + 72, false) * GPS_PI2;
9614
- const cuc = view.getFloat64(base + 80, false) * GPS_PI2;
9615
- const e = view.getFloat64(base + 88, false);
9616
- const cus = view.getFloat64(base + 96, false) * GPS_PI2;
9617
- const sqrtA = view.getFloat64(base + 104, false);
9618
- const cic = view.getFloat64(base + 112, false) * GPS_PI2;
9619
- const omega0 = view.getFloat64(base + 120, false) * GPS_PI2;
9620
- const cis = view.getFloat64(base + 128, false) * GPS_PI2;
9621
- const i0 = view.getFloat64(base + 136, false) * GPS_PI2;
9622
- const crc = view.getFloat64(base + 144, false);
9623
- const omega = view.getFloat64(base + 152, false) * GPS_PI2;
9624
- const omegaDot = view.getFloat64(base + 160, false) * GPS_PI2;
9625
- const idot = view.getFloat64(base + 168, false) * GPS_PI2;
9626
- const flags = view.getUint32(base + 176, false);
9603
+ var SUB_GLO_EPHEMERIS = 9;
9604
+ var SUB_BDS_EPHEMERIS = 21;
9605
+ function readKepler(view, base) {
9606
+ return {
9607
+ svid: view.getUint8(base + 5),
9608
+ week: view.getUint16(base + 6, false),
9609
+ iode: view.getUint8(base + 11),
9610
+ tocSec: view.getInt32(base + 16, false),
9611
+ toeSec: view.getUint32(base + 20, false),
9612
+ tgd: view.getFloat64(base + 24, false),
9613
+ af2: view.getFloat64(base + 32, false),
9614
+ af1: view.getFloat64(base + 40, false),
9615
+ af0: view.getFloat64(base + 48, false),
9616
+ crs: view.getFloat64(base + 56, false),
9617
+ deltaN: view.getFloat64(base + 64, false) * GPS_PI2,
9618
+ m0: view.getFloat64(base + 72, false) * GPS_PI2,
9619
+ cuc: view.getFloat64(base + 80, false) * GPS_PI2,
9620
+ e: view.getFloat64(base + 88, false),
9621
+ cus: view.getFloat64(base + 96, false) * GPS_PI2,
9622
+ sqrtA: view.getFloat64(base + 104, false),
9623
+ cic: view.getFloat64(base + 112, false) * GPS_PI2,
9624
+ omega0: view.getFloat64(base + 120, false) * GPS_PI2,
9625
+ cis: view.getFloat64(base + 128, false) * GPS_PI2,
9626
+ i0: view.getFloat64(base + 136, false) * GPS_PI2,
9627
+ crc: view.getFloat64(base + 144, false),
9628
+ omega: view.getFloat64(base + 152, false) * GPS_PI2,
9629
+ omegaDot: view.getFloat64(base + 160, false) * GPS_PI2,
9630
+ idot: view.getFloat64(base + 168, false) * GPS_PI2,
9631
+ flags: view.getUint32(base + 176, false)
9632
+ };
9633
+ }
9634
+ function keplerCommon(r) {
9635
+ return {
9636
+ af0: r.af0,
9637
+ af1: r.af1,
9638
+ af2: r.af2,
9639
+ iode: r.iode,
9640
+ crs: r.crs,
9641
+ deltaN: r.deltaN,
9642
+ m0: r.m0,
9643
+ cuc: r.cuc,
9644
+ e: r.e,
9645
+ cus: r.cus,
9646
+ sqrtA: r.sqrtA,
9647
+ cic: r.cic,
9648
+ omega0: r.omega0,
9649
+ cis: r.cis,
9650
+ i0: r.i0,
9651
+ crc: r.crc,
9652
+ omega: r.omega,
9653
+ omegaDot: r.omegaDot,
9654
+ idot: r.idot,
9655
+ tgd: r.tgd
9656
+ };
9657
+ }
9658
+ function decodeGpsEphemeris2(view, base) {
9659
+ const r = readKepler(view, base);
9660
+ if (r.svid < 1 || r.svid > 32) return null;
9661
+ const tocMs = gpsMs3(r.week, r.tocSec);
9627
9662
  return {
9628
9663
  system: "G",
9629
- prn: `G${String(prn).padStart(2, "0")}`,
9630
- toc: sowOf4(gpsMs3(week, toc)),
9631
- tocDate: new Date(gpsMs3(week, toc)),
9632
- af0,
9633
- af1,
9634
- af2,
9635
- iode,
9636
- crs,
9637
- deltaN,
9638
- m0,
9639
- cuc,
9640
- e,
9641
- cus,
9642
- sqrtA,
9643
- toe,
9644
- cic,
9645
- omega0,
9646
- cis,
9647
- i0,
9648
- crc,
9649
- omega,
9650
- omegaDot,
9651
- idot,
9652
- week,
9653
- svHealth: flags >>> 4 & 127,
9654
- tgd
9664
+ prn: `G${String(r.svid).padStart(2, "0")}`,
9665
+ toc: sowOf4(tocMs),
9666
+ tocDate: new Date(tocMs),
9667
+ toe: r.toeSec,
9668
+ week: r.week,
9669
+ svHealth: r.flags >>> 4 & 127,
9670
+ ...keplerCommon(r)
9671
+ };
9672
+ }
9673
+ function decodeBdsEphemeris3(view, base) {
9674
+ const r = readKepler(view, base);
9675
+ if (r.svid < 1 || r.svid > 63) return null;
9676
+ const bdsWeek = r.week - BDS_WEEK_OFFSET;
9677
+ const tocSec = r.tocSec - BDS_LEAP_SEC;
9678
+ const toeSec = r.toeSec - BDS_LEAP_SEC;
9679
+ const tocDate = new Date(
9680
+ BDT_EPOCH_MS4 + bdsWeek * MS_PER_WEEK9 + tocSec * 1e3
9681
+ );
9682
+ return {
9683
+ system: "C",
9684
+ prn: `C${String(r.svid).padStart(2, "0")}`,
9685
+ toc: sowOf4(tocDate.getTime()),
9686
+ tocDate,
9687
+ toe: toeSec,
9688
+ week: bdsWeek,
9689
+ // Health from the same flags nibble as GPS (0 = healthy for the observed
9690
+ // operational BeiDou sats); flags bit 0 is a set-on-all format marker,
9691
+ // not SatH1, so it must not be used here.
9692
+ svHealth: r.flags >>> 4 & 127,
9693
+ ...keplerCommon(r)
9694
+ };
9695
+ }
9696
+ function decodeGloEphemeris2(view, base) {
9697
+ const slot = view.getUint8(base + 5);
9698
+ if (slot < 1 || slot > 24) return null;
9699
+ const week = view.getUint16(base + 6, false);
9700
+ const tow = view.getUint32(base + 8, false);
9701
+ const gpsTimeMs = gpsMs3(week, tow);
9702
+ const leapMs = getGpsLeap(new Date(gpsTimeMs)) * 1e3;
9703
+ const tocMs = gpsTimeMs - leapMs;
9704
+ return {
9705
+ system: "R",
9706
+ prn: `R${String(slot).padStart(2, "0")}`,
9707
+ tocDate: new Date(tocMs),
9708
+ // RINEX stores −τn as the clock bias; the record carries τn (ICD sign).
9709
+ tauN: -view.getFloat64(base + 113, false),
9710
+ gammaN: view.getFloat64(base + 121, false),
9711
+ messageFrameTime: (tocMs - GPS_EPOCH_MS14) / 1e3 % SEC_PER_WEEK10,
9712
+ // State vector: metres / m·s⁻¹ / m·s⁻² → km / km·s⁻¹ / km·s⁻².
9713
+ x: view.getFloat64(base + 33, false) / 1e3,
9714
+ xDot: view.getFloat64(base + 41, false) / 1e3,
9715
+ xAcc: view.getFloat64(base + 49, false) / 1e3,
9716
+ y: view.getFloat64(base + 57, false) / 1e3,
9717
+ yDot: view.getFloat64(base + 65, false) / 1e3,
9718
+ yAcc: view.getFloat64(base + 73, false) / 1e3,
9719
+ z: view.getFloat64(base + 81, false) / 1e3,
9720
+ zDot: view.getFloat64(base + 89, false) / 1e3,
9721
+ zAcc: view.getFloat64(base + 97, false) / 1e3,
9722
+ health: 0,
9723
+ // Bn health bit not located; observed sats are operational
9724
+ freqNum: view.getInt8(base + 29)
9725
+ // FCN, signed byte (−7…+6)
9655
9726
  };
9656
9727
  }
9657
9728
  function parseTrimbleNav(data) {
@@ -9666,8 +9737,8 @@ function parseTrimbleNav(data) {
9666
9737
  if (f.type !== RETSVDATA) continue;
9667
9738
  const sub = data[f.payload];
9668
9739
  retsvCounts[sub] = (retsvCounts[sub] ?? 0) + 1;
9669
- if (sub === SUB_GPS_EPHEMERIS && f.len >= 176) {
9670
- const eph = decodeGpsEphemeris2(data, view, f.start);
9740
+ if ((sub === SUB_GPS_EPHEMERIS || sub === SUB_BDS_EPHEMERIS) && f.len >= 176) {
9741
+ const eph = sub === SUB_GPS_EPHEMERIS ? decodeGpsEphemeris2(view, f.start) : decodeBdsEphemeris3(view, f.start);
9671
9742
  if (!eph) continue;
9672
9743
  if (lastIode.get(eph.prn) === eph.iode) continue;
9673
9744
  lastIode.set(eph.prn, eph.iode);
@@ -9683,6 +9754,13 @@ function parseTrimbleNav(data) {
9683
9754
  ionoCorrections["GPSA"] = alpha;
9684
9755
  ionoCorrections["GPSB"] = beta;
9685
9756
  leapSeconds = Math.trunc(view.getFloat64(p + 94, false));
9757
+ } else if (sub === SUB_GLO_EPHEMERIS && f.len >= 125) {
9758
+ const eph = decodeGloEphemeris2(view, f.start);
9759
+ if (!eph) continue;
9760
+ const key = eph.tocDate.getTime();
9761
+ if (lastIode.get(eph.prn) === key) continue;
9762
+ lastIode.set(eph.prn, key);
9763
+ ephemerides.push(eph);
9686
9764
  }
9687
9765
  }
9688
9766
  return {
@@ -10076,7 +10154,7 @@ function* binexRecords(data, view, stats) {
10076
10154
  // src/binex/nav.ts
10077
10155
  var GPS_EPOCH_MS16 = Date.UTC(1980, 0, 6);
10078
10156
  var GLO_DAY0_MS = Date.UTC(1980, 0, 1);
10079
- var BDT_EPOCH_MS4 = Date.UTC(2006, 0, 1);
10157
+ var BDT_EPOCH_MS5 = Date.UTC(2006, 0, 1);
10080
10158
  var SEC_PER_WEEK11 = 7 * 86400;
10081
10159
  var MS_PER_WEEK11 = SEC_PER_WEEK11 * 1e3;
10082
10160
  var SC2RAD = GPS_PI;
@@ -10245,7 +10323,7 @@ function decodeBeidou(view, p, le) {
10245
10323
  const iode = flag1 >> 6 & 31;
10246
10324
  const svHealth = flag1 & 1;
10247
10325
  const tgd = bdsTgd(flag2 >> 4);
10248
- const tocDate = new Date(BDT_EPOCH_MS4 + week * MS_PER_WEEK11 + toes * 1e3);
10326
+ const tocDate = new Date(BDT_EPOCH_MS5 + week * MS_PER_WEEK11 + toes * 1e3);
10249
10327
  return {
10250
10328
  system: "C",
10251
10329
  prn: `C${two5(prn)}`,
@@ -10713,13 +10791,13 @@ var GM_GPS = 3986005e8;
10713
10791
  var GM_GAL = 3986004418e5;
10714
10792
  var GM_BDS = 3986004418e5;
10715
10793
  var GPS_EPOCH_MS18 = Date.UTC(1980, 0, 6);
10716
- var BDT_EPOCH_MS5 = Date.UTC(2006, 0, 1);
10794
+ var BDT_EPOCH_MS6 = Date.UTC(2006, 0, 1);
10717
10795
  var WEEK_MS = 6048e5;
10718
10796
  var BDT_MINUS_GPST_MS = 14e3;
10719
10797
  var BDS_GEO_PRNS = /* @__PURE__ */ new Set([1, 2, 3, 4, 5, 59, 60, 61, 62, 63]);
10720
10798
  function almanacEpochMs(alm) {
10721
10799
  if (alm.system === "C") {
10722
- return BDT_EPOCH_MS5 + alm.weekAlm * WEEK_MS + alm.toaSec * 1e3 + BDT_MINUS_GPST_MS;
10800
+ return BDT_EPOCH_MS6 + alm.weekAlm * WEEK_MS + alm.toaSec * 1e3 + BDT_MINUS_GPST_MS;
10723
10801
  }
10724
10802
  return GPS_EPOCH_MS18 + alm.weekAlm * WEEK_MS + alm.toaSec * 1e3;
10725
10803
  }
package/dist/index.js CHANGED
@@ -79,7 +79,7 @@ import {
79
79
  parseTrimble,
80
80
  parseTrimbleNav,
81
81
  trimbleFrames
82
- } from "./chunk-U47XUQAT.js";
82
+ } from "./chunk-EPATQ3LT.js";
83
83
  import {
84
84
  binexCrc16,
85
85
  binexCrc32,
package/dist/trimble.cjs CHANGED
@@ -66,70 +66,228 @@ function* trimbleFrames(data, stats) {
66
66
  }
67
67
  }
68
68
 
69
+ // src/constants/time.ts
70
+ var MILLISECONDS_IN_SECOND = 1e3;
71
+ var MILLISECONDS_GPS_TAI = 19e3;
72
+ var START_NTP_TIME = /* @__PURE__ */ new Date("1900-01-01T00:00:00Z");
73
+
74
+ // src/time/gnss.ts
75
+ function getTaiDate(date) {
76
+ return new Date(date.getTime() + MILLISECONDS_GPS_TAI);
77
+ }
78
+ function getNtpTime(date) {
79
+ return getTaiDate(date).getTime() - START_NTP_TIME.getTime();
80
+ }
81
+
82
+ // src/time/utc.ts
83
+ var LEAP_SECONDS_TABLE = [
84
+ [3692217600, 37],
85
+ // 1 Jan 2017
86
+ [3644697600, 36],
87
+ // 1 Jul 2015
88
+ [3550089600, 35],
89
+ // 1 Jul 2012
90
+ [3439756800, 34],
91
+ // 1 Jan 2009
92
+ [3345062400, 33],
93
+ // 1 Jan 2006
94
+ [3124137600, 32],
95
+ // 1 Jan 1999
96
+ [3076704e3, 31],
97
+ // 1 Jul 1997
98
+ [3029443200, 30],
99
+ // 1 Jan 1996
100
+ [2982009600, 29],
101
+ // 1 Jul 1994
102
+ [2950473600, 28],
103
+ // 1 Jul 1993
104
+ [2918937600, 27],
105
+ // 1 Jul 1992
106
+ [2871676800, 26],
107
+ // 1 Jan 1991
108
+ [2840140800, 25],
109
+ // 1 Jan 1990
110
+ [2776982400, 24],
111
+ // 1 Jan 1988
112
+ [2698012800, 23],
113
+ // 1 Jul 1985
114
+ [2634854400, 22],
115
+ // 1 Jul 1983
116
+ [2603318400, 21],
117
+ // 1 Jul 1982
118
+ [2571782400, 20],
119
+ // 1 Jul 1981
120
+ [2524521600, 19],
121
+ // 1 Jan 1980
122
+ [2492985600, 18],
123
+ // 1 Jan 1979
124
+ [2461449600, 17],
125
+ // 1 Jan 1978
126
+ [2429913600, 16],
127
+ // 1 Jan 1977
128
+ [2398291200, 15],
129
+ // 1 Jan 1976
130
+ [2366755200, 14],
131
+ // 1 Jan 1975
132
+ [2335219200, 13],
133
+ // 1 Jan 1974
134
+ [2303683200, 12],
135
+ // 1 Jan 1973
136
+ [2287785600, 11],
137
+ // 1 Jul 1972
138
+ [2272060800, 10]
139
+ // 1 Jan 1972
140
+ ];
141
+ function getLeap(date) {
142
+ const ntp_time = getNtpTime(date);
143
+ for (const [timestamp, leapSeconds] of LEAP_SECONDS_TABLE) {
144
+ if (ntp_time / MILLISECONDS_IN_SECOND - leapSeconds >= timestamp) {
145
+ return leapSeconds;
146
+ }
147
+ }
148
+ return 8;
149
+ }
150
+ function getGpsLeap(date) {
151
+ const leap_seconds = getLeap(date);
152
+ if (leap_seconds < 0) return 0;
153
+ return leap_seconds - 19;
154
+ }
155
+
69
156
  // src/trimble/nav.ts
70
157
  var GPS_EPOCH_MS = Date.UTC(1980, 0, 6);
158
+ var BDT_EPOCH_MS = Date.UTC(2006, 0, 1);
71
159
  var SEC_PER_WEEK = 7 * 86400;
72
160
  var MS_PER_WEEK = SEC_PER_WEEK * 1e3;
73
161
  var GPS_PI = 3.1415926535898;
162
+ var BDS_WEEK_OFFSET = 1356;
163
+ var BDS_LEAP_SEC = 14;
74
164
  var gpsMs = (week, sec) => GPS_EPOCH_MS + week * MS_PER_WEEK + sec * 1e3;
75
165
  var sowOf = (dateMs) => dateMs / 1e3 % SEC_PER_WEEK;
76
166
  var SUB_GPS_EPHEMERIS = 1;
77
167
  var SUB_ION_UTC = 3;
78
- function decodeGpsEphemeris(data, view, base) {
79
- const prn = data[base + 5];
80
- if (prn < 1 || prn > 32) return null;
81
- const week = view.getUint16(base + 6, false);
82
- const iode = data[base + 11];
83
- const toc = view.getInt32(base + 16, false);
84
- const toe = view.getUint32(base + 20, false);
85
- const tgd = view.getFloat64(base + 24, false);
86
- const af2 = view.getFloat64(base + 32, false);
87
- const af1 = view.getFloat64(base + 40, false);
88
- const af0 = view.getFloat64(base + 48, false);
89
- const crs = view.getFloat64(base + 56, false);
90
- const deltaN = view.getFloat64(base + 64, false) * GPS_PI;
91
- const m0 = view.getFloat64(base + 72, false) * GPS_PI;
92
- const cuc = view.getFloat64(base + 80, false) * GPS_PI;
93
- const e = view.getFloat64(base + 88, false);
94
- const cus = view.getFloat64(base + 96, false) * GPS_PI;
95
- const sqrtA = view.getFloat64(base + 104, false);
96
- const cic = view.getFloat64(base + 112, false) * GPS_PI;
97
- const omega0 = view.getFloat64(base + 120, false) * GPS_PI;
98
- const cis = view.getFloat64(base + 128, false) * GPS_PI;
99
- const i0 = view.getFloat64(base + 136, false) * GPS_PI;
100
- const crc = view.getFloat64(base + 144, false);
101
- const omega = view.getFloat64(base + 152, false) * GPS_PI;
102
- const omegaDot = view.getFloat64(base + 160, false) * GPS_PI;
103
- const idot = view.getFloat64(base + 168, false) * GPS_PI;
104
- const flags = view.getUint32(base + 176, false);
168
+ var SUB_GLO_EPHEMERIS = 9;
169
+ var SUB_BDS_EPHEMERIS = 21;
170
+ function readKepler(view, base) {
171
+ return {
172
+ svid: view.getUint8(base + 5),
173
+ week: view.getUint16(base + 6, false),
174
+ iode: view.getUint8(base + 11),
175
+ tocSec: view.getInt32(base + 16, false),
176
+ toeSec: view.getUint32(base + 20, false),
177
+ tgd: view.getFloat64(base + 24, false),
178
+ af2: view.getFloat64(base + 32, false),
179
+ af1: view.getFloat64(base + 40, false),
180
+ af0: view.getFloat64(base + 48, false),
181
+ crs: view.getFloat64(base + 56, false),
182
+ deltaN: view.getFloat64(base + 64, false) * GPS_PI,
183
+ m0: view.getFloat64(base + 72, false) * GPS_PI,
184
+ cuc: view.getFloat64(base + 80, false) * GPS_PI,
185
+ e: view.getFloat64(base + 88, false),
186
+ cus: view.getFloat64(base + 96, false) * GPS_PI,
187
+ sqrtA: view.getFloat64(base + 104, false),
188
+ cic: view.getFloat64(base + 112, false) * GPS_PI,
189
+ omega0: view.getFloat64(base + 120, false) * GPS_PI,
190
+ cis: view.getFloat64(base + 128, false) * GPS_PI,
191
+ i0: view.getFloat64(base + 136, false) * GPS_PI,
192
+ crc: view.getFloat64(base + 144, false),
193
+ omega: view.getFloat64(base + 152, false) * GPS_PI,
194
+ omegaDot: view.getFloat64(base + 160, false) * GPS_PI,
195
+ idot: view.getFloat64(base + 168, false) * GPS_PI,
196
+ flags: view.getUint32(base + 176, false)
197
+ };
198
+ }
199
+ function keplerCommon(r) {
200
+ return {
201
+ af0: r.af0,
202
+ af1: r.af1,
203
+ af2: r.af2,
204
+ iode: r.iode,
205
+ crs: r.crs,
206
+ deltaN: r.deltaN,
207
+ m0: r.m0,
208
+ cuc: r.cuc,
209
+ e: r.e,
210
+ cus: r.cus,
211
+ sqrtA: r.sqrtA,
212
+ cic: r.cic,
213
+ omega0: r.omega0,
214
+ cis: r.cis,
215
+ i0: r.i0,
216
+ crc: r.crc,
217
+ omega: r.omega,
218
+ omegaDot: r.omegaDot,
219
+ idot: r.idot,
220
+ tgd: r.tgd
221
+ };
222
+ }
223
+ function decodeGpsEphemeris(view, base) {
224
+ const r = readKepler(view, base);
225
+ if (r.svid < 1 || r.svid > 32) return null;
226
+ const tocMs = gpsMs(r.week, r.tocSec);
105
227
  return {
106
228
  system: "G",
107
- prn: `G${String(prn).padStart(2, "0")}`,
108
- toc: sowOf(gpsMs(week, toc)),
109
- tocDate: new Date(gpsMs(week, toc)),
110
- af0,
111
- af1,
112
- af2,
113
- iode,
114
- crs,
115
- deltaN,
116
- m0,
117
- cuc,
118
- e,
119
- cus,
120
- sqrtA,
121
- toe,
122
- cic,
123
- omega0,
124
- cis,
125
- i0,
126
- crc,
127
- omega,
128
- omegaDot,
129
- idot,
130
- week,
131
- svHealth: flags >>> 4 & 127,
132
- tgd
229
+ prn: `G${String(r.svid).padStart(2, "0")}`,
230
+ toc: sowOf(tocMs),
231
+ tocDate: new Date(tocMs),
232
+ toe: r.toeSec,
233
+ week: r.week,
234
+ svHealth: r.flags >>> 4 & 127,
235
+ ...keplerCommon(r)
236
+ };
237
+ }
238
+ function decodeBdsEphemeris(view, base) {
239
+ const r = readKepler(view, base);
240
+ if (r.svid < 1 || r.svid > 63) return null;
241
+ const bdsWeek = r.week - BDS_WEEK_OFFSET;
242
+ const tocSec = r.tocSec - BDS_LEAP_SEC;
243
+ const toeSec = r.toeSec - BDS_LEAP_SEC;
244
+ const tocDate = new Date(
245
+ BDT_EPOCH_MS + bdsWeek * MS_PER_WEEK + tocSec * 1e3
246
+ );
247
+ return {
248
+ system: "C",
249
+ prn: `C${String(r.svid).padStart(2, "0")}`,
250
+ toc: sowOf(tocDate.getTime()),
251
+ tocDate,
252
+ toe: toeSec,
253
+ week: bdsWeek,
254
+ // Health from the same flags nibble as GPS (0 = healthy for the observed
255
+ // operational BeiDou sats); flags bit 0 is a set-on-all format marker,
256
+ // not SatH1, so it must not be used here.
257
+ svHealth: r.flags >>> 4 & 127,
258
+ ...keplerCommon(r)
259
+ };
260
+ }
261
+ function decodeGloEphemeris(view, base) {
262
+ const slot = view.getUint8(base + 5);
263
+ if (slot < 1 || slot > 24) return null;
264
+ const week = view.getUint16(base + 6, false);
265
+ const tow = view.getUint32(base + 8, false);
266
+ const gpsTimeMs = gpsMs(week, tow);
267
+ const leapMs = getGpsLeap(new Date(gpsTimeMs)) * 1e3;
268
+ const tocMs = gpsTimeMs - leapMs;
269
+ return {
270
+ system: "R",
271
+ prn: `R${String(slot).padStart(2, "0")}`,
272
+ tocDate: new Date(tocMs),
273
+ // RINEX stores −τn as the clock bias; the record carries τn (ICD sign).
274
+ tauN: -view.getFloat64(base + 113, false),
275
+ gammaN: view.getFloat64(base + 121, false),
276
+ messageFrameTime: (tocMs - GPS_EPOCH_MS) / 1e3 % SEC_PER_WEEK,
277
+ // State vector: metres / m·s⁻¹ / m·s⁻² → km / km·s⁻¹ / km·s⁻².
278
+ x: view.getFloat64(base + 33, false) / 1e3,
279
+ xDot: view.getFloat64(base + 41, false) / 1e3,
280
+ xAcc: view.getFloat64(base + 49, false) / 1e3,
281
+ y: view.getFloat64(base + 57, false) / 1e3,
282
+ yDot: view.getFloat64(base + 65, false) / 1e3,
283
+ yAcc: view.getFloat64(base + 73, false) / 1e3,
284
+ z: view.getFloat64(base + 81, false) / 1e3,
285
+ zDot: view.getFloat64(base + 89, false) / 1e3,
286
+ zAcc: view.getFloat64(base + 97, false) / 1e3,
287
+ health: 0,
288
+ // Bn health bit not located; observed sats are operational
289
+ freqNum: view.getInt8(base + 29)
290
+ // FCN, signed byte (−7…+6)
133
291
  };
134
292
  }
135
293
  function parseTrimbleNav(data) {
@@ -144,8 +302,8 @@ function parseTrimbleNav(data) {
144
302
  if (f.type !== RETSVDATA) continue;
145
303
  const sub = data[f.payload];
146
304
  retsvCounts[sub] = (retsvCounts[sub] ?? 0) + 1;
147
- if (sub === SUB_GPS_EPHEMERIS && f.len >= 176) {
148
- const eph = decodeGpsEphemeris(data, view, f.start);
305
+ if ((sub === SUB_GPS_EPHEMERIS || sub === SUB_BDS_EPHEMERIS) && f.len >= 176) {
306
+ const eph = sub === SUB_GPS_EPHEMERIS ? decodeGpsEphemeris(view, f.start) : decodeBdsEphemeris(view, f.start);
149
307
  if (!eph) continue;
150
308
  if (lastIode.get(eph.prn) === eph.iode) continue;
151
309
  lastIode.set(eph.prn, eph.iode);
@@ -161,6 +319,13 @@ function parseTrimbleNav(data) {
161
319
  ionoCorrections["GPSA"] = alpha;
162
320
  ionoCorrections["GPSB"] = beta;
163
321
  leapSeconds = Math.trunc(view.getFloat64(p + 94, false));
322
+ } else if (sub === SUB_GLO_EPHEMERIS && f.len >= 125) {
323
+ const eph = decodeGloEphemeris(view, f.start);
324
+ if (!eph) continue;
325
+ const key = eph.tocDate.getTime();
326
+ if (lastIode.get(eph.prn) === key) continue;
327
+ lastIode.set(eph.prn, key);
328
+ ephemerides.push(eph);
164
329
  }
165
330
  }
166
331
  return {
@@ -25,24 +25,29 @@ declare function trimbleFrames(data: Uint8Array, stats: {
25
25
 
26
26
  /**
27
27
  * Trimble RT17/RT27 navigation-message decoding: RETSVDATA (0x55)
28
- * GPS ephemeris (subtype 1) and ION / UTC data (subtype 3).
28
+ * GPS ephemeris (subtype 1), GLONASS ephemeris (subtype 9), BeiDou
29
+ * ephemeris (subtype 21) and ION / UTC data (subtype 3).
29
30
  *
30
- * Ported field-for-field from RTKLIB's `src/rcv/rt17.c`
31
+ * The GPS path is ported field-for-field from RTKLIB's `src/rcv/rt17.c`
31
32
  * (`decode_gps_ephemeris` / `decode_ion_utc_data`, tomojitakasu/RTKLIB,
32
33
  * Copyright (C) 2014 D. A. Cook / T. Takasu, BSD-2-Clause). All scalar
33
34
  * fields are big-endian; the semicircle angular/harmonic fields are
34
- * scaled by π to radians, exactly as RTKLIB does.
35
+ * scaled by π to radians, exactly as RTKLIB does. BeiDou (subtype 21)
36
+ * reuses the identical 176-byte Keplerian struct — established from a
37
+ * real DLF100NLD1 capture (√a ≈ 5282.6 m^½ ⇒ BeiDou MEO, i₀ ≈ 55°) — with
38
+ * the GPS→BDT time-scale conversion (week − 1356, SOW − 14 s) applied so
39
+ * the record matches `parseSbfNav`'s BDSNav output.
35
40
  *
36
41
  * Output records mirror what `parseNavFile` produces for the equivalent
37
- * RINEX 3 GPS navigation record and match the NovAtel/SBF ephemeris
38
- * paths (Keplerian `tocDate` a GPS-scale Date, angles in radians).
42
+ * RINEX 3 navigation record and match the NovAtel/SBF ephemeris paths
43
+ * (GPS: GPS-scale `tocDate`; BeiDou: naive-BDT `tocDate`; angles in rad).
39
44
  *
40
- * RTKLIB decodes only these two RETSVDATA subtypes; the GLONASS,
41
- * Galileo, BeiDou and QZSS ephemeris/almanac subtypes (RETSVDATA
42
- * subtypes 9/11/13/21/23/27, seen on the DLF100NLD1 Trimble stream) are
43
- * not handled here. Validated against a real DLF100NLD1 capture: the
44
- * subtype-1 GPS ephemerides decode to physical Keplerian elements
45
- * (√a ≈ 5153.6 m^½, i₀ ≈ 55°, week 2429).
45
+ * The subtype→constellation map is confirmed by RTKLIB's rt17.c
46
+ * RETSVDATA table (st[]: 1 = GPS Eph, 9 = GLONASS Eph, 11 = Galileo Eph,
47
+ * 21 = BeiDou Eph) — but RTKLIB only *decodes* subtypes 1 and 3, so the
48
+ * GLONASS/BeiDou field layouts here were reverse-engineered and validated
49
+ * against physics + the 2026-07-27 BRDC. Still not decoded: Galileo
50
+ * (subtype 11) and the QZSS/almanac subtypes (13/23/27 on this stream).
46
51
  */
47
52
 
48
53
  interface TrimbleNavResult {
@@ -61,9 +66,10 @@ interface TrimbleNavResult {
61
66
  badChecksum: number;
62
67
  }
63
68
  /**
64
- * Decode every RETSVDATA navigation message (GPS ephemeris, ION/UTC) in
65
- * a Trimble binary byte stream. Repeated broadcasts of an unchanged GPS
66
- * ephemeris are suppressed by issue of data (IODE), as RTKLIB does.
69
+ * Decode every RETSVDATA navigation message (GPS/BeiDou/GLONASS
70
+ * ephemeris, ION/UTC) in a Trimble binary byte stream. Repeated
71
+ * broadcasts of an unchanged ephemeris are suppressed by issue of data
72
+ * (Keplerian) / reference epoch (GLONASS), as RTKLIB does.
67
73
  */
68
74
  declare function parseTrimbleNav(data: Uint8Array): TrimbleNavResult;
69
75
 
package/dist/trimble.d.ts CHANGED
@@ -25,24 +25,29 @@ declare function trimbleFrames(data: Uint8Array, stats: {
25
25
 
26
26
  /**
27
27
  * Trimble RT17/RT27 navigation-message decoding: RETSVDATA (0x55)
28
- * GPS ephemeris (subtype 1) and ION / UTC data (subtype 3).
28
+ * GPS ephemeris (subtype 1), GLONASS ephemeris (subtype 9), BeiDou
29
+ * ephemeris (subtype 21) and ION / UTC data (subtype 3).
29
30
  *
30
- * Ported field-for-field from RTKLIB's `src/rcv/rt17.c`
31
+ * The GPS path is ported field-for-field from RTKLIB's `src/rcv/rt17.c`
31
32
  * (`decode_gps_ephemeris` / `decode_ion_utc_data`, tomojitakasu/RTKLIB,
32
33
  * Copyright (C) 2014 D. A. Cook / T. Takasu, BSD-2-Clause). All scalar
33
34
  * fields are big-endian; the semicircle angular/harmonic fields are
34
- * scaled by π to radians, exactly as RTKLIB does.
35
+ * scaled by π to radians, exactly as RTKLIB does. BeiDou (subtype 21)
36
+ * reuses the identical 176-byte Keplerian struct — established from a
37
+ * real DLF100NLD1 capture (√a ≈ 5282.6 m^½ ⇒ BeiDou MEO, i₀ ≈ 55°) — with
38
+ * the GPS→BDT time-scale conversion (week − 1356, SOW − 14 s) applied so
39
+ * the record matches `parseSbfNav`'s BDSNav output.
35
40
  *
36
41
  * Output records mirror what `parseNavFile` produces for the equivalent
37
- * RINEX 3 GPS navigation record and match the NovAtel/SBF ephemeris
38
- * paths (Keplerian `tocDate` a GPS-scale Date, angles in radians).
42
+ * RINEX 3 navigation record and match the NovAtel/SBF ephemeris paths
43
+ * (GPS: GPS-scale `tocDate`; BeiDou: naive-BDT `tocDate`; angles in rad).
39
44
  *
40
- * RTKLIB decodes only these two RETSVDATA subtypes; the GLONASS,
41
- * Galileo, BeiDou and QZSS ephemeris/almanac subtypes (RETSVDATA
42
- * subtypes 9/11/13/21/23/27, seen on the DLF100NLD1 Trimble stream) are
43
- * not handled here. Validated against a real DLF100NLD1 capture: the
44
- * subtype-1 GPS ephemerides decode to physical Keplerian elements
45
- * (√a ≈ 5153.6 m^½, i₀ ≈ 55°, week 2429).
45
+ * The subtype→constellation map is confirmed by RTKLIB's rt17.c
46
+ * RETSVDATA table (st[]: 1 = GPS Eph, 9 = GLONASS Eph, 11 = Galileo Eph,
47
+ * 21 = BeiDou Eph) — but RTKLIB only *decodes* subtypes 1 and 3, so the
48
+ * GLONASS/BeiDou field layouts here were reverse-engineered and validated
49
+ * against physics + the 2026-07-27 BRDC. Still not decoded: Galileo
50
+ * (subtype 11) and the QZSS/almanac subtypes (13/23/27 on this stream).
46
51
  */
47
52
 
48
53
  interface TrimbleNavResult {
@@ -61,9 +66,10 @@ interface TrimbleNavResult {
61
66
  badChecksum: number;
62
67
  }
63
68
  /**
64
- * Decode every RETSVDATA navigation message (GPS ephemeris, ION/UTC) in
65
- * a Trimble binary byte stream. Repeated broadcasts of an unchanged GPS
66
- * ephemeris are suppressed by issue of data (IODE), as RTKLIB does.
69
+ * Decode every RETSVDATA navigation message (GPS/BeiDou/GLONASS
70
+ * ephemeris, ION/UTC) in a Trimble binary byte stream. Repeated
71
+ * broadcasts of an unchanged ephemeris are suppressed by issue of data
72
+ * (Keplerian) / reference epoch (GLONASS), as RTKLIB does.
67
73
  */
68
74
  declare function parseTrimbleNav(data: Uint8Array): TrimbleNavResult;
69
75
 
package/dist/trimble.js CHANGED
@@ -2,7 +2,9 @@ import {
2
2
  parseTrimble,
3
3
  parseTrimbleNav,
4
4
  trimbleFrames
5
- } from "./chunk-U47XUQAT.js";
5
+ } from "./chunk-EPATQ3LT.js";
6
+ import "./chunk-HVXYFUCB.js";
7
+ import "./chunk-LEEU5OIO.js";
6
8
  export {
7
9
  parseTrimble,
8
10
  parseTrimbleNav,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gnss-js",
3
- "version": "1.39.0",
3
+ "version": "1.41.0",
4
4
  "description": "Comprehensive GNSS library for JavaScript — time scales, coordinates, RINEX parsing, RTCM3 decoding, orbit computation, and signal analysis",
5
5
  "type": "module",
6
6
  "sideEffects": false,