@airframes/acars-decoder 1.8.13 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -85,56 +85,6 @@ var IcaoDecoder = class _IcaoDecoder {
85
85
  }
86
86
  };
87
87
 
88
- // lib/DecoderPlugin.ts
89
- var DecoderPlugin = class {
90
- decoder;
91
- name = "unknown";
92
- defaultResult() {
93
- return {
94
- decoded: false,
95
- decoder: {
96
- name: "unknown",
97
- type: "pattern-match",
98
- decodeLevel: "none"
99
- },
100
- formatted: {
101
- description: "Unknown",
102
- items: []
103
- },
104
- raw: {},
105
- remaining: {}
106
- };
107
- }
108
- options;
109
- constructor(decoder, options = {}) {
110
- this.decoder = decoder;
111
- this.options = options;
112
- }
113
- id() {
114
- console.log(
115
- "DecoderPlugin subclass has not overriden id() to provide a unique ID for this plugin!"
116
- );
117
- return "abstract_decoder_plugin";
118
- }
119
- meetsStateRequirements() {
120
- return true;
121
- }
122
- // onRegister(store: Store<any>) {
123
- // this.store = store;
124
- // }
125
- qualifiers() {
126
- const labels = [];
127
- return {
128
- labels
129
- };
130
- }
131
- decode(message) {
132
- const decodeResult = this.defaultResult();
133
- decodeResult.remaining.text = message.text;
134
- return decodeResult;
135
- }
136
- };
137
-
138
88
  // lib/utils/coordinate_utils.ts
139
89
  var CoordinateUtils = class _CoordinateUtils {
140
90
  /**
@@ -144,11 +94,11 @@ var CoordinateUtils = class _CoordinateUtils {
144
94
  * @returns An object with latitude and longitude properties
145
95
  */
146
96
  static decodeStringCoordinates(stringCoords) {
147
- const firstChar = stringCoords.substring(0, 1);
148
- let middleChar = stringCoords.substring(6, 7);
97
+ const firstChar = stringCoords.charAt(0);
98
+ let middleChar = stringCoords.charAt(6);
149
99
  let longitudeChars = stringCoords.substring(7, 13);
150
- if (middleChar == " ") {
151
- middleChar = stringCoords.substring(7, 8);
100
+ if (middleChar === " ") {
101
+ middleChar = stringCoords.charAt(7);
152
102
  longitudeChars = stringCoords.substring(8, 14);
153
103
  }
154
104
  if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
@@ -166,24 +116,26 @@ var CoordinateUtils = class _CoordinateUtils {
166
116
  * @returns An object with latitude and longitude properties
167
117
  */
168
118
  static decodeStringCoordinatesDecimalMinutes(stringCoords) {
169
- const firstChar = stringCoords.substring(0, 1);
170
- let middleChar = stringCoords.substring(6, 7);
119
+ const firstChar = stringCoords.charAt(0);
120
+ let middleChar = stringCoords.charAt(6);
171
121
  let longitudeChars = stringCoords.substring(7, 13);
172
- if (middleChar == " ") {
173
- middleChar = stringCoords.substring(7, 8);
122
+ if (middleChar === " ") {
123
+ middleChar = stringCoords.charAt(7);
174
124
  longitudeChars = stringCoords.substring(8, 14);
175
125
  }
176
- const latDeg = Math.trunc(Number(stringCoords.substring(1, 6)) / 1e3);
177
- const latMin = Number(stringCoords.substring(1, 6)) % 1e3 / 10;
178
- const lonDeg = Math.trunc(Number(longitudeChars) / 1e3);
179
- const lonMin = Number(longitudeChars) % 1e3 / 10;
180
- if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
181
- return {
182
- latitude: (latDeg + latMin / 60) * _CoordinateUtils.getDirection(firstChar),
183
- longitude: (lonDeg + lonMin / 60) * _CoordinateUtils.getDirection(middleChar)
184
- };
126
+ if (firstChar !== "N" && firstChar !== "S" || middleChar !== "W" && middleChar !== "E") {
127
+ return void 0;
185
128
  }
186
- return void 0;
129
+ const latRaw = Number(stringCoords.substring(1, 6));
130
+ const lonRaw = Number(longitudeChars);
131
+ const latDeg = Math.trunc(latRaw / 1e3);
132
+ const latMin = latRaw % 1e3 / 10;
133
+ const lonDeg = Math.trunc(lonRaw / 1e3);
134
+ const lonMin = lonRaw % 1e3 / 10;
135
+ return {
136
+ latitude: (latDeg + latMin / 60) * _CoordinateUtils.getDirection(firstChar),
137
+ longitude: (lonDeg + lonMin / 60) * _CoordinateUtils.getDirection(middleChar)
138
+ };
187
139
  }
188
140
  static coordinateString(coords) {
189
141
  const latDir = coords.latitude > 0 ? "N" : "S";
@@ -214,25 +166,13 @@ var DateTimeUtils = class {
214
166
  // Expects a six digit date string and a four digit UTC time string
215
167
  // (DDMMYY) (HHMM)
216
168
  static UTCDateTimeToString(dateString, timeString) {
217
- let utcDate = /* @__PURE__ */ new Date();
218
- utcDate.setUTCDate(+dateString.substr(0, 2));
219
- utcDate.setUTCMonth(+dateString.substr(2, 2));
220
- if (dateString.length === 6) {
221
- utcDate.setUTCFullYear(2e3 + +dateString.substr(4, 2));
222
- }
223
- if (timeString.length === 6) {
224
- utcDate.setUTCHours(
225
- +timeString.substr(0, 2),
226
- +timeString.substr(2, 2),
227
- +timeString.substr(4, 2)
228
- );
229
- } else {
230
- utcDate.setUTCHours(
231
- +timeString.substr(0, 2),
232
- +timeString.substr(2, 2),
233
- 0
234
- );
235
- }
169
+ const day = +dateString.substr(0, 2);
170
+ const month = +dateString.substr(2, 2) - 1;
171
+ const year = dateString.length === 6 ? 2e3 + +dateString.substr(4, 2) : (/* @__PURE__ */ new Date()).getUTCFullYear();
172
+ const hours = +timeString.substr(0, 2);
173
+ const minutes = +timeString.substr(2, 2);
174
+ const seconds = timeString.length === 6 ? +timeString.substr(4, 2) : 0;
175
+ const utcDate = new Date(Date.UTC(year, month, day, hours, minutes, seconds));
236
176
  return utcDate.toUTCString();
237
177
  }
238
178
  /**
@@ -577,7 +517,7 @@ var ResultFormatter = class {
577
517
  decodeResult.raw.fuel_remaining = value;
578
518
  decodeResult.formatted.items.push({
579
519
  type: "fuel_remaining",
580
- code: " FUEL_REM",
520
+ code: "FUEL_REM",
581
521
  label: "Fuel Remaining",
582
522
  value: decodeResult.raw.fuel_remaining.toString()
583
523
  });
@@ -971,7 +911,7 @@ var ResultFormatter = class {
971
911
  type: "sequence",
972
912
  code: "SEQ",
973
913
  label: "Sequence Number",
974
- value: decodeResult.raw.sequence_number
914
+ value: decodeResult.raw.sequence_number.toString()
975
915
  });
976
916
  }
977
917
  static sequenceResponse(decodeResult, value) {
@@ -980,7 +920,7 @@ var ResultFormatter = class {
980
920
  type: "sequence",
981
921
  code: "SEQ_RESP",
982
922
  label: "Sequence Response",
983
- value: decodeResult.raw.sequence_response
923
+ value: decodeResult.raw.sequence_response.toString()
984
924
  });
985
925
  }
986
926
  static unknown(decodeResult, value, sep = ",") {
@@ -992,7 +932,101 @@ var ResultFormatter = class {
992
932
  }
993
933
  };
994
934
 
935
+ // lib/DecoderPlugin.ts
936
+ var DecoderPlugin = class {
937
+ decoder;
938
+ name = "unknown";
939
+ defaultResult() {
940
+ return {
941
+ decoded: false,
942
+ decoder: {
943
+ name: "unknown",
944
+ type: "pattern-match",
945
+ decodeLevel: "none"
946
+ },
947
+ formatted: {
948
+ description: "Unknown",
949
+ items: []
950
+ },
951
+ raw: {},
952
+ remaining: {}
953
+ };
954
+ }
955
+ /**
956
+ * Creates a DecodeResult pre-populated with the plugin name, description, and message.
957
+ * Replaces the common boilerplate at the start of every decode() method.
958
+ */
959
+ initResult(message, description) {
960
+ const result = this.defaultResult();
961
+ result.decoder.name = this.name;
962
+ result.formatted.description = description;
963
+ result.message = message;
964
+ return result;
965
+ }
966
+ /**
967
+ * Sets the decoded flag and decodeLevel on a result.
968
+ * If decoded is true and no explicit level is given, infers 'full' or 'partial'
969
+ * based on whether remaining.text is set.
970
+ */
971
+ setDecodeLevel(result, decoded, level) {
972
+ result.decoded = decoded;
973
+ if (decoded) {
974
+ result.decoder.decodeLevel = level ?? (result.remaining.text ? "partial" : "full");
975
+ } else {
976
+ result.decoder.decodeLevel = "none";
977
+ }
978
+ }
979
+ /**
980
+ * Logs a debug message prefixed with the plugin name, only if options.debug is true.
981
+ */
982
+ debug(options, ...args) {
983
+ if (options.debug) {
984
+ console.log(`[${this.name}]`, ...args);
985
+ }
986
+ }
987
+ /**
988
+ * Marks a result as a failed decode with 'none' level, sets the remaining text
989
+ * as unknown, and logs a debug message. Returns the result for convenient early return.
990
+ */
991
+ failUnknown(result, text, options = {}) {
992
+ this.debug(options, `Unknown message: ${text}`);
993
+ ResultFormatter.unknown(result, text);
994
+ result.decoded = false;
995
+ result.decoder.decodeLevel = "none";
996
+ return result;
997
+ }
998
+ options;
999
+ constructor(decoder, options = {}) {
1000
+ this.decoder = decoder;
1001
+ this.options = options;
1002
+ }
1003
+ id() {
1004
+ console.log(
1005
+ "DecoderPlugin subclass has not overriden id() to provide a unique ID for this plugin!"
1006
+ );
1007
+ return "abstract_decoder_plugin";
1008
+ }
1009
+ meetsStateRequirements() {
1010
+ return true;
1011
+ }
1012
+ // onRegister(store: Store<any>) {
1013
+ // this.store = store;
1014
+ // }
1015
+ qualifiers() {
1016
+ const labels = [];
1017
+ return {
1018
+ labels
1019
+ };
1020
+ }
1021
+ decode(message, options = {}) {
1022
+ const decodeResult = this.defaultResult();
1023
+ decodeResult.remaining.text = message.text;
1024
+ return decodeResult;
1025
+ }
1026
+ };
1027
+
995
1028
  // lib/plugins/CBand.ts
1029
+ var CBAND_HEADER = /^(?<msgno>[A-Z]\d{2}[A-Z])(?<airline>[A-Z0-9]{2})(?<number>[0-9]{4})/;
996
1030
  var CBand = class extends DecoderPlugin {
997
1031
  name = "c-band";
998
1032
  qualifiers() {
@@ -1001,35 +1035,43 @@ var CBand = class extends DecoderPlugin {
1001
1035
  };
1002
1036
  }
1003
1037
  decode(message, options = {}) {
1004
- let decodeResult = this.defaultResult();
1038
+ const text = message.text;
1039
+ if (text.length < 10) {
1040
+ const result = this.defaultResult();
1041
+ result.decoder.name = this.name;
1042
+ result.message = message;
1043
+ return result;
1044
+ }
1045
+ const cband = CBAND_HEADER.exec(text);
1046
+ if (!cband?.groups) {
1047
+ const result = this.defaultResult();
1048
+ result.decoder.name = this.name;
1049
+ result.message = message;
1050
+ return result;
1051
+ }
1052
+ const decoded = this.decoder.decode(
1053
+ {
1054
+ label: message.label,
1055
+ sublabel: message.sublabel,
1056
+ text: text.substring(10)
1057
+ },
1058
+ options
1059
+ );
1060
+ const decodeResult = this.defaultResult();
1005
1061
  decodeResult.decoder.name = this.name;
1006
1062
  decodeResult.message = message;
1007
- let cband = message.text.match(
1008
- /^(?<msgno>[A-Z]\d{2}[A-Z])(?<airline>[A-Z0-9]{2})(?<number>[0-9]{4})/
1009
- );
1010
- if (cband?.groups) {
1011
- const messageText = message.text.substring(10);
1012
- const decoded = this.decoder.decode(
1013
- {
1014
- label: message.label,
1015
- sublabel: message.sublabel,
1016
- text: messageText
1017
- },
1018
- options
1063
+ if (decoded.decoded) {
1064
+ ResultFormatter.flightNumber(
1065
+ decodeResult,
1066
+ cband.groups.airline + Number(cband.groups.number)
1019
1067
  );
1020
- if (decoded.decoded) {
1021
- ResultFormatter.flightNumber(
1022
- decodeResult,
1023
- cband.groups.airline + Number(cband.groups.number)
1024
- );
1025
- decodeResult.decoded = true;
1026
- decodeResult.decoder.decodeLevel = decoded.decoder.decodeLevel;
1027
- decodeResult.decoder.name = this.name + "-" + decoded.decoder.name;
1028
- decodeResult.raw = { ...decodeResult.raw, ...decoded.raw };
1029
- decodeResult.formatted.description = decoded.formatted.description;
1030
- decodeResult.formatted.items.push(...decoded.formatted.items);
1031
- decodeResult.remaining = decoded.remaining;
1032
- }
1068
+ decodeResult.decoded = true;
1069
+ decodeResult.decoder.decodeLevel = decoded.decoder.decodeLevel;
1070
+ decodeResult.decoder.name = this.name + "-" + decoded.decoder.name;
1071
+ decodeResult.raw = { ...decodeResult.raw, ...decoded.raw };
1072
+ decodeResult.formatted.description = decoded.formatted.description;
1073
+ decodeResult.formatted.items.push(...decoded.formatted.items);
1074
+ decodeResult.remaining = decoded.remaining;
1033
1075
  }
1034
1076
  return decodeResult;
1035
1077
  }
@@ -1114,7 +1156,9 @@ var FlightPlanUtils = class _FlightPlanUtils {
1114
1156
  label: "Route Status",
1115
1157
  value: "Route Planned"
1116
1158
  });
1117
- decodeResult.raw.route_status = header;
1159
+ if (header.length > 2) {
1160
+ addRoute(decodeResult, header.substring(2));
1161
+ }
1118
1162
  } else if (header.startsWith("RI")) {
1119
1163
  decodeResult.raw.route_status = "RI";
1120
1164
  decodeResult.formatted.items.push({
@@ -1212,6 +1256,11 @@ function addCompanyRoute(decodeResult, value) {
1212
1256
  }
1213
1257
 
1214
1258
  // lib/utils/arinc_702_helper.ts
1259
+ function asciiStringToBytes(data) {
1260
+ const bytes = new Uint8Array(data.length);
1261
+ for (let i = 0; i < data.length; i++) bytes[i] = data.charCodeAt(i) & 255;
1262
+ return bytes;
1263
+ }
1215
1264
  var Arinc702Helper = class _Arinc702Helper {
1216
1265
  /**
1217
1266
  * Decodes an ARINC 702 message
@@ -1730,7 +1779,7 @@ function processSummary(decodeResult, data) {
1730
1779
  }
1731
1780
  function crc16IbmSdlcRev(data) {
1732
1781
  let crc = 65535;
1733
- const bytes = Buffer.from(data, "ascii");
1782
+ const bytes = asciiStringToBytes(data);
1734
1783
  for (const byte of bytes) {
1735
1784
  crc ^= byte;
1736
1785
  for (let i = 0; i < 8; i++) {
@@ -1751,7 +1800,7 @@ function crc16IbmSdlcRev(data) {
1751
1800
  function crc16Genibus(data) {
1752
1801
  let crc = 65535;
1753
1802
  const polynomial = 4129;
1754
- const bytes = Buffer.from(data, "ascii");
1803
+ const bytes = asciiStringToBytes(data);
1755
1804
  for (const byte of bytes) {
1756
1805
  crc ^= byte << 8;
1757
1806
  for (let i = 0; i < 8; i++) {
@@ -1776,6 +1825,7 @@ function processMessageReference(decodeResult, data) {
1776
1825
  }
1777
1826
 
1778
1827
  // lib/plugins/ARINC_702.ts
1828
+ var NEWLINE_REGEX = /[\n\r]/g;
1779
1829
  var Arinc702 = class extends DecoderPlugin {
1780
1830
  name = "arinc-702";
1781
1831
  qualifiers() {
@@ -1787,7 +1837,7 @@ var Arinc702 = class extends DecoderPlugin {
1787
1837
  let decodeResult = this.defaultResult();
1788
1838
  decodeResult.decoder.name = this.name;
1789
1839
  decodeResult.message = message;
1790
- const msg = message.text.replace(/\n|\r/g, "");
1840
+ const msg = message.text.replace(NEWLINE_REGEX, "");
1791
1841
  let decoded = false;
1792
1842
  decoded = Arinc702Helper.decodeH1Message(decodeResult, msg);
1793
1843
  if (decoded) {
@@ -2061,19 +2111,10 @@ var Label_10_POS = class extends DecoderPlugin {
2061
2111
  };
2062
2112
  }
2063
2113
  decode(message, options = {}) {
2064
- const decodeResult = this.defaultResult();
2065
- decodeResult.decoder.name = this.name;
2066
- decodeResult.formatted.description = "Position Report";
2067
- decodeResult.message = message;
2114
+ const decodeResult = this.initResult(message, "Position Report");
2068
2115
  const parts = message.text.split(",");
2069
2116
  if (parts.length !== 12) {
2070
- if (options.debug) {
2071
- console.log(`Decoder: Unknown 10 message: ${message.text}`);
2072
- }
2073
- ResultFormatter.unknown(decodeResult, message.text);
2074
- decodeResult.decoded = false;
2075
- decodeResult.decoder.decodeLevel = "none";
2076
- return decodeResult;
2117
+ return this.failUnknown(decodeResult, message.text, options);
2077
2118
  }
2078
2119
  const lat = parts[1].trim();
2079
2120
  const lon = parts[2].trim();
@@ -2088,8 +2129,7 @@ var Label_10_POS = class extends DecoderPlugin {
2088
2129
  ...parts.slice(3, 7),
2089
2130
  ...parts.slice(8)
2090
2131
  ]);
2091
- decodeResult.decoded = true;
2092
- decodeResult.decoder.decodeLevel = "partial";
2132
+ this.setDecodeLevel(decodeResult, true, "partial");
2093
2133
  return decodeResult;
2094
2134
  }
2095
2135
  };
@@ -2216,19 +2256,10 @@ var Label_12_POS = class extends DecoderPlugin {
2216
2256
  };
2217
2257
  }
2218
2258
  decode(message, options = {}) {
2219
- const decodeResult = this.defaultResult();
2220
- decodeResult.decoder.name = this.name;
2221
- decodeResult.formatted.description = "Position Report";
2222
- decodeResult.message = message;
2259
+ const decodeResult = this.initResult(message, "Position Report");
2223
2260
  const data = message.text.substring(3).split(",");
2224
2261
  if (!message.text.startsWith("POS") || data.length !== 12) {
2225
- if (options.debug) {
2226
- console.log(`Decoder: Unknown 12 message: ${message.text}`);
2227
- }
2228
- ResultFormatter.unknown(decodeResult, message.text);
2229
- decodeResult.decoded = false;
2230
- decodeResult.decoder.decodeLevel = "none";
2231
- return decodeResult;
2262
+ return this.failUnknown(decodeResult, message.text, options);
2232
2263
  }
2233
2264
  const lat = data[0].substring(0, 8);
2234
2265
  const lon = data[0].substring(8);
@@ -2262,8 +2293,7 @@ var Label_12_POS = class extends DecoderPlugin {
2262
2293
  ResultFormatter.departureAirport(decodeResult, data[9]);
2263
2294
  ResultFormatter.arrivalAirport(decodeResult, data[10]);
2264
2295
  ResultFormatter.unknown(decodeResult, data[11]);
2265
- decodeResult.decoded = true;
2266
- decodeResult.decoder.decodeLevel = "partial";
2296
+ this.setDecodeLevel(decodeResult, true, "partial");
2267
2297
  return decodeResult;
2268
2298
  }
2269
2299
  };
@@ -2376,10 +2406,7 @@ var Label_15 = class extends DecoderPlugin {
2376
2406
  };
2377
2407
  }
2378
2408
  decode(message, options = {}) {
2379
- const decodeResult = this.defaultResult();
2380
- decodeResult.decoder.name = this.name;
2381
- decodeResult.formatted.description = "Position Report";
2382
- decodeResult.message = message;
2409
+ const decodeResult = this.initResult(message, "Position Report");
2383
2410
  if (message.text.startsWith("(2") && message.text.endsWith("(Z")) {
2384
2411
  const between = message.text.substring(2, message.text.length - 2);
2385
2412
  ResultFormatter.position(
@@ -2417,16 +2444,9 @@ var Label_15 = class extends DecoderPlugin {
2417
2444
  ResultFormatter.unknown(decodeResult, between.substring(26));
2418
2445
  }
2419
2446
  } else {
2420
- if (options.debug) {
2421
- console.log(`Decoder: Unknown 15 message: ${message.text}`);
2422
- }
2423
- ResultFormatter.unknown(decodeResult, message.text);
2424
- decodeResult.decoded = false;
2425
- decodeResult.decoder.decodeLevel = "none";
2426
- return decodeResult;
2447
+ return this.failUnknown(decodeResult, message.text, options);
2427
2448
  }
2428
- decodeResult.decoded = true;
2429
- decodeResult.decoder.decodeLevel = "partial";
2449
+ this.setDecodeLevel(decodeResult, true, "partial");
2430
2450
  return decodeResult;
2431
2451
  }
2432
2452
  };
@@ -2441,10 +2461,7 @@ var Label_15_FST = class extends DecoderPlugin {
2441
2461
  };
2442
2462
  }
2443
2463
  decode(message, options = {}) {
2444
- const decodeResult = this.defaultResult();
2445
- decodeResult.decoder.name = this.name;
2446
- decodeResult.formatted.description = "Position Report";
2447
- decodeResult.message = message;
2464
+ const decodeResult = this.initResult(message, "Position Report");
2448
2465
  const parts = message.text.split(" ");
2449
2466
  const header = parts[0];
2450
2467
  const stringCoords = header.substring(13);
@@ -2460,15 +2477,12 @@ var Label_15_FST = class extends DecoderPlugin {
2460
2477
  Number(stringCoords.substring(15)) * 100
2461
2478
  );
2462
2479
  } else {
2463
- decodeResult.decoded = false;
2464
- decodeResult.decoder.decodeLevel = "none";
2465
- return decodeResult;
2480
+ return this.failUnknown(decodeResult, message.text, options);
2466
2481
  }
2467
2482
  ResultFormatter.departureAirport(decodeResult, header.substring(5, 9));
2468
2483
  ResultFormatter.arrivalAirport(decodeResult, header.substring(9, 13));
2469
2484
  ResultFormatter.unknownArr(decodeResult, parts.slice(1), " ");
2470
- decodeResult.decoded = true;
2471
- decodeResult.decoder.decodeLevel = "partial";
2485
+ this.setDecodeLevel(decodeResult, true, "partial");
2472
2486
  return decodeResult;
2473
2487
  }
2474
2488
  };
@@ -2607,19 +2621,10 @@ var Label_16_POSA1 = class extends DecoderPlugin {
2607
2621
  };
2608
2622
  }
2609
2623
  decode(message, options = {}) {
2610
- const decodeResult = this.defaultResult();
2611
- decodeResult.decoder.name = this.name;
2612
- decodeResult.formatted.description = "Position Report";
2613
- decodeResult.message = message;
2624
+ const decodeResult = this.initResult(message, "Position Report");
2614
2625
  const fields = message.text.split(",");
2615
2626
  if (fields.length !== 11 || !fields[0].startsWith("POSA1")) {
2616
- if (options.debug) {
2617
- console.log(`Decoder: Unknown 16 message: ${message.text}`);
2618
- }
2619
- decodeResult.remaining.text = message.text;
2620
- decodeResult.decoded = false;
2621
- decodeResult.decoder.decodeLevel = "none";
2622
- return decodeResult;
2627
+ return this.failUnknown(decodeResult, message.text, options);
2623
2628
  }
2624
2629
  ResultFormatter.position(
2625
2630
  decodeResult,
@@ -2637,8 +2642,7 @@ var Label_16_POSA1 = class extends DecoderPlugin {
2637
2642
  { name: nextWaypoint, time: nextTime }
2638
2643
  ]
2639
2644
  });
2640
- decodeResult.decoded = true;
2641
- decodeResult.decoder.decodeLevel = "partial";
2645
+ this.setDecodeLevel(decodeResult, true, "partial");
2642
2646
  return decodeResult;
2643
2647
  }
2644
2648
  };
@@ -3020,42 +3024,31 @@ var Label_20_POS = class extends DecoderPlugin {
3020
3024
  };
3021
3025
  }
3022
3026
  decode(message, options = {}) {
3023
- const decodeResult = this.defaultResult();
3024
- decodeResult.decoder.name = this.name;
3025
- decodeResult.formatted.description = "Position Report";
3026
- decodeResult.message = message;
3027
+ const decodeResult = this.initResult(message, "Position Report");
3027
3028
  decodeResult.raw.preamble = message.text.substring(0, 3);
3028
3029
  const content = message.text.substring(3);
3029
3030
  const fields = content.split(",");
3030
3031
  if (fields.length == 11) {
3031
- if (options.debug) {
3032
- console.log(`DEBUG: ${this.name}: Variation 1 detected`);
3033
- }
3032
+ this.debug(options, "Variation 1 detected");
3034
3033
  const rawCoords = fields[0];
3035
3034
  ResultFormatter.position(
3036
3035
  decodeResult,
3037
3036
  CoordinateUtils.decodeStringCoordinates(rawCoords)
3038
3037
  );
3039
- decodeResult.decoded = true;
3040
- decodeResult.decoder.decodeLevel = "full";
3038
+ this.setDecodeLevel(decodeResult, true, "full");
3041
3039
  } else if (fields.length == 5) {
3042
- if (options.debug) {
3043
- console.log(`DEBUG: ${this.name}: Variation 2 detected`);
3044
- }
3040
+ this.debug(options, "Variation 2 detected");
3045
3041
  const position = CoordinateUtils.decodeStringCoordinates(fields[0]);
3046
3042
  if (position) {
3047
3043
  ResultFormatter.position(decodeResult, position);
3048
3044
  }
3049
- decodeResult.decoded = true;
3050
- decodeResult.decoder.decodeLevel = "full";
3045
+ this.setDecodeLevel(decodeResult, true, "full");
3051
3046
  } else {
3052
- if (options.debug) {
3053
- console.log(
3054
- `DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${content}`
3055
- );
3056
- }
3057
- decodeResult.decoded = false;
3058
- decodeResult.decoder.decodeLevel = "none";
3047
+ this.debug(
3048
+ options,
3049
+ `Unknown variation. Field count: ${fields.length}, content: ${content}`
3050
+ );
3051
+ this.setDecodeLevel(decodeResult, false);
3059
3052
  }
3060
3053
  return decodeResult;
3061
3054
  }
@@ -3071,10 +3064,7 @@ var Label_21_POS = class extends DecoderPlugin {
3071
3064
  };
3072
3065
  }
3073
3066
  decode(message, options = {}) {
3074
- const decodeResult = this.defaultResult();
3075
- decodeResult.decoder.name = this.name;
3076
- decodeResult.formatted.description = "Position Report";
3077
- decodeResult.message = message;
3067
+ const decodeResult = this.initResult(message, "Position Report");
3078
3068
  decodeResult.raw.preamble = message.text.substring(0, 3);
3079
3069
  const content = message.text.substring(3);
3080
3070
  const fields = content.split(",");
@@ -3096,16 +3086,13 @@ var Label_21_POS = class extends DecoderPlugin {
3096
3086
  fields[4],
3097
3087
  fields[5]
3098
3088
  ]);
3099
- decodeResult.decoded = true;
3100
- decodeResult.decoder.decodeLevel = "partial";
3089
+ this.setDecodeLevel(decodeResult, true, "partial");
3101
3090
  } else {
3102
- if (options.debug) {
3103
- console.log(
3104
- `DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${content}`
3105
- );
3106
- }
3107
- decodeResult.decoded = false;
3108
- decodeResult.decoder.decodeLevel = "none";
3091
+ this.debug(
3092
+ options,
3093
+ `Unknown variation. Field count: ${fields.length}, content: ${content}`
3094
+ );
3095
+ this.setDecodeLevel(decodeResult, false);
3109
3096
  }
3110
3097
  return decodeResult;
3111
3098
  }
@@ -3133,15 +3120,11 @@ var Label_22_OFF = class extends DecoderPlugin {
3133
3120
  };
3134
3121
  }
3135
3122
  decode(message, options = {}) {
3136
- const decodeResult = this.defaultResult();
3137
- decodeResult.decoder.name = this.name;
3138
- decodeResult.formatted.description = "Takeoff Report";
3139
- decodeResult.message = message;
3123
+ const decodeResult = this.initResult(message, "Takeoff Report");
3140
3124
  if (message.text.startsWith("OFF01")) {
3141
3125
  const fields = message.text.substring(5).split("/");
3142
3126
  if (fields.length != 2) {
3143
- decodeResult.decoded = false;
3144
- decodeResult.decoder.decodeLevel = "none";
3127
+ this.setDecodeLevel(decodeResult, false);
3145
3128
  return decodeResult;
3146
3129
  }
3147
3130
  ResultFormatter.flightNumber(decodeResult, fields[0]);
@@ -3167,13 +3150,11 @@ var Label_22_OFF = class extends DecoderPlugin {
3167
3150
  DateTimeUtils.convertHHMMSSToTod(fields[1].substring(16, 22))
3168
3151
  );
3169
3152
  ResultFormatter.unknown(decodeResult, fields[1].substring(22));
3170
- decodeResult.decoded = true;
3171
- decodeResult.decoder.decodeLevel = "partial";
3153
+ this.setDecodeLevel(decodeResult, true, "partial");
3172
3154
  } else if (message.text.startsWith("OFF02\r\n")) {
3173
3155
  const fields = message.text.substring(7).split(",");
3174
3156
  if (fields.length != 4) {
3175
- decodeResult.decoded = false;
3176
- decodeResult.decoder.decodeLevel = "none";
3157
+ this.setDecodeLevel(decodeResult, false);
3177
3158
  return decodeResult;
3178
3159
  }
3179
3160
  ResultFormatter.departureAirport(decodeResult, fields[0]);
@@ -3183,13 +3164,11 @@ var Label_22_OFF = class extends DecoderPlugin {
3183
3164
  DateTimeUtils.convertHHMMSSToTod(fields[2])
3184
3165
  );
3185
3166
  ResultFormatter.unknown(decodeResult, fields[3]);
3186
- decodeResult.decoded = true;
3187
- decodeResult.decoder.decodeLevel = "partial";
3167
+ this.setDecodeLevel(decodeResult, true, "partial");
3188
3168
  } else if (message.text.startsWith("OFF02")) {
3189
3169
  const fields = message.text.substring(5).split("/");
3190
3170
  if (fields.length != 2) {
3191
- decodeResult.decoded = false;
3192
- decodeResult.decoder.decodeLevel = "none";
3171
+ this.setDecodeLevel(decodeResult, false);
3193
3172
  return decodeResult;
3194
3173
  }
3195
3174
  ResultFormatter.flightNumber(decodeResult, fields[0]);
@@ -3218,14 +3197,10 @@ var Label_22_OFF = class extends DecoderPlugin {
3218
3197
  decodeResult,
3219
3198
  DateTimeUtils.convertHHMMSSToTod(fields[1].substring(36, 40))
3220
3199
  );
3221
- decodeResult.decoded = true;
3222
- decodeResult.decoder.decodeLevel = "partial";
3200
+ this.setDecodeLevel(decodeResult, true, "partial");
3223
3201
  } else {
3224
- if (options.debug) {
3225
- console.log(`DEBUG: ${this.name}: Unknown variation.`);
3226
- }
3227
- decodeResult.decoded = false;
3228
- decodeResult.decoder.decodeLevel = "none";
3202
+ this.debug(options, "Unknown variation.");
3203
+ this.setDecodeLevel(decodeResult, false);
3229
3204
  }
3230
3205
  return decodeResult;
3231
3206
  }
@@ -3241,19 +3216,14 @@ var Label_22_POS = class extends DecoderPlugin {
3241
3216
  };
3242
3217
  }
3243
3218
  decode(message, options = {}) {
3244
- const decodeResult = this.defaultResult();
3245
- decodeResult.decoder.name = this.name;
3246
- decodeResult.formatted.description = "Position Report";
3247
- decodeResult.message = message;
3219
+ const decodeResult = this.initResult(message, "Position Report");
3248
3220
  const fields = message.text.split(",");
3249
3221
  if (fields.length !== 11) {
3250
- if (options.debug) {
3251
- console.log(
3252
- `DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${fields.join(",")}`
3253
- );
3254
- }
3255
- decodeResult.decoded = false;
3256
- decodeResult.decoder.decodeLevel = "none";
3222
+ this.debug(
3223
+ options,
3224
+ `Unknown variation. Field count: ${fields.length}, content: ${fields.join(",")}`
3225
+ );
3226
+ this.setDecodeLevel(decodeResult, false);
3257
3227
  return decodeResult;
3258
3228
  }
3259
3229
  const latStr = fields[0].substring(1, 8);
@@ -3270,8 +3240,7 @@ var Label_22_POS = class extends DecoderPlugin {
3270
3240
  );
3271
3241
  ResultFormatter.altitude(decodeResult, Number(fields[3]));
3272
3242
  ResultFormatter.unknownArr(decodeResult, [fields[1], ...fields.slice(4)]);
3273
- decodeResult.decoded = true;
3274
- decodeResult.decoder.decodeLevel = "partial";
3243
+ this.setDecodeLevel(decodeResult, true, "partial");
3275
3244
  return decodeResult;
3276
3245
  }
3277
3246
  };
@@ -3563,218 +3532,143 @@ var Label_44_ETA = class extends DecoderPlugin {
3563
3532
  };
3564
3533
  }
3565
3534
  decode(message, options = {}) {
3566
- const decodeResult = this.defaultResult();
3567
- decodeResult.decoder.name = this.name;
3568
- decodeResult.formatted.description = "ETA Report";
3569
- decodeResult.message = message;
3535
+ const result = this.initResult(message, "ETA Report");
3570
3536
  const data = message.text.split(",");
3571
- if (data.length >= 9) {
3572
- if (options.debug) {
3573
- console.log("Label 44 ETA Report: groups");
3574
- console.log(data);
3575
- }
3576
- ResultFormatter.position(
3577
- decodeResult,
3578
- CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1])
3579
- );
3580
- ResultFormatter.altitude(decodeResult, 100 * Number(data[2]));
3581
- ResultFormatter.departureAirport(decodeResult, data[3]);
3582
- ResultFormatter.arrivalAirport(decodeResult, data[4]);
3583
- ResultFormatter.month(decodeResult, Number(data[5].substring(0, 2)));
3584
- ResultFormatter.day(decodeResult, Number(data[5].substring(2, 4)));
3585
- ResultFormatter.timestamp(
3586
- decodeResult,
3587
- DateTimeUtils.convertHHMMSSToTod(data[6])
3588
- );
3589
- ResultFormatter.eta(
3590
- decodeResult,
3591
- DateTimeUtils.convertHHMMSSToTod(data[7])
3592
- );
3593
- const fuel = Number(data[8]);
3594
- if (!isNaN(fuel)) {
3595
- ResultFormatter.remainingFuel(decodeResult, Number(fuel));
3596
- }
3597
- if (data.length > 9) {
3598
- ResultFormatter.unknownArr(decodeResult, data.slice(9));
3599
- }
3600
- } else {
3601
- if (options.debug) {
3602
- console.log(`Decoder: Unknown 44 message: ${message.text}`);
3603
- }
3604
- ResultFormatter.unknown(decodeResult, message.text);
3605
- decodeResult.decoded = false;
3606
- decodeResult.decoder.decodeLevel = "none";
3607
- return decodeResult;
3537
+ if (data.length < 9) {
3538
+ return this.failUnknown(result, message.text, options);
3539
+ }
3540
+ this.debug(options, "ETA Report: fields", data);
3541
+ ResultFormatter.position(
3542
+ result,
3543
+ CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1])
3544
+ );
3545
+ ResultFormatter.altitude(result, 100 * Number(data[2]));
3546
+ ResultFormatter.departureAirport(result, data[3]);
3547
+ ResultFormatter.arrivalAirport(result, data[4]);
3548
+ ResultFormatter.month(result, Number(data[5].substring(0, 2)));
3549
+ ResultFormatter.day(result, Number(data[5].substring(2, 4)));
3550
+ ResultFormatter.timestamp(
3551
+ result,
3552
+ DateTimeUtils.convertHHMMSSToTod(data[6])
3553
+ );
3554
+ ResultFormatter.eta(result, DateTimeUtils.convertHHMMSSToTod(data[7]));
3555
+ const fuel = Number(data[8]);
3556
+ if (!isNaN(fuel)) {
3557
+ ResultFormatter.remainingFuel(result, fuel);
3558
+ }
3559
+ if (data.length > 9) {
3560
+ ResultFormatter.unknownArr(result, data.slice(9));
3561
+ }
3562
+ this.setDecodeLevel(result, true, "full");
3563
+ return result;
3564
+ }
3565
+ };
3566
+
3567
+ // lib/plugins/Label_44_Base.ts
3568
+ var Label_44_Base = class extends DecoderPlugin {
3569
+ decode(message, options = {}) {
3570
+ const result = this.initResult(message, this.description);
3571
+ const data = message.text.split(",");
3572
+ if (data.length < this.minFields) {
3573
+ return this.failUnknown(result, message.text, options);
3574
+ }
3575
+ this.debug(options, `${this.description}: fields`, data);
3576
+ ResultFormatter.position(
3577
+ result,
3578
+ CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1])
3579
+ );
3580
+ ResultFormatter.departureAirport(result, data[2]);
3581
+ ResultFormatter.arrivalAirport(result, data[3]);
3582
+ ResultFormatter.month(result, Number(data[4].substring(0, 2)));
3583
+ ResultFormatter.day(result, Number(data[4].substring(2, 4)));
3584
+ this.decodeEventFields(result, data, options);
3585
+ this.setDecodeLevel(result, true, "full");
3586
+ return result;
3587
+ }
3588
+ /**
3589
+ * Helper to parse a fuel value from a CSV field.
3590
+ * Returns undefined if the value is not a valid number.
3591
+ */
3592
+ parseFuel(result, value) {
3593
+ const fuel = Number(value);
3594
+ if (!isNaN(fuel)) {
3595
+ ResultFormatter.remainingFuel(result, fuel);
3596
+ }
3597
+ }
3598
+ /**
3599
+ * Helper to add any remaining fields as unknown.
3600
+ */
3601
+ addRemainingFields(result, data, startIndex) {
3602
+ if (data.length > startIndex) {
3603
+ ResultFormatter.unknownArr(result, data.slice(startIndex));
3608
3604
  }
3609
- decodeResult.decoded = true;
3610
- decodeResult.decoder.decodeLevel = "full";
3611
- return decodeResult;
3612
3605
  }
3613
3606
  };
3614
3607
 
3615
3608
  // lib/plugins/Label_44_IN.ts
3616
- var Label_44_IN = class extends DecoderPlugin {
3609
+ var Label_44_IN = class extends Label_44_Base {
3617
3610
  name = "label-44-in";
3611
+ get description() {
3612
+ return "In Gate Report";
3613
+ }
3614
+ get minFields() {
3615
+ return 7;
3616
+ }
3618
3617
  qualifiers() {
3619
3618
  return {
3620
3619
  labels: ["44"],
3621
3620
  preambles: ["00IN01", "00IN02", "00IN03", "IN01", "IN02", "IN03"]
3622
3621
  };
3623
3622
  }
3624
- decode(message, options = {}) {
3625
- const decodeResult = this.defaultResult();
3626
- decodeResult.decoder.name = this.name;
3627
- decodeResult.formatted.description = "In Air Report";
3628
- decodeResult.message = message;
3629
- const data = message.text.split(",");
3630
- if (data.length >= 7) {
3631
- if (options.debug) {
3632
- console.log("Label 44 In Air Report: groups");
3633
- console.log(data);
3634
- }
3635
- ResultFormatter.position(
3636
- decodeResult,
3637
- CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1])
3638
- );
3639
- ResultFormatter.departureAirport(decodeResult, data[2]);
3640
- ResultFormatter.arrivalAirport(decodeResult, data[3]);
3641
- ResultFormatter.month(decodeResult, Number(data[4].substring(0, 2)));
3642
- ResultFormatter.day(decodeResult, Number(data[4].substring(2, 4)));
3643
- ResultFormatter.in(
3644
- decodeResult,
3645
- DateTimeUtils.convertHHMMSSToTod(data[5])
3646
- );
3647
- const fuel = Number(data[6]);
3648
- if (!isNaN(fuel)) {
3649
- ResultFormatter.remainingFuel(decodeResult, Number(fuel));
3650
- }
3651
- if (data.length > 7) {
3652
- ResultFormatter.unknownArr(decodeResult, data.slice(7));
3653
- }
3654
- } else {
3655
- if (options.debug) {
3656
- console.log(`Decoder: Unknown 44 message: ${message.text}`);
3657
- }
3658
- ResultFormatter.unknown(decodeResult, message.text);
3659
- decodeResult.decoded = false;
3660
- decodeResult.decoder.decodeLevel = "none";
3661
- return decodeResult;
3662
- }
3663
- decodeResult.decoded = true;
3664
- decodeResult.decoder.decodeLevel = "full";
3665
- return decodeResult;
3623
+ decodeEventFields(result, data, _options) {
3624
+ ResultFormatter.in(result, DateTimeUtils.convertHHMMSSToTod(data[5]));
3625
+ this.parseFuel(result, data[6]);
3626
+ this.addRemainingFields(result, data, 7);
3666
3627
  }
3667
3628
  };
3668
3629
 
3669
3630
  // lib/plugins/Label_44_OFF.ts
3670
- var Label_44_OFF = class extends DecoderPlugin {
3631
+ var Label_44_OFF = class extends Label_44_Base {
3671
3632
  name = "label-44-off";
3633
+ get description() {
3634
+ return "Off Runway Report";
3635
+ }
3636
+ get minFields() {
3637
+ return 8;
3638
+ }
3672
3639
  qualifiers() {
3673
3640
  return {
3674
3641
  labels: ["44"],
3675
3642
  preambles: ["00OFF01", "00OFF02", "00OFF03", "OFF01", "OFF02", "OFF03"]
3676
3643
  };
3677
3644
  }
3678
- decode(message, options = {}) {
3679
- const decodeResult = this.defaultResult();
3680
- decodeResult.decoder.name = this.name;
3681
- decodeResult.formatted.description = "Off Runway Report";
3682
- decodeResult.message = message;
3683
- const data = message.text.split(",");
3684
- if (data.length >= 8) {
3685
- if (options.debug) {
3686
- console.log("Label 44 Off Runway Report: groups");
3687
- console.log(data);
3688
- }
3689
- ResultFormatter.position(
3690
- decodeResult,
3691
- CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1])
3692
- );
3693
- ResultFormatter.departureAirport(decodeResult, data[2]);
3694
- ResultFormatter.arrivalAirport(decodeResult, data[3]);
3695
- ResultFormatter.month(decodeResult, Number(data[4].substring(0, 2)));
3696
- ResultFormatter.day(decodeResult, Number(data[4].substring(2, 4)));
3697
- ResultFormatter.off(
3698
- decodeResult,
3699
- DateTimeUtils.convertHHMMSSToTod(data[5])
3700
- );
3701
- ResultFormatter.eta(
3702
- decodeResult,
3703
- DateTimeUtils.convertHHMMSSToTod(data[6])
3704
- );
3705
- const fuel = Number(data[7]);
3706
- if (!isNaN(fuel)) {
3707
- ResultFormatter.remainingFuel(decodeResult, Number(fuel));
3708
- }
3709
- if (data.length > 8) {
3710
- ResultFormatter.unknownArr(decodeResult, data.slice(8));
3711
- }
3712
- } else {
3713
- if (options.debug) {
3714
- console.log(`Decoder: Unknown 44 message: ${message.text}`);
3715
- }
3716
- ResultFormatter.unknown(decodeResult, message.text);
3717
- decodeResult.decoded = false;
3718
- decodeResult.decoder.decodeLevel = "none";
3719
- return decodeResult;
3720
- }
3721
- decodeResult.decoded = true;
3722
- decodeResult.decoder.decodeLevel = "full";
3723
- return decodeResult;
3645
+ decodeEventFields(result, data, _options) {
3646
+ ResultFormatter.off(result, DateTimeUtils.convertHHMMSSToTod(data[5]));
3647
+ ResultFormatter.eta(result, DateTimeUtils.convertHHMMSSToTod(data[6]));
3648
+ this.parseFuel(result, data[7]);
3649
+ this.addRemainingFields(result, data, 8);
3724
3650
  }
3725
3651
  };
3726
3652
 
3727
3653
  // lib/plugins/Label_44_ON.ts
3728
- var Label_44_ON = class extends DecoderPlugin {
3654
+ var Label_44_ON = class extends Label_44_Base {
3729
3655
  name = "label-44-on";
3656
+ get description() {
3657
+ return "On Runway Report";
3658
+ }
3659
+ get minFields() {
3660
+ return 7;
3661
+ }
3730
3662
  qualifiers() {
3731
3663
  return {
3732
3664
  labels: ["44"],
3733
3665
  preambles: ["00ON01", "00ON02", "00ON03", "ON01", "ON02", "ON03"]
3734
3666
  };
3735
3667
  }
3736
- decode(message, options = {}) {
3737
- const decodeResult = this.defaultResult();
3738
- decodeResult.decoder.name = this.name;
3739
- decodeResult.formatted.description = "On Runway Report";
3740
- decodeResult.message = message;
3741
- const data = message.text.split(",");
3742
- if (data.length >= 7) {
3743
- if (options.debug) {
3744
- console.log("Label 44 On Runway Report: groups");
3745
- console.log(data);
3746
- }
3747
- ResultFormatter.position(
3748
- decodeResult,
3749
- CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1])
3750
- );
3751
- ResultFormatter.departureAirport(decodeResult, data[2]);
3752
- ResultFormatter.arrivalAirport(decodeResult, data[3]);
3753
- ResultFormatter.month(decodeResult, Number(data[4].substring(0, 2)));
3754
- ResultFormatter.day(decodeResult, Number(data[4].substring(2, 4)));
3755
- ResultFormatter.on(
3756
- decodeResult,
3757
- DateTimeUtils.convertHHMMSSToTod(data[5])
3758
- );
3759
- const fuel = Number(data[6]);
3760
- if (!isNaN(fuel)) {
3761
- ResultFormatter.remainingFuel(decodeResult, Number(fuel));
3762
- }
3763
- if (data.length > 7) {
3764
- ResultFormatter.unknownArr(decodeResult, data.slice(7));
3765
- }
3766
- } else {
3767
- if (options.debug) {
3768
- console.log(`Decoder: Unknown 44 message: ${message.text}`);
3769
- }
3770
- ResultFormatter.unknown(decodeResult, message.text);
3771
- decodeResult.decoded = false;
3772
- decodeResult.decoder.decodeLevel = "none";
3773
- return decodeResult;
3774
- }
3775
- decodeResult.decoded = true;
3776
- decodeResult.decoder.decodeLevel = "full";
3777
- return decodeResult;
3668
+ decodeEventFields(result, data, _options) {
3669
+ ResultFormatter.on(result, DateTimeUtils.convertHHMMSSToTod(data[5]));
3670
+ this.parseFuel(result, data[6]);
3671
+ this.addRemainingFields(result, data, 7);
3778
3672
  }
3779
3673
  };
3780
3674
 
@@ -3788,17 +3682,11 @@ var Label_44_POS = class extends DecoderPlugin {
3788
3682
  };
3789
3683
  }
3790
3684
  decode(message, options = {}) {
3791
- const decodeResult = this.defaultResult();
3792
- decodeResult.decoder.name = this.name;
3793
- decodeResult.formatted.description = "Position Report";
3794
- decodeResult.message = message;
3685
+ const decodeResult = this.initResult(message, "Position Report");
3795
3686
  const regex = /^.*,(?<unsplit_coords>.*),(?<flight_level_or_ground>.*),(?<departure_icao>.*),(?<arrival_icao>.*),(?<current_date>.*),(?<current_time>.*),(?<eta_time>.*),(?<fuel_in_tons>.*)$/;
3796
3687
  const results = message.text.match(regex);
3797
3688
  if (results?.groups) {
3798
- if (options.debug) {
3799
- console.log("Label 44 Position Report: groups");
3800
- console.log(results.groups);
3801
- }
3689
+ this.debug(options, "Position Report: groups", results.groups);
3802
3690
  ResultFormatter.position(
3803
3691
  decodeResult,
3804
3692
  CoordinateUtils.decodeStringCoordinatesDecimalMinutes(
@@ -3831,10 +3719,10 @@ var Label_44_POS = class extends DecoderPlugin {
3831
3719
  );
3832
3720
  ResultFormatter.arrivalAirport(decodeResult, results.groups.arrival_icao);
3833
3721
  ResultFormatter.altitude(decodeResult, flight_level * 100);
3722
+ this.setDecodeLevel(decodeResult, true, "full");
3723
+ return decodeResult;
3834
3724
  }
3835
- decodeResult.decoded = true;
3836
- decodeResult.decoder.decodeLevel = "full";
3837
- return decodeResult;
3725
+ return this.failUnknown(decodeResult, message.text, options);
3838
3726
  }
3839
3727
  };
3840
3728
 
@@ -3912,10 +3800,7 @@ var Label_4A = class extends DecoderPlugin {
3912
3800
  };
3913
3801
  }
3914
3802
  decode(message, options = {}) {
3915
- const decodeResult = this.defaultResult();
3916
- decodeResult.decoder.name = this.name;
3917
- decodeResult.message = message;
3918
- decodeResult.formatted.description = "Latest New Format";
3803
+ const decodeResult = this.initResult(message, "Latest New Format");
3919
3804
  decodeResult.decoded = true;
3920
3805
  const fields = message.text.split(",");
3921
3806
  if (fields.length === 11) {
@@ -3929,7 +3814,8 @@ var Label_4A = class extends DecoderPlugin {
3929
3814
  ResultFormatter.arrivalAirport(decodeResult, fields[5]);
3930
3815
  ResultFormatter.unknownArr(decodeResult, fields.slice(8));
3931
3816
  } else if (fields.length === 6) {
3932
- if (fields[0].match(/^[NS]/)) {
3817
+ const f0 = fields[0];
3818
+ if (f0.length > 0 && (f0[0] === "N" || f0[0] === "S")) {
3933
3819
  ResultFormatter.position(
3934
3820
  decodeResult,
3935
3821
  CoordinateUtils.decodeStringCoordinates(fields[0].substring(0, 13))
@@ -3971,13 +3857,7 @@ var Label_4A = class extends DecoderPlugin {
3971
3857
  decodeResult.decoded = false;
3972
3858
  ResultFormatter.unknown(decodeResult, message.text);
3973
3859
  }
3974
- if (decodeResult.decoded) {
3975
- if (!decodeResult.remaining.text)
3976
- decodeResult.decoder.decodeLevel = "full";
3977
- else decodeResult.decoder.decodeLevel = "partial";
3978
- } else {
3979
- decodeResult.decoder.decodeLevel = "none";
3980
- }
3860
+ this.setDecodeLevel(decodeResult, decodeResult.decoded);
3981
3861
  return decodeResult;
3982
3862
  }
3983
3863
  };
@@ -3992,10 +3872,7 @@ var Label_4A_01 = class extends DecoderPlugin {
3992
3872
  };
3993
3873
  }
3994
3874
  decode(message, options = {}) {
3995
- const decodeResult = this.defaultResult();
3996
- decodeResult.decoder.name = this.name;
3997
- decodeResult.message = message;
3998
- decodeResult.formatted.description = "Latest New Format";
3875
+ const decodeResult = this.initResult(message, "Latest New Format");
3999
3876
  decodeResult.decoded = true;
4000
3877
  let rgx = message.text.match(
4001
3878
  /^01([A-Z]{2})([A-Z]{2})\s*(\w+)\/(\d{6})([A-Z]{4})([A-Z]{4})\r\n([+-]\s*\d+)(\d{3}\.\d)([+-]\s*\d+\.\d)/
@@ -4016,13 +3893,7 @@ var Label_4A_01 = class extends DecoderPlugin {
4016
3893
  decodeResult.decoded = false;
4017
3894
  ResultFormatter.unknown(decodeResult, message.text);
4018
3895
  }
4019
- if (decodeResult.decoded) {
4020
- if (!decodeResult.remaining.text)
4021
- decodeResult.decoder.decodeLevel = "full";
4022
- else decodeResult.decoder.decodeLevel = "partial";
4023
- } else {
4024
- decodeResult.decoder.decodeLevel = "none";
4025
- }
3896
+ this.setDecodeLevel(decodeResult, decodeResult.decoded);
4026
3897
  return decodeResult;
4027
3898
  }
4028
3899
  };
@@ -4037,10 +3908,7 @@ var Label_4A_DIS = class extends DecoderPlugin {
4037
3908
  };
4038
3909
  }
4039
3910
  decode(message, options = {}) {
4040
- const decodeResult = this.defaultResult();
4041
- decodeResult.decoder.name = this.name;
4042
- decodeResult.message = message;
4043
- decodeResult.formatted.description = "Latest New Format";
3911
+ const decodeResult = this.initResult(message, "Latest New Format");
4044
3912
  decodeResult.decoded = true;
4045
3913
  const fields = message.text.split(",");
4046
3914
  ResultFormatter.timestamp(
@@ -4049,13 +3917,7 @@ var Label_4A_DIS = class extends DecoderPlugin {
4049
3917
  );
4050
3918
  ResultFormatter.callsign(decodeResult, fields[2]);
4051
3919
  ResultFormatter.text(decodeResult, fields.slice(3).join(""));
4052
- if (decodeResult.decoded) {
4053
- if (!decodeResult.remaining.text)
4054
- decodeResult.decoder.decodeLevel = "full";
4055
- else decodeResult.decoder.decodeLevel = "partial";
4056
- } else {
4057
- decodeResult.decoder.decodeLevel = "none";
4058
- }
3920
+ this.setDecodeLevel(decodeResult, decodeResult.decoded);
4059
3921
  return decodeResult;
4060
3922
  }
4061
3923
  };
@@ -4070,10 +3932,7 @@ var Label_4A_DOOR = class extends DecoderPlugin {
4070
3932
  };
4071
3933
  }
4072
3934
  decode(message, options = {}) {
4073
- const decodeResult = this.defaultResult();
4074
- decodeResult.decoder.name = this.name;
4075
- decodeResult.message = message;
4076
- decodeResult.formatted.description = "Latest New Format";
3935
+ const decodeResult = this.initResult(message, "Latest New Format");
4077
3936
  decodeResult.decoded = true;
4078
3937
  const fields = message.text.split(" ");
4079
3938
  if (fields.length === 3) {
@@ -4090,13 +3949,7 @@ var Label_4A_DOOR = class extends DecoderPlugin {
4090
3949
  decodeResult.decoded = false;
4091
3950
  ResultFormatter.unknown(decodeResult, message.text);
4092
3951
  }
4093
- if (decodeResult.decoded) {
4094
- if (!decodeResult.remaining.text)
4095
- decodeResult.decoder.decodeLevel = "full";
4096
- else decodeResult.decoder.decodeLevel = "partial";
4097
- } else {
4098
- decodeResult.decoder.decodeLevel = "none";
4099
- }
3952
+ this.setDecodeLevel(decodeResult, decodeResult.decoded);
4100
3953
  return decodeResult;
4101
3954
  }
4102
3955
  };
@@ -4343,6 +4196,9 @@ var Label_4T_ETA = class extends DecoderPlugin {
4343
4196
  };
4344
4197
 
4345
4198
  // lib/plugins/Label_80.ts
4199
+ var POS_REGEX = /^(?<latd>[NS])(?<lat>.+)(?<lngd>[EW])(?<lng>.+)/;
4200
+ var WS_REGEX = /\s+/;
4201
+ var NEWLINE_REGEX2 = /\r?\n/;
4346
4202
  var Label_80 = class extends DecoderPlugin {
4347
4203
  name = "label-80";
4348
4204
  qualifiers() {
@@ -4352,10 +4208,11 @@ var Label_80 = class extends DecoderPlugin {
4352
4208
  };
4353
4209
  }
4354
4210
  decode(message, options = {}) {
4355
- const decodeResult = this.defaultResult();
4356
- decodeResult.decoder.name = this.name;
4357
- decodeResult.formatted.description = "Airline Defined Position Report";
4358
- const lines = message.text.split(/\r?\n/);
4211
+ const decodeResult = this.initResult(
4212
+ message,
4213
+ "Airline Defined Position Report"
4214
+ );
4215
+ const lines = message.text.split(NEWLINE_REGEX2);
4359
4216
  if (lines.length === 1 && lines[0].includes(",")) {
4360
4217
  this.parseCsvFormat(lines[0], decodeResult);
4361
4218
  } else {
@@ -4380,8 +4237,7 @@ var Label_80 = class extends DecoderPlugin {
4380
4237
  }
4381
4238
  }
4382
4239
  if (decodeResult.formatted.items.length > 0) {
4383
- decodeResult.decoded = true;
4384
- decodeResult.decoder.decodeLevel = decodeResult.remaining.text === void 0 ? "full" : "partial";
4240
+ this.setDecodeLevel(decodeResult, true);
4385
4241
  }
4386
4242
  return decodeResult;
4387
4243
  }
@@ -4391,7 +4247,7 @@ var Label_80 = class extends DecoderPlugin {
4391
4247
  ResultFormatter.unknown(results, header, "/");
4392
4248
  return;
4393
4249
  }
4394
- const msgInfo = fields[0].split(/\s+/);
4250
+ const msgInfo = fields[0].split(WS_REGEX);
4395
4251
  if (msgInfo.length === 3) {
4396
4252
  ResultFormatter.unknownArr(results, msgInfo.slice(0, 2), " ");
4397
4253
  ResultFormatter.flightNumber(results, msgInfo[2]);
@@ -4399,14 +4255,14 @@ var Label_80 = class extends DecoderPlugin {
4399
4255
  ResultFormatter.unknown(results, header, "/");
4400
4256
  return;
4401
4257
  }
4402
- const otherInfo1 = fields[1].split(/\s+/);
4258
+ const otherInfo1 = fields[1].split(WS_REGEX);
4403
4259
  if (otherInfo1.length === 2) {
4404
4260
  ResultFormatter.day(results, parseInt(otherInfo1[0], 10));
4405
4261
  ResultFormatter.departureAirport(results, otherInfo1[1]);
4406
4262
  } else {
4407
4263
  ResultFormatter.unknownArr(results, otherInfo1, " ");
4408
4264
  }
4409
- const otherInfo2 = fields[2].split(/\s+/);
4265
+ const otherInfo2 = fields[2].split(WS_REGEX);
4410
4266
  if (otherInfo2.length === 2) {
4411
4267
  ResultFormatter.arrivalAirport(results, otherInfo2[0]);
4412
4268
  ResultFormatter.tail(results, otherInfo2[1].replace(".", ""));
@@ -4418,7 +4274,7 @@ var Label_80 = class extends DecoderPlugin {
4418
4274
  }
4419
4275
  }
4420
4276
  parseTags(part, results) {
4421
- const kvPair = part.split(/\s+/);
4277
+ const kvPair = part.split(WS_REGEX);
4422
4278
  if (kvPair.length < 2) {
4423
4279
  ResultFormatter.unknown(results, part, "/");
4424
4280
  return;
@@ -4426,9 +4282,8 @@ var Label_80 = class extends DecoderPlugin {
4426
4282
  const tag = kvPair[0];
4427
4283
  const val = kvPair.slice(1).join(" ");
4428
4284
  switch (tag) {
4429
- case "POS":
4430
- const posRegex = /^(?<latd>[NS])(?<lat>.+)(?<lngd>[EW])(?<lng>.+)/;
4431
- const posResult = val.match(posRegex);
4285
+ case "POS": {
4286
+ const posResult = POS_REGEX.exec(val);
4432
4287
  const lat = Number(posResult?.groups?.lat) * (posResult?.groups?.latd === "S" ? -1 : 1);
4433
4288
  const lon = Number(posResult?.groups?.lng) * (posResult?.groups?.lngd === "W" ? -1 : 1);
4434
4289
  const position = {
@@ -4437,6 +4292,7 @@ var Label_80 = class extends DecoderPlugin {
4437
4292
  };
4438
4293
  ResultFormatter.position(results, position);
4439
4294
  break;
4295
+ }
4440
4296
  case "ALT":
4441
4297
  ResultFormatter.altitude(results, parseInt(val.replace("+", ""), 10));
4442
4298
  break;
@@ -4469,10 +4325,11 @@ var Label_80 = class extends DecoderPlugin {
4469
4325
  DateTimeUtils.convertHHMMSSToTod(val)
4470
4326
  );
4471
4327
  break;
4472
- case "ETA":
4328
+ case "ETA": {
4473
4329
  const hhmm = val.split(".")[0].replace(":", "");
4474
4330
  ResultFormatter.eta(results, DateTimeUtils.convertHHMMSSToTod(hhmm));
4475
4331
  break;
4332
+ }
4476
4333
  case "HDG":
4477
4334
  ResultFormatter.heading(results, parseInt(val, 10));
4478
4335
  break;
@@ -4496,7 +4353,7 @@ var Label_80 = class extends DecoderPlugin {
4496
4353
  if (csvParts.length !== 9) {
4497
4354
  return;
4498
4355
  }
4499
- const header = csvParts[0].trim().split(/\s+/);
4356
+ const header = csvParts[0].trim().split(WS_REGEX);
4500
4357
  ResultFormatter.unknown(results, header[0], " ");
4501
4358
  ResultFormatter.unknown(results, header[1], " ");
4502
4359
  ResultFormatter.position(
@@ -4519,6 +4376,9 @@ var Label_80 = class extends DecoderPlugin {
4519
4376
  };
4520
4377
 
4521
4378
  // lib/plugins/Label_83.ts
4379
+ var WS_REGEX2 = /\s+/;
4380
+ var ALL_WS_REGEX = /\s/g;
4381
+ var ALL_DOTS_REGEX = /\./g;
4522
4382
  var Label_83 = class extends DecoderPlugin {
4523
4383
  name = "label-83";
4524
4384
  qualifiers() {
@@ -4533,8 +4393,8 @@ var Label_83 = class extends DecoderPlugin {
4533
4393
  decodeResult.formatted.description = "Airline Defined";
4534
4394
  decodeResult.decoded = true;
4535
4395
  const text = message.text;
4536
- if (text.substring(0, 10) === "4DH3 ETAT2") {
4537
- const fields = text.split(/\s+/);
4396
+ if (text.startsWith("4DH3 ETAT2")) {
4397
+ const fields = text.split(WS_REGEX2);
4538
4398
  if (fields[2].length > 5) {
4539
4399
  decodeResult.raw.day = fields[2].substring(5);
4540
4400
  }
@@ -4542,15 +4402,15 @@ var Label_83 = class extends DecoderPlugin {
4542
4402
  const subfields = fields[3].split("/");
4543
4403
  ResultFormatter.departureAirport(decodeResult, subfields[0]);
4544
4404
  ResultFormatter.arrivalAirport(decodeResult, subfields[1]);
4545
- ResultFormatter.tail(decodeResult, fields[4].replace(/\./g, ""));
4405
+ ResultFormatter.tail(decodeResult, fields[4].replace(ALL_DOTS_REGEX, ""));
4546
4406
  ResultFormatter.eta(
4547
4407
  decodeResult,
4548
4408
  DateTimeUtils.convertHHMMSSToTod(fields[6] + "00")
4549
4409
  );
4550
- } else if (text.substring(0, 5) === "001PR") {
4410
+ } else if (text.startsWith("001PR")) {
4551
4411
  decodeResult.raw.day = text.substring(5, 7);
4552
4412
  const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(
4553
- text.substring(13, 28).replace(/\./g, "")
4413
+ text.substring(13, 28).replace(ALL_DOTS_REGEX, "")
4554
4414
  );
4555
4415
  if (position) {
4556
4416
  ResultFormatter.position(decodeResult, position);
@@ -4558,15 +4418,15 @@ var Label_83 = class extends DecoderPlugin {
4558
4418
  ResultFormatter.altitude(decodeResult, Number(text.substring(28, 33)));
4559
4419
  ResultFormatter.unknown(decodeResult, text.substring(33));
4560
4420
  } else {
4561
- const fields = text.replace(/\s/g, "").split(",");
4421
+ const fields = text.replace(ALL_WS_REGEX, "").split(",");
4562
4422
  if (fields.length === 9) {
4563
4423
  ResultFormatter.departureAirport(decodeResult, fields[0]);
4564
4424
  ResultFormatter.arrivalAirport(decodeResult, fields[1]);
4565
4425
  decodeResult.raw.day = fields[2].substring(0, 2);
4566
4426
  decodeResult.raw.time = fields[2].substring(2);
4567
4427
  ResultFormatter.position(decodeResult, {
4568
- latitude: Number(fields[3].replace(/\s/g, "")),
4569
- longitude: Number(fields[4].replace(/\s/g, ""))
4428
+ latitude: Number(fields[3]),
4429
+ longitude: Number(fields[4])
4570
4430
  });
4571
4431
  ResultFormatter.altitude(decodeResult, Number(fields[5]));
4572
4432
  ResultFormatter.groundspeed(decodeResult, Number(fields[6]));
@@ -4630,13 +4490,15 @@ var Label_B6_Forwardslash = class extends DecoderPlugin {
4630
4490
  };
4631
4491
  }
4632
4492
  decode(message, options = {}) {
4633
- const decodeResult = this.defaultResult();
4634
- decodeResult.decoder.name = this.name;
4635
- decodeResult.formatted.description = "CPDLC Message";
4636
- decodeResult.message = message;
4637
- if (options.debug) {
4638
- console.log("CPDLC: " + message);
4493
+ const decodeResult = this.initResult(message, "CPDLC Message");
4494
+ const body = message.text.substring(1);
4495
+ if (body.length > 0) {
4496
+ ResultFormatter.text(decodeResult, body);
4497
+ this.setDecodeLevel(decodeResult, true, "partial");
4498
+ } else {
4499
+ this.setDecodeLevel(decodeResult, false);
4639
4500
  }
4501
+ this.debug(options, "CPDLC body:", body);
4640
4502
  return decodeResult;
4641
4503
  }
4642
4504
  };
@@ -4907,10 +4769,7 @@ var Label_H1_FLR = class extends DecoderPlugin {
4907
4769
  };
4908
4770
  }
4909
4771
  decode(message, options = {}) {
4910
- let decodeResult = this.defaultResult();
4911
- decodeResult.decoder.name = this.name;
4912
- decodeResult.formatted.description = "Fault Log Report";
4913
- decodeResult.message = message;
4772
+ const decodeResult = this.initResult(message, "Fault Log Report");
4914
4773
  const parts = message.text.split("/FR");
4915
4774
  if (parts.length > 1) {
4916
4775
  const fields = parts[0].split("/");
@@ -4934,15 +4793,9 @@ var Label_H1_FLR = class extends DecoderPlugin {
4934
4793
  label: "Fault Report",
4935
4794
  value: decodeResult.raw.fault_message
4936
4795
  });
4937
- decodeResult.decoded = true;
4938
- decodeResult.decoder.decodeLevel = "partial";
4796
+ this.setDecodeLevel(decodeResult, true, "partial");
4939
4797
  } else {
4940
- if (options.debug) {
4941
- console.log(`Decoder: Unknown H1 message: ${message.text}`);
4942
- }
4943
- ResultFormatter.unknown(decodeResult, message.text);
4944
- decodeResult.decoded = false;
4945
- decodeResult.decoder.decodeLevel = "none";
4798
+ return this.failUnknown(decodeResult, message.text, options);
4946
4799
  }
4947
4800
  return decodeResult;
4948
4801
  }
@@ -4957,30 +4810,21 @@ var Label_H1_M_POS = class extends DecoderPlugin {
4957
4810
  };
4958
4811
  }
4959
4812
  decode(message, options = {}) {
4960
- let decodeResult = this.defaultResult();
4961
- decodeResult.decoder.name = this.name;
4962
- decodeResult.formatted.description = "M-Series Periodic Position Report";
4963
- decodeResult.message = message;
4813
+ const decodeResult = this.initResult(
4814
+ message,
4815
+ "M-Series Periodic Position Report"
4816
+ );
4964
4817
  const headerRegex = /^M(\d{2})A([A-Z]{2})(\d{4})/;
4965
4818
  const headerMatch = message.text.match(headerRegex);
4966
4819
  if (!headerMatch) {
4967
- if (options.debug) {
4968
- console.log(`Decoder: Unknown H1 M-POS message: ${message.text}`);
4969
- }
4970
- ResultFormatter.unknown(decodeResult, message.text);
4971
- decodeResult.decoded = false;
4972
- decodeResult.decoder.decodeLevel = "none";
4973
- return decodeResult;
4820
+ return this.failUnknown(decodeResult, message.text, options);
4974
4821
  }
4975
4822
  const airline = headerMatch[2];
4976
4823
  const flightNum = headerMatch[3];
4977
4824
  const afterHeader = message.text.substring(headerMatch[0].length);
4978
4825
  const fields = afterHeader.split(",");
4979
4826
  if (fields.length < 7) {
4980
- ResultFormatter.unknown(decodeResult, message.text);
4981
- decodeResult.decoded = false;
4982
- decodeResult.decoder.decodeLevel = "none";
4983
- return decodeResult;
4827
+ return this.failUnknown(decodeResult, message.text, options);
4984
4828
  }
4985
4829
  ResultFormatter.flightNumber(decodeResult, `${airline}${flightNum}`);
4986
4830
  ResultFormatter.departureAirport(decodeResult, fields[0]);
@@ -5004,15 +4848,48 @@ var Label_H1_M_POS = class extends DecoderPlugin {
5004
4848
  if (fields.length > 7) {
5005
4849
  ResultFormatter.unknownArr(decodeResult, fields.slice(7));
5006
4850
  }
5007
- decodeResult.decoded = true;
5008
- decodeResult.decoder.decodeLevel = fields.length > 7 ? "partial" : "full";
4851
+ this.setDecodeLevel(
4852
+ decodeResult,
4853
+ true,
4854
+ fields.length > 7 ? "partial" : "full"
4855
+ );
5009
4856
  return decodeResult;
5010
4857
  }
5011
4858
  };
5012
4859
 
4860
+ // lib/utils/compression.ts
4861
+ import * as pako from "pako";
4862
+ function inflateData(data, raw) {
4863
+ const chunks = [];
4864
+ const inflator = new pako.Inflate({ windowBits: raw ? -15 : 15 });
4865
+ inflator.onData = (chunk) => {
4866
+ chunks.push(chunk);
4867
+ };
4868
+ inflator.push(data, 2);
4869
+ if (chunks.length === 0) return void 0;
4870
+ if (chunks.length === 1) return chunks[0];
4871
+ const totalLen = chunks.reduce((sum, c) => sum + c.length, 0);
4872
+ const result = new Uint8Array(totalLen);
4873
+ let offset = 0;
4874
+ for (const chunk of chunks) {
4875
+ result.set(chunk, offset);
4876
+ offset += chunk.length;
4877
+ }
4878
+ return result;
4879
+ }
4880
+ function base64ToUint8Array(base64) {
4881
+ const cleaned = base64.replace(/-/g, "+").replace(/_/g, "/").replace(/[^A-Za-z0-9+/]/g, "");
4882
+ const padded = cleaned + "=".repeat((4 - cleaned.length % 4) % 4);
4883
+ const binary = atob(padded);
4884
+ const bytes = new Uint8Array(binary.length);
4885
+ for (let i = 0; i < binary.length; i++) {
4886
+ bytes[i] = binary.charCodeAt(i);
4887
+ }
4888
+ return bytes;
4889
+ }
4890
+
5013
4891
  // lib/plugins/Label_H1_OHMA.ts
5014
- import * as zlib from "minizlib";
5015
- import { Buffer as Buffer2 } from "buffer";
4892
+ var textDecoder = new TextDecoder();
5016
4893
  var Label_H1_OHMA = class extends DecoderPlugin {
5017
4894
  name = "label-h1-ohma";
5018
4895
  qualifiers() {
@@ -5028,12 +4905,12 @@ var Label_H1_OHMA = class extends DecoderPlugin {
5028
4905
  decodeResult.message = message;
5029
4906
  const data = message.text.split("OHMA")[1];
5030
4907
  try {
5031
- const compressedBuffer = Buffer2.from(data, "base64");
5032
- const decompress = new zlib.Inflate({});
5033
- decompress.write(compressedBuffer);
5034
- decompress.flush(zlib.constants.Z_SYNC_FLUSH);
5035
- const result = decompress.read();
5036
- const jsonText = result?.toString() || "";
4908
+ const compressedBuffer = base64ToUint8Array(data);
4909
+ const result = inflateData(compressedBuffer, false);
4910
+ if (!result || result.length === 0) {
4911
+ throw new Error("Decompression produced no output");
4912
+ }
4913
+ const jsonText = textDecoder.decode(result);
5037
4914
  let formattedMsg;
5038
4915
  let jsonMessage;
5039
4916
  try {
@@ -5363,10 +5240,7 @@ var Label_H1_WRN = class extends DecoderPlugin {
5363
5240
  };
5364
5241
  }
5365
5242
  decode(message, options = {}) {
5366
- let decodeResult = this.defaultResult();
5367
- decodeResult.decoder.name = this.name;
5368
- decodeResult.formatted.description = "Warning Message";
5369
- decodeResult.message = message;
5243
+ const decodeResult = this.initResult(message, "Warning Message");
5370
5244
  const parts = message.text.split("/WN");
5371
5245
  if (parts.length > 1) {
5372
5246
  const fields = parts[0].split("/");
@@ -5387,15 +5261,9 @@ var Label_H1_WRN = class extends DecoderPlugin {
5387
5261
  label: "Warning Message",
5388
5262
  value: decodeResult.raw.warning_message
5389
5263
  });
5390
- decodeResult.decoded = true;
5391
- decodeResult.decoder.decodeLevel = "partial";
5264
+ this.setDecodeLevel(decodeResult, true, "partial");
5392
5265
  } else {
5393
- if (options.debug) {
5394
- console.log(`Decoder: Unknown H1 message: ${message.text}`);
5395
- }
5396
- ResultFormatter.unknown(decodeResult, message.text);
5397
- decodeResult.decoded = false;
5398
- decodeResult.decoder.decodeLevel = "none";
5266
+ return this.failUnknown(decodeResult, message.text, options);
5399
5267
  }
5400
5268
  return decodeResult;
5401
5269
  }
@@ -5447,10 +5315,47 @@ var Label_HX = class extends DecoderPlugin {
5447
5315
  }
5448
5316
  };
5449
5317
 
5318
+ // lib/utils/ascii85.ts
5319
+ function ascii85Decode(input) {
5320
+ let str = input;
5321
+ if (str.startsWith("<~")) str = str.slice(2);
5322
+ if (str.endsWith("~>")) str = str.slice(0, -2);
5323
+ str = str.replace(/\s/g, "");
5324
+ if (str.length === 0) return new Uint8Array(0);
5325
+ const output = [];
5326
+ let i = 0;
5327
+ while (i < str.length) {
5328
+ if (str[i] === "z") {
5329
+ output.push(0, 0, 0, 0);
5330
+ i++;
5331
+ continue;
5332
+ }
5333
+ const remaining = str.length - i;
5334
+ const chunkLen = Math.min(5, remaining);
5335
+ if (chunkLen === 1) break;
5336
+ let padded = str.slice(i, i + chunkLen);
5337
+ while (padded.length < 5) padded += "u";
5338
+ let value = 0;
5339
+ for (let j = 0; j < 5; j++) {
5340
+ const digit = padded.charCodeAt(j) - 33;
5341
+ if (digit < 0 || digit > 84) return null;
5342
+ value = value * 85 + digit;
5343
+ }
5344
+ if (chunkLen === 5 && value > 4294967295) return null;
5345
+ const v = value >>> 0;
5346
+ const numBytes = chunkLen === 5 ? 4 : chunkLen - 1;
5347
+ if (numBytes >= 1) output.push(v >>> 24 & 255);
5348
+ if (numBytes >= 2) output.push(v >>> 16 & 255);
5349
+ if (numBytes >= 3) output.push(v >>> 8 & 255);
5350
+ if (numBytes >= 4) output.push(v & 255);
5351
+ i += chunkLen;
5352
+ }
5353
+ return new Uint8Array(output);
5354
+ }
5355
+
5450
5356
  // lib/utils/miam.ts
5451
- import * as Base85 from "base85";
5452
- import * as zlib2 from "minizlib";
5453
- import { Buffer as Buffer3 } from "buffer";
5357
+ var textDecoder2 = new TextDecoder();
5358
+ var textEncoder = new TextEncoder();
5454
5359
  var MIAMVersion = /* @__PURE__ */ ((MIAMVersion2) => {
5455
5360
  MIAMVersion2[MIAMVersion2["V1"] = 1] = "V1";
5456
5361
  MIAMVersion2[MIAMVersion2["V2"] = 2] = "V2";
@@ -5537,7 +5442,7 @@ var MIAMCoreUtils = class {
5537
5442
  error: "Empty MIAM message header"
5538
5443
  };
5539
5444
  }
5540
- let hdr = Base85.decode("<~" + rawHdr + "~>", "ascii85");
5445
+ let hdr = ascii85Decode("<~" + rawHdr + "~>");
5541
5446
  if (!hdr || hdr.length < hpad) {
5542
5447
  return {
5543
5448
  decoded: false,
@@ -5549,17 +5454,24 @@ var MIAMCoreUtils = class {
5549
5454
  if (rawBody.length > 0) {
5550
5455
  if ("0123".indexOf(bpad) >= 0) {
5551
5456
  const bpadValue = parseInt(bpad);
5552
- body = Base85.decode("<~" + rawBody + "~>", "ascii85") || void 0;
5553
- if (body && body.length >= bpadValue) {
5457
+ const decoded = ascii85Decode("<~" + rawBody + "~>");
5458
+ if (decoded === null) {
5459
+ return {
5460
+ decoded: false,
5461
+ error: "Ascii85 decode failed for MIAM message body"
5462
+ };
5463
+ }
5464
+ body = decoded;
5465
+ if (body.length >= bpadValue) {
5554
5466
  body = body.subarray(0, body.length - bpadValue);
5555
5467
  }
5556
5468
  } else if (bpad === "-") {
5557
- body = Buffer3.from(rawBody);
5469
+ body = textEncoder.encode(rawBody);
5558
5470
  }
5559
5471
  }
5560
5472
  hdr = hdr.subarray(0, hdr.length - hpad);
5561
- const version = hdr.readUInt8(0) & 15;
5562
- const pduType = hdr.readUInt8(0) >> 4 & 15;
5473
+ const version = hdr[0] & 15;
5474
+ const pduType = hdr[0] >> 4 & 15;
5563
5475
  if (isMIAMVersion(version) && isMIAMCorePdu(pduType)) {
5564
5476
  const versionPduHandler = this.VersionPduHandlerTable[version][pduType];
5565
5477
  return versionPduHandler(hdr, body);
@@ -5856,7 +5768,7 @@ var MIAMCoreUtils = class {
5856
5768
  ];
5857
5769
  let crc = (seed || 0) & 65535;
5858
5770
  for (let i = 0; i < buf.length; i++) {
5859
- crc = (crc << 8 >>> 0 ^ crctable[(crc >>> 8 ^ buf.readUInt8(i)) >>> 0 & 255]) >>> 0;
5771
+ crc = (crc << 8 >>> 0 ^ crctable[(crc >>> 8 ^ buf[i]) >>> 0 & 255]) >>> 0;
5860
5772
  }
5861
5773
  return crc & 65535;
5862
5774
  }
@@ -6121,7 +6033,7 @@ var MIAMCoreUtils = class {
6121
6033
  ];
6122
6034
  let crc = seed || 0;
6123
6035
  for (let i = 0; i < buf.length; i++) {
6124
- crc = (crc << 8 >>> 0 ^ crctable[(crc >>> 24 ^ buf.readUInt8(i)) >>> 0]) >>> 0;
6036
+ crc = (crc << 8 >>> 0 ^ crctable[(crc >>> 24 ^ buf[i]) >>> 0]) >>> 0;
6125
6037
  }
6126
6038
  return crc;
6127
6039
  }
@@ -6158,7 +6070,7 @@ var MIAMCoreUtils = class {
6158
6070
  let msgNum = 0;
6159
6071
  let ackOptions = 0;
6160
6072
  if (version === 1 /* V1 */) {
6161
- pduSize = hdr.readUInt8(1) << 16 | hdr.readUInt8(2) << 8 | hdr.readUInt8(3);
6073
+ pduSize = hdr[1] << 16 | hdr[2] << 8 | hdr[3];
6162
6074
  const msgSize = hdr.length + (body === void 0 ? 0 : body.length);
6163
6075
  if (pduSize > msgSize) {
6164
6076
  pduIsComplete = false;
@@ -6167,17 +6079,17 @@ var MIAMCoreUtils = class {
6167
6079
  );
6168
6080
  }
6169
6081
  hdr = hdr.subarray(4);
6170
- tail = hdr.subarray(0, 7).toString("ascii");
6082
+ tail = textDecoder2.decode(hdr.subarray(0, 7));
6171
6083
  hdr = hdr.subarray(7);
6172
6084
  } else if (version === 2 /* V2 */) {
6173
6085
  hdr = hdr.subarray(1);
6174
6086
  }
6175
- msgNum = hdr.readUInt8(0) >> 1 & 127;
6176
- ackOptions = hdr.readUInt8(0) & 1;
6087
+ msgNum = hdr[0] >> 1 & 127;
6088
+ ackOptions = hdr[0] & 1;
6177
6089
  hdr = hdr.subarray(1);
6178
- pduCompression = (hdr.readUInt8(0) << 2 | hdr.readUInt8(1) >> 6 & 3) & 7;
6179
- pduEncoding = hdr.readUInt8(1) >> 4 & 3;
6180
- pduAppType = hdr.readUInt8(1) & 15;
6090
+ pduCompression = (hdr[0] << 2 | hdr[1] >> 6 & 3) & 7;
6091
+ pduEncoding = hdr[1] >> 4 & 3;
6092
+ pduAppType = hdr[1] & 15;
6181
6093
  hdr = hdr.subarray(2);
6182
6094
  let appIdLen;
6183
6095
  if (isMIAMCoreApp(pduAppType)) {
@@ -6203,12 +6115,12 @@ var MIAMCoreUtils = class {
6203
6115
  error: "Header too short for v" + version + " appType: " + pduAppType
6204
6116
  };
6205
6117
  }
6206
- pduAppId = hdr.subarray(0, appIdLen).toString("ascii");
6118
+ pduAppId = textDecoder2.decode(hdr.subarray(0, appIdLen));
6207
6119
  hdr = hdr.subarray(appIdLen);
6208
6120
  if (crcLen === 4) {
6209
- pduCrc = hdr.readUInt8(0) << 24 | hdr.readUInt8(1) << 16 | hdr.readUInt8(2) << 8 | hdr.readUInt8(3);
6121
+ pduCrc = hdr[0] << 24 | hdr[1] << 16 | hdr[2] << 8 | hdr[3];
6210
6122
  } else if (crcLen === 2) {
6211
- pduCrc = hdr.readUInt8(0) << 8 | hdr.readUInt8(1);
6123
+ pduCrc = hdr[0] << 8 | hdr[1];
6212
6124
  }
6213
6125
  hdr = hdr.subarray(crcLen);
6214
6126
  if (body !== void 0 && body.length > 0) {
@@ -6216,10 +6128,12 @@ var MIAMCoreUtils = class {
6216
6128
  pduCompression
6217
6129
  ) >= 0) {
6218
6130
  try {
6219
- const decompress = new zlib2.InflateRaw({});
6220
- decompress.write(body);
6221
- decompress.flush(zlib2.constants.Z_SYNC_FLUSH);
6222
- pduData = decompress.read();
6131
+ const inflated = inflateData(body, true);
6132
+ if (inflated === void 0) {
6133
+ pduErrors.push("Inflation produced no output for body");
6134
+ } else {
6135
+ pduData = inflated;
6136
+ }
6223
6137
  } catch (e) {
6224
6138
  pduErrors.push("Inflation failed for body: " + e);
6225
6139
  }
@@ -6277,12 +6191,12 @@ var MIAMCoreUtils = class {
6277
6191
  label,
6278
6192
  ...sublabel ? { sublabel } : {},
6279
6193
  ...mfi ? { mfi } : {},
6280
- ...pduData ? { text: pduData.toString("ascii") } : {}
6194
+ ...pduData ? { text: textDecoder2.decode(pduData) } : {}
6281
6195
  };
6282
6196
  } else {
6283
6197
  pdu.non_acars = {
6284
6198
  appId: pduAppId,
6285
- ...pduData ? { text: pduData.toString("ascii") } : {}
6199
+ ...pduData ? { text: textDecoder2.decode(pduData) } : {}
6286
6200
  };
6287
6201
  }
6288
6202
  return {
@@ -6403,12 +6317,11 @@ var Label_SQ = class extends DecoderPlugin {
6403
6317
  };
6404
6318
  }
6405
6319
  decode(message, options = {}) {
6406
- const decodeResult = this.defaultResult();
6407
- decodeResult.decoder.name = this.name;
6320
+ const decodeResult = this.initResult(message, "Ground Station Squitter");
6408
6321
  decodeResult.raw.preamble = message.text.substring(0, 4);
6409
- decodeResult.raw.version = message.text.substring(1, 2);
6322
+ decodeResult.raw.version = Number(message.text.substring(1, 2));
6410
6323
  decodeResult.raw.network = message.text.substring(3, 4);
6411
- if (decodeResult.raw.version === "2") {
6324
+ if (decodeResult.raw.version === 2) {
6412
6325
  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+)\/.*/;
6413
6326
  const result = message.text.match(regex);
6414
6327
  if (result?.groups && result.length >= 8) {
@@ -6424,7 +6337,6 @@ var Label_SQ = class extends DecoderPlugin {
6424
6337
  decodeResult.raw.vdlFrequency = Number(result.groups.vfreq) / 1e3;
6425
6338
  }
6426
6339
  }
6427
- decodeResult.formatted.description = "Ground Station Squitter";
6428
6340
  var formattedNetwork = "Unknown";
6429
6341
  if (decodeResult.raw.network == "A") {
6430
6342
  formattedNetwork = "ARINC";
@@ -6442,7 +6354,7 @@ var Label_SQ = class extends DecoderPlugin {
6442
6354
  type: "version",
6443
6355
  code: "VER",
6444
6356
  label: "Version",
6445
- value: decodeResult.raw.version
6357
+ value: String(decodeResult.raw.version)
6446
6358
  }
6447
6359
  ];
6448
6360
  if (decodeResult.raw.groundStation) {
@@ -6495,8 +6407,7 @@ var Label_SQ = class extends DecoderPlugin {
6495
6407
  value: `${decodeResult.raw.vdlFrequency} MHz`
6496
6408
  });
6497
6409
  }
6498
- decodeResult.decoded = true;
6499
- decodeResult.decoder.decodeLevel = "full";
6410
+ this.setDecodeLevel(decodeResult, true, "full");
6500
6411
  return decodeResult;
6501
6412
  }
6502
6413
  };
@@ -6648,103 +6559,130 @@ var Label_QQ = class extends DecoderPlugin {
6648
6559
  };
6649
6560
 
6650
6561
  // lib/MessageDecoder.ts
6562
+ var pluginClasses = [
6563
+ CBand,
6564
+ Arinc702,
6565
+ Label_ColonComma,
6566
+ Label_5Z_Slash,
6567
+ Label_10_LDR,
6568
+ Label_10_POS,
6569
+ Label_10_Slash,
6570
+ Label_12_N_Space,
6571
+ Label_12_POS,
6572
+ Label_13Through18_Slash,
6573
+ Label_15,
6574
+ Label_15_FST,
6575
+ Label_16_Honeywell,
6576
+ Label_16_N_Space,
6577
+ Label_16_POSA1,
6578
+ Label_16_TOD,
6579
+ Label_1L_3Line,
6580
+ Label_1L_070,
6581
+ Label_1L_660,
6582
+ Label_1L_Slash,
6583
+ Label_20_POS,
6584
+ Label_21_POS,
6585
+ Label_22_OFF,
6586
+ Label_22_POS,
6587
+ Label_24_Slash,
6588
+ Label_2P_FM3,
6589
+ Label_2P_FM4,
6590
+ Label_2P_FM5,
6591
+ Label_30_Slash_EA,
6592
+ Label_44_ETA,
6593
+ Label_44_IN,
6594
+ Label_44_OFF,
6595
+ Label_44_ON,
6596
+ Label_44_POS,
6597
+ Label_44_Slash,
6598
+ Label_4A,
6599
+ Label_4A_01,
6600
+ Label_4A_DIS,
6601
+ Label_4A_DOOR,
6602
+ Label_4A_Slash_01,
6603
+ Label_4N,
6604
+ Label_4T_AGFSR,
6605
+ Label_4T_ETA,
6606
+ Label_B6_Forwardslash,
6607
+ Label_H2_02E,
6608
+ Label_H1_ATIS,
6609
+ Label_H1_EZF,
6610
+ Label_H1_FLR,
6611
+ Label_H1_M_POS,
6612
+ Label_H1_OHMA,
6613
+ Label_H1_OFP,
6614
+ Label_H1_Paren,
6615
+ Label_H1_WRN,
6616
+ Label_H1_StarPOS,
6617
+ Label_HX,
6618
+ Label_58,
6619
+ Label_80,
6620
+ Label_83,
6621
+ Label_8E,
6622
+ Label_1M_Slash,
6623
+ Label_MA,
6624
+ Label_SQ,
6625
+ Label_QP,
6626
+ Label_QQ,
6627
+ Label_QR,
6628
+ Label_QS
6629
+ ];
6651
6630
  var MessageDecoder = class {
6652
6631
  name;
6653
6632
  plugins;
6654
6633
  debug;
6634
+ /** Maps a label string to the candidate entries (wildcard + label-specific) in registration order. */
6635
+ candidatesByLabel = /* @__PURE__ */ new Map();
6636
+ /** Wildcard entries (plugins that register the '*' label). */
6637
+ wildcardEntries = [];
6638
+ /** Membership set for wildcard entries to dedupe when a plugin also registers a specific label. */
6639
+ wildcardSet = /* @__PURE__ */ new Set();
6655
6640
  constructor() {
6656
6641
  this.name = "acars-decoder-typescript";
6657
6642
  this.plugins = [];
6658
6643
  this.debug = false;
6659
- this.registerPlugin(new CBand(this));
6660
- this.registerPlugin(new Arinc702(this));
6661
- this.registerPlugin(new Label_ColonComma(this));
6662
- this.registerPlugin(new Label_5Z_Slash(this));
6663
- this.registerPlugin(new Label_10_LDR(this));
6664
- this.registerPlugin(new Label_10_POS(this));
6665
- this.registerPlugin(new Label_10_Slash(this));
6666
- this.registerPlugin(new Label_12_N_Space(this));
6667
- this.registerPlugin(new Label_12_POS(this));
6668
- this.registerPlugin(new Label_13Through18_Slash(this));
6669
- this.registerPlugin(new Label_15(this));
6670
- this.registerPlugin(new Label_15_FST(this));
6671
- this.registerPlugin(new Label_16_Honeywell(this));
6672
- this.registerPlugin(new Label_16_N_Space(this));
6673
- this.registerPlugin(new Label_16_POSA1(this));
6674
- this.registerPlugin(new Label_16_TOD(this));
6675
- this.registerPlugin(new Label_1L_3Line(this));
6676
- this.registerPlugin(new Label_1L_070(this));
6677
- this.registerPlugin(new Label_1L_660(this));
6678
- this.registerPlugin(new Label_1L_Slash(this));
6679
- this.registerPlugin(new Label_20_POS(this));
6680
- this.registerPlugin(new Label_21_POS(this));
6681
- this.registerPlugin(new Label_22_OFF(this));
6682
- this.registerPlugin(new Label_22_POS(this));
6683
- this.registerPlugin(new Label_24_Slash(this));
6684
- this.registerPlugin(new Label_2P_FM3(this));
6685
- this.registerPlugin(new Label_2P_FM4(this));
6686
- this.registerPlugin(new Label_2P_FM5(this));
6687
- this.registerPlugin(new Label_30_Slash_EA(this));
6688
- this.registerPlugin(new Label_44_ETA(this));
6689
- this.registerPlugin(new Label_44_IN(this));
6690
- this.registerPlugin(new Label_44_OFF(this));
6691
- this.registerPlugin(new Label_44_ON(this));
6692
- this.registerPlugin(new Label_44_POS(this));
6693
- this.registerPlugin(new Label_44_Slash(this));
6694
- this.registerPlugin(new Label_4A(this));
6695
- this.registerPlugin(new Label_4A_01(this));
6696
- this.registerPlugin(new Label_4A_DIS(this));
6697
- this.registerPlugin(new Label_4A_DOOR(this));
6698
- this.registerPlugin(new Label_4A_Slash_01(this));
6699
- this.registerPlugin(new Label_4N(this));
6700
- this.registerPlugin(new Label_4T_AGFSR(this));
6701
- this.registerPlugin(new Label_4T_ETA(this));
6702
- this.registerPlugin(new Label_B6_Forwardslash(this));
6703
- this.registerPlugin(new Label_H2_02E(this));
6704
- this.registerPlugin(new Label_H1_ATIS(this));
6705
- this.registerPlugin(new Label_H1_EZF(this));
6706
- this.registerPlugin(new Label_H1_FLR(this));
6707
- this.registerPlugin(new Label_H1_M_POS(this));
6708
- this.registerPlugin(new Label_H1_OHMA(this));
6709
- this.registerPlugin(new Label_H1_OFP(this));
6710
- this.registerPlugin(new Label_H1_Paren(this));
6711
- this.registerPlugin(new Label_H1_WRN(this));
6712
- this.registerPlugin(new Label_H1_StarPOS(this));
6713
- this.registerPlugin(new Label_HX(this));
6714
- this.registerPlugin(new Label_58(this));
6715
- this.registerPlugin(new Label_80(this));
6716
- this.registerPlugin(new Label_83(this));
6717
- this.registerPlugin(new Label_8E(this));
6718
- this.registerPlugin(new Label_1M_Slash(this));
6719
- this.registerPlugin(new Label_MA(this));
6720
- this.registerPlugin(new Label_SQ(this));
6721
- this.registerPlugin(new Label_QP(this));
6722
- this.registerPlugin(new Label_QQ(this));
6723
- this.registerPlugin(new Label_QR(this));
6724
- this.registerPlugin(new Label_QS(this));
6644
+ for (const PluginClass of pluginClasses) {
6645
+ this.registerPlugin(new PluginClass(this));
6646
+ }
6725
6647
  }
6726
6648
  registerPlugin(plugin) {
6727
6649
  this.plugins.push(plugin);
6650
+ const qualifiers = plugin.qualifiers();
6651
+ const entry = {
6652
+ plugin,
6653
+ preambles: qualifiers.preambles && qualifiers.preambles.length > 0 ? qualifiers.preambles : void 0
6654
+ };
6655
+ for (const label of qualifiers.labels) {
6656
+ if (label === "*") {
6657
+ if (!this.wildcardSet.has(plugin)) {
6658
+ this.wildcardEntries.push(entry);
6659
+ this.wildcardSet.add(plugin);
6660
+ const wildcardInsertIndex = this.wildcardEntries.length - 1;
6661
+ for (const bucket of this.candidatesByLabel.values()) {
6662
+ bucket.splice(wildcardInsertIndex, 0, entry);
6663
+ }
6664
+ }
6665
+ } else {
6666
+ let bucket = this.candidatesByLabel.get(label);
6667
+ if (!bucket) {
6668
+ bucket = this.wildcardEntries.slice();
6669
+ this.candidatesByLabel.set(label, bucket);
6670
+ }
6671
+ if (!this.wildcardSet.has(plugin)) {
6672
+ bucket.push(entry);
6673
+ }
6674
+ }
6675
+ }
6728
6676
  return true;
6729
6677
  }
6730
6678
  decode(message, options = {}) {
6731
- const usablePlugins = this.plugins.filter((plugin) => {
6732
- const qualifiers = plugin.qualifiers();
6733
- if (qualifiers.labels.includes(message.label) || qualifiers.labels.length === 1 && qualifiers.labels[0] === "*") {
6734
- if (qualifiers.preambles && qualifiers.preambles.length > 0) {
6735
- const matching = qualifiers.preambles.filter((preamble) => {
6736
- return message.text.substring(0, preamble.length) === preamble;
6737
- });
6738
- return matching.length >= 1;
6739
- } else {
6740
- return true;
6741
- }
6742
- }
6743
- return false;
6744
- });
6679
+ const text = message.text;
6680
+ const candidates = this.candidatesByLabel.get(message.label) ?? this.wildcardEntries;
6745
6681
  if (options.debug) {
6746
6682
  console.log("Usable plugins");
6747
- console.log(usablePlugins);
6683
+ console.log(
6684
+ candidates.filter((e) => this.matchesPreambles(text, e.preambles)).map((e) => e.plugin)
6685
+ );
6748
6686
  }
6749
6687
  let result = {
6750
6688
  decoded: false,
@@ -6756,7 +6694,7 @@ var MessageDecoder = class {
6756
6694
  },
6757
6695
  message,
6758
6696
  remaining: {
6759
- text: message.text
6697
+ text
6760
6698
  },
6761
6699
  raw: {},
6762
6700
  formatted: {
@@ -6764,10 +6702,14 @@ var MessageDecoder = class {
6764
6702
  items: []
6765
6703
  }
6766
6704
  };
6767
- for (let i = 0; i < usablePlugins.length; i++) {
6768
- const plugin = usablePlugins[i];
6769
- result = plugin.decode(message);
6770
- if (result.decoded) {
6705
+ for (let i = 0; i < candidates.length; i++) {
6706
+ const entry = candidates[i];
6707
+ if (!this.matchesPreambles(text, entry.preambles)) {
6708
+ continue;
6709
+ }
6710
+ const pluginResult = entry.plugin.decode(message, options);
6711
+ if (pluginResult.decoded) {
6712
+ result = pluginResult;
6771
6713
  break;
6772
6714
  }
6773
6715
  }
@@ -6777,6 +6719,17 @@ var MessageDecoder = class {
6777
6719
  }
6778
6720
  return result;
6779
6721
  }
6722
+ matchesPreambles(text, preambles) {
6723
+ if (!preambles) {
6724
+ return true;
6725
+ }
6726
+ for (let i = 0; i < preambles.length; i++) {
6727
+ if (text.startsWith(preambles[i])) {
6728
+ return true;
6729
+ }
6730
+ }
6731
+ return false;
6732
+ }
6780
6733
  };
6781
6734
  export {
6782
6735
  IcaoDecoder,