@airframes/acars-decoder 1.6.12 → 1.6.13
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 +906 -700
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +906 -700
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -129,7 +129,7 @@ var DecoderPlugin = class {
|
|
|
129
129
|
};
|
|
130
130
|
|
|
131
131
|
// lib/utils/coordinate_utils.ts
|
|
132
|
-
var CoordinateUtils = class {
|
|
132
|
+
var CoordinateUtils = class _CoordinateUtils {
|
|
133
133
|
/**
|
|
134
134
|
* Decode a string of coordinates into an object with latitude and longitude in millidegrees
|
|
135
135
|
* @param stringCoords - The string of coordinates to decode
|
|
@@ -146,8 +146,8 @@ var CoordinateUtils = class {
|
|
|
146
146
|
longitudeChars = stringCoords.substring(8, 14);
|
|
147
147
|
}
|
|
148
148
|
if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
|
|
149
|
-
results.latitude = Number(stringCoords.substring(1, 6)) / 1e3 * (firstChar
|
|
150
|
-
results.longitude = Number(longitudeChars) / 1e3 * (middleChar
|
|
149
|
+
results.latitude = Number(stringCoords.substring(1, 6)) / 1e3 * _CoordinateUtils.getDirection(firstChar);
|
|
150
|
+
results.longitude = Number(longitudeChars) / 1e3 * _CoordinateUtils.getDirection(middleChar);
|
|
151
151
|
} else {
|
|
152
152
|
return;
|
|
153
153
|
}
|
|
@@ -173,8 +173,8 @@ var CoordinateUtils = class {
|
|
|
173
173
|
const lonDeg = Math.trunc(Number(longitudeChars) / 1e3);
|
|
174
174
|
const lonMin = Number(longitudeChars) % 1e3 / 10;
|
|
175
175
|
if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
|
|
176
|
-
results.latitude = (latDeg + latMin / 60) * (firstChar
|
|
177
|
-
results.longitude = (lonDeg + lonMin / 60) * (middleChar
|
|
176
|
+
results.latitude = (latDeg + latMin / 60) * _CoordinateUtils.getDirection(firstChar);
|
|
177
|
+
results.longitude = (lonDeg + lonMin / 60) * _CoordinateUtils.getDirection(middleChar);
|
|
178
178
|
} else {
|
|
179
179
|
return;
|
|
180
180
|
}
|
|
@@ -281,6 +281,15 @@ var RouteUtils = class _RouteUtils {
|
|
|
281
281
|
|
|
282
282
|
// lib/utils/result_formatter.ts
|
|
283
283
|
var ResultFormatter = class {
|
|
284
|
+
static route(decodeResult, route) {
|
|
285
|
+
decodeResult.raw.route = route;
|
|
286
|
+
decodeResult.formatted.items.push({
|
|
287
|
+
type: "aircraft_route",
|
|
288
|
+
code: "ROUTE",
|
|
289
|
+
label: "Aircraft Route",
|
|
290
|
+
value: RouteUtils.routeToString(route)
|
|
291
|
+
});
|
|
292
|
+
}
|
|
284
293
|
static state_change(decodeResult, from, to) {
|
|
285
294
|
decodeResult.raw.state_change = {
|
|
286
295
|
from,
|
|
@@ -317,6 +326,9 @@ var ResultFormatter = class {
|
|
|
317
326
|
});
|
|
318
327
|
}
|
|
319
328
|
static position(decodeResult, value) {
|
|
329
|
+
if (!value || isNaN(value.latitude) || isNaN(value.longitude)) {
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
320
332
|
decodeResult.raw.position = value;
|
|
321
333
|
decodeResult.formatted.items.push({
|
|
322
334
|
type: "aircraft_position",
|
|
@@ -553,17 +565,50 @@ var ResultFormatter = class {
|
|
|
553
565
|
value: DateTimeUtils.timestampToString(time, "tod")
|
|
554
566
|
});
|
|
555
567
|
}
|
|
556
|
-
static
|
|
557
|
-
decodeResult.raw.
|
|
568
|
+
static day(decodeResult, day) {
|
|
569
|
+
decodeResult.raw.day_of_month = day;
|
|
570
|
+
decodeResult.formatted.items.push({
|
|
571
|
+
type: "day_of_month",
|
|
572
|
+
code: "MSG_DAY",
|
|
573
|
+
label: "Day of Month",
|
|
574
|
+
value: `${day}`
|
|
575
|
+
});
|
|
576
|
+
}
|
|
577
|
+
static departureDay(decodeResult, day) {
|
|
578
|
+
decodeResult.raw.departure_day_of_month = day;
|
|
579
|
+
decodeResult.formatted.items.push({
|
|
580
|
+
type: "day_of_month",
|
|
581
|
+
code: "DEP_DAY",
|
|
582
|
+
label: "Departure Day",
|
|
583
|
+
value: `${day}`
|
|
584
|
+
});
|
|
585
|
+
}
|
|
586
|
+
static arrivalDay(decodeResult, day) {
|
|
587
|
+
decodeResult.raw.arrival_day_of_month = day;
|
|
588
|
+
decodeResult.formatted.items.push({
|
|
589
|
+
type: "day_of_month",
|
|
590
|
+
code: "ARR_DAY",
|
|
591
|
+
label: "Arrival Day",
|
|
592
|
+
value: `${day}`
|
|
593
|
+
});
|
|
594
|
+
}
|
|
595
|
+
static text(decodeResult, text) {
|
|
596
|
+
decodeResult.raw.text = text;
|
|
558
597
|
decodeResult.formatted.items.push({
|
|
559
598
|
type: "text",
|
|
560
599
|
code: "TEXT",
|
|
561
600
|
label: "Text Message",
|
|
562
|
-
value:
|
|
601
|
+
value: text
|
|
563
602
|
});
|
|
564
603
|
}
|
|
565
|
-
static unknown(decodeResult, value) {
|
|
566
|
-
decodeResult.remaining.text
|
|
604
|
+
static unknown(decodeResult, value, sep = ",") {
|
|
605
|
+
if (!decodeResult.remaining.text)
|
|
606
|
+
decodeResult.remaining.text = value;
|
|
607
|
+
else
|
|
608
|
+
decodeResult.remaining.text += sep + value;
|
|
609
|
+
}
|
|
610
|
+
static unknownArr(decodeResult, value, sep = ",") {
|
|
611
|
+
this.unknown(decodeResult, value.join(sep), sep);
|
|
567
612
|
}
|
|
568
613
|
};
|
|
569
614
|
|
|
@@ -639,14 +684,14 @@ var Label_5Z_Slash = class extends DecoderPlugin {
|
|
|
639
684
|
decodeResult.raw.day_of_month = Number(info[3]);
|
|
640
685
|
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(info[4]));
|
|
641
686
|
ResultFormatter.arrivalRunway(decodeResult, info[5].slice(1));
|
|
642
|
-
decodeResult
|
|
687
|
+
ResultFormatter.unknownArr(decodeResult, data.slice(3), "/");
|
|
643
688
|
} else if (type === "B3") {
|
|
644
689
|
ResultFormatter.departureAirport(decodeResult, header[1].substring(0, 3), "IATA");
|
|
645
690
|
ResultFormatter.arrivalAirport(decodeResult, header[1].substring(3), "IATA");
|
|
646
691
|
decodeResult.raw.day_of_month = Number(header[2]);
|
|
647
692
|
ResultFormatter.arrivalRunway(decodeResult, header[3].slice(1));
|
|
648
693
|
if (header.length > 4) {
|
|
649
|
-
decodeResult
|
|
694
|
+
ResultFormatter.unknownArr(decodeResult, header.slice(4), "/");
|
|
650
695
|
}
|
|
651
696
|
} else if (type === "C3" && data[1] === "C3 GATE REQ ") {
|
|
652
697
|
const info = data[2].split(" ");
|
|
@@ -654,7 +699,7 @@ var Label_5Z_Slash = class extends DecoderPlugin {
|
|
|
654
699
|
ResultFormatter.arrivalAirport(decodeResult, info[2]);
|
|
655
700
|
decodeResult.raw.day_of_month = Number(info[3]);
|
|
656
701
|
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(info[4]));
|
|
657
|
-
decodeResult
|
|
702
|
+
ResultFormatter.unknownArr(decodeResult, info.slice(5), " ");
|
|
658
703
|
} else if (type === "C3") {
|
|
659
704
|
ResultFormatter.departureAirport(decodeResult, header[1].substring(0, 3), "IATA");
|
|
660
705
|
ResultFormatter.arrivalAirport(decodeResult, header[1].substring(3), "IATA");
|
|
@@ -666,7 +711,7 @@ var Label_5Z_Slash = class extends DecoderPlugin {
|
|
|
666
711
|
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(airports[4]));
|
|
667
712
|
const estimates = data[3].split(" ");
|
|
668
713
|
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(estimates[1] + "00"));
|
|
669
|
-
decodeResult
|
|
714
|
+
ResultFormatter.unknown(decodeResult, estimates[2]);
|
|
670
715
|
} else {
|
|
671
716
|
if (options.debug) {
|
|
672
717
|
console.log(`Decoder: Unkown 5Z RDC format: ${message.text}`);
|
|
@@ -678,7 +723,7 @@ var Label_5Z_Slash = class extends DecoderPlugin {
|
|
|
678
723
|
if (options.debug) {
|
|
679
724
|
console.log(`Decoder: Unknown 5Z message: ${message.text}`);
|
|
680
725
|
}
|
|
681
|
-
decodeResult
|
|
726
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
682
727
|
decodeResult.decoded = false;
|
|
683
728
|
decodeResult.decoder.decodeLevel = "none";
|
|
684
729
|
}
|
|
@@ -706,7 +751,7 @@ var Label_10_LDR = class extends DecoderPlugin {
|
|
|
706
751
|
if (options.debug) {
|
|
707
752
|
console.log(`Decoder: Unknown 10 message: ${message.text}`);
|
|
708
753
|
}
|
|
709
|
-
decodeResult
|
|
754
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
710
755
|
decodeResult.decoded = false;
|
|
711
756
|
decodeResult.decoder.decodeLevel = "none";
|
|
712
757
|
return decodeResult;
|
|
@@ -727,7 +772,7 @@ var Label_10_LDR = class extends DecoderPlugin {
|
|
|
727
772
|
if (altRwy != "") {
|
|
728
773
|
ResultFormatter.alternateRunway(decodeResult, altRwy);
|
|
729
774
|
}
|
|
730
|
-
decodeResult
|
|
775
|
+
ResultFormatter.unknownArr(decodeResult, [...parts.slice(0, 5), ...parts.slice(15)]);
|
|
731
776
|
decodeResult.decoded = true;
|
|
732
777
|
decodeResult.decoder.decodeLevel = "partial";
|
|
733
778
|
return decodeResult;
|
|
@@ -754,7 +799,7 @@ var Label_10_POS = class extends DecoderPlugin {
|
|
|
754
799
|
if (options.debug) {
|
|
755
800
|
console.log(`Decoder: Unknown 10 message: ${message.text}`);
|
|
756
801
|
}
|
|
757
|
-
decodeResult
|
|
802
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
758
803
|
decodeResult.decoded = false;
|
|
759
804
|
decodeResult.decoder.decodeLevel = "none";
|
|
760
805
|
return decodeResult;
|
|
@@ -767,7 +812,7 @@ var Label_10_POS = class extends DecoderPlugin {
|
|
|
767
812
|
};
|
|
768
813
|
ResultFormatter.position(decodeResult, position);
|
|
769
814
|
ResultFormatter.altitude(decodeResult, Number(parts[7]));
|
|
770
|
-
decodeResult
|
|
815
|
+
ResultFormatter.unknownArr(decodeResult, [parts[0], ...parts.slice(3, 7), ...parts.slice(8)]);
|
|
771
816
|
decodeResult.decoded = true;
|
|
772
817
|
decodeResult.decoder.decodeLevel = "partial";
|
|
773
818
|
return decodeResult;
|
|
@@ -794,7 +839,7 @@ var Label_10_Slash = class extends DecoderPlugin {
|
|
|
794
839
|
if (options.debug) {
|
|
795
840
|
console.log(`Decoder: Unknown 10 message: ${message.text}`);
|
|
796
841
|
}
|
|
797
|
-
decodeResult
|
|
842
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
798
843
|
decodeResult.decoded = false;
|
|
799
844
|
decodeResult.decoder.decodeLevel = "none";
|
|
800
845
|
return decodeResult;
|
|
@@ -821,17 +866,11 @@ var Label_10_Slash = class extends DecoderPlugin {
|
|
|
821
866
|
time: DateTimeUtils.convertHHMMSSToTod(parts[15] + "00"),
|
|
822
867
|
timeFormat: "tod"
|
|
823
868
|
}];
|
|
824
|
-
|
|
825
|
-
decodeResult.formatted.items.push({
|
|
826
|
-
type: "aircraft_route",
|
|
827
|
-
code: "ROUTE",
|
|
828
|
-
label: "Aircraft Route",
|
|
829
|
-
value: RouteUtils.routeToString(decodeResult.raw.route)
|
|
830
|
-
});
|
|
869
|
+
ResultFormatter.route(decodeResult, { waypoints });
|
|
831
870
|
if (parts[16]) {
|
|
832
871
|
ResultFormatter.departureAirport(decodeResult, parts[16]);
|
|
833
872
|
}
|
|
834
|
-
decodeResult
|
|
873
|
+
ResultFormatter.unknownArr(decodeResult, [parts[3], parts[4], ...parts.slice(9, 11), ...parts.slice(17)], "/");
|
|
835
874
|
decodeResult.decoded = true;
|
|
836
875
|
decodeResult.decoder.decodeLevel = "partial";
|
|
837
876
|
return decodeResult;
|
|
@@ -853,35 +892,29 @@ var Label_12_N_Space = class extends DecoderPlugin {
|
|
|
853
892
|
decodeResult.formatted.description = "Position Report";
|
|
854
893
|
decodeResult.message = message;
|
|
855
894
|
const variant1Regex = /^(?<lat>[NS])\s(?<lat_coord>.*),(?<long>[EW])\s*(?<long_coord>.*),(?<alt>.*),(?<unkwn1>.*),\s*(?<unkwn2>.*),.(?<airframe>.*),(?<unkwn3>.*)$/;
|
|
856
|
-
let results;
|
|
857
|
-
if (results
|
|
895
|
+
let results = message.text.match(variant1Regex);
|
|
896
|
+
if (results?.groups) {
|
|
858
897
|
if (options.debug) {
|
|
859
898
|
console.log(`Label 12 N : results`);
|
|
860
899
|
console.log(results);
|
|
861
900
|
}
|
|
862
|
-
|
|
901
|
+
ResultFormatter.position(decodeResult, {
|
|
863
902
|
latitude: Number(results.groups.lat_coord) * (results.groups.lat == "N" ? 1 : -1),
|
|
864
903
|
longitude: Number(results.groups.long_coord) * (results.groups.long == "E" ? 1 : -1)
|
|
865
|
-
};
|
|
866
|
-
const altitude = results.groups.alt == "GRD" || results.groups.alt == "***" ? 0 : Number(results.groups.alt);
|
|
867
|
-
decodeResult.formatted.items.push({
|
|
868
|
-
type: "aircraft_position",
|
|
869
|
-
code: "POS",
|
|
870
|
-
label: "Aircraft Position",
|
|
871
|
-
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
872
904
|
});
|
|
905
|
+
const altitude = results.groups.alt == "GRD" || results.groups.alt == "***" ? 0 : Number(results.groups.alt);
|
|
873
906
|
ResultFormatter.altitude(decodeResult, altitude);
|
|
874
|
-
decodeResult
|
|
907
|
+
ResultFormatter.unknownArr(decodeResult, [results.groups.unkwn1, results.groups.unkwn2, results.groups.unkwn3]);
|
|
875
908
|
decodeResult.decoded = true;
|
|
876
909
|
decodeResult.decoder.decodeLevel = "partial";
|
|
877
|
-
|
|
878
|
-
if (options.debug) {
|
|
879
|
-
console.log(`Decoder: Unknown 12 message: ${message.text}`);
|
|
880
|
-
}
|
|
881
|
-
decodeResult.remaining.text = message.text;
|
|
882
|
-
decodeResult.decoded = false;
|
|
883
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
910
|
+
return decodeResult;
|
|
884
911
|
}
|
|
912
|
+
if (options.debug) {
|
|
913
|
+
console.log(`Decoder: Unknown 12 message: ${message.text}`);
|
|
914
|
+
}
|
|
915
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
916
|
+
decodeResult.decoded = false;
|
|
917
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
885
918
|
return decodeResult;
|
|
886
919
|
}
|
|
887
920
|
};
|
|
@@ -908,12 +941,11 @@ var Label_13Through18_Slash = class extends DecoderPlugin {
|
|
|
908
941
|
if (options?.debug) {
|
|
909
942
|
console.log(`Decoder: Unknown OOOI message: ${message.text}`);
|
|
910
943
|
}
|
|
911
|
-
decodeResult
|
|
944
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
912
945
|
decodeResult.decoded = false;
|
|
913
946
|
decodeResult.decoder.decodeLevel = "none";
|
|
914
947
|
return decodeResult;
|
|
915
948
|
}
|
|
916
|
-
decodeResult.remaining.text = "";
|
|
917
949
|
const data = parts[2].split(" ");
|
|
918
950
|
ResultFormatter.departureAirport(decodeResult, data[1]);
|
|
919
951
|
ResultFormatter.arrivalAirport(decodeResult, data[2]);
|
|
@@ -929,7 +961,7 @@ var Label_13Through18_Slash = class extends DecoderPlugin {
|
|
|
929
961
|
ResultFormatter.in(decodeResult, time);
|
|
930
962
|
}
|
|
931
963
|
if (parts.length === 7) {
|
|
932
|
-
decodeResult
|
|
964
|
+
ResultFormatter.unknownArr(decodeResult, parts.slice(4), "/");
|
|
933
965
|
}
|
|
934
966
|
for (let i = 1; i < lines.length; i++) {
|
|
935
967
|
if (lines[i].startsWith("/LOC")) {
|
|
@@ -943,11 +975,9 @@ var Label_13Through18_Slash = class extends DecoderPlugin {
|
|
|
943
975
|
longitude: CoordinateUtils.getDirection(location[1][0]) * CoordinateUtils.dmsToDecimalDegrees(Number(location[1].substring(1, 4)), Number(location[1].substring(4, 6)), Number(location[1].substring(6, 8)))
|
|
944
976
|
};
|
|
945
977
|
}
|
|
946
|
-
|
|
947
|
-
ResultFormatter.position(decodeResult, position);
|
|
948
|
-
}
|
|
978
|
+
ResultFormatter.position(decodeResult, position);
|
|
949
979
|
} else {
|
|
950
|
-
decodeResult
|
|
980
|
+
ResultFormatter.unknown(decodeResult, lines[i], "\r\n");
|
|
951
981
|
}
|
|
952
982
|
}
|
|
953
983
|
decodeResult.decoded = true;
|
|
@@ -992,16 +1022,8 @@ var Label_15 = class extends DecoderPlugin {
|
|
|
992
1022
|
decodeResult.formatted.description = "Position Report";
|
|
993
1023
|
const twoZeeRegex = /^\(2(?<between>.+)\(Z$/;
|
|
994
1024
|
const results = message.text.match(twoZeeRegex);
|
|
995
|
-
if (results) {
|
|
996
|
-
|
|
997
|
-
if (decodeResult.raw.position) {
|
|
998
|
-
decodeResult.formatted.items.push({
|
|
999
|
-
type: "position",
|
|
1000
|
-
code: "POS",
|
|
1001
|
-
label: "Position",
|
|
1002
|
-
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
1003
|
-
});
|
|
1004
|
-
}
|
|
1025
|
+
if (results?.groups) {
|
|
1026
|
+
ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinates(results.groups.between.substr(0, 13)));
|
|
1005
1027
|
}
|
|
1006
1028
|
decodeResult.decoded = true;
|
|
1007
1029
|
decodeResult.decoder.decodeLevel = "partial";
|
|
@@ -1025,31 +1047,23 @@ var Label_15_FST = class extends DecoderPlugin {
|
|
|
1025
1047
|
decodeResult.message = message;
|
|
1026
1048
|
const parts = message.text.split(" ");
|
|
1027
1049
|
const header = parts[0];
|
|
1028
|
-
decodeResult.raw.departure_icao = header.substring(5, 9);
|
|
1029
|
-
decodeResult.raw.arrival_icao = header.substring(9, 13);
|
|
1030
1050
|
const stringCoords = header.substring(13);
|
|
1031
1051
|
const firstChar = stringCoords.substring(0, 1);
|
|
1032
1052
|
const middleChar = stringCoords.substring(7, 8);
|
|
1033
1053
|
decodeResult.raw.position = {};
|
|
1034
1054
|
if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
decodeResult
|
|
1055
|
+
const lat = Number(stringCoords.substring(1, 7)) / 1e4 * (firstChar === "S" ? -1 : 1);
|
|
1056
|
+
const lon = Number(stringCoords.substring(8, 15)) / 1e4 * (middleChar === "W" ? -1 : 1);
|
|
1057
|
+
ResultFormatter.position(decodeResult, { latitude: lat, longitude: lon });
|
|
1058
|
+
ResultFormatter.altitude(decodeResult, Number(stringCoords.substring(15)) * 100);
|
|
1038
1059
|
} else {
|
|
1039
1060
|
decodeResult.decoded = false;
|
|
1040
1061
|
decodeResult.decoder.decodeLevel = "none";
|
|
1041
1062
|
return decodeResult;
|
|
1042
1063
|
}
|
|
1043
|
-
decodeResult.
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
label: "Aircraft Position",
|
|
1047
|
-
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
1048
|
-
});
|
|
1049
|
-
ResultFormatter.altitude(decodeResult, decodeResult.raw.altitude);
|
|
1050
|
-
ResultFormatter.departureAirport(decodeResult, decodeResult.raw.departure_icao);
|
|
1051
|
-
ResultFormatter.arrivalAirport(decodeResult, decodeResult.raw.arrival_icao);
|
|
1052
|
-
decodeResult.remaining.text = parts.slice(1).join(" ");
|
|
1064
|
+
ResultFormatter.departureAirport(decodeResult, header.substring(5, 9));
|
|
1065
|
+
ResultFormatter.arrivalAirport(decodeResult, header.substring(9, 13));
|
|
1066
|
+
ResultFormatter.unknownArr(decodeResult, parts.slice(1), " ");
|
|
1053
1067
|
decodeResult.decoded = true;
|
|
1054
1068
|
decodeResult.decoder.decodeLevel = "partial";
|
|
1055
1069
|
return decodeResult;
|
|
@@ -1072,52 +1086,45 @@ var Label_16_N_Space = class extends DecoderPlugin {
|
|
|
1072
1086
|
decodeResult.message = message;
|
|
1073
1087
|
let variant1Regex = /^(?<lat>[NS])\s(?<lat_coord>.*),(?<long>[EW])\s*(?<long_coord>.*),(?<alt>.*),(?<unkwn1>.*),\s*(?<unkwn2>.*)$/;
|
|
1074
1088
|
let variant2Regex = /^(?<lat>[NS])\s(?<lat_coord>.*)\/(?<long>[EW])\s*(?<long_coord>.*)$/;
|
|
1075
|
-
let results;
|
|
1076
|
-
if (results
|
|
1089
|
+
let results = message.text.match(variant1Regex);
|
|
1090
|
+
if (results?.groups) {
|
|
1077
1091
|
if (options.debug) {
|
|
1078
1092
|
console.log(`Label 16 N : results`);
|
|
1079
1093
|
console.log(results);
|
|
1080
1094
|
}
|
|
1081
|
-
|
|
1095
|
+
let pos = {
|
|
1082
1096
|
latitude: Number(results.groups.lat_coord) * (results.groups.lat == "N" ? 1 : -1),
|
|
1083
1097
|
longitude: Number(results.groups.long_coord) * (results.groups.long == "E" ? 1 : -1)
|
|
1084
1098
|
};
|
|
1085
1099
|
const altitude = results.groups.alt == "GRD" || results.groups.alt == "***" ? 0 : Number(results.groups.alt);
|
|
1086
|
-
|
|
1087
|
-
type: "aircraft_position",
|
|
1088
|
-
code: "POS",
|
|
1089
|
-
label: "Aircraft Position",
|
|
1090
|
-
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
1091
|
-
});
|
|
1100
|
+
ResultFormatter.position(decodeResult, pos);
|
|
1092
1101
|
ResultFormatter.altitude(decodeResult, altitude);
|
|
1093
|
-
decodeResult
|
|
1102
|
+
ResultFormatter.unknownArr(decodeResult, [results.groups.unkwn1, results.groups.unkwn2]);
|
|
1094
1103
|
decodeResult.decoded = true;
|
|
1095
1104
|
decodeResult.decoder.decodeLevel = "partial";
|
|
1096
|
-
|
|
1105
|
+
return decodeResult;
|
|
1106
|
+
}
|
|
1107
|
+
results = message.text.match(variant2Regex);
|
|
1108
|
+
if (results?.groups) {
|
|
1097
1109
|
if (options.debug) {
|
|
1098
1110
|
console.log(`Label 16 N : results`);
|
|
1099
1111
|
console.log(results);
|
|
1100
1112
|
}
|
|
1101
|
-
|
|
1113
|
+
let pos = {
|
|
1102
1114
|
latitude: Number(results.groups.lat_coord) * (results.groups.lat == "N" ? 1 : -1),
|
|
1103
1115
|
longitude: Number(results.groups.long_coord) * (results.groups.long == "E" ? 1 : -1)
|
|
1104
1116
|
};
|
|
1105
|
-
|
|
1106
|
-
type: "aircraft_position",
|
|
1107
|
-
code: "POS",
|
|
1108
|
-
label: "Aircraft Position",
|
|
1109
|
-
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
1110
|
-
});
|
|
1117
|
+
ResultFormatter.position(decodeResult, pos);
|
|
1111
1118
|
decodeResult.decoded = true;
|
|
1112
1119
|
decodeResult.decoder.decodeLevel = "full";
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
}
|
|
1117
|
-
decodeResult.remaining.text = message.text;
|
|
1118
|
-
decodeResult.decoded = false;
|
|
1119
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
1120
|
+
return decodeResult;
|
|
1121
|
+
}
|
|
1122
|
+
if (options.debug) {
|
|
1123
|
+
console.log(`Decoder: Unknown 16 message: ${message.text}`);
|
|
1120
1124
|
}
|
|
1125
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
1126
|
+
decodeResult.decoded = false;
|
|
1127
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
1121
1128
|
return decodeResult;
|
|
1122
1129
|
}
|
|
1123
1130
|
};
|
|
@@ -1156,6 +1163,265 @@ var Label_1M_Slash = class extends DecoderPlugin {
|
|
|
1156
1163
|
}
|
|
1157
1164
|
};
|
|
1158
1165
|
|
|
1166
|
+
// lib/plugins/Label_1L_3-line.ts
|
|
1167
|
+
var Label_1L_3Line = class extends DecoderPlugin {
|
|
1168
|
+
// eslint-disable-line camelcase
|
|
1169
|
+
name = "label-1l-3-line";
|
|
1170
|
+
qualifiers() {
|
|
1171
|
+
return {
|
|
1172
|
+
labels: ["1L"]
|
|
1173
|
+
};
|
|
1174
|
+
}
|
|
1175
|
+
decode(message, options = {}) {
|
|
1176
|
+
const decodeResult = this.defaultResult();
|
|
1177
|
+
decodeResult.decoder.name = this.name;
|
|
1178
|
+
decodeResult.formatted.description = "Position Report";
|
|
1179
|
+
decodeResult.message = message;
|
|
1180
|
+
const lines = message.text.split("\r\n");
|
|
1181
|
+
if (lines.length !== 3) {
|
|
1182
|
+
if (options.debug) {
|
|
1183
|
+
console.log(`Decoder: Unknown 1L message: ${message.text}`);
|
|
1184
|
+
}
|
|
1185
|
+
decodeResult.remaining.text = message.text;
|
|
1186
|
+
decodeResult.decoded = false;
|
|
1187
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
1188
|
+
return decodeResult;
|
|
1189
|
+
}
|
|
1190
|
+
const parts = message.text.replaceAll("\r\n", "/").split("/");
|
|
1191
|
+
const data = /* @__PURE__ */ new Map();
|
|
1192
|
+
data.set("", parts[0]);
|
|
1193
|
+
for (let i = 1; i < parts.length; i++) {
|
|
1194
|
+
const part = parts[i].split(" ");
|
|
1195
|
+
data.set(part[0], part.slice(1).join(" "));
|
|
1196
|
+
}
|
|
1197
|
+
const dep = data.get("DEP");
|
|
1198
|
+
if (dep) {
|
|
1199
|
+
ResultFormatter.departureAirport(decodeResult, dep);
|
|
1200
|
+
data.delete("DEP");
|
|
1201
|
+
}
|
|
1202
|
+
const des = data.get("DES");
|
|
1203
|
+
if (des) {
|
|
1204
|
+
ResultFormatter.arrivalAirport(decodeResult, des);
|
|
1205
|
+
data.delete("DES");
|
|
1206
|
+
}
|
|
1207
|
+
const eta = data.get("ETA");
|
|
1208
|
+
if (eta) {
|
|
1209
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(eta + "00"));
|
|
1210
|
+
data.delete("ETA");
|
|
1211
|
+
}
|
|
1212
|
+
const alt = data.get("ALT");
|
|
1213
|
+
if (alt) {
|
|
1214
|
+
ResultFormatter.altitude(decodeResult, Number(alt));
|
|
1215
|
+
data.delete("ALT");
|
|
1216
|
+
}
|
|
1217
|
+
const fn = data.get("FN");
|
|
1218
|
+
if (fn) {
|
|
1219
|
+
ResultFormatter.flightNumber(decodeResult, fn);
|
|
1220
|
+
data.delete("FN");
|
|
1221
|
+
}
|
|
1222
|
+
const day = data.get("DAY");
|
|
1223
|
+
const utc = data.get("UTC");
|
|
1224
|
+
if (day && utc) {
|
|
1225
|
+
decodeResult.raw.message_timestamp = Date.parse(day + " GMT+0000") / 1e3 + DateTimeUtils.convertHHMMSSToTod(utc);
|
|
1226
|
+
data.delete("DAY");
|
|
1227
|
+
data.delete("UTC");
|
|
1228
|
+
}
|
|
1229
|
+
const lat = data.get("LAT");
|
|
1230
|
+
const lon = data.get("LON");
|
|
1231
|
+
if (lat && lon) {
|
|
1232
|
+
ResultFormatter.position(decodeResult, {
|
|
1233
|
+
latitude: CoordinateUtils.getDirection(lat[0]) * Number(lat.substring(1)),
|
|
1234
|
+
longitude: CoordinateUtils.getDirection(lon[0]) * Number(lon.substring(1))
|
|
1235
|
+
});
|
|
1236
|
+
data.delete("LAT");
|
|
1237
|
+
data.delete("LON");
|
|
1238
|
+
}
|
|
1239
|
+
let remaining = "";
|
|
1240
|
+
for (const [key, value] of data.entries()) {
|
|
1241
|
+
if (key === "") {
|
|
1242
|
+
remaining += value;
|
|
1243
|
+
} else {
|
|
1244
|
+
remaining += `/${key} ${value}`;
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
decodeResult.remaining.text = remaining;
|
|
1248
|
+
decodeResult.decoded = true;
|
|
1249
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
1250
|
+
return decodeResult;
|
|
1251
|
+
}
|
|
1252
|
+
};
|
|
1253
|
+
|
|
1254
|
+
// lib/plugins/Label_1L_070.ts
|
|
1255
|
+
var Label_1L_070 = class extends DecoderPlugin {
|
|
1256
|
+
// eslint-disable-line camelcase
|
|
1257
|
+
name = "label-1l-070";
|
|
1258
|
+
qualifiers() {
|
|
1259
|
+
return {
|
|
1260
|
+
labels: ["1L"],
|
|
1261
|
+
preambles: ["000000070"]
|
|
1262
|
+
};
|
|
1263
|
+
}
|
|
1264
|
+
decode(message, options = {}) {
|
|
1265
|
+
const decodeResult = this.defaultResult();
|
|
1266
|
+
decodeResult.decoder.name = this.name;
|
|
1267
|
+
decodeResult.formatted.description = "Position Report";
|
|
1268
|
+
decodeResult.message = message;
|
|
1269
|
+
if (!message.text.startsWith("000000070")) {
|
|
1270
|
+
if (options.debug) {
|
|
1271
|
+
console.log(`Decoder: Unknown 1L message: ${message.text}`);
|
|
1272
|
+
}
|
|
1273
|
+
decodeResult.remaining.text = message.text;
|
|
1274
|
+
decodeResult.decoded = false;
|
|
1275
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
1276
|
+
return decodeResult;
|
|
1277
|
+
}
|
|
1278
|
+
const parts = message.text.substring(9).split(",");
|
|
1279
|
+
if (parts.length !== 7) {
|
|
1280
|
+
if (options.debug) {
|
|
1281
|
+
console.log(`Decoder: Unknown 1L message: ${message.text}`);
|
|
1282
|
+
}
|
|
1283
|
+
decodeResult.remaining.text = message.text;
|
|
1284
|
+
decodeResult.decoded = false;
|
|
1285
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
1286
|
+
return decodeResult;
|
|
1287
|
+
}
|
|
1288
|
+
ResultFormatter.departureAirport(decodeResult, parts[0]);
|
|
1289
|
+
ResultFormatter.arrivalAirport(decodeResult, parts[1]);
|
|
1290
|
+
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[2] + "00"));
|
|
1291
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[3] + "00"));
|
|
1292
|
+
ResultFormatter.position(decodeResult, {
|
|
1293
|
+
latitude: CoordinateUtils.getDirection(parts[4][0]) * Number(parts[4].substring(1)),
|
|
1294
|
+
longitude: CoordinateUtils.getDirection(parts[5][0]) * Number(parts[5].substring(1))
|
|
1295
|
+
});
|
|
1296
|
+
decodeResult.remaining.text = parts[6];
|
|
1297
|
+
decodeResult.decoded = true;
|
|
1298
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
1299
|
+
return decodeResult;
|
|
1300
|
+
}
|
|
1301
|
+
};
|
|
1302
|
+
|
|
1303
|
+
// lib/plugins/Label_1L_660.ts
|
|
1304
|
+
var Label_1L_660 = class extends DecoderPlugin {
|
|
1305
|
+
// eslint-disable-line camelcase
|
|
1306
|
+
name = "label-1l-660";
|
|
1307
|
+
qualifiers() {
|
|
1308
|
+
return {
|
|
1309
|
+
labels: ["1L"],
|
|
1310
|
+
preambles: ["000000660"]
|
|
1311
|
+
};
|
|
1312
|
+
}
|
|
1313
|
+
decode(message, options = {}) {
|
|
1314
|
+
const decodeResult = this.defaultResult();
|
|
1315
|
+
decodeResult.decoder.name = this.name;
|
|
1316
|
+
decodeResult.formatted.description = "Position Report";
|
|
1317
|
+
decodeResult.message = message;
|
|
1318
|
+
if (!message.text.startsWith("000000660")) {
|
|
1319
|
+
if (options.debug) {
|
|
1320
|
+
console.log(`Decoder: Unknown 1L message: ${message.text}`);
|
|
1321
|
+
}
|
|
1322
|
+
decodeResult.remaining.text = message.text;
|
|
1323
|
+
decodeResult.decoded = false;
|
|
1324
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
1325
|
+
return decodeResult;
|
|
1326
|
+
}
|
|
1327
|
+
const parts = message.text.substring(9).split(",");
|
|
1328
|
+
if (parts.length !== 5) {
|
|
1329
|
+
if (options.debug) {
|
|
1330
|
+
console.log(`Decoder: Unknown 1L message: ${message.text}`);
|
|
1331
|
+
}
|
|
1332
|
+
decodeResult.remaining.text = message.text;
|
|
1333
|
+
decodeResult.decoded = false;
|
|
1334
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
1335
|
+
return decodeResult;
|
|
1336
|
+
}
|
|
1337
|
+
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(parts[0]);
|
|
1338
|
+
if (position) {
|
|
1339
|
+
ResultFormatter.position(decodeResult, position);
|
|
1340
|
+
}
|
|
1341
|
+
const hhmmss = parts[1].substring(0, 6);
|
|
1342
|
+
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(hhmmss));
|
|
1343
|
+
const fl = parts[1].substring(6, 9);
|
|
1344
|
+
ResultFormatter.altitude(decodeResult, Number(fl) * 100);
|
|
1345
|
+
const next = parts[1].substring(9);
|
|
1346
|
+
ResultFormatter.route(decodeResult, { waypoints: [{ name: next.trim() }] });
|
|
1347
|
+
decodeResult.remaining.text = parts.slice(2).join(",");
|
|
1348
|
+
decodeResult.decoded = true;
|
|
1349
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
1350
|
+
return decodeResult;
|
|
1351
|
+
}
|
|
1352
|
+
};
|
|
1353
|
+
|
|
1354
|
+
// lib/plugins/Label_1L_Slash.ts
|
|
1355
|
+
var Label_1L_Slash = class extends DecoderPlugin {
|
|
1356
|
+
// eslint-disable-line camelcase
|
|
1357
|
+
name = "label-1l-1-line";
|
|
1358
|
+
qualifiers() {
|
|
1359
|
+
return {
|
|
1360
|
+
labels: ["1L"],
|
|
1361
|
+
preambles: ["+", "-"]
|
|
1362
|
+
};
|
|
1363
|
+
}
|
|
1364
|
+
decode(message, options = {}) {
|
|
1365
|
+
const decodeResult = this.defaultResult();
|
|
1366
|
+
decodeResult.decoder.name = this.name;
|
|
1367
|
+
decodeResult.formatted.description = "Position Report";
|
|
1368
|
+
decodeResult.message = message;
|
|
1369
|
+
const parts = message.text.split("/");
|
|
1370
|
+
if (parts.length !== 7) {
|
|
1371
|
+
if (options.debug) {
|
|
1372
|
+
console.log(`Decoder: Unknown 1L message: ${message.text}`);
|
|
1373
|
+
}
|
|
1374
|
+
decodeResult.remaining.text = message.text;
|
|
1375
|
+
decodeResult.decoded = false;
|
|
1376
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
1377
|
+
return decodeResult;
|
|
1378
|
+
}
|
|
1379
|
+
const data = /* @__PURE__ */ new Map();
|
|
1380
|
+
data.set("LAT", parts[0].replaceAll(" ", ""));
|
|
1381
|
+
data.set("LON", parts[1].replaceAll(" ", ""));
|
|
1382
|
+
for (let i = 2; i < parts.length; i++) {
|
|
1383
|
+
const part = parts[i].split(" ");
|
|
1384
|
+
data.set(part[0], part.slice(1).join(" "));
|
|
1385
|
+
}
|
|
1386
|
+
console.log(data);
|
|
1387
|
+
const position = {
|
|
1388
|
+
latitude: Number(data.get("LAT")),
|
|
1389
|
+
longitude: Number(data.get("LON"))
|
|
1390
|
+
};
|
|
1391
|
+
data.delete("LAT");
|
|
1392
|
+
data.delete("LON");
|
|
1393
|
+
ResultFormatter.position(decodeResult, position);
|
|
1394
|
+
const utc = data.get("UTC");
|
|
1395
|
+
if (utc) {
|
|
1396
|
+
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(utc));
|
|
1397
|
+
data.delete("UTC");
|
|
1398
|
+
}
|
|
1399
|
+
const alt = data.get("ALT");
|
|
1400
|
+
if (alt) {
|
|
1401
|
+
ResultFormatter.altitude(decodeResult, Number(alt));
|
|
1402
|
+
data.delete("ALT");
|
|
1403
|
+
}
|
|
1404
|
+
const fob = data.get("FOB");
|
|
1405
|
+
if (fob) {
|
|
1406
|
+
ResultFormatter.currentFuel(decodeResult, Number(fob));
|
|
1407
|
+
data.delete("FOB");
|
|
1408
|
+
}
|
|
1409
|
+
const eta = data.get("ETA");
|
|
1410
|
+
if (eta) {
|
|
1411
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(eta + "00"));
|
|
1412
|
+
data.delete("ETA");
|
|
1413
|
+
}
|
|
1414
|
+
let remaining = "";
|
|
1415
|
+
for (const [key, value] of data.entries()) {
|
|
1416
|
+
remaining += `/${key} ${value}`;
|
|
1417
|
+
}
|
|
1418
|
+
decodeResult.remaining.text = remaining;
|
|
1419
|
+
decodeResult.decoded = true;
|
|
1420
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
1421
|
+
return decodeResult;
|
|
1422
|
+
}
|
|
1423
|
+
};
|
|
1424
|
+
|
|
1159
1425
|
// lib/plugins/Label_20_POS.ts
|
|
1160
1426
|
var Label_20_POS = class extends DecoderPlugin {
|
|
1161
1427
|
name = "label-20-pos";
|
|
@@ -1178,30 +1444,16 @@ var Label_20_POS = class extends DecoderPlugin {
|
|
|
1178
1444
|
console.log(`DEBUG: ${this.name}: Variation 1 detected`);
|
|
1179
1445
|
}
|
|
1180
1446
|
const rawCoords = fields[0];
|
|
1181
|
-
|
|
1182
|
-
if (decodeResult.raw.position) {
|
|
1183
|
-
decodeResult.formatted.items.push({
|
|
1184
|
-
type: "position",
|
|
1185
|
-
code: "POS",
|
|
1186
|
-
label: "Position",
|
|
1187
|
-
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
1188
|
-
});
|
|
1189
|
-
}
|
|
1447
|
+
ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinates(rawCoords));
|
|
1190
1448
|
decodeResult.decoded = true;
|
|
1191
1449
|
decodeResult.decoder.decodeLevel = "full";
|
|
1192
1450
|
} else if (fields.length == 5) {
|
|
1193
1451
|
if (options.debug) {
|
|
1194
1452
|
console.log(`DEBUG: ${this.name}: Variation 2 detected`);
|
|
1195
1453
|
}
|
|
1196
|
-
const
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
decodeResult.formatted.items.push({
|
|
1200
|
-
type: "position",
|
|
1201
|
-
code: "POS",
|
|
1202
|
-
label: "Position",
|
|
1203
|
-
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
1204
|
-
});
|
|
1454
|
+
const position = CoordinateUtils.decodeStringCoordinates(fields[0]);
|
|
1455
|
+
if (position) {
|
|
1456
|
+
ResultFormatter.position(decodeResult, position);
|
|
1205
1457
|
}
|
|
1206
1458
|
decodeResult.decoded = true;
|
|
1207
1459
|
decodeResult.decoder.decodeLevel = "full";
|
|
@@ -1240,11 +1492,7 @@ var Label_21_POS = class extends DecoderPlugin {
|
|
|
1240
1492
|
ResultFormatter.temperature(decodeResult, fields[6].replace(/ /g, ""));
|
|
1241
1493
|
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[7]));
|
|
1242
1494
|
ResultFormatter.arrivalAirport(decodeResult, fields[8]);
|
|
1243
|
-
decodeResult
|
|
1244
|
-
fields[1],
|
|
1245
|
-
fields[4],
|
|
1246
|
-
fields[5]
|
|
1247
|
-
].join(",");
|
|
1495
|
+
ResultFormatter.unknownArr(decodeResult, [fields[1], fields[4], fields[5]]);
|
|
1248
1496
|
decodeResult.decoded = true;
|
|
1249
1497
|
decodeResult.decoder.decodeLevel = "partial";
|
|
1250
1498
|
} else {
|
|
@@ -1270,41 +1518,74 @@ function processPosition(decodeResult, value) {
|
|
|
1270
1518
|
ResultFormatter.position(decodeResult, position);
|
|
1271
1519
|
}
|
|
1272
1520
|
|
|
1273
|
-
// lib/plugins/
|
|
1274
|
-
var
|
|
1275
|
-
name = "label-
|
|
1521
|
+
// lib/plugins/Label_22_OFF.ts
|
|
1522
|
+
var Label_22_OFF = class extends DecoderPlugin {
|
|
1523
|
+
name = "label-22-off";
|
|
1276
1524
|
qualifiers() {
|
|
1277
1525
|
return {
|
|
1278
|
-
labels: ["
|
|
1279
|
-
preambles: ["
|
|
1526
|
+
labels: ["22"],
|
|
1527
|
+
preambles: ["OFF"]
|
|
1280
1528
|
};
|
|
1281
1529
|
}
|
|
1282
1530
|
decode(message, options = {}) {
|
|
1283
1531
|
const decodeResult = this.defaultResult();
|
|
1284
1532
|
decodeResult.decoder.name = this.name;
|
|
1285
|
-
decodeResult.formatted.description = "
|
|
1533
|
+
decodeResult.formatted.description = "Takeoff Report";
|
|
1286
1534
|
decodeResult.message = message;
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
ResultFormatter.
|
|
1301
|
-
ResultFormatter.
|
|
1302
|
-
decodeResult.
|
|
1535
|
+
if (message.text.startsWith("OFF01")) {
|
|
1536
|
+
const fields = message.text.substring(5).split("/");
|
|
1537
|
+
if (fields.length != 2) {
|
|
1538
|
+
decodeResult.decoded = false;
|
|
1539
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
1540
|
+
return decodeResult;
|
|
1541
|
+
}
|
|
1542
|
+
ResultFormatter.flightNumber(decodeResult, fields[0]);
|
|
1543
|
+
ResultFormatter.departureDay(decodeResult, Number(fields[1].substring(0, 2)));
|
|
1544
|
+
ResultFormatter.arrivalDay(decodeResult, Number(fields[1].substring(2, 4)));
|
|
1545
|
+
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(4, 8) + "00"));
|
|
1546
|
+
ResultFormatter.departureAirport(decodeResult, fields[1].substring(8, 12));
|
|
1547
|
+
ResultFormatter.arrivalAirport(decodeResult, fields[1].substring(12, 16));
|
|
1548
|
+
ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(16, 22)));
|
|
1549
|
+
ResultFormatter.unknown(decodeResult, fields[1].substring(22));
|
|
1550
|
+
decodeResult.decoded = true;
|
|
1551
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
1552
|
+
} else if (message.text.startsWith("OFF02\r\n")) {
|
|
1553
|
+
const fields = message.text.substring(7).split(",");
|
|
1554
|
+
if (fields.length != 4) {
|
|
1555
|
+
decodeResult.decoded = false;
|
|
1556
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
1557
|
+
return decodeResult;
|
|
1558
|
+
}
|
|
1559
|
+
ResultFormatter.departureAirport(decodeResult, fields[0]);
|
|
1560
|
+
ResultFormatter.arrivalAirport(decodeResult, fields[1]);
|
|
1561
|
+
ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[2] + "00"));
|
|
1562
|
+
ResultFormatter.unknown(decodeResult, fields[3]);
|
|
1563
|
+
decodeResult.decoded = true;
|
|
1564
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
1565
|
+
} else if (message.text.startsWith("OFF02")) {
|
|
1566
|
+
const fields = message.text.substring(5).split("/");
|
|
1567
|
+
if (fields.length != 2) {
|
|
1568
|
+
decodeResult.decoded = false;
|
|
1569
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
1570
|
+
return decodeResult;
|
|
1571
|
+
}
|
|
1572
|
+
ResultFormatter.flightNumber(decodeResult, fields[0]);
|
|
1573
|
+
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(fields[1].substring(0, 14));
|
|
1574
|
+
if (position) {
|
|
1575
|
+
ResultFormatter.position(decodeResult, position);
|
|
1576
|
+
}
|
|
1577
|
+
ResultFormatter.day(decodeResult, Number(fields[1].substring(14, 16)));
|
|
1578
|
+
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(16, 20) + "00"));
|
|
1579
|
+
ResultFormatter.departureAirport(decodeResult, fields[1].substring(20, 24));
|
|
1580
|
+
ResultFormatter.arrivalAirport(decodeResult, fields[1].substring(24, 28));
|
|
1581
|
+
ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(28, 32) + "00"));
|
|
1582
|
+
ResultFormatter.unknown(decodeResult, fields[1].substring(32, 36));
|
|
1583
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(36, 40) + "00"));
|
|
1303
1584
|
decodeResult.decoded = true;
|
|
1304
1585
|
decodeResult.decoder.decodeLevel = "partial";
|
|
1305
1586
|
} else {
|
|
1306
1587
|
if (options.debug) {
|
|
1307
|
-
console.log(`DEBUG: ${this.name}: Unknown variation
|
|
1588
|
+
console.log(`DEBUG: ${this.name}: Unknown variation.`);
|
|
1308
1589
|
}
|
|
1309
1590
|
decodeResult.decoded = false;
|
|
1310
1591
|
decodeResult.decoder.decodeLevel = "none";
|
|
@@ -1313,33 +1594,116 @@ var Label_24_Slash = class extends DecoderPlugin {
|
|
|
1313
1594
|
}
|
|
1314
1595
|
};
|
|
1315
1596
|
|
|
1316
|
-
// lib/plugins/
|
|
1317
|
-
var
|
|
1318
|
-
name = "label-
|
|
1597
|
+
// lib/plugins/Label_22_POS.ts
|
|
1598
|
+
var Label_22_POS = class extends DecoderPlugin {
|
|
1599
|
+
name = "label-22-pos";
|
|
1319
1600
|
qualifiers() {
|
|
1320
1601
|
return {
|
|
1321
|
-
labels: ["
|
|
1322
|
-
preambles: ["
|
|
1602
|
+
labels: ["22"],
|
|
1603
|
+
preambles: ["N", "S"]
|
|
1323
1604
|
};
|
|
1324
1605
|
}
|
|
1325
1606
|
decode(message, options = {}) {
|
|
1326
1607
|
const decodeResult = this.defaultResult();
|
|
1327
1608
|
decodeResult.decoder.name = this.name;
|
|
1328
|
-
decodeResult.formatted.description = "
|
|
1609
|
+
decodeResult.formatted.description = "Position Report";
|
|
1329
1610
|
decodeResult.message = message;
|
|
1330
|
-
const
|
|
1331
|
-
if (
|
|
1611
|
+
const fields = message.text.split(",");
|
|
1612
|
+
if (fields.length !== 11) {
|
|
1332
1613
|
if (options.debug) {
|
|
1333
|
-
console.log(`
|
|
1334
|
-
|
|
1614
|
+
console.log(`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${fields.join(",")}`);
|
|
1615
|
+
}
|
|
1616
|
+
decodeResult.decoded = false;
|
|
1617
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
1618
|
+
return decodeResult;
|
|
1619
|
+
}
|
|
1620
|
+
const latStr = fields[0].substring(1, 8);
|
|
1621
|
+
const lonStr = fields[0].substring(9);
|
|
1622
|
+
const lat = Number(latStr) / 1e4;
|
|
1623
|
+
const lon = Number(lonStr) / 1e4;
|
|
1624
|
+
ResultFormatter.position(decodeResult, {
|
|
1625
|
+
latitude: CoordinateUtils.getDirection(fields[0][0]) * lat,
|
|
1626
|
+
longitude: CoordinateUtils.getDirection(fields[0][8]) * lon
|
|
1627
|
+
});
|
|
1628
|
+
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[2]));
|
|
1629
|
+
ResultFormatter.altitude(decodeResult, Number(fields[3]));
|
|
1630
|
+
ResultFormatter.unknownArr(decodeResult, [fields[1], ...fields.slice(4)]);
|
|
1631
|
+
decodeResult.decoded = true;
|
|
1632
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
1633
|
+
return decodeResult;
|
|
1634
|
+
}
|
|
1635
|
+
};
|
|
1636
|
+
|
|
1637
|
+
// lib/plugins/Label_24_Slash.ts
|
|
1638
|
+
var Label_24_Slash = class extends DecoderPlugin {
|
|
1639
|
+
name = "label-24-slash";
|
|
1640
|
+
qualifiers() {
|
|
1641
|
+
return {
|
|
1642
|
+
labels: ["24"],
|
|
1643
|
+
preambles: ["/"]
|
|
1644
|
+
};
|
|
1645
|
+
}
|
|
1646
|
+
decode(message, options = {}) {
|
|
1647
|
+
const decodeResult = this.defaultResult();
|
|
1648
|
+
decodeResult.decoder.name = this.name;
|
|
1649
|
+
decodeResult.formatted.description = "Position Report";
|
|
1650
|
+
decodeResult.message = message;
|
|
1651
|
+
const fields = message.text.split("/");
|
|
1652
|
+
if (fields.length == 10 && fields[0] == "" && fields[9] == "") {
|
|
1653
|
+
const mmddyy = fields[1].substring(4, 6) + fields[1].substring(2, 4) + fields[1].substring(0, 2);
|
|
1654
|
+
const hhmmss = fields[2] + "00";
|
|
1655
|
+
decodeResult.raw.message_timestamp = DateTimeUtils.convertDateTimeToEpoch(hhmmss, mmddyy);
|
|
1656
|
+
ResultFormatter.flightNumber(decodeResult, fields[3]);
|
|
1657
|
+
ResultFormatter.altitude(decodeResult, Number(fields[4]));
|
|
1658
|
+
const lat = fields[5];
|
|
1659
|
+
const lon = fields[6];
|
|
1660
|
+
const position = {
|
|
1661
|
+
latitude: (lat[0] === "N" ? 1 : -1) * Number(lat.substring(1)),
|
|
1662
|
+
longitude: (lon[0] === "E" ? 1 : -1) * Number(lon.substring(1))
|
|
1663
|
+
};
|
|
1664
|
+
ResultFormatter.position(decodeResult, position);
|
|
1665
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[8] + "00"));
|
|
1666
|
+
ResultFormatter.unknown(decodeResult, fields[7]);
|
|
1667
|
+
decodeResult.decoded = true;
|
|
1668
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
1669
|
+
} else {
|
|
1670
|
+
if (options.debug) {
|
|
1671
|
+
console.log(`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}. Message: ${message.text}`);
|
|
1672
|
+
}
|
|
1673
|
+
decodeResult.decoded = false;
|
|
1674
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
1675
|
+
}
|
|
1676
|
+
return decodeResult;
|
|
1677
|
+
}
|
|
1678
|
+
};
|
|
1679
|
+
|
|
1680
|
+
// lib/plugins/Label_30_Slash_EA.ts
|
|
1681
|
+
var Label_30_Slash_EA = class extends DecoderPlugin {
|
|
1682
|
+
name = "label-30-slash-ea";
|
|
1683
|
+
qualifiers() {
|
|
1684
|
+
return {
|
|
1685
|
+
labels: ["30"],
|
|
1686
|
+
preambles: ["/EA"]
|
|
1687
|
+
};
|
|
1688
|
+
}
|
|
1689
|
+
decode(message, options = {}) {
|
|
1690
|
+
const decodeResult = this.defaultResult();
|
|
1691
|
+
decodeResult.decoder.name = this.name;
|
|
1692
|
+
decodeResult.formatted.description = "ETA Report";
|
|
1693
|
+
decodeResult.message = message;
|
|
1694
|
+
const results = message.text.split(/\n|\//).slice(1);
|
|
1695
|
+
if (results) {
|
|
1696
|
+
if (options.debug) {
|
|
1697
|
+
console.log(`Label 30 EA: results`);
|
|
1698
|
+
console.log(results);
|
|
1335
1699
|
}
|
|
1336
1700
|
}
|
|
1337
1701
|
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(results[0].substr(2, 4) + "00"));
|
|
1338
1702
|
if (results[1].substring(0, 2) === "DS") {
|
|
1339
1703
|
ResultFormatter.arrivalAirport(decodeResult, results[1].substring(2, 6));
|
|
1340
|
-
decodeResult
|
|
1704
|
+
ResultFormatter.unknown(decodeResult, "/".concat(results[2]));
|
|
1341
1705
|
} else {
|
|
1342
|
-
decodeResult
|
|
1706
|
+
ResultFormatter.unknown(decodeResult, "/".concat(results[1], "/", results[2]));
|
|
1343
1707
|
}
|
|
1344
1708
|
decodeResult.decoded = true;
|
|
1345
1709
|
decodeResult.decoder.decodeLevel = "partial";
|
|
@@ -1363,40 +1727,20 @@ var Label_44_ETA = class extends DecoderPlugin {
|
|
|
1363
1727
|
decodeResult.message = message;
|
|
1364
1728
|
const regex = /^.*,(?<unsplit_coords>.*),(?<departure_icao>.*),(?<arrival_icao>.*),(?<current_date>.*),(?<current_time>.*),(?<fuel_in_tons>.*)$/;
|
|
1365
1729
|
const results = message.text.match(regex);
|
|
1366
|
-
if (results) {
|
|
1730
|
+
if (results?.groups) {
|
|
1367
1731
|
if (options.debug) {
|
|
1368
1732
|
console.log(`Label 44 ETA Report: groups`);
|
|
1369
1733
|
console.log(results.groups);
|
|
1370
1734
|
}
|
|
1371
|
-
|
|
1372
|
-
decodeResult
|
|
1373
|
-
decodeResult
|
|
1735
|
+
ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinates(results.groups.unsplit_coords));
|
|
1736
|
+
ResultFormatter.departureAirport(decodeResult, results.groups.departure_icao);
|
|
1737
|
+
ResultFormatter.arrivalAirport(decodeResult, results.groups.arrival_icao);
|
|
1374
1738
|
decodeResult.raw.current_time = Date.parse(
|
|
1375
1739
|
(/* @__PURE__ */ new Date()).getFullYear() + "-" + results.groups.current_date.substr(0, 2) + "-" + results.groups.current_date.substr(2, 2) + "T" + results.groups.current_time.substr(0, 2) + ":" + results.groups.current_time.substr(2, 2) + ":00Z"
|
|
1376
1740
|
);
|
|
1377
1741
|
if (results.groups.fuel_in_tons != "***" && results.groups.fuel_in_tons != "****") {
|
|
1378
|
-
decodeResult
|
|
1379
|
-
}
|
|
1380
|
-
if (decodeResult.raw.position) {
|
|
1381
|
-
decodeResult.formatted.items.push({
|
|
1382
|
-
type: "position",
|
|
1383
|
-
code: "POS",
|
|
1384
|
-
label: "Position",
|
|
1385
|
-
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
1386
|
-
});
|
|
1742
|
+
ResultFormatter.remainingFuel(decodeResult, Number(results.groups.fuel_in_tons));
|
|
1387
1743
|
}
|
|
1388
|
-
decodeResult.formatted.items.push({
|
|
1389
|
-
type: "origin",
|
|
1390
|
-
code: "ORG",
|
|
1391
|
-
label: "Origin",
|
|
1392
|
-
value: decodeResult.raw.departure_icao
|
|
1393
|
-
});
|
|
1394
|
-
decodeResult.formatted.items.push({
|
|
1395
|
-
type: "destination",
|
|
1396
|
-
code: "DST",
|
|
1397
|
-
label: "Destination",
|
|
1398
|
-
value: decodeResult.raw.arrival_icao
|
|
1399
|
-
});
|
|
1400
1744
|
}
|
|
1401
1745
|
decodeResult.decoded = true;
|
|
1402
1746
|
decodeResult.decoder.decodeLevel = "full";
|
|
@@ -1420,40 +1764,20 @@ var Label_44_IN = class extends DecoderPlugin {
|
|
|
1420
1764
|
decodeResult.message = message;
|
|
1421
1765
|
const regex = /^.*,(?<unsplit_coords>.*),(?<departure_icao>.*),(?<arrival_icao>.*),(?<current_date>.*),(?<current_time>.*),(?<fuel_in_tons>.*)$/;
|
|
1422
1766
|
const results = message.text.match(regex);
|
|
1423
|
-
if (results) {
|
|
1767
|
+
if (results?.groups) {
|
|
1424
1768
|
if (options.debug) {
|
|
1425
1769
|
console.log(`Label 44 In Air Report: groups`);
|
|
1426
1770
|
console.log(results.groups);
|
|
1427
1771
|
}
|
|
1428
|
-
|
|
1429
|
-
decodeResult
|
|
1430
|
-
decodeResult
|
|
1772
|
+
ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinates(results.groups.unsplit_coords));
|
|
1773
|
+
ResultFormatter.departureAirport(decodeResult, results.groups.departure_icao);
|
|
1774
|
+
ResultFormatter.arrivalAirport(decodeResult, results.groups.arrival_icao);
|
|
1431
1775
|
decodeResult.raw.current_time = Date.parse(
|
|
1432
1776
|
(/* @__PURE__ */ new Date()).getFullYear() + "-" + results.groups.current_date.substr(0, 2) + "-" + results.groups.current_date.substr(2, 2) + "T" + results.groups.current_time.substr(0, 2) + ":" + results.groups.current_time.substr(2, 2) + ":00Z"
|
|
1433
1777
|
);
|
|
1434
1778
|
if (results.groups.fuel_in_tons != "***" && results.groups.fuel_in_tons != "****") {
|
|
1435
1779
|
decodeResult.raw.fuel_in_tons = Number(results.groups.fuel_in_tons);
|
|
1436
1780
|
}
|
|
1437
|
-
if (decodeResult.raw.position) {
|
|
1438
|
-
decodeResult.formatted.items.push({
|
|
1439
|
-
type: "position",
|
|
1440
|
-
code: "POS",
|
|
1441
|
-
label: "Position",
|
|
1442
|
-
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
1443
|
-
});
|
|
1444
|
-
}
|
|
1445
|
-
decodeResult.formatted.items.push({
|
|
1446
|
-
type: "origin",
|
|
1447
|
-
code: "ORG",
|
|
1448
|
-
label: "Origin",
|
|
1449
|
-
value: decodeResult.raw.departure_icao
|
|
1450
|
-
});
|
|
1451
|
-
decodeResult.formatted.items.push({
|
|
1452
|
-
type: "destination",
|
|
1453
|
-
code: "DST",
|
|
1454
|
-
label: "Destination",
|
|
1455
|
-
value: decodeResult.raw.arrival_icao
|
|
1456
|
-
});
|
|
1457
1781
|
}
|
|
1458
1782
|
decodeResult.decoded = true;
|
|
1459
1783
|
decodeResult.decoder.decodeLevel = "full";
|
|
@@ -1477,13 +1801,14 @@ var Label_44_OFF = class extends DecoderPlugin {
|
|
|
1477
1801
|
decodeResult.message = message;
|
|
1478
1802
|
const regex = /^.*,(?<unsplit_coords>.*),(?<departure_icao>.*),(?<arrival_icao>.*),(?<current_date>.*),(?<current_time>.*),(?<eta_time>.*),(?<fuel_in_tons>.*)$/;
|
|
1479
1803
|
const results = message.text.match(regex);
|
|
1480
|
-
if (results) {
|
|
1804
|
+
if (results?.groups) {
|
|
1481
1805
|
if (options.debug) {
|
|
1482
1806
|
console.log(`Label 44 Off Runway Report: groups`);
|
|
1483
1807
|
console.log(results.groups);
|
|
1484
1808
|
}
|
|
1485
|
-
decodeResult.
|
|
1486
|
-
decodeResult
|
|
1809
|
+
ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinates(results.groups.unsplit_coords));
|
|
1810
|
+
ResultFormatter.departureAirport(decodeResult, results.groups.departure_icao);
|
|
1811
|
+
ResultFormatter.arrivalAirport(decodeResult, results.groups.arrival_icao);
|
|
1487
1812
|
decodeResult.raw.current_time = Date.parse(
|
|
1488
1813
|
(/* @__PURE__ */ new Date()).getFullYear() + "-" + results.groups.current_date.substr(0, 2) + "-" + results.groups.current_date.substr(2, 2) + "T" + results.groups.current_time.substr(0, 2) + ":" + results.groups.current_time.substr(2, 2) + ":00Z"
|
|
1489
1814
|
);
|
|
@@ -1493,27 +1818,6 @@ var Label_44_OFF = class extends DecoderPlugin {
|
|
|
1493
1818
|
if (results.groups.fuel_in_tons != "***" && results.groups.fuel_in_tons != "****") {
|
|
1494
1819
|
decodeResult.raw.fuel_in_tons = Number(results.groups.fuel_in_tons);
|
|
1495
1820
|
}
|
|
1496
|
-
decodeResult.raw.position = CoordinateUtils.decodeStringCoordinates(results.groups.unsplit_coords);
|
|
1497
|
-
if (decodeResult.raw.position) {
|
|
1498
|
-
decodeResult.formatted.items.push({
|
|
1499
|
-
type: "position",
|
|
1500
|
-
code: "POS",
|
|
1501
|
-
label: "Position",
|
|
1502
|
-
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
1503
|
-
});
|
|
1504
|
-
}
|
|
1505
|
-
decodeResult.formatted.items.push({
|
|
1506
|
-
type: "origin",
|
|
1507
|
-
code: "ORG",
|
|
1508
|
-
label: "Origin",
|
|
1509
|
-
value: decodeResult.raw.departure_icao
|
|
1510
|
-
});
|
|
1511
|
-
decodeResult.formatted.items.push({
|
|
1512
|
-
type: "destination",
|
|
1513
|
-
code: "DST",
|
|
1514
|
-
label: "Destination",
|
|
1515
|
-
value: decodeResult.raw.arrival_icao
|
|
1516
|
-
});
|
|
1517
1821
|
}
|
|
1518
1822
|
decodeResult.decoded = true;
|
|
1519
1823
|
decodeResult.decoder.decodeLevel = "full";
|
|
@@ -1537,40 +1841,20 @@ var Label_44_ON = class extends DecoderPlugin {
|
|
|
1537
1841
|
decodeResult.message = message;
|
|
1538
1842
|
const regex = /^.*,(?<unsplit_coords>.*),(?<departure_icao>.*),(?<arrival_icao>.*),(?<current_date>.*),(?<current_time>.*),(?<fuel_in_tons>.*)$/;
|
|
1539
1843
|
const results = message.text.match(regex);
|
|
1540
|
-
if (results) {
|
|
1844
|
+
if (results?.groups) {
|
|
1541
1845
|
if (options.debug) {
|
|
1542
1846
|
console.log(`Label 44 On Runway Report: groups`);
|
|
1543
1847
|
console.log(results.groups);
|
|
1544
1848
|
}
|
|
1545
|
-
|
|
1546
|
-
decodeResult
|
|
1547
|
-
decodeResult
|
|
1849
|
+
ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinates(results.groups.unsplit_coords));
|
|
1850
|
+
ResultFormatter.departureAirport(decodeResult, results.groups.departure_icao);
|
|
1851
|
+
ResultFormatter.arrivalAirport(decodeResult, results.groups.arrival_icao);
|
|
1548
1852
|
decodeResult.raw.current_time = Date.parse(
|
|
1549
1853
|
(/* @__PURE__ */ new Date()).getFullYear() + "-" + results.groups.current_date.substr(0, 2) + "-" + results.groups.current_date.substr(2, 2) + "T" + results.groups.current_time.substr(0, 2) + ":" + results.groups.current_time.substr(2, 2) + ":00Z"
|
|
1550
1854
|
);
|
|
1551
1855
|
if (results.groups.fuel_in_tons != "***" && results.groups.fuel_in_tons != "****") {
|
|
1552
|
-
decodeResult
|
|
1856
|
+
ResultFormatter.remainingFuel(decodeResult, Number(results.groups.fuel_in_tons));
|
|
1553
1857
|
}
|
|
1554
|
-
if (decodeResult.raw.position) {
|
|
1555
|
-
decodeResult.formatted.items.push({
|
|
1556
|
-
type: "position",
|
|
1557
|
-
code: "POS",
|
|
1558
|
-
label: "Position",
|
|
1559
|
-
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
1560
|
-
});
|
|
1561
|
-
}
|
|
1562
|
-
decodeResult.formatted.items.push({
|
|
1563
|
-
type: "origin",
|
|
1564
|
-
code: "ORG",
|
|
1565
|
-
label: "Origin",
|
|
1566
|
-
value: decodeResult.raw.departure_icao
|
|
1567
|
-
});
|
|
1568
|
-
decodeResult.formatted.items.push({
|
|
1569
|
-
type: "destination",
|
|
1570
|
-
code: "DST",
|
|
1571
|
-
label: "Destination",
|
|
1572
|
-
value: decodeResult.raw.arrival_icao
|
|
1573
|
-
});
|
|
1574
1858
|
}
|
|
1575
1859
|
decodeResult.decoded = true;
|
|
1576
1860
|
decodeResult.decoder.decodeLevel = "full";
|
|
@@ -1594,12 +1878,12 @@ var Label_44_POS = class extends DecoderPlugin {
|
|
|
1594
1878
|
decodeResult.message = message;
|
|
1595
1879
|
const regex = /^.*,(?<unsplit_coords>.*),(?<flight_level_or_ground>.*),(?<departure_icao>.*),(?<arrival_icao>.*),(?<current_date>.*),(?<current_time>.*),(?<eta_time>.*),(?<fuel_in_tons>.*)$/;
|
|
1596
1880
|
const results = message.text.match(regex);
|
|
1597
|
-
if (results) {
|
|
1881
|
+
if (results?.groups) {
|
|
1598
1882
|
if (options.debug) {
|
|
1599
1883
|
console.log(`Label 44 Position Report: groups`);
|
|
1600
1884
|
console.log(results.groups);
|
|
1601
1885
|
}
|
|
1602
|
-
|
|
1886
|
+
ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(results.groups.unsplit_coords));
|
|
1603
1887
|
const flight_level = results.groups.flight_level_or_ground == "GRD" || results.groups.flight_level_or_ground == "***" ? 0 : Number(results.groups.flight_level_or_ground);
|
|
1604
1888
|
decodeResult.raw.current_time = Date.parse(
|
|
1605
1889
|
(/* @__PURE__ */ new Date()).getFullYear() + "-" + results.groups.current_date.substr(0, 2) + "-" + results.groups.current_date.substr(2, 2) + "T" + results.groups.current_time.substr(0, 2) + ":" + results.groups.current_time.substr(2, 2) + ":00Z"
|
|
@@ -1610,14 +1894,6 @@ var Label_44_POS = class extends DecoderPlugin {
|
|
|
1610
1894
|
if (results.groups.fuel_in_tons != "***" && results.groups.fuel_in_tons != "****") {
|
|
1611
1895
|
decodeResult.raw.fuel_in_tons = Number(results.groups.fuel_in_tons);
|
|
1612
1896
|
}
|
|
1613
|
-
if (decodeResult.raw.position) {
|
|
1614
|
-
decodeResult.formatted.items.push({
|
|
1615
|
-
type: "aircraft_position",
|
|
1616
|
-
code: "POS",
|
|
1617
|
-
label: "Aircraft Position",
|
|
1618
|
-
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
1619
|
-
});
|
|
1620
|
-
}
|
|
1621
1897
|
ResultFormatter.departureAirport(decodeResult, results.groups.departure_icao);
|
|
1622
1898
|
ResultFormatter.arrivalAirport(decodeResult, results.groups.arrival_icao);
|
|
1623
1899
|
ResultFormatter.altitude(decodeResult, flight_level * 100);
|
|
@@ -1641,13 +1917,13 @@ var Label_4A = class extends DecoderPlugin {
|
|
|
1641
1917
|
decodeResult.decoder.name = this.name;
|
|
1642
1918
|
decodeResult.message = message;
|
|
1643
1919
|
decodeResult.formatted.description = "Latest New Format";
|
|
1644
|
-
let
|
|
1645
|
-
if (
|
|
1920
|
+
let text = message.text;
|
|
1921
|
+
if (text.match(/^M\d{2}A\w{6}/)) {
|
|
1646
1922
|
ResultFormatter.flightNumber(decodeResult, message.text.substring(4, 10).replace(/^([A-Z]+)0*/g, "$1"));
|
|
1647
|
-
|
|
1923
|
+
text = text.substring(10);
|
|
1648
1924
|
}
|
|
1649
1925
|
decodeResult.decoded = true;
|
|
1650
|
-
const fields =
|
|
1926
|
+
const fields = text.split(",");
|
|
1651
1927
|
if (fields.length === 11) {
|
|
1652
1928
|
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[0]));
|
|
1653
1929
|
ResultFormatter.tail(decodeResult, fields[2].replace(".", ""));
|
|
@@ -1655,8 +1931,8 @@ var Label_4A = class extends DecoderPlugin {
|
|
|
1655
1931
|
ResultFormatter.callsign(decodeResult, fields[3]);
|
|
1656
1932
|
ResultFormatter.departureAirport(decodeResult, fields[4]);
|
|
1657
1933
|
ResultFormatter.arrivalAirport(decodeResult, fields[5]);
|
|
1658
|
-
ResultFormatter.altitude(decodeResult,
|
|
1659
|
-
decodeResult
|
|
1934
|
+
ResultFormatter.altitude(decodeResult, Number(text.substring(48, 51)) * 100);
|
|
1935
|
+
ResultFormatter.unknownArr(decodeResult, fields.slice(8));
|
|
1660
1936
|
} else if (fields.length === 6) {
|
|
1661
1937
|
if (fields[0].match(/^[NS]/)) {
|
|
1662
1938
|
ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinates(fields[0].substring(0, 13)));
|
|
@@ -1665,31 +1941,25 @@ var Label_4A = class extends DecoderPlugin {
|
|
|
1665
1941
|
time: DateTimeUtils.convertHHMMSSToTod(fields[1].substring(0, 6)),
|
|
1666
1942
|
timeFormat: "tod"
|
|
1667
1943
|
};
|
|
1668
|
-
ResultFormatter.altitude(decodeResult, fields[1].substring(6, 9) * 100);
|
|
1944
|
+
ResultFormatter.altitude(decodeResult, Number(fields[1].substring(6, 9)) * 100);
|
|
1669
1945
|
let wp2 = {
|
|
1670
1946
|
name: fields[1].substring(9).trim(),
|
|
1671
1947
|
time: DateTimeUtils.convertHHMMSSToTod(fields[2]),
|
|
1672
1948
|
timeFormat: "tod"
|
|
1673
1949
|
};
|
|
1674
|
-
|
|
1675
|
-
decodeResult.formatted.items.push({
|
|
1676
|
-
type: "aircraft_route",
|
|
1677
|
-
code: "ROUTE",
|
|
1678
|
-
label: "Aircraft Route",
|
|
1679
|
-
value: RouteUtils.routeToString(decodeResult.raw.route)
|
|
1680
|
-
});
|
|
1950
|
+
ResultFormatter.route(decodeResult, { waypoints: [wp1, wp2] });
|
|
1681
1951
|
ResultFormatter.temperature(decodeResult, fields[3]);
|
|
1682
|
-
decodeResult
|
|
1952
|
+
ResultFormatter.unknownArr(decodeResult, fields.slice(4));
|
|
1683
1953
|
} else {
|
|
1684
1954
|
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[0]));
|
|
1685
1955
|
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1]));
|
|
1686
|
-
decodeResult
|
|
1687
|
-
ResultFormatter.altitude(decodeResult, fields[3]);
|
|
1956
|
+
ResultFormatter.unknown(decodeResult, fields[2]);
|
|
1957
|
+
ResultFormatter.altitude(decodeResult, Number(fields[3]));
|
|
1688
1958
|
ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinates((fields[4] + fields[5]).replace(/[ \.]/g, "")));
|
|
1689
1959
|
}
|
|
1690
1960
|
} else {
|
|
1691
1961
|
decodeResult.decoded = false;
|
|
1692
|
-
decodeResult
|
|
1962
|
+
ResultFormatter.unknown(decodeResult, text);
|
|
1693
1963
|
}
|
|
1694
1964
|
if (decodeResult.decoded) {
|
|
1695
1965
|
if (!decodeResult.remaining.text)
|
|
@@ -1726,11 +1996,11 @@ var Label_4A_01 = class extends DecoderPlugin {
|
|
|
1726
1996
|
ResultFormatter.departureAirport(decodeResult, rgx[5]);
|
|
1727
1997
|
ResultFormatter.arrivalAirport(decodeResult, rgx[6]);
|
|
1728
1998
|
ResultFormatter.altitude(decodeResult, Number(rgx[7].replace(/ /g, "")));
|
|
1729
|
-
decodeResult
|
|
1999
|
+
ResultFormatter.unknown(decodeResult, rgx[8]);
|
|
1730
2000
|
ResultFormatter.temperature(decodeResult, rgx[9].replace(/ /g, ""));
|
|
1731
2001
|
} else {
|
|
1732
2002
|
decodeResult.decoded = false;
|
|
1733
|
-
decodeResult
|
|
2003
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
1734
2004
|
}
|
|
1735
2005
|
if (decodeResult.decoded) {
|
|
1736
2006
|
if (!decodeResult.remaining.text)
|
|
@@ -1796,7 +2066,7 @@ var Label_4A_DOOR = class extends DecoderPlugin {
|
|
|
1796
2066
|
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[2] + "00"));
|
|
1797
2067
|
} else {
|
|
1798
2068
|
decodeResult.decoded = false;
|
|
1799
|
-
decodeResult.
|
|
2069
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
1800
2070
|
}
|
|
1801
2071
|
if (decodeResult.decoded) {
|
|
1802
2072
|
if (!decodeResult.remaining.text)
|
|
@@ -1826,10 +2096,10 @@ var Label_4A_Slash_01 = class extends DecoderPlugin {
|
|
|
1826
2096
|
decodeResult.formatted.description = "Latest New Format";
|
|
1827
2097
|
decodeResult.decoded = true;
|
|
1828
2098
|
if (message.text.length === 5 && message.text.substring(0, 4) === "/01-") {
|
|
1829
|
-
decodeResult
|
|
2099
|
+
ResultFormatter.unknown(decodeResult, message.text.substring(4));
|
|
1830
2100
|
} else {
|
|
1831
2101
|
decodeResult.decoded = false;
|
|
1832
|
-
decodeResult
|
|
2102
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
1833
2103
|
}
|
|
1834
2104
|
if (decodeResult.decoded) {
|
|
1835
2105
|
if (!decodeResult.remaining.text)
|
|
@@ -1856,25 +2126,25 @@ var Label_4N = class extends DecoderPlugin {
|
|
|
1856
2126
|
decodeResult.decoder.name = this.name;
|
|
1857
2127
|
decodeResult.message = message;
|
|
1858
2128
|
decodeResult.formatted.description = "Airline Defined";
|
|
1859
|
-
let
|
|
1860
|
-
if (
|
|
2129
|
+
let text = message.text;
|
|
2130
|
+
if (text.match(/^M\d{2}A\w{6}/)) {
|
|
1861
2131
|
ResultFormatter.flightNumber(decodeResult, message.text.substring(4, 10).replace(/^([A-Z]+)0*/g, "$1"));
|
|
1862
|
-
|
|
2132
|
+
text = text.substring(10);
|
|
1863
2133
|
}
|
|
1864
2134
|
decodeResult.decoded = true;
|
|
1865
|
-
const fields =
|
|
1866
|
-
if (
|
|
1867
|
-
decodeResult.raw.day_of_month =
|
|
1868
|
-
ResultFormatter.departureAirport(decodeResult,
|
|
1869
|
-
ResultFormatter.arrivalAirport(decodeResult,
|
|
1870
|
-
ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(
|
|
1871
|
-
ResultFormatter.altitude(decodeResult,
|
|
1872
|
-
decodeResult
|
|
2135
|
+
const fields = text.split(",");
|
|
2136
|
+
if (text.length === 51) {
|
|
2137
|
+
decodeResult.raw.day_of_month = text.substring(0, 2);
|
|
2138
|
+
ResultFormatter.departureAirport(decodeResult, text.substring(8, 11));
|
|
2139
|
+
ResultFormatter.arrivalAirport(decodeResult, text.substring(13, 16));
|
|
2140
|
+
ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(text.substring(30, 45).replace(/^(.)0/, "$1")));
|
|
2141
|
+
ResultFormatter.altitude(decodeResult, Number(text.substring(48, 51)) * 100);
|
|
2142
|
+
ResultFormatter.unknownArr(decodeResult, [text.substring(2, 4), text.substring(19, 29)], " ");
|
|
1873
2143
|
} else if (fields.length === 33) {
|
|
1874
2144
|
decodeResult.raw.date = fields[3];
|
|
1875
2145
|
if (fields[1] === "B") {
|
|
1876
2146
|
ResultFormatter.position(decodeResult, { latitude: Number(fields[4]), longitude: Number(fields[5]) });
|
|
1877
|
-
ResultFormatter.altitude(decodeResult, fields[6]);
|
|
2147
|
+
ResultFormatter.altitude(decodeResult, Number(fields[6]));
|
|
1878
2148
|
}
|
|
1879
2149
|
ResultFormatter.departureAirport(decodeResult, fields[8]);
|
|
1880
2150
|
ResultFormatter.arrivalAirport(decodeResult, fields[9]);
|
|
@@ -1884,10 +2154,10 @@ var Label_4N = class extends DecoderPlugin {
|
|
|
1884
2154
|
ResultFormatter.alternateRunway(decodeResult, fields[12].split("/")[0]);
|
|
1885
2155
|
}
|
|
1886
2156
|
ResultFormatter.checksum(decodeResult, fields[32]);
|
|
1887
|
-
decodeResult
|
|
2157
|
+
ResultFormatter.unknownArr(decodeResult, [...fields.slice(1, 3), fields[7], ...fields.slice(13, 32)].filter((f) => f != ""));
|
|
1888
2158
|
} else {
|
|
1889
2159
|
decodeResult.decoded = false;
|
|
1890
|
-
decodeResult
|
|
2160
|
+
ResultFormatter.unknown(decodeResult, text);
|
|
1891
2161
|
}
|
|
1892
2162
|
if (decodeResult.decoded) {
|
|
1893
2163
|
if (!decodeResult.remaining.text)
|
|
@@ -1983,23 +2253,14 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
1983
2253
|
break;
|
|
1984
2254
|
}
|
|
1985
2255
|
case "FOB": {
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
label: this.descriptions[match.groups.field],
|
|
1991
|
-
value: decodeResult.raw.fuel_on_board
|
|
1992
|
-
});
|
|
2256
|
+
const fob = Number(match.groups.value);
|
|
2257
|
+
if (!isNaN(fob)) {
|
|
2258
|
+
ResultFormatter.currentFuel(decodeResult, fob);
|
|
2259
|
+
}
|
|
1993
2260
|
break;
|
|
1994
2261
|
}
|
|
1995
2262
|
case "HDG": {
|
|
1996
|
-
|
|
1997
|
-
decodeResult.formatted.items.push({
|
|
1998
|
-
type: "heading",
|
|
1999
|
-
code: "HDG",
|
|
2000
|
-
label: this.descriptions[match.groups.field],
|
|
2001
|
-
value: decodeResult.raw.heading
|
|
2002
|
-
});
|
|
2263
|
+
ResultFormatter.heading(decodeResult, Number(match.groups.value));
|
|
2003
2264
|
break;
|
|
2004
2265
|
}
|
|
2005
2266
|
case "MCH": {
|
|
@@ -2078,33 +2339,33 @@ var Label_83 = class extends DecoderPlugin {
|
|
|
2078
2339
|
decodeResult.decoder.name = this.name;
|
|
2079
2340
|
decodeResult.message = message;
|
|
2080
2341
|
decodeResult.formatted.description = "Airline Defined";
|
|
2081
|
-
let
|
|
2082
|
-
if (
|
|
2342
|
+
let text = message.text;
|
|
2343
|
+
if (text.match(/^M\d{2}A\w{6}/)) {
|
|
2083
2344
|
ResultFormatter.flightNumber(decodeResult, message.text.substring(4, 10).replace(/^([A-Z]+)0*/g, "$1"));
|
|
2084
|
-
|
|
2345
|
+
text = text.substring(10);
|
|
2085
2346
|
}
|
|
2086
2347
|
decodeResult.decoded = true;
|
|
2087
|
-
if (
|
|
2088
|
-
const fields =
|
|
2348
|
+
if (text.substring(0, 10) === "4DH3 ETAT2") {
|
|
2349
|
+
const fields = text.split(/\s+/);
|
|
2089
2350
|
if (fields[2].length > 5) {
|
|
2090
2351
|
decodeResult.raw.day_of_month = fields[2].substring(5);
|
|
2091
2352
|
}
|
|
2092
|
-
decodeResult
|
|
2353
|
+
ResultFormatter.unknown(decodeResult, fields[2].substring(0, 4));
|
|
2093
2354
|
const subfields = fields[3].split("/");
|
|
2094
2355
|
ResultFormatter.departureAirport(decodeResult, subfields[0]);
|
|
2095
2356
|
ResultFormatter.arrivalAirport(decodeResult, subfields[1]);
|
|
2096
2357
|
ResultFormatter.tail(decodeResult, fields[4].replace(/\./g, ""));
|
|
2097
2358
|
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[6] + "00"));
|
|
2098
|
-
} else if (
|
|
2099
|
-
decodeResult.raw.day_of_month =
|
|
2100
|
-
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(
|
|
2359
|
+
} else if (text.substring(0, 5) === "001PR") {
|
|
2360
|
+
decodeResult.raw.day_of_month = text.substring(5, 7);
|
|
2361
|
+
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(text.substring(13, 28).replace(/\./g, ""));
|
|
2101
2362
|
if (position) {
|
|
2102
2363
|
ResultFormatter.position(decodeResult, position);
|
|
2103
2364
|
}
|
|
2104
|
-
ResultFormatter.altitude(decodeResult, Number(
|
|
2105
|
-
decodeResult
|
|
2365
|
+
ResultFormatter.altitude(decodeResult, Number(text.substring(28, 33)));
|
|
2366
|
+
ResultFormatter.unknown(decodeResult, text.substring(33));
|
|
2106
2367
|
} else {
|
|
2107
|
-
const fields =
|
|
2368
|
+
const fields = text.replace(/\s/g, "").split(",");
|
|
2108
2369
|
if (fields.length === 9) {
|
|
2109
2370
|
ResultFormatter.departureAirport(decodeResult, fields[0]);
|
|
2110
2371
|
ResultFormatter.arrivalAirport(decodeResult, fields[1]);
|
|
@@ -2118,12 +2379,12 @@ var Label_83 = class extends DecoderPlugin {
|
|
|
2118
2379
|
}
|
|
2119
2380
|
);
|
|
2120
2381
|
ResultFormatter.altitude(decodeResult, Number(fields[5]));
|
|
2121
|
-
ResultFormatter.groundspeed(decodeResult, fields[6]);
|
|
2122
|
-
ResultFormatter.heading(decodeResult, fields[7]);
|
|
2123
|
-
decodeResult
|
|
2382
|
+
ResultFormatter.groundspeed(decodeResult, Number(fields[6]));
|
|
2383
|
+
ResultFormatter.heading(decodeResult, Number(fields[7]));
|
|
2384
|
+
ResultFormatter.unknown(decodeResult, fields[8]);
|
|
2124
2385
|
} else {
|
|
2125
2386
|
decodeResult.decoded = false;
|
|
2126
|
-
decodeResult
|
|
2387
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
2127
2388
|
}
|
|
2128
2389
|
}
|
|
2129
2390
|
if (decodeResult.decoded) {
|
|
@@ -2153,7 +2414,7 @@ var Label_8E = class extends DecoderPlugin {
|
|
|
2153
2414
|
decodeResult.message = message;
|
|
2154
2415
|
const regex = /^(?<arrival_icao>\w{4}),(?<arrival_eta>\d{4})$/;
|
|
2155
2416
|
const results = message.text.match(regex);
|
|
2156
|
-
if (results) {
|
|
2417
|
+
if (results?.groups) {
|
|
2157
2418
|
if (options.debug) {
|
|
2158
2419
|
console.log(`Label 8E ETA: groups`);
|
|
2159
2420
|
console.log(results.groups);
|
|
@@ -2204,7 +2465,8 @@ var Label_ColonComma = class extends DecoderPlugin {
|
|
|
2204
2465
|
decodeResult.formatted.items.push({
|
|
2205
2466
|
type: "frequency",
|
|
2206
2467
|
label: "Frequency",
|
|
2207
|
-
value: `${decodeResult.raw.frequency} MHz
|
|
2468
|
+
value: `${decodeResult.raw.frequency} MHz`,
|
|
2469
|
+
code: "FREQ"
|
|
2208
2470
|
});
|
|
2209
2471
|
decodeResult.decoded = true;
|
|
2210
2472
|
decodeResult.decoder.decodeLevel = "full";
|
|
@@ -2212,240 +2474,72 @@ var Label_ColonComma = class extends DecoderPlugin {
|
|
|
2212
2474
|
}
|
|
2213
2475
|
};
|
|
2214
2476
|
|
|
2215
|
-
// lib/
|
|
2216
|
-
var
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2477
|
+
// lib/utils/flight_plan_utils.ts
|
|
2478
|
+
var FlightPlanUtils = class _FlightPlanUtils {
|
|
2479
|
+
/**
|
|
2480
|
+
* Processes flight plan data
|
|
2481
|
+
*
|
|
2482
|
+
* Expected format is [header, key1, val1, ... keyN, valN]
|
|
2483
|
+
*
|
|
2484
|
+
* @param decodeResult - results
|
|
2485
|
+
* @param data - original message split by ':'
|
|
2486
|
+
* @returns whether all fields were processed or not
|
|
2487
|
+
*/
|
|
2488
|
+
static processFlightPlan(decodeResult, data) {
|
|
2489
|
+
let allKnownFields = _FlightPlanUtils.parseHeader(decodeResult, data[0]);
|
|
2490
|
+
for (let i = 1; i < data.length; i += 2) {
|
|
2491
|
+
const key = data[i];
|
|
2492
|
+
const value = data[i + 1];
|
|
2493
|
+
switch (key) {
|
|
2494
|
+
case "A":
|
|
2495
|
+
addProcedure(decodeResult, value, "arrival");
|
|
2496
|
+
break;
|
|
2497
|
+
case "AA":
|
|
2498
|
+
addArrivalAirport(decodeResult, value);
|
|
2499
|
+
break;
|
|
2500
|
+
case "AP":
|
|
2501
|
+
addProcedure(decodeResult, value, "approach");
|
|
2502
|
+
break;
|
|
2503
|
+
case "CR":
|
|
2504
|
+
addCompanyRoute(decodeResult, value);
|
|
2505
|
+
break;
|
|
2506
|
+
case "D":
|
|
2507
|
+
addProcedure(decodeResult, value, "departure");
|
|
2508
|
+
break;
|
|
2509
|
+
case "DA":
|
|
2510
|
+
addDepartureAirport(decodeResult, value);
|
|
2511
|
+
break;
|
|
2512
|
+
case "F":
|
|
2513
|
+
addRoute(decodeResult, value);
|
|
2514
|
+
break;
|
|
2515
|
+
case "R":
|
|
2516
|
+
addRunway(decodeResult, value);
|
|
2517
|
+
break;
|
|
2518
|
+
// case 'WS': // something about routes, has altitude, so current parsing won't work
|
|
2519
|
+
// break;
|
|
2520
|
+
default:
|
|
2521
|
+
if (allKnownFields) {
|
|
2522
|
+
decodeResult.remaining.text = "";
|
|
2523
|
+
allKnownFields = false;
|
|
2524
|
+
}
|
|
2525
|
+
decodeResult.remaining.text += `:${key}:${value}`;
|
|
2526
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
2240
2527
|
}
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
decodeResult.raw.fault_message = msg;
|
|
2528
|
+
}
|
|
2529
|
+
return allKnownFields;
|
|
2530
|
+
}
|
|
2531
|
+
static parseHeader(decodeResult, header) {
|
|
2532
|
+
let allKnownFields = true;
|
|
2533
|
+
if (header.startsWith("RF")) {
|
|
2248
2534
|
decodeResult.formatted.items.push({
|
|
2249
|
-
type: "
|
|
2250
|
-
code: "
|
|
2251
|
-
label: "
|
|
2252
|
-
value:
|
|
2535
|
+
type: "status",
|
|
2536
|
+
code: "ROUTE_STATUS",
|
|
2537
|
+
label: "Route Status",
|
|
2538
|
+
value: "Route Filed"
|
|
2253
2539
|
});
|
|
2254
|
-
decodeResult.
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
if (options.debug) {
|
|
2258
|
-
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
2259
|
-
}
|
|
2260
|
-
decodeResult.remaining.text = message.text;
|
|
2261
|
-
decodeResult.decoded = false;
|
|
2262
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
2263
|
-
}
|
|
2264
|
-
return decodeResult;
|
|
2265
|
-
}
|
|
2266
|
-
};
|
|
2267
|
-
function processUnknown(decodeResult, value) {
|
|
2268
|
-
decodeResult.remaining.text += value;
|
|
2269
|
-
}
|
|
2270
|
-
|
|
2271
|
-
// lib/plugins/Label_H1_OHMA.ts
|
|
2272
|
-
import * as zlib from "minizlib";
|
|
2273
|
-
var Label_H1_OHMA = class extends DecoderPlugin {
|
|
2274
|
-
name = "label-h1-ohma";
|
|
2275
|
-
qualifiers() {
|
|
2276
|
-
return {
|
|
2277
|
-
labels: ["H1"],
|
|
2278
|
-
preambles: ["OHMA", "/RTNBOCR.OHMA", "#T1B/RTNBOCR.OHMA"]
|
|
2279
|
-
};
|
|
2280
|
-
}
|
|
2281
|
-
decode(message, options = {}) {
|
|
2282
|
-
let decodeResult = this.defaultResult();
|
|
2283
|
-
decodeResult.decoder.name = this.name;
|
|
2284
|
-
decodeResult.formatted.description = "OHMA Message";
|
|
2285
|
-
decodeResult.message = message;
|
|
2286
|
-
decodeResult.remaining.text = "";
|
|
2287
|
-
const data = message.text.split("OHMA")[1];
|
|
2288
|
-
try {
|
|
2289
|
-
const compressedBuffer = Buffer.from(data, "base64");
|
|
2290
|
-
const decompress = new zlib.Inflate({ windowBits: 15 });
|
|
2291
|
-
decompress.write(compressedBuffer);
|
|
2292
|
-
decompress.flush(zlib.constants.Z_SYNC_FLUSH);
|
|
2293
|
-
const result = decompress.read();
|
|
2294
|
-
const jsonText = result.toString();
|
|
2295
|
-
let formattedMsg;
|
|
2296
|
-
let jsonMessage;
|
|
2297
|
-
try {
|
|
2298
|
-
jsonMessage = JSON.parse(jsonText).message;
|
|
2299
|
-
} catch {
|
|
2300
|
-
jsonMessage = jsonText;
|
|
2301
|
-
}
|
|
2302
|
-
try {
|
|
2303
|
-
const ohmaMsg = JSON.parse(jsonMessage);
|
|
2304
|
-
formattedMsg = JSON.stringify(ohmaMsg, null, 2);
|
|
2305
|
-
} catch {
|
|
2306
|
-
formattedMsg = jsonMessage;
|
|
2307
|
-
}
|
|
2308
|
-
decodeResult.decoded = true;
|
|
2309
|
-
decodeResult.decoder.decodeLevel = "full";
|
|
2310
|
-
decodeResult.raw.ohma = jsonText;
|
|
2311
|
-
decodeResult.formatted.items.push({
|
|
2312
|
-
type: "ohma",
|
|
2313
|
-
code: "OHMA",
|
|
2314
|
-
label: "OHMA Downlink",
|
|
2315
|
-
value: formattedMsg
|
|
2316
|
-
});
|
|
2317
|
-
} catch (e) {
|
|
2318
|
-
if (options.debug) {
|
|
2319
|
-
console.log(`Decoder: Unknown H1 OHMA message: ${message.text}`, e);
|
|
2320
|
-
}
|
|
2321
|
-
decodeResult.remaining.text += message.text;
|
|
2322
|
-
decodeResult.decoded = false;
|
|
2323
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
2324
|
-
}
|
|
2325
|
-
return decodeResult;
|
|
2326
|
-
}
|
|
2327
|
-
};
|
|
2328
|
-
|
|
2329
|
-
// lib/plugins/Label_H1_WRN.ts
|
|
2330
|
-
var Label_H1_WRN = class extends DecoderPlugin {
|
|
2331
|
-
name = "label-h1-wrn";
|
|
2332
|
-
qualifiers() {
|
|
2333
|
-
return {
|
|
2334
|
-
labels: ["H1"],
|
|
2335
|
-
preambles: ["WRN", "#CFBWRN"]
|
|
2336
|
-
};
|
|
2337
|
-
}
|
|
2338
|
-
decode(message, options = {}) {
|
|
2339
|
-
let decodeResult = this.defaultResult();
|
|
2340
|
-
decodeResult.decoder.name = this.name;
|
|
2341
|
-
decodeResult.formatted.description = "Warning Message";
|
|
2342
|
-
decodeResult.message = message;
|
|
2343
|
-
const parts = message.text.split("/WN");
|
|
2344
|
-
if (parts.length > 1) {
|
|
2345
|
-
decodeResult.remaining.text = "";
|
|
2346
|
-
const fields = parts[0].split("/");
|
|
2347
|
-
for (let i = 1; i < fields.length; i++) {
|
|
2348
|
-
const field = fields[i];
|
|
2349
|
-
if (field.startsWith("PN")) {
|
|
2350
|
-
processUnknown2(decodeResult, "/" + field);
|
|
2351
|
-
} else {
|
|
2352
|
-
processUnknown2(decodeResult, "/" + field);
|
|
2353
|
-
}
|
|
2354
|
-
}
|
|
2355
|
-
const data = parts[1].substring(0, 20);
|
|
2356
|
-
const msg = parts[1].substring(20);
|
|
2357
|
-
const datetime = data.substring(0, 12);
|
|
2358
|
-
const date = datetime.substring(4, 6) + datetime.substring(2, 4) + datetime.substring(0, 2);
|
|
2359
|
-
processUnknown2(decodeResult, data.substring(12));
|
|
2360
|
-
decodeResult.raw.message_timestamp = DateTimeUtils.convertDateTimeToEpoch(datetime.substring(6), date);
|
|
2361
|
-
decodeResult.raw.warning_message = msg;
|
|
2362
|
-
decodeResult.formatted.items.push({
|
|
2363
|
-
type: "warning",
|
|
2364
|
-
code: "WRN",
|
|
2365
|
-
label: "Warning Message",
|
|
2366
|
-
value: decodeResult.raw.warning_message
|
|
2367
|
-
});
|
|
2368
|
-
decodeResult.decoded = true;
|
|
2369
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
2370
|
-
} else {
|
|
2371
|
-
if (options.debug) {
|
|
2372
|
-
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
2373
|
-
}
|
|
2374
|
-
decodeResult.remaining.text = message.text;
|
|
2375
|
-
decodeResult.decoded = false;
|
|
2376
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
2377
|
-
}
|
|
2378
|
-
return decodeResult;
|
|
2379
|
-
}
|
|
2380
|
-
};
|
|
2381
|
-
function processUnknown2(decodeResult, value) {
|
|
2382
|
-
decodeResult.remaining.text += value;
|
|
2383
|
-
}
|
|
2384
|
-
|
|
2385
|
-
// lib/utils/flight_plan_utils.ts
|
|
2386
|
-
var FlightPlanUtils = class _FlightPlanUtils {
|
|
2387
|
-
/**
|
|
2388
|
-
* Processes flight plan data
|
|
2389
|
-
*
|
|
2390
|
-
* Expected format is [header, key1, val1, ... keyN, valN]
|
|
2391
|
-
*
|
|
2392
|
-
* @param decodeResult - results
|
|
2393
|
-
* @param data - original message split by ':'
|
|
2394
|
-
* @returns whether all fields were processed or not
|
|
2395
|
-
*/
|
|
2396
|
-
static processFlightPlan(decodeResult, data) {
|
|
2397
|
-
let allKnownFields = _FlightPlanUtils.parseHeader(decodeResult, data[0]);
|
|
2398
|
-
for (let i = 1; i < data.length; i += 2) {
|
|
2399
|
-
const key = data[i];
|
|
2400
|
-
const value = data[i + 1];
|
|
2401
|
-
switch (key) {
|
|
2402
|
-
case "A":
|
|
2403
|
-
addProcedure(decodeResult, value, "arrival");
|
|
2404
|
-
break;
|
|
2405
|
-
case "AA":
|
|
2406
|
-
addArrivalAirport(decodeResult, value);
|
|
2407
|
-
break;
|
|
2408
|
-
case "AP":
|
|
2409
|
-
addProcedure(decodeResult, value, "approach");
|
|
2410
|
-
break;
|
|
2411
|
-
case "CR":
|
|
2412
|
-
addCompanyRoute(decodeResult, value);
|
|
2413
|
-
break;
|
|
2414
|
-
case "D":
|
|
2415
|
-
addProcedure(decodeResult, value, "departure");
|
|
2416
|
-
break;
|
|
2417
|
-
case "DA":
|
|
2418
|
-
addDepartureAirport(decodeResult, value);
|
|
2419
|
-
break;
|
|
2420
|
-
case "F":
|
|
2421
|
-
addRoute(decodeResult, value);
|
|
2422
|
-
break;
|
|
2423
|
-
case "R":
|
|
2424
|
-
addRunway(decodeResult, value);
|
|
2425
|
-
break;
|
|
2426
|
-
default:
|
|
2427
|
-
if (allKnownFields) {
|
|
2428
|
-
decodeResult.remaining.text = "";
|
|
2429
|
-
allKnownFields = false;
|
|
2430
|
-
}
|
|
2431
|
-
decodeResult.remaining.text += `:${key}:${value}`;
|
|
2432
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
2433
|
-
}
|
|
2434
|
-
}
|
|
2435
|
-
return allKnownFields;
|
|
2436
|
-
}
|
|
2437
|
-
static parseHeader(decodeResult, header) {
|
|
2438
|
-
let allKnownFields = true;
|
|
2439
|
-
if (header.startsWith("RF")) {
|
|
2440
|
-
decodeResult.formatted.items.push({
|
|
2441
|
-
type: "status",
|
|
2442
|
-
code: "ROUTE_STATUS",
|
|
2443
|
-
label: "Route Status",
|
|
2444
|
-
value: "Route Filed"
|
|
2445
|
-
});
|
|
2446
|
-
decodeResult.raw.route_status = "RF";
|
|
2447
|
-
if (header.length > 2) {
|
|
2448
|
-
addRoute(decodeResult, header.substring(2));
|
|
2540
|
+
decodeResult.raw.route_status = "RF";
|
|
2541
|
+
if (header.length > 2) {
|
|
2542
|
+
addRoute(decodeResult, header.substring(2));
|
|
2449
2543
|
}
|
|
2450
2544
|
} else if (header.startsWith("RP")) {
|
|
2451
2545
|
decodeResult.raw.route_status = "RP";
|
|
@@ -2485,13 +2579,7 @@ function addRunway(decodeResult, value) {
|
|
|
2485
2579
|
}
|
|
2486
2580
|
function addRoute(decodeResult, value) {
|
|
2487
2581
|
const route = value.split(".");
|
|
2488
|
-
|
|
2489
|
-
decodeResult.formatted.items.push({
|
|
2490
|
-
type: "aircraft_route",
|
|
2491
|
-
code: "ROUTE",
|
|
2492
|
-
label: "Aircraft Route",
|
|
2493
|
-
value: RouteUtils.routeToString(decodeResult.raw.route)
|
|
2494
|
-
});
|
|
2582
|
+
ResultFormatter.route(decodeResult, { waypoints: route.map((leg) => RouteUtils.getWaypoint(leg)) });
|
|
2495
2583
|
}
|
|
2496
2584
|
function addProcedure(decodeResult, value, type) {
|
|
2497
2585
|
if (decodeResult.raw.procedures === void 0) {
|
|
@@ -2577,21 +2665,23 @@ var H1Helper = class {
|
|
|
2577
2665
|
} else if (fields[i].startsWith("RI") || fields[i].startsWith("RF") || fields[i].startsWith("RP")) {
|
|
2578
2666
|
FlightPlanUtils.processFlightPlan(decodeResult, fields[i].split(":"));
|
|
2579
2667
|
} else if (fields[i].startsWith("PR")) {
|
|
2580
|
-
decodeResult
|
|
2668
|
+
ResultFormatter.unknown(decodeResult, fields[i], "/");
|
|
2581
2669
|
} else if (fields[i].startsWith("AF")) {
|
|
2582
2670
|
processAirField(decodeResult, fields[i].substring(2).split(","));
|
|
2583
2671
|
} else if (fields[i].startsWith("TD")) {
|
|
2584
2672
|
processTimeOfDeparture(decodeResult, fields[i].substring(2).split(","));
|
|
2585
2673
|
} else if (fields[i].startsWith("FX")) {
|
|
2586
|
-
decodeResult
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
}
|
|
2674
|
+
ResultFormatter.freetext(decodeResult, fields[i].substring(2));
|
|
2675
|
+
} else if (fields[i].startsWith("ET")) {
|
|
2676
|
+
if (fields[i].length === 7) {
|
|
2677
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[i].substring(3) + "00"));
|
|
2678
|
+
} else if (fields[i].length === 8) {
|
|
2679
|
+
ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[i].substring(4) + "00"));
|
|
2680
|
+
} else {
|
|
2681
|
+
ResultFormatter.unknown(decodeResult, fields[i], "/");
|
|
2682
|
+
}
|
|
2593
2683
|
} else {
|
|
2594
|
-
decodeResult
|
|
2684
|
+
ResultFormatter.unknown(decodeResult, fields[i], "/");
|
|
2595
2685
|
}
|
|
2596
2686
|
}
|
|
2597
2687
|
if (decodeResult.formatted.items.length > 0) {
|
|
@@ -2605,7 +2695,7 @@ function processAirField(decodeResult, data) {
|
|
|
2605
2695
|
ResultFormatter.departureAirport(decodeResult, data[0]);
|
|
2606
2696
|
ResultFormatter.arrivalAirport(decodeResult, data[1]);
|
|
2607
2697
|
} else {
|
|
2608
|
-
decodeResult
|
|
2698
|
+
ResultFormatter.unknown(decodeResult, data.join(","), "AF/");
|
|
2609
2699
|
}
|
|
2610
2700
|
}
|
|
2611
2701
|
function processTimeOfDeparture(decodeResult, data) {
|
|
@@ -2625,7 +2715,7 @@ function processTimeOfDeparture(decodeResult, data) {
|
|
|
2625
2715
|
value: `${data[1].substring(0, 2)}:${data[1].substring(2)}`
|
|
2626
2716
|
});
|
|
2627
2717
|
} else {
|
|
2628
|
-
decodeResult
|
|
2718
|
+
ResultFormatter.unknown(decodeResult, data.join(","), "/TD");
|
|
2629
2719
|
}
|
|
2630
2720
|
}
|
|
2631
2721
|
function processIdentification(decodeResult, data) {
|
|
@@ -2641,7 +2731,7 @@ function processDT(decodeResult, data) {
|
|
|
2641
2731
|
if (!decodeResult.raw.arrival_icao) {
|
|
2642
2732
|
ResultFormatter.arrivalAirport(decodeResult, data[0]);
|
|
2643
2733
|
} else if (decodeResult.raw.arrival_icao != data[0]) {
|
|
2644
|
-
decodeResult
|
|
2734
|
+
ResultFormatter.unknownArr(decodeResult, data);
|
|
2645
2735
|
}
|
|
2646
2736
|
if (data.length > 1) {
|
|
2647
2737
|
ResultFormatter.arrivalRunway(decodeResult, data[1]);
|
|
@@ -2656,7 +2746,7 @@ function processDT(decodeResult, data) {
|
|
|
2656
2746
|
ResultFormatter.remainingFuel(decodeResult, Number(data[4]));
|
|
2657
2747
|
}
|
|
2658
2748
|
if (data.length > 5) {
|
|
2659
|
-
decodeResult
|
|
2749
|
+
ResultFormatter.unknownArr(decodeResult, data);
|
|
2660
2750
|
}
|
|
2661
2751
|
}
|
|
2662
2752
|
function processLR(decodeResult, data) {
|
|
@@ -2681,9 +2771,9 @@ function parseMessageType(decodeResult, messageType) {
|
|
|
2681
2771
|
return processMessageType(decodeResult, type);
|
|
2682
2772
|
} else if (parts.length == 2) {
|
|
2683
2773
|
if (parts[0].length > 0) {
|
|
2684
|
-
decodeResult
|
|
2774
|
+
ResultFormatter.unknown(decodeResult, parts[0].substring(0, 3));
|
|
2685
2775
|
decodeResult.raw.flight_number = parts[0].substring(3);
|
|
2686
|
-
decodeResult
|
|
2776
|
+
ResultFormatter.unknown(decodeResult, parts[1].length == 5 ? parts[1].substring(0, 2) : parts[1].substring(0, 3), "#");
|
|
2687
2777
|
}
|
|
2688
2778
|
const type = parts[1].length == 5 ? parts[1].substring(2, 5) : parts[1].substring(3, 6);
|
|
2689
2779
|
if (parts[1].substring(3, 6) === "POS" && parts[1].length > 6) {
|
|
@@ -2691,7 +2781,7 @@ function parseMessageType(decodeResult, messageType) {
|
|
|
2691
2781
|
}
|
|
2692
2782
|
processMessageType(decodeResult, type);
|
|
2693
2783
|
} else {
|
|
2694
|
-
decodeResult
|
|
2784
|
+
ResultFormatter.unknown(decodeResult, messageType);
|
|
2695
2785
|
}
|
|
2696
2786
|
}
|
|
2697
2787
|
function processMessageType(decodeResult, type) {
|
|
@@ -2805,16 +2895,205 @@ var Label_H1 = class extends DecoderPlugin {
|
|
|
2805
2895
|
let decodeResult = this.defaultResult();
|
|
2806
2896
|
decodeResult.decoder.name = this.name;
|
|
2807
2897
|
decodeResult.message = message;
|
|
2808
|
-
decodeResult.remaining.text = "";
|
|
2809
2898
|
const msg = message.text.replace(/\n|\r/g, "");
|
|
2810
2899
|
const decoded = H1Helper.decodeH1Message(decodeResult, msg);
|
|
2811
2900
|
decodeResult.decoded = decoded;
|
|
2812
|
-
decodeResult.decoder.decodeLevel = decodeResult.remaining.text
|
|
2901
|
+
decodeResult.decoder.decodeLevel = !decodeResult.remaining.text ? "full" : "partial";
|
|
2813
2902
|
if (decodeResult.formatted.items.length === 0) {
|
|
2814
2903
|
if (options.debug) {
|
|
2815
2904
|
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
2816
2905
|
}
|
|
2817
|
-
decodeResult
|
|
2906
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
2907
|
+
decodeResult.decoded = false;
|
|
2908
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2909
|
+
}
|
|
2910
|
+
return decodeResult;
|
|
2911
|
+
}
|
|
2912
|
+
};
|
|
2913
|
+
|
|
2914
|
+
// lib/plugins/Label_H1_FLR.ts
|
|
2915
|
+
var Label_H1_FLR = class extends DecoderPlugin {
|
|
2916
|
+
name = "label-h1-flr";
|
|
2917
|
+
qualifiers() {
|
|
2918
|
+
return {
|
|
2919
|
+
labels: ["H1"],
|
|
2920
|
+
preambles: ["FLR", "#CFBFLR"]
|
|
2921
|
+
};
|
|
2922
|
+
}
|
|
2923
|
+
decode(message, options = {}) {
|
|
2924
|
+
let decodeResult = this.defaultResult();
|
|
2925
|
+
decodeResult.decoder.name = this.name;
|
|
2926
|
+
decodeResult.formatted.description = "Fault Log Report";
|
|
2927
|
+
decodeResult.message = message;
|
|
2928
|
+
const parts = message.text.split("/FR");
|
|
2929
|
+
if (parts.length > 1) {
|
|
2930
|
+
const fields = parts[0].split("/");
|
|
2931
|
+
for (let i = 1; i < fields.length; i++) {
|
|
2932
|
+
const field = fields[i];
|
|
2933
|
+
ResultFormatter.unknown(decodeResult, field, "/");
|
|
2934
|
+
}
|
|
2935
|
+
const data = parts[1].substring(0, 20);
|
|
2936
|
+
const msg = parts[1].substring(20);
|
|
2937
|
+
const datetime = data.substring(0, 12);
|
|
2938
|
+
const date = datetime.substring(4, 6) + datetime.substring(2, 4) + datetime.substring(0, 2);
|
|
2939
|
+
ResultFormatter.unknown(decodeResult, data.substring(12), "/");
|
|
2940
|
+
decodeResult.raw.message_timestamp = DateTimeUtils.convertDateTimeToEpoch(datetime.substring(6), date);
|
|
2941
|
+
decodeResult.raw.fault_message = msg;
|
|
2942
|
+
decodeResult.formatted.items.push({
|
|
2943
|
+
type: "fault",
|
|
2944
|
+
code: "FR",
|
|
2945
|
+
label: "Fault Report",
|
|
2946
|
+
value: decodeResult.raw.fault_message
|
|
2947
|
+
});
|
|
2948
|
+
decodeResult.decoded = true;
|
|
2949
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
2950
|
+
} else {
|
|
2951
|
+
if (options.debug) {
|
|
2952
|
+
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
2953
|
+
}
|
|
2954
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
2955
|
+
decodeResult.decoded = false;
|
|
2956
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
2957
|
+
}
|
|
2958
|
+
return decodeResult;
|
|
2959
|
+
}
|
|
2960
|
+
};
|
|
2961
|
+
|
|
2962
|
+
// lib/plugins/Label_H1_OHMA.ts
|
|
2963
|
+
import * as zlib from "minizlib";
|
|
2964
|
+
var Label_H1_OHMA = class extends DecoderPlugin {
|
|
2965
|
+
name = "label-h1-ohma";
|
|
2966
|
+
qualifiers() {
|
|
2967
|
+
return {
|
|
2968
|
+
labels: ["H1"],
|
|
2969
|
+
preambles: ["OHMA", "/RTNBOCR.OHMA", "#T1B/RTNBOCR.OHMA"]
|
|
2970
|
+
};
|
|
2971
|
+
}
|
|
2972
|
+
decode(message, options = {}) {
|
|
2973
|
+
let decodeResult = this.defaultResult();
|
|
2974
|
+
decodeResult.decoder.name = this.name;
|
|
2975
|
+
decodeResult.formatted.description = "OHMA Message";
|
|
2976
|
+
decodeResult.message = message;
|
|
2977
|
+
const data = message.text.split("OHMA")[1];
|
|
2978
|
+
try {
|
|
2979
|
+
const compressedBuffer = Buffer.from(data, "base64");
|
|
2980
|
+
const decompress = new zlib.Inflate({ windowBits: 15 });
|
|
2981
|
+
decompress.write(compressedBuffer);
|
|
2982
|
+
decompress.flush(zlib.constants.Z_SYNC_FLUSH);
|
|
2983
|
+
const result = decompress.read();
|
|
2984
|
+
const jsonText = result.toString();
|
|
2985
|
+
let formattedMsg;
|
|
2986
|
+
let jsonMessage;
|
|
2987
|
+
try {
|
|
2988
|
+
jsonMessage = JSON.parse(jsonText).message;
|
|
2989
|
+
} catch {
|
|
2990
|
+
jsonMessage = jsonText;
|
|
2991
|
+
}
|
|
2992
|
+
try {
|
|
2993
|
+
const ohmaMsg = JSON.parse(jsonMessage);
|
|
2994
|
+
formattedMsg = JSON.stringify(ohmaMsg, null, 2);
|
|
2995
|
+
} catch {
|
|
2996
|
+
formattedMsg = jsonMessage;
|
|
2997
|
+
}
|
|
2998
|
+
decodeResult.decoded = true;
|
|
2999
|
+
decodeResult.decoder.decodeLevel = "full";
|
|
3000
|
+
decodeResult.raw.ohma = jsonText;
|
|
3001
|
+
decodeResult.formatted.items.push({
|
|
3002
|
+
type: "ohma",
|
|
3003
|
+
code: "OHMA",
|
|
3004
|
+
label: "OHMA Downlink",
|
|
3005
|
+
value: formattedMsg
|
|
3006
|
+
});
|
|
3007
|
+
} catch (e) {
|
|
3008
|
+
if (options.debug) {
|
|
3009
|
+
console.log(`Decoder: Unknown H1 OHMA message: ${message.text}`, e);
|
|
3010
|
+
}
|
|
3011
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
3012
|
+
decodeResult.decoded = false;
|
|
3013
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
3014
|
+
}
|
|
3015
|
+
return decodeResult;
|
|
3016
|
+
}
|
|
3017
|
+
};
|
|
3018
|
+
|
|
3019
|
+
// lib/plugins/Label_H1_StarPOS.ts
|
|
3020
|
+
var Label_H1_StarPOS = class extends DecoderPlugin {
|
|
3021
|
+
name = "label-h1-star-pos";
|
|
3022
|
+
qualifiers() {
|
|
3023
|
+
return {
|
|
3024
|
+
labels: ["H1"],
|
|
3025
|
+
preambles: ["*POS"]
|
|
3026
|
+
};
|
|
3027
|
+
}
|
|
3028
|
+
decode(message, options = {}) {
|
|
3029
|
+
let decodeResult = this.defaultResult();
|
|
3030
|
+
decodeResult.decoder.name = this.name;
|
|
3031
|
+
decodeResult.formatted.description = "Position Report";
|
|
3032
|
+
decodeResult.message = message;
|
|
3033
|
+
const msg = message.text;
|
|
3034
|
+
if (msg.length !== 43 || !msg.startsWith("*POS")) {
|
|
3035
|
+
if (options.debug) {
|
|
3036
|
+
console.log(`Decoder: Unknown H1 message: ${msg}`);
|
|
3037
|
+
}
|
|
3038
|
+
ResultFormatter.unknown(decodeResult, msg);
|
|
3039
|
+
decodeResult.decoded = false;
|
|
3040
|
+
decodeResult.decoder.decodeLevel = "none";
|
|
3041
|
+
return decodeResult;
|
|
3042
|
+
}
|
|
3043
|
+
decodeResult.raw.month = Number(msg.substring(4, 6));
|
|
3044
|
+
decodeResult.raw.day_of_month = Number(msg.substring(6, 8));
|
|
3045
|
+
ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(msg.substring(8, 12) + "00"));
|
|
3046
|
+
ResultFormatter.position(decodeResult, {
|
|
3047
|
+
// Deg Min, no sec
|
|
3048
|
+
latitude: CoordinateUtils.getDirection(msg.substring(12, 13)) * (Number(msg.substring(13, 15)) + Number(msg.substring(15, 17)) / 60),
|
|
3049
|
+
longitude: CoordinateUtils.getDirection(msg.substring(17, 18)) * (Number(msg.substring(18, 21)) + Number(msg.substring(21, 23)) / 60)
|
|
3050
|
+
});
|
|
3051
|
+
ResultFormatter.altitude(decodeResult, Number(msg.substring(23, 28)));
|
|
3052
|
+
ResultFormatter.unknown(decodeResult, msg.substring(28));
|
|
3053
|
+
decodeResult.decoded = true;
|
|
3054
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
3055
|
+
return decodeResult;
|
|
3056
|
+
}
|
|
3057
|
+
};
|
|
3058
|
+
|
|
3059
|
+
// lib/plugins/Label_H1_WRN.ts
|
|
3060
|
+
var Label_H1_WRN = class extends DecoderPlugin {
|
|
3061
|
+
name = "label-h1-wrn";
|
|
3062
|
+
qualifiers() {
|
|
3063
|
+
return {
|
|
3064
|
+
labels: ["H1"],
|
|
3065
|
+
preambles: ["WRN", "#CFBWRN"]
|
|
3066
|
+
};
|
|
3067
|
+
}
|
|
3068
|
+
decode(message, options = {}) {
|
|
3069
|
+
let decodeResult = this.defaultResult();
|
|
3070
|
+
decodeResult.decoder.name = this.name;
|
|
3071
|
+
decodeResult.formatted.description = "Warning Message";
|
|
3072
|
+
decodeResult.message = message;
|
|
3073
|
+
const parts = message.text.split("/WN");
|
|
3074
|
+
if (parts.length > 1) {
|
|
3075
|
+
const fields = parts[0].split("/");
|
|
3076
|
+
ResultFormatter.unknownArr(decodeResult, fields.slice(1), "/");
|
|
3077
|
+
const data = parts[1].substring(0, 20);
|
|
3078
|
+
const msg = parts[1].substring(20);
|
|
3079
|
+
const datetime = data.substring(0, 12);
|
|
3080
|
+
const date = datetime.substring(4, 6) + datetime.substring(2, 4) + datetime.substring(0, 2);
|
|
3081
|
+
ResultFormatter.unknown(decodeResult, data.substring(12), "/");
|
|
3082
|
+
decodeResult.raw.message_timestamp = DateTimeUtils.convertDateTimeToEpoch(datetime.substring(6), date);
|
|
3083
|
+
decodeResult.raw.warning_message = msg;
|
|
3084
|
+
decodeResult.formatted.items.push({
|
|
3085
|
+
type: "warning",
|
|
3086
|
+
code: "WRN",
|
|
3087
|
+
label: "Warning Message",
|
|
3088
|
+
value: decodeResult.raw.warning_message
|
|
3089
|
+
});
|
|
3090
|
+
decodeResult.decoded = true;
|
|
3091
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
3092
|
+
} else {
|
|
3093
|
+
if (options.debug) {
|
|
3094
|
+
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
3095
|
+
}
|
|
3096
|
+
ResultFormatter.unknown(decodeResult, message.text);
|
|
2818
3097
|
decodeResult.decoded = false;
|
|
2819
3098
|
decodeResult.decoder.decodeLevel = "none";
|
|
2820
3099
|
}
|
|
@@ -2845,25 +3124,18 @@ var Label_HX = class extends DecoderPlugin {
|
|
|
2845
3124
|
let londir = parts[4].substring(0, 1);
|
|
2846
3125
|
let londeg = Number(parts[4].substring(1, 4));
|
|
2847
3126
|
let lonmin = Number(parts[4].substring(4, 8));
|
|
2848
|
-
|
|
3127
|
+
let pos = {
|
|
2849
3128
|
latitude: (latdeg + latmin / 60) * (latdir === "N" ? 1 : -1),
|
|
2850
3129
|
longitude: (londeg + lonmin / 60) * (londir === "E" ? 1 : -1)
|
|
2851
3130
|
};
|
|
2852
|
-
decodeResult
|
|
3131
|
+
ResultFormatter.unknownArr(decodeResult, parts.slice(5), " ");
|
|
3132
|
+
ResultFormatter.position(decodeResult, pos);
|
|
2853
3133
|
} else if (parts[2] === "43") {
|
|
2854
3134
|
ResultFormatter.departureAirport(decodeResult, parts[3]);
|
|
2855
|
-
decodeResult
|
|
3135
|
+
ResultFormatter.unknownArr(decodeResult, parts.slice(4), " ");
|
|
2856
3136
|
} else {
|
|
2857
3137
|
decodeResult.decoded = false;
|
|
2858
3138
|
}
|
|
2859
|
-
if (decodeResult.raw.position) {
|
|
2860
|
-
decodeResult.formatted.items.push({
|
|
2861
|
-
type: "aircraft_position",
|
|
2862
|
-
code: "POS",
|
|
2863
|
-
label: "Aircraft Position",
|
|
2864
|
-
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
2865
|
-
});
|
|
2866
|
-
}
|
|
2867
3139
|
if (decodeResult.decoded) {
|
|
2868
3140
|
if (!decodeResult.remaining.text)
|
|
2869
3141
|
decodeResult.decoder.decodeLevel = "full";
|
|
@@ -2893,7 +3165,7 @@ var Label_SQ = class extends DecoderPlugin {
|
|
|
2893
3165
|
if (decodeResult.raw.version === "2") {
|
|
2894
3166
|
const regex = /0(\d)X(?<org>\w)(?<iata>\w\w\w)(?<icao>\w\w\w\w)(?<station>\d)(?<lat>\d+)(?<latd>[NS])(?<lng>\d+)(?<lngd>[EW])V(?<vfreq>\d+)\/.*/;
|
|
2895
3167
|
const result = message.text.match(regex);
|
|
2896
|
-
if (result && result.length >= 8) {
|
|
3168
|
+
if (result?.groups && result.length >= 8) {
|
|
2897
3169
|
decodeResult.raw.groundStation = {
|
|
2898
3170
|
number: result.groups.station,
|
|
2899
3171
|
iataCode: result.groups.iata,
|
|
@@ -2903,7 +3175,7 @@ var Label_SQ = class extends DecoderPlugin {
|
|
|
2903
3175
|
longitude: Number(result.groups.lng) / 100 * (result.groups.lngd === "W" ? -1 : 1)
|
|
2904
3176
|
}
|
|
2905
3177
|
};
|
|
2906
|
-
decodeResult.raw.vdlFrequency = result.groups.vfreq / 1e3;
|
|
3178
|
+
decodeResult.raw.vdlFrequency = Number(result.groups.vfreq) / 1e3;
|
|
2907
3179
|
}
|
|
2908
3180
|
}
|
|
2909
3181
|
decodeResult.formatted.description = "Ground Station Squitter";
|
|
@@ -2994,31 +3266,11 @@ var Label_QR = class extends DecoderPlugin {
|
|
|
2994
3266
|
decode(message, options = {}) {
|
|
2995
3267
|
const decodeResult = this.defaultResult();
|
|
2996
3268
|
decodeResult.decoder.name = this.name;
|
|
2997
|
-
decodeResult.raw.origin = message.text.substring(0, 4);
|
|
2998
|
-
decodeResult.raw.destination = message.text.substring(4, 8);
|
|
2999
|
-
decodeResult.raw.wheels_on = message.text.substring(8, 12);
|
|
3000
|
-
decodeResult.remaining.text = message.text.substring(12);
|
|
3001
3269
|
decodeResult.formatted.description = "ON Report";
|
|
3002
|
-
decodeResult.
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
label: "Origin",
|
|
3007
|
-
value: decodeResult.raw.origin
|
|
3008
|
-
},
|
|
3009
|
-
{
|
|
3010
|
-
type: "destination",
|
|
3011
|
-
code: "DST",
|
|
3012
|
-
label: "Destination",
|
|
3013
|
-
value: decodeResult.raw.destination
|
|
3014
|
-
},
|
|
3015
|
-
{
|
|
3016
|
-
type: "wheels_on",
|
|
3017
|
-
code: "WON",
|
|
3018
|
-
label: "Wheels ON",
|
|
3019
|
-
value: decodeResult.raw.wheels_on
|
|
3020
|
-
}
|
|
3021
|
-
];
|
|
3270
|
+
ResultFormatter.departureAirport(decodeResult, message.text.substring(0, 4));
|
|
3271
|
+
ResultFormatter.arrivalAirport(decodeResult, message.text.substring(4, 8));
|
|
3272
|
+
ResultFormatter.on(decodeResult, DateTimeUtils.convertHHMMSSToTod(message.text.substring(8, 12) + "00"));
|
|
3273
|
+
ResultFormatter.unknown(decodeResult, message.text.substring(12));
|
|
3022
3274
|
decodeResult.decoded = true;
|
|
3023
3275
|
if (!decodeResult.remaining.text)
|
|
3024
3276
|
decodeResult.decoder.decodeLevel = "full";
|
|
@@ -3039,31 +3291,11 @@ var Label_QP = class extends DecoderPlugin {
|
|
|
3039
3291
|
decode(message, options = {}) {
|
|
3040
3292
|
const decodeResult = this.defaultResult();
|
|
3041
3293
|
decodeResult.decoder.name = this.name;
|
|
3042
|
-
decodeResult.raw.origin = message.text.substring(0, 4);
|
|
3043
|
-
decodeResult.raw.destination = message.text.substring(4, 8);
|
|
3044
|
-
decodeResult.raw.gate_out = message.text.substring(8, 12);
|
|
3045
|
-
decodeResult.remaining.text = message.text.substring(12);
|
|
3046
3294
|
decodeResult.formatted.description = "OUT Report";
|
|
3047
|
-
decodeResult.
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
label: "Origin",
|
|
3052
|
-
value: decodeResult.raw.origin
|
|
3053
|
-
},
|
|
3054
|
-
{
|
|
3055
|
-
type: "destination",
|
|
3056
|
-
code: "DST",
|
|
3057
|
-
label: "Destination",
|
|
3058
|
-
value: decodeResult.raw.destination
|
|
3059
|
-
},
|
|
3060
|
-
{
|
|
3061
|
-
type: "gate_out",
|
|
3062
|
-
code: "GOUT",
|
|
3063
|
-
label: "Gate OUT",
|
|
3064
|
-
value: decodeResult.raw.gate_out
|
|
3065
|
-
}
|
|
3066
|
-
];
|
|
3295
|
+
ResultFormatter.departureAirport(decodeResult, message.text.substring(0, 4));
|
|
3296
|
+
ResultFormatter.arrivalAirport(decodeResult, message.text.substring(4, 8));
|
|
3297
|
+
ResultFormatter.out(decodeResult, DateTimeUtils.convertHHMMSSToTod(message.text.substring(8, 12) + "00"));
|
|
3298
|
+
ResultFormatter.unknown(decodeResult, message.text.substring(12));
|
|
3067
3299
|
decodeResult.decoded = true;
|
|
3068
3300
|
if (!decodeResult.remaining.text)
|
|
3069
3301
|
decodeResult.decoder.decodeLevel = "full";
|
|
@@ -3084,31 +3316,11 @@ var Label_QS = class extends DecoderPlugin {
|
|
|
3084
3316
|
decode(message, options = {}) {
|
|
3085
3317
|
const decodeResult = this.defaultResult();
|
|
3086
3318
|
decodeResult.decoder.name = this.name;
|
|
3087
|
-
decodeResult.raw.origin = message.text.substring(0, 4);
|
|
3088
|
-
decodeResult.raw.destination = message.text.substring(4, 8);
|
|
3089
|
-
decodeResult.raw.gate_in = message.text.substring(8, 12);
|
|
3090
|
-
decodeResult.remaining.text = message.text.substring(12);
|
|
3091
3319
|
decodeResult.formatted.description = "IN Report";
|
|
3092
|
-
decodeResult.
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
label: "Origin",
|
|
3097
|
-
value: decodeResult.raw.origin
|
|
3098
|
-
},
|
|
3099
|
-
{
|
|
3100
|
-
type: "destination",
|
|
3101
|
-
code: "DST",
|
|
3102
|
-
label: "Destination",
|
|
3103
|
-
value: decodeResult.raw.destination
|
|
3104
|
-
},
|
|
3105
|
-
{
|
|
3106
|
-
type: "gate_in",
|
|
3107
|
-
code: "GIN",
|
|
3108
|
-
label: "Gate IN",
|
|
3109
|
-
value: decodeResult.raw.gate_in
|
|
3110
|
-
}
|
|
3111
|
-
];
|
|
3320
|
+
ResultFormatter.departureAirport(decodeResult, message.text.substring(0, 4));
|
|
3321
|
+
ResultFormatter.arrivalAirport(decodeResult, message.text.substring(4, 8));
|
|
3322
|
+
ResultFormatter.in(decodeResult, DateTimeUtils.convertHHMMSSToTod(message.text.substring(8, 12) + "00"));
|
|
3323
|
+
ResultFormatter.unknown(decodeResult, message.text.substring(12));
|
|
3112
3324
|
decodeResult.decoded = true;
|
|
3113
3325
|
if (!decodeResult.remaining.text)
|
|
3114
3326
|
decodeResult.decoder.decodeLevel = "full";
|
|
@@ -3133,43 +3345,30 @@ var Label_QQ = class extends DecoderPlugin {
|
|
|
3133
3345
|
decodeResult.formatted.description = "OFF Report";
|
|
3134
3346
|
ResultFormatter.departureAirport(decodeResult, message.text.substring(0, 4));
|
|
3135
3347
|
ResultFormatter.arrivalAirport(decodeResult, message.text.substring(4, 8));
|
|
3136
|
-
decodeResult.raw.wheels_off = message.text.substring(8, 12);
|
|
3137
3348
|
if (message.text.substring(12, 19) === "\r\n001FE") {
|
|
3138
3349
|
decodeResult.raw.day_of_month = message.text.substring(19, 21);
|
|
3139
|
-
decodeResult.
|
|
3350
|
+
ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(message.text.substring(21, 27)));
|
|
3140
3351
|
let latdir = message.text.substring(27, 28);
|
|
3141
3352
|
let latdeg = Number(message.text.substring(28, 30));
|
|
3142
3353
|
let latmin = Number(message.text.substring(30, 34));
|
|
3143
3354
|
let londir = message.text.substring(34, 35);
|
|
3144
3355
|
let londeg = Number(message.text.substring(35, 38));
|
|
3145
3356
|
let lonmin = Number(message.text.substring(38, 42));
|
|
3146
|
-
|
|
3357
|
+
let pos = {
|
|
3147
3358
|
latitude: (latdeg + latmin / 60) * (latdir === "N" ? 1 : -1),
|
|
3148
3359
|
longitude: (londeg + lonmin / 60) * (londir === "E" ? 1 : -1)
|
|
3149
3360
|
};
|
|
3150
|
-
decodeResult
|
|
3361
|
+
ResultFormatter.unknown(decodeResult, message.text.substring(42, 45));
|
|
3362
|
+
ResultFormatter.position(decodeResult, pos);
|
|
3151
3363
|
if (decodeResult.remaining.text !== "---") {
|
|
3152
|
-
ResultFormatter.groundspeed(decodeResult, message.text.substring(45, 48));
|
|
3364
|
+
ResultFormatter.groundspeed(decodeResult, Number(message.text.substring(45, 48)));
|
|
3153
3365
|
} else {
|
|
3154
3366
|
ResultFormatter.unknown(decodeResult, message.text.substring(45, 48));
|
|
3155
3367
|
}
|
|
3156
3368
|
ResultFormatter.unknown(decodeResult, message.text.substring(48));
|
|
3157
3369
|
} else {
|
|
3158
|
-
decodeResult.
|
|
3159
|
-
|
|
3160
|
-
decodeResult.formatted.items.push({
|
|
3161
|
-
type: "wheels_off",
|
|
3162
|
-
code: "WOFF",
|
|
3163
|
-
label: "Wheels OFF",
|
|
3164
|
-
value: decodeResult.raw.wheels_off
|
|
3165
|
-
});
|
|
3166
|
-
if (decodeResult.raw.position) {
|
|
3167
|
-
decodeResult.formatted.items.push({
|
|
3168
|
-
type: "aircraft_position",
|
|
3169
|
-
code: "POS",
|
|
3170
|
-
label: "Aircraft Position",
|
|
3171
|
-
value: CoordinateUtils.coordinateString(decodeResult.raw.position)
|
|
3172
|
-
});
|
|
3370
|
+
ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(message.text.substring(8, 12) + "00"));
|
|
3371
|
+
ResultFormatter.unknown(decodeResult, message.text.substring(12));
|
|
3173
3372
|
}
|
|
3174
3373
|
decodeResult.decoded = true;
|
|
3175
3374
|
if (!decodeResult.remaining.text)
|
|
@@ -4001,8 +4200,14 @@ var MessageDecoder = class {
|
|
|
4001
4200
|
this.registerPlugin(new Label_15(this));
|
|
4002
4201
|
this.registerPlugin(new Label_15_FST(this));
|
|
4003
4202
|
this.registerPlugin(new Label_16_N_Space(this));
|
|
4203
|
+
this.registerPlugin(new Label_1L_3Line(this));
|
|
4204
|
+
this.registerPlugin(new Label_1L_070(this));
|
|
4205
|
+
this.registerPlugin(new Label_1L_660(this));
|
|
4206
|
+
this.registerPlugin(new Label_1L_Slash(this));
|
|
4004
4207
|
this.registerPlugin(new Label_20_POS(this));
|
|
4005
4208
|
this.registerPlugin(new Label_21_POS(this));
|
|
4209
|
+
this.registerPlugin(new Label_22_OFF(this));
|
|
4210
|
+
this.registerPlugin(new Label_22_POS(this));
|
|
4006
4211
|
this.registerPlugin(new Label_24_Slash(this));
|
|
4007
4212
|
this.registerPlugin(new Label_30_Slash_EA(this));
|
|
4008
4213
|
this.registerPlugin(new Label_44_ETA(this));
|
|
@@ -4021,6 +4226,7 @@ var MessageDecoder = class {
|
|
|
4021
4226
|
this.registerPlugin(new Label_H1_OHMA(this));
|
|
4022
4227
|
this.registerPlugin(new Label_H1_WRN(this));
|
|
4023
4228
|
this.registerPlugin(new Label_H1(this));
|
|
4229
|
+
this.registerPlugin(new Label_H1_StarPOS(this));
|
|
4024
4230
|
this.registerPlugin(new Label_HX(this));
|
|
4025
4231
|
this.registerPlugin(new Label_80(this));
|
|
4026
4232
|
this.registerPlugin(new Label_83(this));
|