@airframes/acars-decoder 1.6.7 → 1.6.8

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
@@ -208,6 +208,12 @@ var Label_5Z = class extends DecoderPlugin {
208
208
 
209
209
  // lib/utils/coordinate_utils.ts
210
210
  var CoordinateUtils = class {
211
+ /**
212
+ * Decode a string of coordinates into an object with latitude and longitude in millidegrees
213
+ * @param stringCoords - The string of coordinates to decode
214
+ *
215
+ * @returns An object with latitude and longitude properties
216
+ */
211
217
  static decodeStringCoordinates(stringCoords) {
212
218
  var results = {};
213
219
  const firstChar = stringCoords.substring(0, 1);
@@ -225,6 +231,33 @@ var CoordinateUtils = class {
225
231
  }
226
232
  return results;
227
233
  }
234
+ /**
235
+ * Decode a string of coordinates into an object with latitude and longitude in degrees and decimal minutes
236
+ * @param stringCoords - The string of coordinates to decode
237
+ *
238
+ * @returns An object with latitude and longitude properties
239
+ */
240
+ static decodeStringCoordinatesDecimalMinutes(stringCoords) {
241
+ var results = {};
242
+ const firstChar = stringCoords.substring(0, 1);
243
+ let middleChar = stringCoords.substring(6, 7);
244
+ let longitudeChars = stringCoords.substring(7, 13);
245
+ if (middleChar == " ") {
246
+ middleChar = stringCoords.substring(7, 8);
247
+ longitudeChars = stringCoords.substring(8, 14);
248
+ }
249
+ const latDeg = Math.trunc(Number(stringCoords.substring(1, 6)) / 1e3);
250
+ const latMin = Number(stringCoords.substring(1, 6)) % 1e3 / 10;
251
+ const lonDeg = Math.trunc(Number(longitudeChars) / 1e3);
252
+ const lonMin = Number(longitudeChars) % 1e3 / 10;
253
+ if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
254
+ results.latitude = (latDeg + latMin / 60) * (firstChar === "S" ? -1 : 1);
255
+ results.longitude = (lonDeg + lonMin / 60) * (middleChar === "W" ? -1 : 1);
256
+ } else {
257
+ return;
258
+ }
259
+ return results;
260
+ }
228
261
  static coordinateString(coords) {
229
262
  const latDir = coords.latitude > 0 ? "N" : "S";
230
263
  const lonDir = coords.longitude > 0 ? "E" : "W";
@@ -595,6 +628,96 @@ var Label_20_POS = class extends DecoderPlugin {
595
628
  }
596
629
  };
597
630
 
631
+ // lib/plugins/Label_21_POS.ts
632
+ var Label_21_POS = class extends DecoderPlugin {
633
+ name = "label-21-pos";
634
+ qualifiers() {
635
+ return {
636
+ labels: ["21"],
637
+ preambles: ["POS"]
638
+ };
639
+ }
640
+ decode(message, options = {}) {
641
+ const decodeResult = this.defaultResult();
642
+ decodeResult.decoder.name = this.name;
643
+ decodeResult.formatted.description = "Position Report";
644
+ decodeResult.message = message;
645
+ decodeResult.raw.preamble = message.text.substring(0, 3);
646
+ const content = message.text.substring(3);
647
+ console.log("Content: " + content);
648
+ const fields = content.split(",");
649
+ console.log("Field Count: " + fields.length);
650
+ if (fields.length == 9) {
651
+ processPosition(decodeResult, fields[0].trim());
652
+ processAlt(decodeResult, fields[3]);
653
+ processTemp(decodeResult, fields[6]);
654
+ processArrvApt(decodeResult, fields[8]);
655
+ decodeResult.raw.remaining = [
656
+ fields[1],
657
+ fields[2],
658
+ fields[4],
659
+ fields[5],
660
+ fields[7]
661
+ ].join(",");
662
+ decodeResult.decoded = true;
663
+ decodeResult.decoder.decodeLevel = "partial";
664
+ } else {
665
+ console.log(`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${content}`);
666
+ decodeResult.decoded = false;
667
+ decodeResult.decoder.decodeLevel = "none";
668
+ }
669
+ return decodeResult;
670
+ }
671
+ };
672
+ function processPosition(decodeResult, value) {
673
+ if (value.length !== 16 && value[0] !== "N" && value[0] !== "S" && value[8] !== "W" && value[8] !== "E") {
674
+ return false;
675
+ }
676
+ const latDir = value[0] === "N" ? 1 : -1;
677
+ const lonDir = value[8] === "E" ? 1 : -1;
678
+ const position = {
679
+ latitude: latDir * Number(value.substring(1, 7)),
680
+ longitude: lonDir * Number(value.substring(9, 15))
681
+ };
682
+ if (position) {
683
+ decodeResult.raw.position = position;
684
+ decodeResult.formatted.items.push({
685
+ type: "aircraft_position",
686
+ code: "POS",
687
+ label: "Aircraft Position",
688
+ value: CoordinateUtils.coordinateString(position)
689
+ });
690
+ }
691
+ return !!position;
692
+ }
693
+ function processAlt(decodeResult, value) {
694
+ decodeResult.raw.altitude = Number(value);
695
+ decodeResult.formatted.items.push({
696
+ type: "altitude",
697
+ code: "ALT",
698
+ label: "Altitude",
699
+ value: `${decodeResult.raw.altitude} feet`
700
+ });
701
+ }
702
+ function processTemp(decodeResult, value) {
703
+ decodeResult.raw.outside_air_temperature = Number(value.substring(1)) * (value.charAt(0) === "M" ? -1 : 1);
704
+ decodeResult.formatted.items.push({
705
+ type: "outside_air_temperature",
706
+ code: "OATEMP",
707
+ label: "Outside Air Temperature (C)",
708
+ value: `${decodeResult.raw.outside_air_temperature}`
709
+ });
710
+ }
711
+ function processArrvApt(decodeResult, value) {
712
+ decodeResult.raw.arrival_icao = value;
713
+ decodeResult.formatted.items.push({
714
+ type: "destination",
715
+ code: "DST",
716
+ label: "Destination",
717
+ value: decodeResult.raw.arrival_icao
718
+ });
719
+ }
720
+
598
721
  // lib/plugins/Label_30_Slash_EA.ts
599
722
  var Label_30_Slash_EA = class extends DecoderPlugin {
600
723
  name = "label-30-slash-ea";
@@ -892,7 +1015,7 @@ var Label_44_POS = class extends DecoderPlugin {
892
1015
  console.log(`Label 44 Position Report: groups`);
893
1016
  console.log(results.groups);
894
1017
  }
895
- decodeResult.raw.position = CoordinateUtils.decodeStringCoordinates(results.groups.unsplit_coords);
1018
+ decodeResult.raw.position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(results.groups.unsplit_coords);
896
1019
  decodeResult.raw.flight_level = results.groups.flight_level_or_ground == "GRD" || results.groups.flight_level_or_ground == "***" ? "0" : Number(results.groups.flight_level_or_ground);
897
1020
  decodeResult.raw.departure_icao = results.groups.departure_icao;
898
1021
  decodeResult.raw.arrival_icao = results.groups.arrival_icao;
@@ -907,9 +1030,9 @@ var Label_44_POS = class extends DecoderPlugin {
907
1030
  }
908
1031
  if (decodeResult.raw.position) {
909
1032
  decodeResult.formatted.items.push({
910
- type: "position",
1033
+ type: "aircraft_position",
911
1034
  code: "POS",
912
- label: "Position",
1035
+ label: "Aircraft Position",
913
1036
  value: CoordinateUtils.coordinateString(decodeResult.raw.position)
914
1037
  });
915
1038
  }
@@ -1217,6 +1340,112 @@ var Label_ColonComma = class extends DecoderPlugin {
1217
1340
  }
1218
1341
  };
1219
1342
 
1343
+ // lib/utils/result_formatter.ts
1344
+ var ResultFormatter = class {
1345
+ static altitude(decodeResult, value) {
1346
+ decodeResult.raw.altitude = value;
1347
+ decodeResult.formatted.items.push({
1348
+ type: "altitude",
1349
+ code: "ALT",
1350
+ label: "Altitude",
1351
+ value: `${decodeResult.raw.altitude} feet`
1352
+ });
1353
+ }
1354
+ static flightNumber(decodeResult, value) {
1355
+ decodeResult.raw.flight_number = value;
1356
+ }
1357
+ static departureAirport(decodeResult, value) {
1358
+ decodeResult.raw.departure_icao = value;
1359
+ decodeResult.formatted.items.push({
1360
+ type: "origin",
1361
+ code: "ORG",
1362
+ label: "Origin",
1363
+ value: decodeResult.raw.departure_icao
1364
+ });
1365
+ }
1366
+ static departureRunway(decodeResult, value) {
1367
+ decodeResult.raw.departure_runway = value;
1368
+ decodeResult.formatted.items.push({
1369
+ type: "runway",
1370
+ code: "DEPRWY",
1371
+ label: "Departure Runway",
1372
+ value: decodeResult.raw.departure_runway
1373
+ });
1374
+ }
1375
+ static arrivalAirport(decodeResult, value) {
1376
+ decodeResult.raw.arrival_icao = value;
1377
+ decodeResult.formatted.items.push({
1378
+ type: "destination",
1379
+ code: "DST",
1380
+ label: "Destination",
1381
+ value: decodeResult.raw.arrival_icao
1382
+ });
1383
+ }
1384
+ static eta(decodeResult, value) {
1385
+ decodeResult.formatted.items.push({
1386
+ type: "eta",
1387
+ code: "ETA",
1388
+ label: "Estimated Time of Arrival",
1389
+ value: value.substring(0, 2) + ":" + value.substring(2, 4) + ":" + value.substring(4, 6)
1390
+ });
1391
+ }
1392
+ static arrivalRunway(decodeResult, value) {
1393
+ decodeResult.raw.arrival_runway = value;
1394
+ decodeResult.formatted.items.push({
1395
+ type: "runway",
1396
+ label: "Arrival Runway",
1397
+ value: decodeResult.raw.arrival_runway
1398
+ });
1399
+ }
1400
+ static currentFuel(decodeResult, value) {
1401
+ decodeResult.raw.fuel_on_board = value;
1402
+ decodeResult.formatted.items.push({
1403
+ type: "fuel_on_board",
1404
+ code: "FOB",
1405
+ label: "Fuel On Board",
1406
+ value: decodeResult.raw.fuel_on_board.toString()
1407
+ });
1408
+ }
1409
+ static remainingFuel(decodeResult, value) {
1410
+ decodeResult.raw.fuel_remaining = value;
1411
+ decodeResult.formatted.items.push({
1412
+ type: "fuel_remaining",
1413
+ label: "Fuel Remaining",
1414
+ value: decodeResult.raw.fuel_remaining.toString()
1415
+ });
1416
+ }
1417
+ static checksum(decodeResult, value) {
1418
+ decodeResult.raw.checksum = Number("0x" + value);
1419
+ decodeResult.formatted.items.push({
1420
+ type: "message_checksum",
1421
+ code: "CHECKSUM",
1422
+ label: "Message Checksum",
1423
+ value: "0x" + ("0000" + decodeResult.raw.checksum.toString(16)).slice(-4)
1424
+ });
1425
+ }
1426
+ static groundspeed(decodeResult, value) {
1427
+ decodeResult.raw.groundspeed = value;
1428
+ decodeResult.formatted.items.push({
1429
+ type: "aircraft_groundspeed",
1430
+ code: "GSPD",
1431
+ label: "Aircraft Groundspeed",
1432
+ value: `${decodeResult.raw.groundspeed}`
1433
+ });
1434
+ }
1435
+ static temperature(decodeResult, value) {
1436
+ decodeResult.raw.outside_air_temperature = Number(value.substring(1)) * (value.charAt(0) === "M" ? -1 : 1);
1437
+ decodeResult.formatted.items.push({
1438
+ type: "outside_air_temperature",
1439
+ code: "OATEMP",
1440
+ label: "Outside Air Temperature (C)",
1441
+ value: `${decodeResult.raw.outside_air_temperature}`
1442
+ });
1443
+ }
1444
+ static unknown(decodeResult, value) {
1445
+ decodeResult.remaining.text += "," + value;
1446
+ }
1447
+ };
1448
+
1220
1449
  // lib/utils/route_utils.ts
1221
1450
  var RouteUtils = class _RouteUtils {
1222
1451
  static routeToString(route) {
@@ -1257,13 +1486,13 @@ var RouteUtils = class _RouteUtils {
1257
1486
  }
1258
1487
  const waypoint = leg.split(",");
1259
1488
  if (waypoint.length == 2) {
1260
- const position = CoordinateUtils.decodeStringCoordinates(waypoint[1]);
1489
+ const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(waypoint[1]);
1261
1490
  if (position) {
1262
1491
  return { name: waypoint[0], latitude: position.latitude, longitude: position.longitude };
1263
1492
  }
1264
1493
  }
1265
1494
  if (leg.length == 13 || leg.length == 14) {
1266
- const position = CoordinateUtils.decodeStringCoordinates(leg);
1495
+ const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(leg);
1267
1496
  const name = waypoint.length == 2 ? waypoint[0] : "";
1268
1497
  if (position) {
1269
1498
  return { name, latitude: position.latitude, longitude: position.longitude };
@@ -1342,13 +1571,126 @@ var FlightPlanUtils = class _FlightPlanUtils {
1342
1571
  }
1343
1572
  static parseHeader(decodeResult, header) {
1344
1573
  let allKnownFields = true;
1345
- const fields = header.split("/");
1574
+ if (header.startsWith("RF")) {
1575
+ decodeResult.formatted.items.push({
1576
+ type: "status",
1577
+ code: "ROUTE_STATUS",
1578
+ label: "Route Status",
1579
+ value: "Route Filed"
1580
+ });
1581
+ decodeResult.raw.route_status = "RF";
1582
+ if (header.length > 2) {
1583
+ addRoute(decodeResult, header.substring(2));
1584
+ }
1585
+ } else if (header.startsWith("RP")) {
1586
+ decodeResult.raw.route_status = "RP";
1587
+ decodeResult.formatted.items.push({
1588
+ type: "status",
1589
+ code: "ROUTE_STATUS",
1590
+ label: "Route Status",
1591
+ value: "Route Planned"
1592
+ });
1593
+ decodeResult.raw.route_status = header;
1594
+ } else if (header.startsWith("RI")) {
1595
+ decodeResult.raw.route_status = "RI";
1596
+ decodeResult.formatted.items.push({
1597
+ type: "status",
1598
+ code: "ROUTE_STATUS",
1599
+ label: "Route Status",
1600
+ value: "Route Inactive"
1601
+ });
1602
+ } else {
1603
+ decodeResult.remaining.text += header;
1604
+ allKnownFields = false;
1605
+ }
1606
+ return allKnownFields;
1607
+ }
1608
+ };
1609
+ function addArrivalAirport(decodeResult, value) {
1610
+ ResultFormatter.arrivalAirport(decodeResult, value);
1611
+ }
1612
+ function addDepartureAirport(decodeResult, value) {
1613
+ ResultFormatter.departureAirport(decodeResult, value);
1614
+ }
1615
+ function addRunway(decodeResult, value) {
1616
+ if (value.length === 8) {
1617
+ ResultFormatter.arrivalRunway(decodeResult, value.substring(4, 7));
1618
+ }
1619
+ ResultFormatter.departureRunway(decodeResult, value.substring(0, 3));
1620
+ }
1621
+ function addRoute(decodeResult, value) {
1622
+ const route = value.split(".");
1623
+ decodeResult.raw.route = { waypoints: route.map((leg) => RouteUtils.getWaypoint(leg)) };
1624
+ decodeResult.formatted.items.push({
1625
+ type: "aircraft_route",
1626
+ code: "ROUTE",
1627
+ label: "Aircraft Route",
1628
+ value: RouteUtils.routeToString(decodeResult.raw.route)
1629
+ });
1630
+ }
1631
+ function addProcedure(decodeResult, value, type) {
1632
+ if (decodeResult.raw.procedures === void 0) {
1633
+ decodeResult.raw.procedures = [];
1634
+ }
1635
+ const data = value.split(".");
1636
+ let waypoints;
1637
+ if (data.length > 1) {
1638
+ waypoints = data.slice(1).map((leg) => RouteUtils.getWaypoint(leg));
1639
+ }
1640
+ const route = { name: data[0], waypoints };
1641
+ decodeResult.raw.procedures.push({ type, route });
1642
+ const procedureName = type.substring(0, 1).toUpperCase() + type.slice(1);
1643
+ let procedureValue = route.name;
1644
+ decodeResult.formatted.items.push({
1645
+ type: `procedure`,
1646
+ code: "proc",
1647
+ label: `${procedureName} Procedure`,
1648
+ value: RouteUtils.routeToString(route)
1649
+ });
1650
+ }
1651
+ function addCompanyRoute(decodeResult, value) {
1652
+ const segments = value.split(".");
1653
+ const parens_idx = segments[0].indexOf("(");
1654
+ let name;
1655
+ let runway;
1656
+ if (parens_idx === -1) {
1657
+ name = segments[0];
1658
+ } else {
1659
+ name = segments[0].slice(0, parens_idx);
1660
+ runway = segments[0].slice(parens_idx + 1, segments[0].indexOf(")"));
1661
+ }
1662
+ let waypoints;
1663
+ if (segments.length > 1) {
1664
+ waypoints = segments.slice(1).map((leg) => RouteUtils.getWaypoint(leg));
1665
+ }
1666
+ decodeResult.raw.company_route = {
1667
+ name,
1668
+ runway,
1669
+ waypoints
1670
+ };
1671
+ decodeResult.formatted.items.push({
1672
+ type: "company_route",
1673
+ code: "CR",
1674
+ label: "Company Route",
1675
+ value: RouteUtils.routeToString(decodeResult.raw.company_route)
1676
+ });
1677
+ }
1678
+
1679
+ // lib/utils/h1_helper.ts
1680
+ var H1Helper = class {
1681
+ static decodeH1Message(decodeResult, message) {
1682
+ let allKnownFields = true;
1683
+ const checksum = message.slice(-4);
1684
+ const data = message.slice(0, message.length - 4);
1685
+ const fields = data.split("/");
1346
1686
  allKnownFields = allKnownFields && parseMessageType(decodeResult, fields[0]);
1347
1687
  for (let i = 1; i < fields.length; ++i) {
1348
1688
  if (fields[i].startsWith("FN")) {
1349
1689
  decodeResult.raw.flight_number = fields[i].substring(2);
1350
1690
  } else if (fields[i].startsWith("SN")) {
1351
1691
  decodeResult.raw.serial_number = fields[i].substring(2);
1692
+ } else if (fields[i].startsWith("DC")) {
1693
+ processDC(decodeResult, fields[i].substring(2).split(","));
1352
1694
  } else if (fields[i].startsWith("TS")) {
1353
1695
  const ts = fields[i].substring(2).split(",");
1354
1696
  let time = DateTimeUtils.convertDateTimeToEpoch(ts[0], ts[1]);
@@ -1356,69 +1698,101 @@ var FlightPlanUtils = class _FlightPlanUtils {
1356
1698
  const date = ts[1].substring(2, 4) + ts[1].substring(0, 2) + ts[1].substring(4, 6);
1357
1699
  time = DateTimeUtils.convertDateTimeToEpoch(ts[0], date);
1358
1700
  }
1701
+ decodeResult.raw.message_date = ts[1];
1359
1702
  decodeResult.raw.message_timestamp = time;
1360
1703
  } else if (fields[i].startsWith("PS")) {
1361
- const pos = fields[i].substring(2);
1362
- allKnownFields == allKnownFields && processPosition(decodeResult, pos);
1704
+ const pos = processPS(decodeResult, fields[i].substring(2).split(","));
1705
+ allKnownFields == allKnownFields && pos;
1363
1706
  } else if (fields[i].startsWith("DT")) {
1364
- const icao = fields[i].substring(2);
1365
- decodeResult.raw.arrival_icao = icao;
1366
- decodeResult.formatted.items.push({
1367
- type: "destination",
1368
- code: "DST",
1369
- label: "Destination",
1370
- value: decodeResult.raw.arrival_icao
1371
- });
1707
+ const data2 = fields[i].substring(2).split(",");
1708
+ const dt = processDT(decodeResult, data2);
1709
+ allKnownFields = allKnownFields && dt;
1372
1710
  } else if (fields[i].startsWith("ID")) {
1373
- const tail = fields[i].substring(2);
1374
- decodeResult.raw.tail = tail;
1711
+ const data2 = fields[i].substring(2).split(",");
1712
+ decodeResult.raw.tail = data2[0];
1375
1713
  decodeResult.formatted.items.push({
1376
1714
  type: "tail",
1715
+ code: "TAIL",
1377
1716
  label: "Tail",
1378
1717
  value: decodeResult.raw.tail
1379
1718
  });
1380
- } else if (fields[i].startsWith("RF")) {
1381
- decodeResult.formatted.items.push({
1382
- type: "status",
1383
- code: "ROUTE_STATUS",
1384
- label: "Route Status",
1385
- value: "Route Filed"
1386
- });
1387
- decodeResult.raw.route_status = "RF";
1388
- if (fields[i].length > 2) {
1389
- addRoute(decodeResult, fields[i].substring(2));
1719
+ if (data2.length > 1) {
1720
+ decodeResult.raw.flight_number = data2[1];
1390
1721
  }
1391
- } else if (fields[i] == "RP") {
1392
- decodeResult.raw.route_status = "RP";
1393
- decodeResult.formatted.items.push({
1394
- type: "status",
1395
- code: "ROUTE_STATUS",
1396
- label: "Route Status",
1397
- value: "Route Planned"
1398
- });
1399
- decodeResult.raw.route_status = fields[i];
1400
- } else if (fields[i] == "RI") {
1401
- decodeResult.raw.route_status = "RI";
1402
- decodeResult.formatted.items.push({
1403
- type: "status",
1404
- code: "ROUTE_STATUS",
1405
- label: "Route Status",
1406
- value: "Route Inactive"
1407
- });
1722
+ if (data2.length > 2) {
1723
+ allKnownFields = false;
1724
+ decodeResult.remaining.text += "," + data2.slice(2).join(",");
1725
+ }
1726
+ } else if (fields[i].startsWith("LR")) {
1727
+ const data2 = fields[i].substring(2).split(",");
1728
+ const lr = processLR(decodeResult, data2);
1729
+ allKnownFields = allKnownFields && lr;
1730
+ } else if (fields[i].startsWith("RI") || fields[i].startsWith("RF") || fields[i].startsWith("RP")) {
1731
+ const fp = FlightPlanUtils.processFlightPlan(decodeResult, fields[i].split(":"));
1732
+ allKnownFields = allKnownFields && fp;
1733
+ } else if (fields[i].startsWith("PR")) {
1734
+ allKnownFields = false;
1735
+ decodeResult.remaining.text += "/" + fields[i];
1736
+ } else if (fields[i].startsWith("PS")) {
1737
+ allKnownFields = false;
1738
+ decodeResult.remaining.text += fields[i];
1408
1739
  } else {
1409
1740
  decodeResult.remaining.text += "/" + fields[i];
1410
1741
  allKnownFields = false;
1411
1742
  }
1412
1743
  }
1744
+ if (decodeResult.formatted.items.length > 0) {
1745
+ ResultFormatter.checksum(decodeResult, checksum);
1746
+ }
1413
1747
  return allKnownFields;
1414
1748
  }
1415
1749
  };
1750
+ function processDT(decodeResult, data) {
1751
+ let allKnownFields = true;
1752
+ if (!decodeResult.raw.arrival_icao) {
1753
+ ResultFormatter.arrivalAirport(decodeResult, data[0]);
1754
+ } else if (decodeResult.raw.arrival_icao != data[0]) {
1755
+ decodeResult.remaining.text += "/" + data;
1756
+ }
1757
+ if (data.length > 1) {
1758
+ ResultFormatter.arrivalRunway(decodeResult, data[1]);
1759
+ }
1760
+ if (data.length > 2) {
1761
+ ResultFormatter.currentFuel(decodeResult, Number(data[2]));
1762
+ }
1763
+ if (data.length > 3) {
1764
+ ResultFormatter.eta(decodeResult, data[3]);
1765
+ }
1766
+ if (data.length > 4) {
1767
+ ResultFormatter.remainingFuel(decodeResult, Number(data[4]));
1768
+ }
1769
+ if (data.length > 5) {
1770
+ allKnownFields = false;
1771
+ decodeResult.remaining.text += "," + data.slice(5).join(",");
1772
+ }
1773
+ return allKnownFields;
1774
+ }
1775
+ function processLR(decodeResult, data) {
1776
+ let allKnownFields = true;
1777
+ if (data.length === 19) {
1778
+ ResultFormatter.unknown(decodeResult, data[1]);
1779
+ ResultFormatter.flightNumber(decodeResult, data[2]);
1780
+ ResultFormatter.departureAirport(decodeResult, data[3]);
1781
+ ResultFormatter.arrivalAirport(decodeResult, data[4]);
1782
+ ResultFormatter.arrivalRunway(decodeResult, data[5]);
1783
+ ResultFormatter.unknown(decodeResult, data.slice(6, 19).join(","));
1784
+ allKnownFields = false;
1785
+ } else {
1786
+ allKnownFields = false;
1787
+ }
1788
+ return allKnownFields;
1789
+ }
1416
1790
  function parseMessageType(decodeResult, messageType) {
1417
1791
  let decoded = true;
1418
1792
  const parts = messageType.split("#");
1419
1793
  if (parts.length == 1) {
1420
1794
  if (parts[0].startsWith("POS") && parts[0].length !== 3 && !parts[0].startsWith("POS/")) {
1421
- decoded = processPosition(decodeResult, parts[0].substring(3));
1795
+ decoded = processPosition2(decodeResult, parts[0].substring(3).split(","));
1422
1796
  }
1423
1797
  return decoded;
1424
1798
  } else if (parts.length == 2) {
@@ -1428,7 +1802,7 @@ function parseMessageType(decodeResult, messageType) {
1428
1802
  decodeResult.remaining.text += "#" + parts[1].substring(0, 3);
1429
1803
  }
1430
1804
  if (parts[1].substring(3, 6) === "POS" && parts[1].length !== 6 && parts[1].substring(3, 7) !== "POS/") {
1431
- decoded = processPosition(decodeResult, parts[1].substring(6));
1805
+ decoded = processPosition2(decodeResult, parts[1].substring(6).split(","));
1432
1806
  }
1433
1807
  decodeResult.raw.message_type = messageType;
1434
1808
  return decoded;
@@ -1436,8 +1810,21 @@ function parseMessageType(decodeResult, messageType) {
1436
1810
  decodeResult.remaining.text += messageType;
1437
1811
  return false;
1438
1812
  }
1439
- function processPosition(decodeResult, value) {
1440
- const position = CoordinateUtils.decodeStringCoordinates(value);
1813
+ function processDC(decodeResult, data) {
1814
+ decodeResult.raw.message_date = data[0];
1815
+ if (data.length === 1) {
1816
+ } else if (data.length === 2) {
1817
+ const date = data[0].substring(2, 4) + data[0].substring(0, 2) + data[0].substring(4, 6);
1818
+ const time = DateTimeUtils.convertDateTimeToEpoch(data[1], data[0]);
1819
+ decodeResult.raw.message_timestamp = time;
1820
+ } else {
1821
+ return false;
1822
+ }
1823
+ return true;
1824
+ }
1825
+ function processPS(decodeResult, data) {
1826
+ let allKnownFields = true;
1827
+ const position = CoordinateUtils.decodeStringCoordinates(data[0]);
1441
1828
  if (position) {
1442
1829
  decodeResult.raw.position = position;
1443
1830
  decodeResult.formatted.items.push({
@@ -1446,46 +1833,76 @@ function processPosition(decodeResult, value) {
1446
1833
  label: "Aircraft Position",
1447
1834
  value: CoordinateUtils.coordinateString(position)
1448
1835
  });
1449
- }
1450
- return !!position;
1451
- }
1452
- function addArrivalAirport(decodeResult, value) {
1453
- decodeResult.raw.arrival_icao = value;
1454
- decodeResult.formatted.items.push({
1455
- type: "destination",
1456
- code: "DST",
1457
- label: "Destination",
1458
- value: decodeResult.raw.arrival_icao
1459
- });
1460
- }
1461
- function addDepartureAirport(decodeResult, value) {
1462
- decodeResult.raw.departure_icao = value;
1463
- decodeResult.formatted.items.push({
1464
- type: "origin",
1465
- code: "ORG",
1466
- label: "Origin",
1467
- value: decodeResult.raw.departure_icao
1468
- });
1836
+ } else {
1837
+ allKnownFields = false;
1838
+ }
1839
+ console.log("PS data.length: ", data.length);
1840
+ console.log("PS data: ", data);
1841
+ if (data.length === 9) {
1842
+ processRoute(decodeResult, data[3], data[1], data[5], data[4], void 0);
1843
+ ResultFormatter.altitude(decodeResult, Number(data[2]) * 100);
1844
+ ResultFormatter.temperature(decodeResult, data[6]);
1845
+ ResultFormatter.unknown(decodeResult, data[7]);
1846
+ ResultFormatter.unknown(decodeResult, data[8]);
1847
+ }
1848
+ if (data.length === 14) {
1849
+ ResultFormatter.altitude(decodeResult, Number(data[3]) * 100);
1850
+ processRoute(decodeResult, data[4], data[2], data[6], data[5], void 0);
1851
+ ResultFormatter.temperature(decodeResult, data[7]);
1852
+ ResultFormatter.groundspeed(decodeResult, Number(data[10]));
1853
+ ResultFormatter.unknown(decodeResult, data[1]);
1854
+ ResultFormatter.unknown(decodeResult, data[8]);
1855
+ ResultFormatter.unknown(decodeResult, data[9]);
1856
+ ResultFormatter.unknown(decodeResult, data.slice(11).join(","));
1857
+ }
1858
+ allKnownFields = false;
1859
+ return allKnownFields;
1469
1860
  }
1470
- function addRunway(decodeResult, value) {
1471
- if (value.length === 8) {
1472
- decodeResult.raw.arrival_runway = value.substring(4, 7);
1861
+ function processPosition2(decodeResult, data) {
1862
+ let allKnownFields = true;
1863
+ const position = CoordinateUtils.decodeStringCoordinates(data[0]);
1864
+ if (position) {
1865
+ decodeResult.raw.position = position;
1473
1866
  decodeResult.formatted.items.push({
1474
- type: "runway",
1475
- label: "Arrival Runway",
1476
- value: decodeResult.raw.arrival_runway
1867
+ type: "aircraft_position",
1868
+ code: "POS",
1869
+ label: "Aircraft Position",
1870
+ value: CoordinateUtils.coordinateString(position)
1477
1871
  });
1478
- }
1479
- decodeResult.raw.departure_runway = value.substring(0, 3);
1480
- decodeResult.formatted.items.push({
1481
- type: "runway",
1482
- label: "Departure Runway",
1483
- value: decodeResult.raw.departure_runway
1484
- });
1872
+ } else {
1873
+ allKnownFields = false;
1874
+ }
1875
+ console.log("data.length: ", data.length);
1876
+ console.log("data: ", data);
1877
+ if (data.length >= 10) {
1878
+ ResultFormatter.altitude(decodeResult, Number(data[3]) * 100);
1879
+ processRoute(decodeResult, data[1], data[2], data[4], data[5], data[6]);
1880
+ ResultFormatter.temperature(decodeResult, data[7]);
1881
+ ResultFormatter.unknown(decodeResult, data[8]);
1882
+ ResultFormatter.unknown(decodeResult, data[9]);
1883
+ }
1884
+ if (data.length >= 14) {
1885
+ ResultFormatter.groundspeed(decodeResult, Number(data[10]));
1886
+ ResultFormatter.unknown(decodeResult, data[11]);
1887
+ ResultFormatter.unknown(decodeResult, data[12]);
1888
+ ResultFormatter.unknown(decodeResult, data[13]);
1889
+ }
1890
+ allKnownFields = false;
1891
+ return allKnownFields;
1485
1892
  }
1486
- function addRoute(decodeResult, value) {
1487
- const route = value.split(".");
1488
- decodeResult.raw.route = { waypoints: route.map((leg) => RouteUtils.getWaypoint(leg)) };
1893
+ function processRoute(decodeResult, last, time, next, eta, then, date) {
1894
+ const lastTime = date ? DateTimeUtils.convertDateTimeToEpoch(time, date) : DateTimeUtils.convertHHMMSSToTod(time);
1895
+ const nextTime = date ? DateTimeUtils.convertDateTimeToEpoch(eta, date) : DateTimeUtils.convertHHMMSSToTod(eta);
1896
+ const timeFormat = date ? "epoch" : "tod";
1897
+ const lastWaypoint = RouteUtils.getWaypoint(last);
1898
+ lastWaypoint.time = lastTime;
1899
+ lastWaypoint.timeFormat = timeFormat;
1900
+ const nextWaypoint = RouteUtils.getWaypoint(next);
1901
+ nextWaypoint.time = nextTime;
1902
+ nextWaypoint.timeFormat = timeFormat;
1903
+ const thenWaypoint = RouteUtils.getWaypoint(then || "?");
1904
+ const waypoints = [lastWaypoint, nextWaypoint, thenWaypoint];
1905
+ decodeResult.raw.route = { waypoints };
1489
1906
  decodeResult.formatted.items.push({
1490
1907
  type: "aircraft_route",
1491
1908
  code: "ROUTE",
@@ -1493,53 +1910,6 @@ function addRoute(decodeResult, value) {
1493
1910
  value: RouteUtils.routeToString(decodeResult.raw.route)
1494
1911
  });
1495
1912
  }
1496
- function addProcedure(decodeResult, value, type) {
1497
- if (decodeResult.raw.procedures === void 0) {
1498
- decodeResult.raw.procedures = [];
1499
- }
1500
- const data = value.split(".");
1501
- let waypoints;
1502
- if (data.length > 1) {
1503
- waypoints = data.slice(1).map((leg) => RouteUtils.getWaypoint(leg));
1504
- }
1505
- const route = { name: data[0], waypoints };
1506
- decodeResult.raw.procedures.push({ type, route });
1507
- const procedureName = type.substring(0, 1).toUpperCase() + type.slice(1);
1508
- let procedureValue = route.name;
1509
- decodeResult.formatted.items.push({
1510
- type: `procedure`,
1511
- code: "proc",
1512
- label: `${procedureName} Procedure`,
1513
- value: RouteUtils.routeToString(route)
1514
- });
1515
- }
1516
- function addCompanyRoute(decodeResult, value) {
1517
- const segments = value.split(".");
1518
- const parens_idx = segments[0].indexOf("(");
1519
- let name;
1520
- let runway;
1521
- if (parens_idx === -1) {
1522
- name = segments[0];
1523
- } else {
1524
- name = segments[0].slice(0, parens_idx);
1525
- runway = segments[0].slice(parens_idx + 1, segments[0].indexOf(")"));
1526
- }
1527
- let waypoints;
1528
- if (segments.length > 1) {
1529
- waypoints = segments.slice(1).map((leg) => RouteUtils.getWaypoint(leg));
1530
- }
1531
- decodeResult.raw.company_route = {
1532
- name,
1533
- runway,
1534
- waypoints
1535
- };
1536
- decodeResult.formatted.items.push({
1537
- type: "company_route",
1538
- code: "CR",
1539
- label: "Company Route",
1540
- value: RouteUtils.routeToString(decodeResult.raw.company_route)
1541
- });
1542
- }
1543
1913
 
1544
1914
  // lib/plugins/Label_H1_FPN.ts
1545
1915
  var Label_H1_FPN = class extends DecoderPlugin {
@@ -1555,15 +1925,12 @@ var Label_H1_FPN = class extends DecoderPlugin {
1555
1925
  decodeResult.decoder.name = this.name;
1556
1926
  decodeResult.formatted.description = "Flight Plan";
1557
1927
  decodeResult.message = message;
1928
+ decodeResult.remaining.text = "";
1558
1929
  const msg = message.text.replace(/\n|\r/g, "");
1559
- const checksum = msg.slice(-4);
1560
- const data = msg.slice(0, msg.length - 4).split(":");
1561
- if (data.length > 1) {
1562
- const fulllyDecoded = FlightPlanUtils.processFlightPlan(decodeResult, data);
1563
- addChecksum(decodeResult, checksum);
1564
- decodeResult.decoded = true;
1565
- decodeResult.decoder.decodeLevel = fulllyDecoded ? "full" : "partial";
1566
- } else {
1930
+ const fulllyDecoded = H1Helper.decodeH1Message(decodeResult, msg);
1931
+ decodeResult.decoded = true;
1932
+ decodeResult.decoder.decodeLevel = fulllyDecoded ? "full" : "partial";
1933
+ if (decodeResult.formatted.items.length === 0) {
1567
1934
  if (options?.debug) {
1568
1935
  console.log(`Decoder: Unknown H1 message: ${message.text}`);
1569
1936
  }
@@ -1574,15 +1941,6 @@ var Label_H1_FPN = class extends DecoderPlugin {
1574
1941
  return decodeResult;
1575
1942
  }
1576
1943
  };
1577
- function addChecksum(decodeResult, value) {
1578
- decodeResult.raw.checksum = Number("0x" + value);
1579
- decodeResult.formatted.items.push({
1580
- type: "message_checksum",
1581
- code: "CHECKSUM",
1582
- label: "Message Checksum",
1583
- value: "0x" + ("0000" + decodeResult.raw.checksum.toString(16)).slice(-4)
1584
- });
1585
- }
1586
1944
 
1587
1945
  // lib/plugins/Label_H1_OHMA.ts
1588
1946
  var zlib = __toESM(require("minizlib"));
@@ -1608,13 +1966,18 @@ var Label_H1_OHMA = class extends DecoderPlugin {
1608
1966
  decompress.flush(zlib.constants.Z_SYNC_FLUSH);
1609
1967
  const result = decompress.read();
1610
1968
  const jsonText = result.toString();
1611
- const json = JSON.parse(jsonText);
1612
1969
  let formattedMsg;
1613
- if (json.message.startsWith("{")) {
1614
- const ohmaMsg = JSON.parse(json.message);
1970
+ let jsonMessage;
1971
+ try {
1972
+ jsonMessage = JSON.parse(jsonText).message;
1973
+ } catch {
1974
+ jsonMessage = jsonText;
1975
+ }
1976
+ try {
1977
+ const ohmaMsg = JSON.parse(jsonMessage);
1615
1978
  formattedMsg = JSON.stringify(ohmaMsg, null, 2);
1616
- } else {
1617
- formattedMsg = json.message;
1979
+ } catch {
1980
+ formattedMsg = jsonMessage;
1618
1981
  }
1619
1982
  decodeResult.decoded = true;
1620
1983
  decodeResult.decoder.decodeLevel = "full";
@@ -1653,225 +2016,20 @@ var Label_H1_POS = class extends DecoderPlugin {
1653
2016
  decodeResult.formatted.description = "Position Report";
1654
2017
  decodeResult.message = message;
1655
2018
  decodeResult.remaining.text = "";
1656
- const checksum = message.text.slice(-4);
1657
- const header = findHeader(message.text.slice(0, -4));
1658
- const decoded = FlightPlanUtils.processFlightPlan(decodeResult, header.split(":"));
1659
- const parts = message.text.replace(header, "").slice(0, -4).split(",");
1660
- if (parts.length == 1) {
1661
- if (decoded) {
1662
- processChecksum(decodeResult, checksum);
1663
- decodeResult.decoded = true;
1664
- decodeResult.decoder.decodeLevel = "full";
1665
- } else if (decodeResult.remaining.text.length > 0) {
1666
- processChecksum(decodeResult, checksum);
1667
- decodeResult.decoded = true;
1668
- decodeResult.decoder.decodeLevel = "partial";
1669
- } else {
1670
- decodeResult.decoded = false;
1671
- decodeResult.decoder.decodeLevel = "none";
1672
- }
1673
- } else if (parts.length === 10) {
1674
- processAlt(decodeResult, parts[3]);
1675
- processRoute(decodeResult, parts[1], parts[2], parts[4], parts[5], parts[6]);
1676
- processTemp(decodeResult, parts[7]);
1677
- processUnknown(decodeResult, parts[8]);
1678
- processUnknown(decodeResult, parts[9]);
1679
- processChecksum(decodeResult, checksum);
1680
- decodeResult.decoded = true;
1681
- decodeResult.decoder.decodeLevel = "partial";
1682
- } else if (parts.length === 11) {
1683
- processAlt(decodeResult, parts[3]);
1684
- processRoute(decodeResult, parts[1], parts[2], parts[4], parts[5], parts[6], parts[10]);
1685
- processTemp(decodeResult, parts[7]);
1686
- processUnknown(decodeResult, parts[8]);
1687
- processUnknown(decodeResult, parts[9]);
1688
- processChecksum(decodeResult, checksum);
1689
- decodeResult.decoded = true;
1690
- decodeResult.decoder.decodeLevel = "partial";
1691
- } else if (parts.length === 12) {
1692
- const date = parts[11].substring(2, 4) + parts[11].substring(0, 2) + parts[11].substring(4, 6);
1693
- processUnknown(decodeResult, parts[3]);
1694
- processRoute(decodeResult, parts[1], parts[2], parts[4], parts[5], parts[6], date);
1695
- processTemp(decodeResult, parts[7]);
1696
- processUnknown(decodeResult, parts[8]);
1697
- processUnknown(decodeResult, parts[9]);
1698
- processUnknown(decodeResult, parts[10]);
1699
- processChecksum(decodeResult, checksum);
1700
- decodeResult.decoded = true;
1701
- decodeResult.decoder.decodeLevel = "partial";
1702
- } else if (parts.length === 14) {
1703
- processAlt(decodeResult, parts[3]);
1704
- processRoute(decodeResult, parts[1], parts[2], parts[4], parts[5], parts[6]);
1705
- processTemp(decodeResult, parts[7]);
1706
- processUnknown(decodeResult, parts[8]);
1707
- processUnknown(decodeResult, parts[9]);
1708
- processGndspd(decodeResult, parts[10]);
1709
- processUnknown(decodeResult, parts[11]);
1710
- processUnknown(decodeResult, parts[12]);
1711
- processUnknown(decodeResult, parts[13]);
1712
- processChecksum(decodeResult, checksum);
1713
- decodeResult.decoded = true;
1714
- decodeResult.decoder.decodeLevel = "partial";
1715
- } else if (parts.length === 15) {
1716
- decodeResult.raw.flight_number = parts[1];
1717
- let date = void 0;
1718
- if (parts[2].startsWith("/DC")) {
1719
- date = parts[2].substring(3);
1720
- } else {
1721
- processUnknown(decodeResult, parts[2]);
1722
- }
1723
- processUnknown(decodeResult, parts[3]);
1724
- const fields = parts[4].split("/");
1725
- for (let i = 0; i < fields.length; ++i) {
1726
- const field = fields[i];
1727
- if (field.startsWith("PS")) {
1728
- processPosition2(decodeResult, field.substring(2));
1729
- } else {
1730
- if (i === 0) {
1731
- processUnknown(decodeResult, field);
1732
- } else {
1733
- processUnknown(decodeResult, "/" + field);
1734
- }
1735
- }
1736
- }
1737
- processRoute(decodeResult, parts[7], parts[5], parts[9], parts[8], void 0, date);
1738
- processAlt(decodeResult, parts[6]);
1739
- processTemp(decodeResult, parts[10]);
1740
- processUnknown(decodeResult, parts[11]);
1741
- processUnknown(decodeResult, parts[12]);
1742
- processUnknown(decodeResult, parts[13]);
1743
- processUnknown(decodeResult, parts[14]);
1744
- processChecksum(decodeResult, checksum);
1745
- decodeResult.decoded = true;
1746
- decodeResult.decoder.decodeLevel = "partial";
1747
- } else if (parts.length === 21) {
1748
- processRunway(decodeResult, parts[1]);
1749
- processUnknown(decodeResult, parts.slice(2, 11).join(","));
1750
- processTemp(decodeResult, parts[11]);
1751
- processUnknown(decodeResult, parts.slice(12, 20).join(","));
1752
- FlightPlanUtils.processFlightPlan(decodeResult, parts[20].split(":"));
1753
- processChecksum(decodeResult, checksum);
1754
- decodeResult.decoded = true;
1755
- decodeResult.decoder.decodeLevel = "partial";
1756
- } else if (parts.length === 32) {
1757
- processRunway(decodeResult, parts[1]);
1758
- const time = parts[2];
1759
- processUnknown(decodeResult, parts[3]);
1760
- const past = parts[4];
1761
- processUnknown(decodeResult, parts[5]);
1762
- const eta = parts[6];
1763
- const next = parts[7];
1764
- processUnknown(decodeResult, parts.slice(8, 14).join(","));
1765
- processUnknown(decodeResult, parts[16]);
1766
- processUnknown(decodeResult, parts[17]);
1767
- processUnknown(decodeResult, parts[18]);
1768
- processGndspd(decodeResult, parts[19]);
1769
- processUnknown(decodeResult, parts[20]);
1770
- processUnknown(decodeResult, parts[21]);
1771
- processAlt(decodeResult, parts[22]);
1772
- processUnknown(decodeResult, parts.slice(23, 31).join(","));
1773
- const allProcessed = FlightPlanUtils.processFlightPlan(decodeResult, (parts[31] + checksum).split(":"));
1774
- processRoute(decodeResult, past, time, next, eta);
1775
- decodeResult.decoded = true;
1776
- decodeResult.decoder.decodeLevel = "partial";
1777
- } else {
1778
- if (options.debug) {
2019
+ const fulllyDecoded = H1Helper.decodeH1Message(decodeResult, message.text);
2020
+ decodeResult.decoded = true;
2021
+ decodeResult.decoder.decodeLevel = fulllyDecoded ? "full" : "partial";
2022
+ if (decodeResult.formatted.items.length === 0) {
2023
+ if (options?.debug) {
1779
2024
  console.log(`Decoder: Unknown H1 message: ${message.text}`);
1780
2025
  }
1781
- decodeResult.remaining.text += message.text;
2026
+ decodeResult.remaining.text = message.text;
1782
2027
  decodeResult.decoded = false;
1783
2028
  decodeResult.decoder.decodeLevel = "none";
1784
2029
  }
1785
2030
  return decodeResult;
1786
2031
  }
1787
2032
  };
1788
- function processUnknown(decodeResult, value) {
1789
- decodeResult.remaining.text += "," + value;
1790
- }
1791
- function processPosition2(decodeResult, value) {
1792
- const position = CoordinateUtils.decodeStringCoordinates(value);
1793
- if (position) {
1794
- decodeResult.raw.position = position;
1795
- decodeResult.formatted.items.push({
1796
- type: "aircraft_position",
1797
- code: "POS",
1798
- label: "Aircraft Position",
1799
- value: CoordinateUtils.coordinateString(position)
1800
- });
1801
- }
1802
- }
1803
- function processAlt(decodeResult, value) {
1804
- decodeResult.raw.altitude = Number(value) * 100;
1805
- decodeResult.formatted.items.push({
1806
- type: "altitude",
1807
- code: "ALT",
1808
- label: "Altitude",
1809
- value: `${decodeResult.raw.altitude} feet`
1810
- });
1811
- }
1812
- function processTemp(decodeResult, value) {
1813
- decodeResult.raw.outside_air_temperature = Number(value.substring(1)) * (value.charAt(0) === "M" ? -1 : 1);
1814
- decodeResult.formatted.items.push({
1815
- type: "outside_air_temperature",
1816
- code: "OATEMP",
1817
- label: "Outside Air Temperature (C)",
1818
- value: `${decodeResult.raw.outside_air_temperature}`
1819
- });
1820
- }
1821
- function processRunway(decodeResult, value) {
1822
- decodeResult.raw.arrival_runway = value.replace("RW", "");
1823
- decodeResult.formatted.items.push({
1824
- type: "runway",
1825
- label: "Arrival Runway",
1826
- value: decodeResult.raw.arrival_runway
1827
- });
1828
- }
1829
- function processGndspd(decodeResult, value) {
1830
- decodeResult.raw.groundspeed = Number(value);
1831
- decodeResult.formatted.items.push({
1832
- type: "aircraft_groundspeed",
1833
- code: "GSPD",
1834
- label: "Aircraft Groundspeed",
1835
- value: `${decodeResult.raw.groundspeed}`
1836
- });
1837
- }
1838
- function processRoute(decodeResult, last, time, next, eta, then, date) {
1839
- const lastTime = date ? DateTimeUtils.convertDateTimeToEpoch(time, date) : DateTimeUtils.convertHHMMSSToTod(time);
1840
- const nextTime = date ? DateTimeUtils.convertDateTimeToEpoch(eta, date) : DateTimeUtils.convertHHMMSSToTod(eta);
1841
- const timeFormat = date ? "epoch" : "tod";
1842
- const lastWaypoint = RouteUtils.getWaypoint(last);
1843
- lastWaypoint.time = lastTime;
1844
- lastWaypoint.timeFormat = timeFormat;
1845
- const nextWaypoint = RouteUtils.getWaypoint(next);
1846
- nextWaypoint.time = nextTime;
1847
- nextWaypoint.timeFormat = timeFormat;
1848
- const thenWaypoint = RouteUtils.getWaypoint(then || "?");
1849
- const waypoints = [lastWaypoint, nextWaypoint, thenWaypoint];
1850
- decodeResult.raw.route = { waypoints };
1851
- decodeResult.formatted.items.push({
1852
- type: "aircraft_route",
1853
- code: "ROUTE",
1854
- label: "Aircraft Route",
1855
- value: RouteUtils.routeToString(decodeResult.raw.route)
1856
- });
1857
- }
1858
- function processChecksum(decodeResult, value) {
1859
- decodeResult.raw.checksum = Number("0x" + value);
1860
- decodeResult.formatted.items.push({
1861
- type: "message_checksum",
1862
- code: "CHECKSUM",
1863
- label: "Message Checksum",
1864
- value: "0x" + ("0000" + decodeResult.raw.checksum.toString(16)).slice(-4)
1865
- });
1866
- }
1867
- function findHeader(text) {
1868
- const parts = text.split(",");
1869
- const header = parts[0];
1870
- if (header.indexOf("/TS") === -1) {
1871
- return header;
1872
- }
1873
- return parts[0] + "," + parts[1];
1874
- }
1875
2033
 
1876
2034
  // lib/plugins/Label_H1_WRN.ts
1877
2035
  var Label_H1_WRN = class extends DecoderPlugin {
@@ -1894,16 +2052,16 @@ var Label_H1_WRN = class extends DecoderPlugin {
1894
2052
  for (let i = 1; i < fields.length; i++) {
1895
2053
  const field = fields[i];
1896
2054
  if (field.startsWith("PN")) {
1897
- processUnknown2(decodeResult, "/" + field);
2055
+ processUnknown(decodeResult, "/" + field);
1898
2056
  } else {
1899
- processUnknown2(decodeResult, "/" + field);
2057
+ processUnknown(decodeResult, "/" + field);
1900
2058
  }
1901
2059
  }
1902
2060
  const data = parts[1].substring(0, 20);
1903
2061
  const msg = parts[1].substring(20);
1904
2062
  const datetime = data.substring(0, 12);
1905
2063
  const date = datetime.substring(4, 6) + datetime.substring(2, 4) + datetime.substring(0, 2);
1906
- processUnknown2(decodeResult, data.substring(12));
2064
+ processUnknown(decodeResult, data.substring(12));
1907
2065
  decodeResult.raw.message_timestamp = DateTimeUtils.convertDateTimeToEpoch(datetime.substring(6), date);
1908
2066
  decodeResult.raw.warning_message = msg;
1909
2067
  decodeResult.formatted.items.push({
@@ -1925,7 +2083,7 @@ var Label_H1_WRN = class extends DecoderPlugin {
1925
2083
  return decodeResult;
1926
2084
  }
1927
2085
  };
1928
- function processUnknown2(decodeResult, value) {
2086
+ function processUnknown(decodeResult, value) {
1929
2087
  decodeResult.remaining.text += value;
1930
2088
  }
1931
2089
 
@@ -3026,6 +3184,7 @@ var MessageDecoder = class {
3026
3184
  this.registerPlugin(new Label_15_FST(this));
3027
3185
  this.registerPlugin(new Label_16_N_Space(this));
3028
3186
  this.registerPlugin(new Label_20_POS(this));
3187
+ this.registerPlugin(new Label_21_POS(this));
3029
3188
  this.registerPlugin(new Label_30_Slash_EA(this));
3030
3189
  this.registerPlugin(new Label_44_ETA(this));
3031
3190
  this.registerPlugin(new Label_44_IN(this));