@airframes/acars-decoder 1.6.2 → 1.6.4

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.
package/dist/index.js CHANGED
@@ -204,6 +204,32 @@ var Label_5Z = class extends DecoderPlugin {
204
204
  }
205
205
  };
206
206
 
207
+ // lib/utils/coordinate_utils.ts
208
+ var CoordinateUtils = class {
209
+ static decodeStringCoordinates(stringCoords) {
210
+ var results = {};
211
+ const firstChar = stringCoords.substring(0, 1);
212
+ let middleChar = stringCoords.substring(6, 7);
213
+ let longitudeChars = stringCoords.substring(7, 13);
214
+ if (middleChar == " ") {
215
+ middleChar = stringCoords.substring(7, 8);
216
+ longitudeChars = stringCoords.substring(8, 14);
217
+ }
218
+ if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
219
+ results.latitude = Number(stringCoords.substring(1, 6)) / 1e3 * (firstChar === "S" ? -1 : 1);
220
+ results.longitude = Number(longitudeChars) / 1e3 * (middleChar === "W" ? -1 : 1);
221
+ } else {
222
+ return;
223
+ }
224
+ return results;
225
+ }
226
+ static coordinateString(coords) {
227
+ const latDir = coords.latitude > 0 ? "N" : "S";
228
+ const lonDir = coords.longitude > 0 ? "E" : "W";
229
+ return `${Math.abs(coords.latitude).toFixed(3)} ${latDir}, ${Math.abs(coords.longitude).toFixed(3)} ${lonDir}`;
230
+ }
231
+ };
232
+
207
233
  // lib/plugins/Label_12_N_Space.ts
208
234
  var Label_12_N_Space = class extends DecoderPlugin {
209
235
  name = "label-12-n-space";
@@ -225,16 +251,16 @@ var Label_12_N_Space = class extends DecoderPlugin {
225
251
  console.log(`Label 12 N : results`);
226
252
  console.log(results);
227
253
  }
228
- decodeResult.raw.latitude_direction = results.groups.lat;
229
- decodeResult.raw.latitude = Number(results.groups.lat_coord);
230
- decodeResult.raw.longitude_direction = results.groups.long;
231
- decodeResult.raw.longitude = Number(results.groups.long_coord);
254
+ decodeResult.raw.position = {
255
+ latitude: Number(results.groups.lat_coord) * (results.groups.lat == "N" ? 1 : -1),
256
+ longitude: Number(results.groups.long_coord) * (results.groups.long == "E" ? 1 : -1)
257
+ };
232
258
  decodeResult.raw.flight_level = results.groups.alt == "GRD" || results.groups.alt == "***" ? "0" : Number(results.groups.alt);
233
259
  decodeResult.formatted.items.push({
234
260
  type: "aircraft_position",
235
261
  code: "POS",
236
262
  label: "Aircraft Position",
237
- value: `${results.groups.lat_coord} ${decodeResult.raw.latitude_direction}, ${results.groups.long_coord} ${decodeResult.raw.longitude_direction}`
263
+ value: CoordinateUtils.coordinateString(decodeResult.raw.position)
238
264
  });
239
265
  decodeResult.formatted.items.push({
240
266
  type: "flight_level",
@@ -257,37 +283,6 @@ var Label_12_N_Space = class extends DecoderPlugin {
257
283
  }
258
284
  };
259
285
 
260
- // lib/utils/coordinate_utils.ts
261
- var CoordinateUtils = class {
262
- static decodeStringCoordinates(stringCoords) {
263
- var results = {};
264
- const firstChar = stringCoords.substring(0, 1);
265
- let middleChar = stringCoords.substring(6, 7);
266
- let longitudeChars = stringCoords.substring(7, 13);
267
- if (middleChar == " ") {
268
- middleChar = stringCoords.substring(7, 8);
269
- longitudeChars = stringCoords.substring(8, 14);
270
- }
271
- if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
272
- results.latitudeDirection = firstChar;
273
- results.latitude = Number(stringCoords.substring(1, 6)) / 1e3 * (firstChar === "S" ? -1 : 1);
274
- results.longitudeDirection = middleChar;
275
- results.longitude = Number(longitudeChars) / 1e3 * (middleChar === "W" ? -1 : 1);
276
- } else {
277
- return;
278
- }
279
- return results;
280
- }
281
- static coordinateString(coords) {
282
- return `${Math.abs(coords.latitude)} ${coords.latitudeDirection}, ${Math.abs(coords.longitude)} ${coords.longitudeDirection}`;
283
- }
284
- static latLonToCoordinateString(lat, lon) {
285
- const latDir = lat > 0 ? "N" : "S";
286
- const lonDir = lon > 0 ? "E" : "W";
287
- return `${Math.abs(lat)} ${latDir}, ${Math.abs(lon)} ${lonDir}`;
288
- }
289
- };
290
-
291
286
  // lib/plugins/Label_15.ts
292
287
  var Label_15 = class extends DecoderPlugin {
293
288
  name = "label-5z";
@@ -341,9 +336,7 @@ var Label_15_FST = class extends DecoderPlugin {
341
336
  const middleChar = stringCoords.substring(7, 8);
342
337
  decodeResult.raw.position = {};
343
338
  if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
344
- decodeResult.raw.position.latitudeDirection = firstChar;
345
339
  decodeResult.raw.position.latitude = Number(stringCoords.substring(1, 7)) / 1e4 * (firstChar === "S" ? -1 : 1);
346
- decodeResult.raw.position.longitudeDirection = middleChar;
347
340
  decodeResult.raw.position.longitude = Number(stringCoords.substring(8, 26)) / 1e5 * (middleChar === "W" ? -1 : 1);
348
341
  } else {
349
342
  decodeResult.decoded = false;
@@ -395,16 +388,16 @@ var Label_16_N_Space = class extends DecoderPlugin {
395
388
  console.log(`Label 16 N : results`);
396
389
  console.log(results);
397
390
  }
398
- decodeResult.raw.latitude_direction = results.groups.lat;
399
- decodeResult.raw.latitude = Number(results.groups.lat_coord);
400
- decodeResult.raw.longitude_direction = results.groups.long;
401
- decodeResult.raw.longitude = Number(results.groups.long_coord);
391
+ decodeResult.raw.position = {
392
+ latitude: Number(results.groups.lat_coord) * (results.groups.lat == "N" ? 1 : -1),
393
+ longitude: Number(results.groups.long_coord) * (results.groups.long == "E" ? 1 : -1)
394
+ };
402
395
  decodeResult.raw.flight_level = results.groups.alt == "GRD" || results.groups.alt == "***" ? "0" : Number(results.groups.alt);
403
396
  decodeResult.formatted.items.push({
404
397
  type: "aircraft_position",
405
398
  code: "POS",
406
399
  label: "Aircraft Position",
407
- value: `${decodeResult.raw.latitude} ${decodeResult.raw.latitude_direction}, ${decodeResult.raw.longitude} ${decodeResult.raw.longitude_direction}`
400
+ value: CoordinateUtils.coordinateString(decodeResult.raw.position)
408
401
  });
409
402
  decodeResult.formatted.items.push({
410
403
  type: "flight_level",
@@ -420,15 +413,15 @@ var Label_16_N_Space = class extends DecoderPlugin {
420
413
  console.log(`Label 16 N : results`);
421
414
  console.log(results);
422
415
  }
423
- decodeResult.raw.latitude_direction = results.groups.lat;
424
- decodeResult.raw.latitude = Number(results.groups.lat_coord);
425
- decodeResult.raw.longitude_direction = results.groups.long;
426
- decodeResult.raw.longitude = Number(results.groups.long_coord);
416
+ decodeResult.raw.position = {
417
+ latitude: Number(results.groups.lat_coord) * (results.groups.lat == "N" ? 1 : -1),
418
+ longitude: Number(results.groups.long_coord) * (results.groups.long == "E" ? 1 : -1)
419
+ };
427
420
  decodeResult.formatted.items.push({
428
421
  type: "aircraft_position",
429
422
  code: "POS",
430
423
  label: "Aircraft Position",
431
- value: `${results.groups.lat_coord} ${decodeResult.raw.latitude_direction}, ${results.groups.long_coord} ${decodeResult.raw.longitude_direction}`
424
+ value: CoordinateUtils.coordinateString(decodeResult.raw.position)
432
425
  });
433
426
  decodeResult.decoded = true;
434
427
  decodeResult.decoder.decodeLevel = "full";
@@ -483,11 +476,14 @@ var DateTimeUtils = class {
483
476
  /**
484
477
  *
485
478
  * @param time HHMMSS
486
- * @param date MMDDYY
479
+ * @param date MMDDYY or MMDDYYYY
487
480
  * @returns seconds since epoch
488
481
  */
489
482
  static convertDateTimeToEpoch(time, date) {
490
- const timestamp = `20${date.substring(4, 6)}-${date.substring(0, 2)}-${date.substring(2, 4)}T${time.substring(0, 2)}:${time.substring(2, 4)}:${time.substring(4, 6)}.000Z`;
483
+ if (date.length === 6) {
484
+ date = date.substring(0, 4) + `20${date.substring(4, 6)}`;
485
+ }
486
+ const timestamp = `${date.substring(4, 8)}-${date.substring(0, 2)}-${date.substring(2, 4)}T${time.substring(0, 2)}:${time.substring(2, 4)}:${time.substring(4, 6)}.000Z`;
491
487
  const millis = Date.parse(timestamp);
492
488
  return millis / 1e3;
493
489
  }
@@ -579,11 +575,13 @@ var Label_20_POS = class extends DecoderPlugin {
579
575
  console.log(`DEBUG: ${this.name}: Variation 2 detected`);
580
576
  const rawCoords = fields[0];
581
577
  decodeResult.raw.position = CoordinateUtils.decodeStringCoordinates(rawCoords);
582
- decodeResult.formatted.items.push({
583
- type: "position",
584
- label: "Position",
585
- value: CoordinateUtils.coordinateString(decodeResult.raw.position)
586
- });
578
+ if (decodeResult.raw.position) {
579
+ decodeResult.formatted.items.push({
580
+ type: "position",
581
+ label: "Position",
582
+ value: CoordinateUtils.coordinateString(decodeResult.raw.position)
583
+ });
584
+ }
587
585
  decodeResult.decoded = true;
588
586
  decodeResult.decoder.decodeLevel = "full";
589
587
  } else {
@@ -1089,7 +1087,7 @@ var Label_80 = class extends DecoderPlugin {
1089
1087
  const lon = Number(posResult.groups.lng) * (posResult.groups.lngd === "W" ? -1 : 1);
1090
1088
  const latitude = Number.isInteger(lat) ? lat / 1e3 : lat / 100;
1091
1089
  const longitude = Number.isInteger(lon) ? lon / 1e3 : lon / 100;
1092
- decodeResult.raw.aircraft_position = {
1090
+ decodeResult.raw.position = {
1093
1091
  latitude,
1094
1092
  longitude
1095
1093
  };
@@ -1097,7 +1095,7 @@ var Label_80 = class extends DecoderPlugin {
1097
1095
  type: "position",
1098
1096
  code: "POS",
1099
1097
  label: "Position",
1100
- value: `${Math.abs(latitude).toPrecision(5)} ${posResult.groups.latd}, ${Math.abs(longitude).toPrecision(5)} ${posResult.groups.lngd}`
1098
+ value: CoordinateUtils.coordinateString(decodeResult.raw.position)
1101
1099
  });
1102
1100
  break;
1103
1101
  }
@@ -1240,7 +1238,10 @@ var RouteUtils = class _RouteUtils {
1240
1238
  static waypointToString(waypoint) {
1241
1239
  let s = waypoint.name;
1242
1240
  if (waypoint.latitude && waypoint.longitude) {
1243
- s += `(${CoordinateUtils.latLonToCoordinateString(waypoint.latitude, waypoint.longitude)})`;
1241
+ s += `(${CoordinateUtils.coordinateString({ latitude: waypoint.latitude, longitude: waypoint.longitude })})`;
1242
+ }
1243
+ if (waypoint.offset) {
1244
+ s += `[${waypoint.offset.bearing}\xB0 ${waypoint.offset.distance}nm]`;
1244
1245
  }
1245
1246
  if (waypoint.time && waypoint.timeFormat) {
1246
1247
  s += `@${_RouteUtils.timestampToString(waypoint.time, waypoint.timeFormat)}`;
@@ -1248,14 +1249,23 @@ var RouteUtils = class _RouteUtils {
1248
1249
  return s;
1249
1250
  }
1250
1251
  static getWaypoint(leg) {
1252
+ const regex = leg.match(/^([A-Z]+)(\d{3})-(\d{4})$/);
1253
+ if (regex?.length == 4) {
1254
+ return { name: regex[1], offset: { bearing: parseInt(regex[2]), distance: parseInt(regex[3]) / 10 } };
1255
+ }
1251
1256
  const waypoint = leg.split(",");
1252
1257
  if (waypoint.length == 2) {
1253
1258
  const position = CoordinateUtils.decodeStringCoordinates(waypoint[1]);
1254
- return { name: waypoint[0], latitude: position.latitude, longitude: position.longitude };
1259
+ if (position) {
1260
+ return { name: waypoint[0], latitude: position.latitude, longitude: position.longitude };
1261
+ }
1255
1262
  }
1256
- if (leg.length == 14) {
1263
+ if (leg.length == 13 || leg.length == 14) {
1257
1264
  const position = CoordinateUtils.decodeStringCoordinates(leg);
1258
- return { name: waypoint[0], latitude: position.latitude, longitude: position.longitude };
1265
+ const name = waypoint.length == 2 ? waypoint[0] : "";
1266
+ if (position) {
1267
+ return { name, latitude: position.latitude, longitude: position.longitude };
1268
+ }
1259
1269
  }
1260
1270
  return { name: leg };
1261
1271
  }
@@ -1315,7 +1325,7 @@ var FlightPlanUtils = class {
1315
1325
  addRoute(decodeResult, value);
1316
1326
  break;
1317
1327
  case "R":
1318
- addDepartureRunway(decodeResult, value);
1328
+ addRunway(decodeResult, value);
1319
1329
  break;
1320
1330
  default:
1321
1331
  if (allKnownFields) {
@@ -1329,41 +1339,106 @@ var FlightPlanUtils = class {
1329
1339
  return allKnownFields;
1330
1340
  }
1331
1341
  };
1342
+ function parseMessageType(decodeResult, messageType) {
1343
+ let decoded = true;
1344
+ const parts = messageType.split("#");
1345
+ if (parts.length == 1) {
1346
+ if (parts[0].startsWith("POS") && parts[0].length !== 3 && !parts[0].startsWith("POS/")) {
1347
+ decoded = processPosition(decodeResult, parts[0].substring(3));
1348
+ }
1349
+ return decoded;
1350
+ } else if (parts.length == 2) {
1351
+ if (parts[0].length > 0) {
1352
+ decodeResult.remaining.text += parts[0].substring(0, 3);
1353
+ decodeResult.raw.flight_number = parts[0].substring(3);
1354
+ decodeResult.remaining.text += "#" + parts[1].substring(0, 3);
1355
+ }
1356
+ if (parts[1].substring(3, 6) === "POS" && parts[1].length !== 6 && parts[1].substring(3, 7) !== "POS/") {
1357
+ decoded = processPosition(decodeResult, parts[1].substring(6));
1358
+ }
1359
+ decodeResult.raw.message_type = messageType;
1360
+ return decoded;
1361
+ }
1362
+ decodeResult.remaining.text += messageType;
1363
+ return false;
1364
+ }
1332
1365
  function parseHeader(decodeResult, header) {
1333
1366
  let allKnownFields = true;
1334
1367
  const fields = header.split("/");
1335
- for (let i = 1; i < fields.length - 1; ++i) {
1368
+ allKnownFields = allKnownFields && parseMessageType(decodeResult, fields[0]);
1369
+ for (let i = 1; i < fields.length; ++i) {
1336
1370
  if (fields[i].startsWith("FN")) {
1337
1371
  decodeResult.raw.flight_number = fields[i].substring(2);
1338
1372
  } else if (fields[i].startsWith("SN")) {
1339
1373
  decodeResult.raw.serial_number = fields[i].substring(2);
1340
1374
  } else if (fields[i].startsWith("TS")) {
1341
1375
  const ts = fields[i].substring(2).split(",");
1342
- decodeResult.raw.message_timestamp = DateTimeUtils.convertDateTimeToEpoch(ts[0], ts[1]);
1376
+ let time = DateTimeUtils.convertDateTimeToEpoch(ts[0], ts[1]);
1377
+ if (Number.isNaN(time)) {
1378
+ const date = ts[1].substring(2, 4) + ts[1].substring(0, 2) + ts[1].substring(4, 6);
1379
+ time = DateTimeUtils.convertDateTimeToEpoch(ts[0], date);
1380
+ }
1381
+ decodeResult.raw.message_timestamp = time;
1382
+ } else if (fields[i].startsWith("PS")) {
1383
+ const pos = fields[i].substring(2);
1384
+ allKnownFields == allKnownFields && processPosition(decodeResult, pos);
1385
+ } else if (fields[i].startsWith("DT")) {
1386
+ const icao = fields[i].substring(2);
1387
+ decodeResult.raw.arrival_icao = icao;
1388
+ decodeResult.formatted.items.push({
1389
+ type: "destination",
1390
+ code: "DST",
1391
+ label: "Destination",
1392
+ value: decodeResult.raw.arrival_icao
1393
+ });
1394
+ } else if (fields[i].startsWith("RF")) {
1395
+ decodeResult.formatted.items.push({
1396
+ type: "status",
1397
+ code: "ROUTE_STATUS",
1398
+ label: "Route Status",
1399
+ value: "Route Filed"
1400
+ });
1401
+ decodeResult.raw.route_status = "RF";
1402
+ if (fields[i].length > 2) {
1403
+ addRoute(decodeResult, fields[i].substring(2));
1404
+ }
1405
+ } else if (fields[i] == "RP") {
1406
+ decodeResult.raw.route_status = "RP";
1407
+ decodeResult.formatted.items.push({
1408
+ type: "status",
1409
+ code: "ROUTE_STATUS",
1410
+ label: "Route Status",
1411
+ value: "Route Planned"
1412
+ });
1413
+ decodeResult.raw.route_status = fields[i];
1414
+ } else if (fields[i] == "RI") {
1415
+ decodeResult.raw.route_status = "RI";
1416
+ decodeResult.formatted.items.push({
1417
+ type: "status",
1418
+ code: "ROUTE_STATUS",
1419
+ label: "Route Status",
1420
+ value: "Route Inactive"
1421
+ });
1343
1422
  } else {
1344
1423
  decodeResult.remaining.text += "/" + fields[i];
1345
1424
  allKnownFields = false;
1346
1425
  }
1347
1426
  }
1348
- decodeResult.raw.route_status = fields[fields.length - 1];
1349
- var text;
1350
- if (decodeResult.raw.route_status == "RP") {
1351
- text = "Route Planned";
1352
- } else if (decodeResult.raw.route_status == "RI") {
1353
- text = "Route Inactive";
1354
- } else if (decodeResult.raw.route_status == "RF") {
1355
- text = "Route Filed";
1356
- } else {
1357
- text = decodeResult.raw.route_status;
1358
- }
1359
- decodeResult.formatted.items.push({
1360
- type: "status",
1361
- code: "ROUTE_STATUS",
1362
- label: "Route Status",
1363
- value: text
1364
- });
1365
1427
  return allKnownFields;
1366
1428
  }
1429
+ function processPosition(decodeResult, value) {
1430
+ const position = CoordinateUtils.decodeStringCoordinates(value);
1431
+ if (position) {
1432
+ decodeResult.raw.position = position;
1433
+ decodeResult.formatted.items.push({
1434
+ type: "aircraft_position",
1435
+ code: "POS",
1436
+ label: "Aircraft Position",
1437
+ value: CoordinateUtils.coordinateString(position)
1438
+ });
1439
+ }
1440
+ return !!position;
1441
+ }
1367
1442
  function addArrivalAirport(decodeResult, value) {
1368
1443
  decodeResult.raw.arrival_icao = value;
1369
1444
  decodeResult.formatted.items.push({
@@ -1382,12 +1457,20 @@ function addDepartureAirport(decodeResult, value) {
1382
1457
  value: decodeResult.raw.departure_icao
1383
1458
  });
1384
1459
  }
1385
- function addDepartureRunway(decodeResult, value) {
1386
- decodeResult.raw.runway = value;
1460
+ function addRunway(decodeResult, value) {
1461
+ if (value.length === 8) {
1462
+ decodeResult.raw.arrival_runway = value.substring(4, 7);
1463
+ decodeResult.formatted.items.push({
1464
+ type: "runway",
1465
+ label: "Arrival Runway",
1466
+ value: decodeResult.raw.arrival_runway
1467
+ });
1468
+ }
1469
+ decodeResult.raw.departure_runway = value.substring(0, 3);
1387
1470
  decodeResult.formatted.items.push({
1388
1471
  type: "runway",
1389
- label: "Runway",
1390
- value: decodeResult.raw.runway
1472
+ label: "Departure Runway",
1473
+ value: decodeResult.raw.departure_runway
1391
1474
  });
1392
1475
  }
1393
1476
  function addRoute(decodeResult, value) {
@@ -1497,7 +1580,7 @@ var Label_H1_POS = class extends DecoderPlugin {
1497
1580
  qualifiers() {
1498
1581
  return {
1499
1582
  labels: ["H1"],
1500
- preambles: ["POS", "#M1BPOS"]
1583
+ preambles: ["POS", "#M1BPOS", "/.POS"]
1501
1584
  //TODO - support data before #
1502
1585
  };
1503
1586
  }
@@ -1506,30 +1589,25 @@ var Label_H1_POS = class extends DecoderPlugin {
1506
1589
  decodeResult.decoder.name = this.name;
1507
1590
  decodeResult.formatted.description = "Position Report";
1508
1591
  decodeResult.message = message;
1592
+ decodeResult.remaining.text = "";
1509
1593
  const checksum = message.text.slice(-4);
1510
- const parts = message.text.replace("#M1B", "").replace("POS", "").slice(0, -4).split(",");
1511
- console.log(parts);
1512
- if (parts.length == 1 && parts[0].startsWith("/RF")) {
1513
- decodeResult.raw.route_status == "RF";
1514
- decodeResult.formatted.items.push({
1515
- type: "status",
1516
- code: "ROUTE_STATUS",
1517
- label: "Route Status",
1518
- value: "Route Filed"
1519
- });
1520
- decodeResult.raw.route = { waypoints: parts[0].substring(3, parts[0].length).split(".").map((leg) => RouteUtils.getWaypoint(leg)) };
1521
- decodeResult.formatted.items.push({
1522
- type: "aircraft_route",
1523
- code: "ROUTE",
1524
- label: "Aircraft Route",
1525
- value: RouteUtils.routeToString(decodeResult.raw.route)
1526
- });
1527
- processChecksum(decodeResult, checksum);
1528
- decodeResult.decoded = true;
1529
- decodeResult.decoder.decodeLevel = "full";
1594
+ const header = findHeader(message.text.slice(0, -4));
1595
+ const decoded = FlightPlanUtils.processFlightPlan(decodeResult, header.split(":"));
1596
+ const parts = message.text.replace(header, "").slice(0, -4).split(",");
1597
+ if (parts.length == 1) {
1598
+ if (decoded) {
1599
+ processChecksum(decodeResult, checksum);
1600
+ decodeResult.decoded = true;
1601
+ decodeResult.decoder.decodeLevel = "full";
1602
+ } else if (decodeResult.remaining.text.length > 0) {
1603
+ processChecksum(decodeResult, checksum);
1604
+ decodeResult.decoded = true;
1605
+ decodeResult.decoder.decodeLevel = "partial";
1606
+ } else {
1607
+ decodeResult.decoded = false;
1608
+ decodeResult.decoder.decodeLevel = "none";
1609
+ }
1530
1610
  } else if (parts.length === 10) {
1531
- decodeResult.remaining.text = "";
1532
- processPosition(decodeResult, parts[0]);
1533
1611
  processAlt(decodeResult, parts[3]);
1534
1612
  processRoute(decodeResult, parts[1], parts[2], parts[4], parts[5], parts[6]);
1535
1613
  processTemp(decodeResult, parts[7]);
@@ -1539,8 +1617,6 @@ var Label_H1_POS = class extends DecoderPlugin {
1539
1617
  decodeResult.decoded = true;
1540
1618
  decodeResult.decoder.decodeLevel = "partial";
1541
1619
  } else if (parts.length === 11) {
1542
- decodeResult.remaining.text = "";
1543
- processPosition(decodeResult, parts[0]);
1544
1620
  processAlt(decodeResult, parts[3]);
1545
1621
  processRoute(decodeResult, parts[1], parts[2], parts[4], parts[5], parts[6], parts[10]);
1546
1622
  processTemp(decodeResult, parts[7]);
@@ -1549,9 +1625,18 @@ var Label_H1_POS = class extends DecoderPlugin {
1549
1625
  processChecksum(decodeResult, checksum);
1550
1626
  decodeResult.decoded = true;
1551
1627
  decodeResult.decoder.decodeLevel = "partial";
1628
+ } else if (parts.length === 12) {
1629
+ const date = parts[11].substring(2, 4) + parts[11].substring(0, 2) + parts[11].substring(4, 6);
1630
+ processUnknown(decodeResult, parts[3]);
1631
+ processRoute(decodeResult, parts[1], parts[2], parts[4], parts[5], parts[6], date);
1632
+ processTemp(decodeResult, parts[7]);
1633
+ processUnknown(decodeResult, parts[8]);
1634
+ processUnknown(decodeResult, parts[9]);
1635
+ processUnknown(decodeResult, parts[10]);
1636
+ processChecksum(decodeResult, checksum);
1637
+ decodeResult.decoded = true;
1638
+ decodeResult.decoder.decodeLevel = "partial";
1552
1639
  } else if (parts.length === 14) {
1553
- decodeResult.remaining.text = "";
1554
- processPosition(decodeResult, parts[0]);
1555
1640
  processAlt(decodeResult, parts[3]);
1556
1641
  processRoute(decodeResult, parts[1], parts[2], parts[4], parts[5], parts[6]);
1557
1642
  processTemp(decodeResult, parts[7]);
@@ -1564,9 +1649,48 @@ var Label_H1_POS = class extends DecoderPlugin {
1564
1649
  processChecksum(decodeResult, checksum);
1565
1650
  decodeResult.decoded = true;
1566
1651
  decodeResult.decoder.decodeLevel = "partial";
1652
+ } else if (parts.length === 15) {
1653
+ processUnknown(decodeResult, parts[1]);
1654
+ let date = void 0;
1655
+ if (parts[2].startsWith("/DC")) {
1656
+ date = parts[2].substring(3);
1657
+ } else {
1658
+ processUnknown(decodeResult, parts[2]);
1659
+ }
1660
+ processUnknown(decodeResult, parts[3]);
1661
+ const fields = parts[4].split("/");
1662
+ for (let i = 0; i < fields.length; ++i) {
1663
+ const field = fields[i];
1664
+ if (field.startsWith("PS")) {
1665
+ processPosition2(decodeResult, field.substring(2));
1666
+ } else {
1667
+ if (i === 0) {
1668
+ processUnknown(decodeResult, field);
1669
+ } else {
1670
+ processUnknown(decodeResult, "/" + field);
1671
+ }
1672
+ }
1673
+ }
1674
+ processRoute(decodeResult, parts[7], parts[5], parts[9], parts[8], void 0, date);
1675
+ processAlt(decodeResult, parts[6]);
1676
+ processTemp(decodeResult, parts[10]);
1677
+ processUnknown(decodeResult, parts[11]);
1678
+ processUnknown(decodeResult, parts[12]);
1679
+ processUnknown(decodeResult, parts[13]);
1680
+ processUnknown(decodeResult, parts[14]);
1681
+ processChecksum(decodeResult, checksum);
1682
+ decodeResult.decoded = true;
1683
+ decodeResult.decoder.decodeLevel = "partial";
1684
+ } else if (parts.length === 21) {
1685
+ processRunway(decodeResult, parts[1]);
1686
+ processUnknown(decodeResult, parts.slice(2, 11).join(","));
1687
+ processTemp(decodeResult, parts[11]);
1688
+ processUnknown(decodeResult, parts.slice(12, 20).join(","));
1689
+ FlightPlanUtils.processFlightPlan(decodeResult, parts[20].split(":"));
1690
+ processChecksum(decodeResult, checksum);
1691
+ decodeResult.decoded = true;
1692
+ decodeResult.decoder.decodeLevel = "partial";
1567
1693
  } else if (parts.length === 32) {
1568
- decodeResult.remaining.text = "";
1569
- processPosition(decodeResult, parts[0]);
1570
1694
  processRunway(decodeResult, parts[1]);
1571
1695
  const time = parts[2];
1572
1696
  processUnknown(decodeResult, parts[3]);
@@ -1584,14 +1708,14 @@ var Label_H1_POS = class extends DecoderPlugin {
1584
1708
  processAlt(decodeResult, parts[22]);
1585
1709
  processUnknown(decodeResult, parts.slice(23, 31).join(","));
1586
1710
  const allProcessed = FlightPlanUtils.processFlightPlan(decodeResult, (parts[31] + checksum).split(":"));
1587
- processRoute(decodeResult, past, time, next, eta, "?");
1711
+ processRoute(decodeResult, past, time, next, eta);
1588
1712
  decodeResult.decoded = true;
1589
1713
  decodeResult.decoder.decodeLevel = "partial";
1590
1714
  } else {
1591
1715
  if (options.debug) {
1592
1716
  console.log(`Decoder: Unknown H1 message: ${message.text}`);
1593
1717
  }
1594
- decodeResult.remaining.text = message.text;
1718
+ decodeResult.remaining.text += message.text;
1595
1719
  decodeResult.decoded = false;
1596
1720
  decodeResult.decoder.decodeLevel = "none";
1597
1721
  }
@@ -1601,18 +1725,17 @@ var Label_H1_POS = class extends DecoderPlugin {
1601
1725
  function processUnknown(decodeResult, value) {
1602
1726
  decodeResult.remaining.text += "," + value;
1603
1727
  }
1604
- function processPosition(decodeResult, value) {
1728
+ function processPosition2(decodeResult, value) {
1605
1729
  const position = CoordinateUtils.decodeStringCoordinates(value);
1606
- decodeResult.raw.latitude_direction = position.latitudeDirection;
1607
- decodeResult.raw.latitude = Math.abs(position.latitude);
1608
- decodeResult.raw.longitude_direction = position.longitudeDirection;
1609
- decodeResult.raw.longitude = Math.abs(position.longitude);
1610
- decodeResult.formatted.items.push({
1611
- type: "aircraft_position",
1612
- code: "POS",
1613
- label: "Aircraft Position",
1614
- value: CoordinateUtils.coordinateString(position)
1615
- });
1730
+ if (position) {
1731
+ decodeResult.raw.position = position;
1732
+ decodeResult.formatted.items.push({
1733
+ type: "aircraft_position",
1734
+ code: "POS",
1735
+ label: "Aircraft Position",
1736
+ value: CoordinateUtils.coordinateString(position)
1737
+ });
1738
+ }
1616
1739
  }
1617
1740
  function processAlt(decodeResult, value) {
1618
1741
  decodeResult.raw.altitude = Number(value) * 100;
@@ -1633,11 +1756,11 @@ function processTemp(decodeResult, value) {
1633
1756
  });
1634
1757
  }
1635
1758
  function processRunway(decodeResult, value) {
1636
- decodeResult.raw.runway = value.replace("RW", "");
1759
+ decodeResult.raw.arrival_runway = value.replace("RW", "");
1637
1760
  decodeResult.formatted.items.push({
1638
1761
  type: "runway",
1639
- label: "Runway",
1640
- value: decodeResult.raw.runway
1762
+ label: "Arrival Runway",
1763
+ value: decodeResult.raw.arrival_runway
1641
1764
  });
1642
1765
  }
1643
1766
  function processGndspd(decodeResult, value) {
@@ -1650,16 +1773,17 @@ function processGndspd(decodeResult, value) {
1650
1773
  });
1651
1774
  }
1652
1775
  function processRoute(decodeResult, last, time, next, eta, then, date) {
1653
- let waypoints;
1654
- waypoints = date === void 0 ? [
1655
- { name: last || "?,", time: DateTimeUtils.convertHHMMSSToTod(time), timeFormat: "tod" },
1656
- { name: next || "?", time: DateTimeUtils.convertHHMMSSToTod(eta), timeFormat: "tod" },
1657
- { name: then || "?" }
1658
- ] : [
1659
- { name: last || "?,", time: DateTimeUtils.convertDateTimeToEpoch(time, date), timeFormat: "epoch" },
1660
- { name: next || "?", time: DateTimeUtils.convertDateTimeToEpoch(eta, date), timeFormat: "epoch" },
1661
- { name: then || "?" }
1662
- ];
1776
+ const lastTime = date ? DateTimeUtils.convertDateTimeToEpoch(time, date) : DateTimeUtils.convertHHMMSSToTod(time);
1777
+ const nextTime = date ? DateTimeUtils.convertDateTimeToEpoch(eta, date) : DateTimeUtils.convertHHMMSSToTod(eta);
1778
+ const timeFormat = date ? "epoch" : "tod";
1779
+ const lastWaypoint = RouteUtils.getWaypoint(last);
1780
+ lastWaypoint.time = lastTime;
1781
+ lastWaypoint.timeFormat = timeFormat;
1782
+ const nextWaypoint = RouteUtils.getWaypoint(next);
1783
+ nextWaypoint.time = nextTime;
1784
+ nextWaypoint.timeFormat = timeFormat;
1785
+ const thenWaypoint = RouteUtils.getWaypoint(then || "?");
1786
+ const waypoints = [lastWaypoint, nextWaypoint, thenWaypoint];
1663
1787
  decodeResult.raw.route = { waypoints };
1664
1788
  decodeResult.formatted.items.push({
1665
1789
  type: "aircraft_route",
@@ -1677,6 +1801,70 @@ function processChecksum(decodeResult, value) {
1677
1801
  value: "0x" + ("0000" + decodeResult.raw.checksum.toString(16)).slice(-4)
1678
1802
  });
1679
1803
  }
1804
+ function findHeader(text) {
1805
+ const parts = text.split(",");
1806
+ const header = parts[0];
1807
+ if (header.indexOf("/TS") === -1) {
1808
+ return header;
1809
+ }
1810
+ return parts[0] + "," + parts[1];
1811
+ }
1812
+
1813
+ // lib/plugins/Label_H1_WRN.ts
1814
+ var Label_H1_WRN = class extends DecoderPlugin {
1815
+ name = "label-h1-wrn";
1816
+ qualifiers() {
1817
+ return {
1818
+ labels: ["H1"],
1819
+ preambles: ["WRN", "#CFBWRN"]
1820
+ };
1821
+ }
1822
+ decode(message, options = {}) {
1823
+ let decodeResult = this.defaultResult;
1824
+ decodeResult.decoder.name = this.name;
1825
+ decodeResult.formatted.description = "Warning Message";
1826
+ decodeResult.message = message;
1827
+ const parts = message.text.split("/WN");
1828
+ if (parts.length > 1) {
1829
+ decodeResult.remaining.text = "";
1830
+ const fields = parts[0].split("/");
1831
+ for (let i = 1; i < fields.length; i++) {
1832
+ const field = fields[i];
1833
+ if (field.startsWith("PN")) {
1834
+ processUnknown2(decodeResult, "/" + field);
1835
+ } else {
1836
+ processUnknown2(decodeResult, "/" + field);
1837
+ }
1838
+ }
1839
+ const data = parts[1].substring(0, 20);
1840
+ const msg = parts[1].substring(20);
1841
+ const datetime = data.substring(0, 12);
1842
+ const date = datetime.substring(4, 6) + datetime.substring(2, 4) + datetime.substring(0, 2);
1843
+ processUnknown2(decodeResult, data.substring(12));
1844
+ decodeResult.raw.message_timestamp = DateTimeUtils.convertDateTimeToEpoch(datetime.substring(6), date);
1845
+ decodeResult.raw.warning_message = msg;
1846
+ decodeResult.formatted.items.push({
1847
+ type: "warning",
1848
+ code: "WRN",
1849
+ label: "Warning Message",
1850
+ value: decodeResult.raw.warning_message
1851
+ });
1852
+ decodeResult.decoded = true;
1853
+ decodeResult.decoder.decodeLevel = "partial";
1854
+ } else {
1855
+ if (options.debug) {
1856
+ console.log(`Decoder: Unknown H1 message: ${message.text}`);
1857
+ }
1858
+ decodeResult.remaining.text = message.text;
1859
+ decodeResult.decoded = false;
1860
+ decodeResult.decoder.decodeLevel = "none";
1861
+ }
1862
+ return decodeResult;
1863
+ }
1864
+ };
1865
+ function processUnknown2(decodeResult, value) {
1866
+ decodeResult.remaining.text += value;
1867
+ }
1680
1868
 
1681
1869
  // lib/plugins/Label_SQ.ts
1682
1870
  var Label_SQ = class extends DecoderPlugin {
@@ -1959,7 +2147,7 @@ var Label_QQ = class extends DecoderPlugin {
1959
2147
 
1960
2148
  // lib/utils/miam.ts
1961
2149
  var Base85 = __toESM(require("base85"));
1962
- var Zlib = __toESM(require("zlib"));
2150
+ var zlib = __toESM(require("minizlib"));
1963
2151
  var MIAMCoreV1CRCLength = 4;
1964
2152
  var MIAMCoreV2CRCLength = 2;
1965
2153
  var MIAMCoreUtils = class {
@@ -2669,7 +2857,10 @@ var MIAMCoreUtils = class {
2669
2857
  if (body !== void 0 && body.length > 0) {
2670
2858
  if ([1 /* Deflate */, 1 /* Deflate */].indexOf(pduCompression) >= 0) {
2671
2859
  try {
2672
- pduData = Zlib.inflateRawSync(body, { windowBits: 15 });
2860
+ const decompress = new zlib.InflateRaw({ windowBits: 15 });
2861
+ decompress.write(body);
2862
+ decompress.flush(zlib.constants.Z_SYNC_FLUSH);
2863
+ pduData = decompress.read();
2673
2864
  } catch (e) {
2674
2865
  pduErrors.push("Inflation failed for body: " + e);
2675
2866
  }
@@ -2781,6 +2972,7 @@ var MessageDecoder = class {
2781
2972
  this.registerPlugin(new Label_B6_Forwardslash(this));
2782
2973
  this.registerPlugin(new Label_H1_FPN(this));
2783
2974
  this.registerPlugin(new Label_H1_POS(this));
2975
+ this.registerPlugin(new Label_H1_WRN(this));
2784
2976
  this.registerPlugin(new Label_80(this));
2785
2977
  this.registerPlugin(new Label_8E(this));
2786
2978
  this.registerPlugin(new Label_1M_Slash(this));