@airframes/acars-decoder 1.8.14 → 1.9.1

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
@@ -94,11 +94,11 @@ var CoordinateUtils = class _CoordinateUtils {
94
94
  * @returns An object with latitude and longitude properties
95
95
  */
96
96
  static decodeStringCoordinates(stringCoords) {
97
- const firstChar = stringCoords.substring(0, 1);
98
- let middleChar = stringCoords.substring(6, 7);
97
+ const firstChar = stringCoords.charAt(0);
98
+ let middleChar = stringCoords.charAt(6);
99
99
  let longitudeChars = stringCoords.substring(7, 13);
100
- if (middleChar == " ") {
101
- middleChar = stringCoords.substring(7, 8);
100
+ if (middleChar === " ") {
101
+ middleChar = stringCoords.charAt(7);
102
102
  longitudeChars = stringCoords.substring(8, 14);
103
103
  }
104
104
  if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
@@ -116,24 +116,26 @@ var CoordinateUtils = class _CoordinateUtils {
116
116
  * @returns An object with latitude and longitude properties
117
117
  */
118
118
  static decodeStringCoordinatesDecimalMinutes(stringCoords) {
119
- const firstChar = stringCoords.substring(0, 1);
120
- let middleChar = stringCoords.substring(6, 7);
119
+ const firstChar = stringCoords.charAt(0);
120
+ let middleChar = stringCoords.charAt(6);
121
121
  let longitudeChars = stringCoords.substring(7, 13);
122
- if (middleChar == " ") {
123
- middleChar = stringCoords.substring(7, 8);
122
+ if (middleChar === " ") {
123
+ middleChar = stringCoords.charAt(7);
124
124
  longitudeChars = stringCoords.substring(8, 14);
125
125
  }
126
- const latDeg = Math.trunc(Number(stringCoords.substring(1, 6)) / 1e3);
127
- const latMin = Number(stringCoords.substring(1, 6)) % 1e3 / 10;
128
- const lonDeg = Math.trunc(Number(longitudeChars) / 1e3);
129
- const lonMin = Number(longitudeChars) % 1e3 / 10;
130
- if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
131
- return {
132
- latitude: (latDeg + latMin / 60) * _CoordinateUtils.getDirection(firstChar),
133
- longitude: (lonDeg + lonMin / 60) * _CoordinateUtils.getDirection(middleChar)
134
- };
126
+ if (firstChar !== "N" && firstChar !== "S" || middleChar !== "W" && middleChar !== "E") {
127
+ return void 0;
135
128
  }
136
- 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
+ };
137
139
  }
138
140
  static coordinateString(coords) {
139
141
  const latDir = coords.latitude > 0 ? "N" : "S";
@@ -164,25 +166,13 @@ var DateTimeUtils = class {
164
166
  // Expects a six digit date string and a four digit UTC time string
165
167
  // (DDMMYY) (HHMM)
166
168
  static UTCDateTimeToString(dateString, timeString) {
167
- let utcDate = /* @__PURE__ */ new Date();
168
- utcDate.setUTCDate(+dateString.substr(0, 2));
169
- utcDate.setUTCMonth(+dateString.substr(2, 2));
170
- if (dateString.length === 6) {
171
- utcDate.setUTCFullYear(2e3 + +dateString.substr(4, 2));
172
- }
173
- if (timeString.length === 6) {
174
- utcDate.setUTCHours(
175
- +timeString.substr(0, 2),
176
- +timeString.substr(2, 2),
177
- +timeString.substr(4, 2)
178
- );
179
- } else {
180
- utcDate.setUTCHours(
181
- +timeString.substr(0, 2),
182
- +timeString.substr(2, 2),
183
- 0
184
- );
185
- }
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));
186
176
  return utcDate.toUTCString();
187
177
  }
188
178
  /**
@@ -527,7 +517,7 @@ var ResultFormatter = class {
527
517
  decodeResult.raw.fuel_remaining = value;
528
518
  decodeResult.formatted.items.push({
529
519
  type: "fuel_remaining",
530
- code: " FUEL_REM",
520
+ code: "FUEL_REM",
531
521
  label: "Fuel Remaining",
532
522
  value: decodeResult.raw.fuel_remaining.toString()
533
523
  });
@@ -586,7 +576,7 @@ var ResultFormatter = class {
586
576
  type: "message_checksum",
587
577
  code: "CHECKSUM",
588
578
  label: "Message Checksum",
589
- value: "0x" + ("0000" + decodeResult.raw.checksum.toString(16)).slice(-4)
579
+ value: "0x" + (decodeResult.raw.checksum >>> 0).toString(16).padStart(4, "0")
590
580
  });
591
581
  }
592
582
  static groundspeed(decodeResult, value) {
@@ -921,7 +911,7 @@ var ResultFormatter = class {
921
911
  type: "sequence",
922
912
  code: "SEQ",
923
913
  label: "Sequence Number",
924
- value: decodeResult.raw.sequence_number
914
+ value: decodeResult.raw.sequence_number.toString()
925
915
  });
926
916
  }
927
917
  static sequenceResponse(decodeResult, value) {
@@ -930,7 +920,7 @@ var ResultFormatter = class {
930
920
  type: "sequence",
931
921
  code: "SEQ_RESP",
932
922
  label: "Sequence Response",
933
- value: decodeResult.raw.sequence_response
923
+ value: decodeResult.raw.sequence_response.toString()
934
924
  });
935
925
  }
936
926
  static unknown(decodeResult, value, sep = ",") {
@@ -1036,6 +1026,7 @@ var DecoderPlugin = class {
1036
1026
  };
1037
1027
 
1038
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})/;
1039
1030
  var CBand = class extends DecoderPlugin {
1040
1031
  name = "c-band";
1041
1032
  qualifiers() {
@@ -1044,35 +1035,43 @@ var CBand = class extends DecoderPlugin {
1044
1035
  };
1045
1036
  }
1046
1037
  decode(message, options = {}) {
1047
- 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();
1048
1061
  decodeResult.decoder.name = this.name;
1049
1062
  decodeResult.message = message;
1050
- let cband = message.text.match(
1051
- /^(?<msgno>[A-Z]\d{2}[A-Z])(?<airline>[A-Z0-9]{2})(?<number>[0-9]{4})/
1052
- );
1053
- if (cband?.groups) {
1054
- const messageText = message.text.substring(10);
1055
- const decoded = this.decoder.decode(
1056
- {
1057
- label: message.label,
1058
- sublabel: message.sublabel,
1059
- text: messageText
1060
- },
1061
- options
1063
+ if (decoded.decoded) {
1064
+ ResultFormatter.flightNumber(
1065
+ decodeResult,
1066
+ cband.groups.airline + Number(cband.groups.number)
1062
1067
  );
1063
- if (decoded.decoded) {
1064
- ResultFormatter.flightNumber(
1065
- decodeResult,
1066
- cband.groups.airline + Number(cband.groups.number)
1067
- );
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;
1075
- }
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;
1076
1075
  }
1077
1076
  return decodeResult;
1078
1077
  }
@@ -1157,7 +1156,9 @@ var FlightPlanUtils = class _FlightPlanUtils {
1157
1156
  label: "Route Status",
1158
1157
  value: "Route Planned"
1159
1158
  });
1160
- decodeResult.raw.route_status = header;
1159
+ if (header.length > 2) {
1160
+ addRoute(decodeResult, header.substring(2));
1161
+ }
1161
1162
  } else if (header.startsWith("RI")) {
1162
1163
  decodeResult.raw.route_status = "RI";
1163
1164
  decodeResult.formatted.items.push({
@@ -1235,7 +1236,11 @@ function addCompanyRoute(decodeResult, value) {
1235
1236
  name = segments[0];
1236
1237
  } else {
1237
1238
  name = segments[0].slice(0, parens_idx);
1238
- runway = segments[0].slice(parens_idx + 1, segments[0].indexOf(")"));
1239
+ const close_paren_idx = segments[0].indexOf(")");
1240
+ runway = segments[0].slice(
1241
+ parens_idx + 1,
1242
+ close_paren_idx === -1 ? void 0 : close_paren_idx
1243
+ );
1239
1244
  }
1240
1245
  let waypoints;
1241
1246
  if (segments.length > 1) {
@@ -1255,6 +1260,11 @@ function addCompanyRoute(decodeResult, value) {
1255
1260
  }
1256
1261
 
1257
1262
  // lib/utils/arinc_702_helper.ts
1263
+ function asciiStringToBytes(data) {
1264
+ const bytes = new Uint8Array(data.length);
1265
+ for (let i = 0; i < data.length; i++) bytes[i] = data.charCodeAt(i) & 255;
1266
+ return bytes;
1267
+ }
1258
1268
  var Arinc702Helper = class _Arinc702Helper {
1259
1269
  /**
1260
1270
  * Decodes an ARINC 702 message
@@ -1773,7 +1783,7 @@ function processSummary(decodeResult, data) {
1773
1783
  }
1774
1784
  function crc16IbmSdlcRev(data) {
1775
1785
  let crc = 65535;
1776
- const bytes = Buffer.from(data, "ascii");
1786
+ const bytes = asciiStringToBytes(data);
1777
1787
  for (const byte of bytes) {
1778
1788
  crc ^= byte;
1779
1789
  for (let i = 0; i < 8; i++) {
@@ -1794,7 +1804,7 @@ function crc16IbmSdlcRev(data) {
1794
1804
  function crc16Genibus(data) {
1795
1805
  let crc = 65535;
1796
1806
  const polynomial = 4129;
1797
- const bytes = Buffer.from(data, "ascii");
1807
+ const bytes = asciiStringToBytes(data);
1798
1808
  for (const byte of bytes) {
1799
1809
  crc ^= byte << 8;
1800
1810
  for (let i = 0; i < 8; i++) {
@@ -1819,6 +1829,7 @@ function processMessageReference(decodeResult, data) {
1819
1829
  }
1820
1830
 
1821
1831
  // lib/plugins/ARINC_702.ts
1832
+ var NEWLINE_REGEX = /[\n\r]/g;
1822
1833
  var Arinc702 = class extends DecoderPlugin {
1823
1834
  name = "arinc-702";
1824
1835
  qualifiers() {
@@ -1830,7 +1841,7 @@ var Arinc702 = class extends DecoderPlugin {
1830
1841
  let decodeResult = this.defaultResult();
1831
1842
  decodeResult.decoder.name = this.name;
1832
1843
  decodeResult.message = message;
1833
- const msg = message.text.replace(/\n|\r/g, "");
1844
+ const msg = message.text.replace(NEWLINE_REGEX, "");
1834
1845
  let decoded = false;
1835
1846
  decoded = Arinc702Helper.decodeH1Message(decodeResult, msg);
1836
1847
  if (decoded) {
@@ -1897,6 +1908,12 @@ var Arinc702 = class extends DecoderPlugin {
1897
1908
  }
1898
1909
  };
1899
1910
 
1911
+ // lib/utils/acars_free_text.ts
1912
+ function formatAcarsFreeText(text) {
1913
+ if (!text) return "";
1914
+ return text.trim().replace(/\s+/g, " ");
1915
+ }
1916
+
1900
1917
  // lib/plugins/Label_5Z_Slash.ts
1901
1918
  var Label_5Z_Slash = class extends DecoderPlugin {
1902
1919
  name = "label-5z-slash";
@@ -1938,7 +1955,10 @@ var Label_5Z_Slash = class extends DecoderPlugin {
1938
1955
  decodeResult.formatted.description = "Airline Designated Downlink";
1939
1956
  const lines = message.text.split("\r\n");
1940
1957
  if (lines[0] === "/TXT") {
1941
- ResultFormatter.text(decodeResult, lines.slice(1).join("\r\n"));
1958
+ ResultFormatter.text(
1959
+ decodeResult,
1960
+ formatAcarsFreeText(lines.slice(1).join("\r\n"))
1961
+ );
1942
1962
  decodeResult.decoded = true;
1943
1963
  decodeResult.decoder.decodeLevel = "full";
1944
1964
  return decodeResult;
@@ -2480,6 +2500,111 @@ var Label_15_FST = class extends DecoderPlugin {
2480
2500
  }
2481
2501
  };
2482
2502
 
2503
+ // lib/plugins/Label_16_AUTPOS.ts
2504
+ var Label_16_AUTPOS = class extends DecoderPlugin {
2505
+ name = "label-16-autpos";
2506
+ qualifiers() {
2507
+ return {
2508
+ labels: ["16"],
2509
+ preambles: [""]
2510
+ };
2511
+ }
2512
+ decode(message) {
2513
+ let decodeResult = this.defaultResult();
2514
+ decodeResult.decoder.name = this.name;
2515
+ decodeResult.message = message;
2516
+ const regex = /^(\d{6})\/AUTPOS\/LLD (N|S)(\d{2})(\d{2})(\d{2}) (E|W)(\d{3})(\d{2})(\d{2})\s*\r?\n\/ALT (\d+)\/SAT ([*\-\d]{4})\r?\n\/WND ([*\d]{3})([\*\d]{3})\/TAT ([*\-\d]{4})\/TAS ([*\d]{3,4})\/CRZ ([*\d]{3,4})\r?\n\/FOB (\d{6})\r?\n\/DAT (\d{6})\/TIM (\d{6})/;
2517
+ const match = regex.exec(message.text);
2518
+ if (!match) {
2519
+ decodeResult.decoded = false;
2520
+ return decodeResult;
2521
+ }
2522
+ decodeResult.decoded = true;
2523
+ decodeResult.decoder.decodeLevel = "full";
2524
+ decodeResult.formatted.description = "Position Report";
2525
+ const [
2526
+ ,
2527
+ flight,
2528
+ latHem,
2529
+ latDeg,
2530
+ latMin,
2531
+ latSec,
2532
+ lonHem,
2533
+ lonDeg,
2534
+ lonMin,
2535
+ lonSec,
2536
+ altitude,
2537
+ sat,
2538
+ windDir,
2539
+ windSpd,
2540
+ tat,
2541
+ tas,
2542
+ crz,
2543
+ fob,
2544
+ dat,
2545
+ tim
2546
+ ] = match;
2547
+ ResultFormatter.day(decodeResult, parseInt(flight.slice(0, 2), 10));
2548
+ ResultFormatter.flightNumber(decodeResult, flight.slice(2));
2549
+ let latitude = CoordinateUtils.dmsToDecimalDegrees(
2550
+ parseInt(latDeg, 10),
2551
+ parseInt(latMin, 10),
2552
+ parseInt(latSec, 10)
2553
+ );
2554
+ if (latHem === "S") latitude = -latitude;
2555
+ let longitude = CoordinateUtils.dmsToDecimalDegrees(
2556
+ parseInt(lonDeg, 10),
2557
+ parseInt(lonMin, 10),
2558
+ parseInt(lonSec, 10)
2559
+ );
2560
+ if (lonHem === "W") longitude = -longitude;
2561
+ ResultFormatter.position(decodeResult, {
2562
+ latitude,
2563
+ longitude
2564
+ });
2565
+ const alt = parseInt(altitude, 10);
2566
+ ResultFormatter.altitude(decodeResult, alt);
2567
+ if (!windSpd.includes("*") && !windDir.includes("*")) {
2568
+ ResultFormatter.windData(decodeResult, [
2569
+ {
2570
+ waypoint: {
2571
+ name: "POSITION"
2572
+ },
2573
+ flightLevel: Math.round(alt / 100),
2574
+ windDirection: parseInt(windDir, 10),
2575
+ windSpeed: parseInt(windSpd, 10)
2576
+ }
2577
+ ]);
2578
+ }
2579
+ if (!tat.includes("*")) {
2580
+ ResultFormatter.totalAirTemp(decodeResult, tat);
2581
+ }
2582
+ if (!tas.includes("*")) {
2583
+ ResultFormatter.airspeed(decodeResult, parseInt(tas, 10));
2584
+ }
2585
+ if (!sat.includes("*")) {
2586
+ ResultFormatter.temperature(decodeResult, sat);
2587
+ }
2588
+ if (!crz.includes("*")) {
2589
+ ResultFormatter.mach(decodeResult, parseInt(crz, 10) / 1e3);
2590
+ }
2591
+ if (!fob.includes("*")) {
2592
+ ResultFormatter.currentFuel(decodeResult, parseInt(fob, 10));
2593
+ }
2594
+ if (!dat.includes("*") && !tim.includes("*")) {
2595
+ const yy = dat.slice(0, 2);
2596
+ const mm = dat.slice(2, 4);
2597
+ const dd = dat.slice(4, 6);
2598
+ const ddmmyy = `${dd}${mm}${yy}`;
2599
+ ResultFormatter.timestamp(
2600
+ decodeResult,
2601
+ DateTimeUtils.convertDateTimeToEpoch(tim, ddmmyy)
2602
+ );
2603
+ }
2604
+ return decodeResult;
2605
+ }
2606
+ };
2607
+
2483
2608
  // lib/plugins/Label_16_Honeywell.ts
2484
2609
  var Label_16_Honeywell = class extends DecoderPlugin {
2485
2610
  name = "label-16-honeywell";
@@ -3254,7 +3379,7 @@ var Label_2P_FM3 = class extends DecoderPlugin {
3254
3379
  const parts = message.text.split(",");
3255
3380
  if (parts.length === 7) {
3256
3381
  const header = parts[0].split("FM3 ");
3257
- if (header.length == 0) {
3382
+ if (header.length < 2) {
3258
3383
  ResultFormatter.unknown(decodeResult, message.text);
3259
3384
  decodeResult.decoded = false;
3260
3385
  decodeResult.decoder.decodeLevel = "none";
@@ -3325,7 +3450,7 @@ var Label_2P_FM4 = class extends DecoderPlugin {
3325
3450
  const parts = message.text.split(",");
3326
3451
  if (parts.length === 10) {
3327
3452
  const header = parts[0].split("FM4");
3328
- if (header.length == 0) {
3453
+ if (header.length < 2) {
3329
3454
  ResultFormatter.unknown(decodeResult, message.text);
3330
3455
  decodeResult.decoded = false;
3331
3456
  decodeResult.decoder.decodeLevel = "none";
@@ -3384,7 +3509,7 @@ var Label_2P_FM5 = class extends DecoderPlugin {
3384
3509
  const parts = message.text.split(",");
3385
3510
  if (parts.length === 12) {
3386
3511
  const header = parts[0].split("FM5 ");
3387
- if (header.length == 0) {
3512
+ if (header.length < 2) {
3388
3513
  ResultFormatter.unknown(decodeResult, message.text);
3389
3514
  decodeResult.decoded = false;
3390
3515
  decodeResult.decoder.decodeLevel = "none";
@@ -3807,7 +3932,8 @@ var Label_4A = class extends DecoderPlugin {
3807
3932
  ResultFormatter.arrivalAirport(decodeResult, fields[5]);
3808
3933
  ResultFormatter.unknownArr(decodeResult, fields.slice(8));
3809
3934
  } else if (fields.length === 6) {
3810
- if (fields[0].match(/^[NS]/)) {
3935
+ const f0 = fields[0];
3936
+ if (f0.length > 0 && (f0[0] === "N" || f0[0] === "S")) {
3811
3937
  ResultFormatter.position(
3812
3938
  decodeResult,
3813
3939
  CoordinateUtils.decodeStringCoordinates(fields[0].substring(0, 13))
@@ -4188,6 +4314,9 @@ var Label_4T_ETA = class extends DecoderPlugin {
4188
4314
  };
4189
4315
 
4190
4316
  // lib/plugins/Label_80.ts
4317
+ var POS_REGEX = /^(?<latd>[NS])(?<lat>.+)(?<lngd>[EW])(?<lng>.+)/;
4318
+ var WS_REGEX = /\s+/;
4319
+ var NEWLINE_REGEX2 = /\r?\n/;
4191
4320
  var Label_80 = class extends DecoderPlugin {
4192
4321
  name = "label-80";
4193
4322
  qualifiers() {
@@ -4201,7 +4330,7 @@ var Label_80 = class extends DecoderPlugin {
4201
4330
  message,
4202
4331
  "Airline Defined Position Report"
4203
4332
  );
4204
- const lines = message.text.split(/\r?\n/);
4333
+ const lines = message.text.split(NEWLINE_REGEX2);
4205
4334
  if (lines.length === 1 && lines[0].includes(",")) {
4206
4335
  this.parseCsvFormat(lines[0], decodeResult);
4207
4336
  } else {
@@ -4236,7 +4365,7 @@ var Label_80 = class extends DecoderPlugin {
4236
4365
  ResultFormatter.unknown(results, header, "/");
4237
4366
  return;
4238
4367
  }
4239
- const msgInfo = fields[0].split(/\s+/);
4368
+ const msgInfo = fields[0].split(WS_REGEX);
4240
4369
  if (msgInfo.length === 3) {
4241
4370
  ResultFormatter.unknownArr(results, msgInfo.slice(0, 2), " ");
4242
4371
  ResultFormatter.flightNumber(results, msgInfo[2]);
@@ -4244,14 +4373,14 @@ var Label_80 = class extends DecoderPlugin {
4244
4373
  ResultFormatter.unknown(results, header, "/");
4245
4374
  return;
4246
4375
  }
4247
- const otherInfo1 = fields[1].split(/\s+/);
4376
+ const otherInfo1 = fields[1].split(WS_REGEX);
4248
4377
  if (otherInfo1.length === 2) {
4249
4378
  ResultFormatter.day(results, parseInt(otherInfo1[0], 10));
4250
4379
  ResultFormatter.departureAirport(results, otherInfo1[1]);
4251
4380
  } else {
4252
4381
  ResultFormatter.unknownArr(results, otherInfo1, " ");
4253
4382
  }
4254
- const otherInfo2 = fields[2].split(/\s+/);
4383
+ const otherInfo2 = fields[2].split(WS_REGEX);
4255
4384
  if (otherInfo2.length === 2) {
4256
4385
  ResultFormatter.arrivalAirport(results, otherInfo2[0]);
4257
4386
  ResultFormatter.tail(results, otherInfo2[1].replace(".", ""));
@@ -4263,7 +4392,7 @@ var Label_80 = class extends DecoderPlugin {
4263
4392
  }
4264
4393
  }
4265
4394
  parseTags(part, results) {
4266
- const kvPair = part.split(/\s+/);
4395
+ const kvPair = part.split(WS_REGEX);
4267
4396
  if (kvPair.length < 2) {
4268
4397
  ResultFormatter.unknown(results, part, "/");
4269
4398
  return;
@@ -4271,9 +4400,8 @@ var Label_80 = class extends DecoderPlugin {
4271
4400
  const tag = kvPair[0];
4272
4401
  const val = kvPair.slice(1).join(" ");
4273
4402
  switch (tag) {
4274
- case "POS":
4275
- const posRegex = /^(?<latd>[NS])(?<lat>.+)(?<lngd>[EW])(?<lng>.+)/;
4276
- const posResult = val.match(posRegex);
4403
+ case "POS": {
4404
+ const posResult = POS_REGEX.exec(val);
4277
4405
  const lat = Number(posResult?.groups?.lat) * (posResult?.groups?.latd === "S" ? -1 : 1);
4278
4406
  const lon = Number(posResult?.groups?.lng) * (posResult?.groups?.lngd === "W" ? -1 : 1);
4279
4407
  const position = {
@@ -4282,6 +4410,7 @@ var Label_80 = class extends DecoderPlugin {
4282
4410
  };
4283
4411
  ResultFormatter.position(results, position);
4284
4412
  break;
4413
+ }
4285
4414
  case "ALT":
4286
4415
  ResultFormatter.altitude(results, parseInt(val.replace("+", ""), 10));
4287
4416
  break;
@@ -4314,10 +4443,11 @@ var Label_80 = class extends DecoderPlugin {
4314
4443
  DateTimeUtils.convertHHMMSSToTod(val)
4315
4444
  );
4316
4445
  break;
4317
- case "ETA":
4446
+ case "ETA": {
4318
4447
  const hhmm = val.split(".")[0].replace(":", "");
4319
4448
  ResultFormatter.eta(results, DateTimeUtils.convertHHMMSSToTod(hhmm));
4320
4449
  break;
4450
+ }
4321
4451
  case "HDG":
4322
4452
  ResultFormatter.heading(results, parseInt(val, 10));
4323
4453
  break;
@@ -4341,7 +4471,7 @@ var Label_80 = class extends DecoderPlugin {
4341
4471
  if (csvParts.length !== 9) {
4342
4472
  return;
4343
4473
  }
4344
- const header = csvParts[0].trim().split(/\s+/);
4474
+ const header = csvParts[0].trim().split(WS_REGEX);
4345
4475
  ResultFormatter.unknown(results, header[0], " ");
4346
4476
  ResultFormatter.unknown(results, header[1], " ");
4347
4477
  ResultFormatter.position(
@@ -4364,6 +4494,9 @@ var Label_80 = class extends DecoderPlugin {
4364
4494
  };
4365
4495
 
4366
4496
  // lib/plugins/Label_83.ts
4497
+ var WS_REGEX2 = /\s+/;
4498
+ var ALL_WS_REGEX = /\s/g;
4499
+ var ALL_DOTS_REGEX = /\./g;
4367
4500
  var Label_83 = class extends DecoderPlugin {
4368
4501
  name = "label-83";
4369
4502
  qualifiers() {
@@ -4378,8 +4511,8 @@ var Label_83 = class extends DecoderPlugin {
4378
4511
  decodeResult.formatted.description = "Airline Defined";
4379
4512
  decodeResult.decoded = true;
4380
4513
  const text = message.text;
4381
- if (text.substring(0, 10) === "4DH3 ETAT2") {
4382
- const fields = text.split(/\s+/);
4514
+ if (text.startsWith("4DH3 ETAT2")) {
4515
+ const fields = text.split(WS_REGEX2);
4383
4516
  if (fields[2].length > 5) {
4384
4517
  decodeResult.raw.day = fields[2].substring(5);
4385
4518
  }
@@ -4387,15 +4520,15 @@ var Label_83 = class extends DecoderPlugin {
4387
4520
  const subfields = fields[3].split("/");
4388
4521
  ResultFormatter.departureAirport(decodeResult, subfields[0]);
4389
4522
  ResultFormatter.arrivalAirport(decodeResult, subfields[1]);
4390
- ResultFormatter.tail(decodeResult, fields[4].replace(/\./g, ""));
4523
+ ResultFormatter.tail(decodeResult, fields[4].replace(ALL_DOTS_REGEX, ""));
4391
4524
  ResultFormatter.eta(
4392
4525
  decodeResult,
4393
4526
  DateTimeUtils.convertHHMMSSToTod(fields[6] + "00")
4394
4527
  );
4395
- } else if (text.substring(0, 5) === "001PR") {
4528
+ } else if (text.startsWith("001PR")) {
4396
4529
  decodeResult.raw.day = text.substring(5, 7);
4397
4530
  const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(
4398
- text.substring(13, 28).replace(/\./g, "")
4531
+ text.substring(13, 28).replace(ALL_DOTS_REGEX, "")
4399
4532
  );
4400
4533
  if (position) {
4401
4534
  ResultFormatter.position(decodeResult, position);
@@ -4403,15 +4536,15 @@ var Label_83 = class extends DecoderPlugin {
4403
4536
  ResultFormatter.altitude(decodeResult, Number(text.substring(28, 33)));
4404
4537
  ResultFormatter.unknown(decodeResult, text.substring(33));
4405
4538
  } else {
4406
- const fields = text.replace(/\s/g, "").split(",");
4539
+ const fields = text.replace(ALL_WS_REGEX, "").split(",");
4407
4540
  if (fields.length === 9) {
4408
4541
  ResultFormatter.departureAirport(decodeResult, fields[0]);
4409
4542
  ResultFormatter.arrivalAirport(decodeResult, fields[1]);
4410
4543
  decodeResult.raw.day = fields[2].substring(0, 2);
4411
4544
  decodeResult.raw.time = fields[2].substring(2);
4412
4545
  ResultFormatter.position(decodeResult, {
4413
- latitude: Number(fields[3].replace(/\s/g, "")),
4414
- longitude: Number(fields[4].replace(/\s/g, ""))
4546
+ latitude: Number(fields[3]),
4547
+ longitude: Number(fields[4])
4415
4548
  });
4416
4549
  ResultFormatter.altitude(decodeResult, Number(fields[5]));
4417
4550
  ResultFormatter.groundspeed(decodeResult, Number(fields[6]));
@@ -4475,13 +4608,15 @@ var Label_B6_Forwardslash = class extends DecoderPlugin {
4475
4608
  };
4476
4609
  }
4477
4610
  decode(message, options = {}) {
4478
- const decodeResult = this.defaultResult();
4479
- decodeResult.decoder.name = this.name;
4480
- decodeResult.formatted.description = "CPDLC Message";
4481
- decodeResult.message = message;
4482
- if (options.debug) {
4483
- console.log("CPDLC: " + message);
4611
+ const decodeResult = this.initResult(message, "CPDLC Message");
4612
+ const body = message.text.substring(1);
4613
+ if (body.length > 0) {
4614
+ ResultFormatter.text(decodeResult, body);
4615
+ this.setDecodeLevel(decodeResult, true, "partial");
4616
+ } else {
4617
+ this.setDecodeLevel(decodeResult, false);
4484
4618
  }
4619
+ this.debug(options, "CPDLC body:", body);
4485
4620
  return decodeResult;
4486
4621
  }
4487
4622
  };
@@ -4631,6 +4766,7 @@ var Label_H1_ATIS = class extends DecoderPlugin {
4631
4766
  const checksum = match[6];
4632
4767
  ResultFormatter.flightNumber(decodeResult, flight);
4633
4768
  ResultFormatter.arrivalAirport(decodeResult, facility);
4769
+ ResultFormatter.sequenceNumber(decodeResult, parseInt(seq, 10));
4634
4770
  decodeResult.raw.atis_code = code;
4635
4771
  decodeResult.formatted.items.push({
4636
4772
  type: "atis",
@@ -4840,9 +4976,39 @@ var Label_H1_M_POS = class extends DecoderPlugin {
4840
4976
  }
4841
4977
  };
4842
4978
 
4979
+ // lib/utils/compression.ts
4980
+ import * as pako from "pako";
4981
+ function inflateData(data, raw) {
4982
+ const chunks = [];
4983
+ const inflator = new pako.Inflate({ windowBits: raw ? -15 : 15 });
4984
+ inflator.onData = (chunk) => {
4985
+ chunks.push(chunk);
4986
+ };
4987
+ inflator.push(data, 2);
4988
+ if (chunks.length === 0) return void 0;
4989
+ if (chunks.length === 1) return chunks[0];
4990
+ const totalLen = chunks.reduce((sum, c) => sum + c.length, 0);
4991
+ const result = new Uint8Array(totalLen);
4992
+ let offset = 0;
4993
+ for (const chunk of chunks) {
4994
+ result.set(chunk, offset);
4995
+ offset += chunk.length;
4996
+ }
4997
+ return result;
4998
+ }
4999
+ function base64ToUint8Array(base64) {
5000
+ const cleaned = base64.replace(/-/g, "+").replace(/_/g, "/").replace(/[^A-Za-z0-9+/]/g, "");
5001
+ const padded = cleaned + "=".repeat((4 - cleaned.length % 4) % 4);
5002
+ const binary = atob(padded);
5003
+ const bytes = new Uint8Array(binary.length);
5004
+ for (let i = 0; i < binary.length; i++) {
5005
+ bytes[i] = binary.charCodeAt(i);
5006
+ }
5007
+ return bytes;
5008
+ }
5009
+
4843
5010
  // lib/plugins/Label_H1_OHMA.ts
4844
- import * as zlib from "minizlib";
4845
- import { Buffer as Buffer2 } from "buffer";
5011
+ var textDecoder = new TextDecoder();
4846
5012
  var Label_H1_OHMA = class extends DecoderPlugin {
4847
5013
  name = "label-h1-ohma";
4848
5014
  qualifiers() {
@@ -4858,12 +5024,12 @@ var Label_H1_OHMA = class extends DecoderPlugin {
4858
5024
  decodeResult.message = message;
4859
5025
  const data = message.text.split("OHMA")[1];
4860
5026
  try {
4861
- const compressedBuffer = Buffer2.from(data, "base64");
4862
- const decompress = new zlib.Inflate({});
4863
- decompress.write(compressedBuffer);
4864
- decompress.flush(zlib.constants.Z_SYNC_FLUSH);
4865
- const result = decompress.read();
4866
- const jsonText = result?.toString() || "";
5027
+ const compressedBuffer = base64ToUint8Array(data);
5028
+ const result = inflateData(compressedBuffer, false);
5029
+ if (!result || result.length === 0) {
5030
+ throw new Error("Decompression produced no output");
5031
+ }
5032
+ const jsonText = textDecoder.decode(result);
4867
5033
  let formattedMsg;
4868
5034
  let jsonMessage;
4869
5035
  try {
@@ -5268,10 +5434,47 @@ var Label_HX = class extends DecoderPlugin {
5268
5434
  }
5269
5435
  };
5270
5436
 
5437
+ // lib/utils/ascii85.ts
5438
+ function ascii85Decode(input) {
5439
+ let str = input;
5440
+ if (str.startsWith("<~")) str = str.slice(2);
5441
+ if (str.endsWith("~>")) str = str.slice(0, -2);
5442
+ str = str.replace(/\s/g, "");
5443
+ if (str.length === 0) return new Uint8Array(0);
5444
+ const output = [];
5445
+ let i = 0;
5446
+ while (i < str.length) {
5447
+ if (str[i] === "z") {
5448
+ output.push(0, 0, 0, 0);
5449
+ i++;
5450
+ continue;
5451
+ }
5452
+ const remaining = str.length - i;
5453
+ const chunkLen = Math.min(5, remaining);
5454
+ if (chunkLen === 1) break;
5455
+ let padded = str.slice(i, i + chunkLen);
5456
+ while (padded.length < 5) padded += "u";
5457
+ let value = 0;
5458
+ for (let j = 0; j < 5; j++) {
5459
+ const digit = padded.charCodeAt(j) - 33;
5460
+ if (digit < 0 || digit > 84) return null;
5461
+ value = value * 85 + digit;
5462
+ }
5463
+ if (chunkLen === 5 && value > 4294967295) return null;
5464
+ const v = value >>> 0;
5465
+ const numBytes = chunkLen === 5 ? 4 : chunkLen - 1;
5466
+ if (numBytes >= 1) output.push(v >>> 24 & 255);
5467
+ if (numBytes >= 2) output.push(v >>> 16 & 255);
5468
+ if (numBytes >= 3) output.push(v >>> 8 & 255);
5469
+ if (numBytes >= 4) output.push(v & 255);
5470
+ i += chunkLen;
5471
+ }
5472
+ return new Uint8Array(output);
5473
+ }
5474
+
5271
5475
  // lib/utils/miam.ts
5272
- import * as Base85 from "base85";
5273
- import * as zlib2 from "minizlib";
5274
- import { Buffer as Buffer3 } from "buffer";
5476
+ var textDecoder2 = new TextDecoder();
5477
+ var textEncoder = new TextEncoder();
5275
5478
  var MIAMVersion = /* @__PURE__ */ ((MIAMVersion2) => {
5276
5479
  MIAMVersion2[MIAMVersion2["V1"] = 1] = "V1";
5277
5480
  MIAMVersion2[MIAMVersion2["V2"] = 2] = "V2";
@@ -5358,7 +5561,7 @@ var MIAMCoreUtils = class {
5358
5561
  error: "Empty MIAM message header"
5359
5562
  };
5360
5563
  }
5361
- let hdr = Base85.decode("<~" + rawHdr + "~>", "ascii85");
5564
+ let hdr = ascii85Decode("<~" + rawHdr + "~>");
5362
5565
  if (!hdr || hdr.length < hpad) {
5363
5566
  return {
5364
5567
  decoded: false,
@@ -5370,17 +5573,24 @@ var MIAMCoreUtils = class {
5370
5573
  if (rawBody.length > 0) {
5371
5574
  if ("0123".indexOf(bpad) >= 0) {
5372
5575
  const bpadValue = parseInt(bpad);
5373
- body = Base85.decode("<~" + rawBody + "~>", "ascii85") || void 0;
5374
- if (body && body.length >= bpadValue) {
5576
+ const decoded = ascii85Decode("<~" + rawBody + "~>");
5577
+ if (decoded === null) {
5578
+ return {
5579
+ decoded: false,
5580
+ error: "Ascii85 decode failed for MIAM message body"
5581
+ };
5582
+ }
5583
+ body = decoded;
5584
+ if (body.length >= bpadValue) {
5375
5585
  body = body.subarray(0, body.length - bpadValue);
5376
5586
  }
5377
5587
  } else if (bpad === "-") {
5378
- body = Buffer3.from(rawBody);
5588
+ body = textEncoder.encode(rawBody);
5379
5589
  }
5380
5590
  }
5381
5591
  hdr = hdr.subarray(0, hdr.length - hpad);
5382
- const version = hdr.readUInt8(0) & 15;
5383
- const pduType = hdr.readUInt8(0) >> 4 & 15;
5592
+ const version = hdr[0] & 15;
5593
+ const pduType = hdr[0] >> 4 & 15;
5384
5594
  if (isMIAMVersion(version) && isMIAMCorePdu(pduType)) {
5385
5595
  const versionPduHandler = this.VersionPduHandlerTable[version][pduType];
5386
5596
  return versionPduHandler(hdr, body);
@@ -5677,7 +5887,7 @@ var MIAMCoreUtils = class {
5677
5887
  ];
5678
5888
  let crc = (seed || 0) & 65535;
5679
5889
  for (let i = 0; i < buf.length; i++) {
5680
- crc = (crc << 8 >>> 0 ^ crctable[(crc >>> 8 ^ buf.readUInt8(i)) >>> 0 & 255]) >>> 0;
5890
+ crc = (crc << 8 >>> 0 ^ crctable[(crc >>> 8 ^ buf[i]) >>> 0 & 255]) >>> 0;
5681
5891
  }
5682
5892
  return crc & 65535;
5683
5893
  }
@@ -5942,7 +6152,7 @@ var MIAMCoreUtils = class {
5942
6152
  ];
5943
6153
  let crc = seed || 0;
5944
6154
  for (let i = 0; i < buf.length; i++) {
5945
- crc = (crc << 8 >>> 0 ^ crctable[(crc >>> 24 ^ buf.readUInt8(i)) >>> 0]) >>> 0;
6155
+ crc = (crc << 8 >>> 0 ^ crctable[(crc >>> 24 ^ buf[i]) >>> 0]) >>> 0;
5946
6156
  }
5947
6157
  return crc;
5948
6158
  }
@@ -5979,7 +6189,7 @@ var MIAMCoreUtils = class {
5979
6189
  let msgNum = 0;
5980
6190
  let ackOptions = 0;
5981
6191
  if (version === 1 /* V1 */) {
5982
- pduSize = hdr.readUInt8(1) << 16 | hdr.readUInt8(2) << 8 | hdr.readUInt8(3);
6192
+ pduSize = hdr[1] << 16 | hdr[2] << 8 | hdr[3];
5983
6193
  const msgSize = hdr.length + (body === void 0 ? 0 : body.length);
5984
6194
  if (pduSize > msgSize) {
5985
6195
  pduIsComplete = false;
@@ -5988,17 +6198,17 @@ var MIAMCoreUtils = class {
5988
6198
  );
5989
6199
  }
5990
6200
  hdr = hdr.subarray(4);
5991
- tail = hdr.subarray(0, 7).toString("ascii");
6201
+ tail = textDecoder2.decode(hdr.subarray(0, 7));
5992
6202
  hdr = hdr.subarray(7);
5993
6203
  } else if (version === 2 /* V2 */) {
5994
6204
  hdr = hdr.subarray(1);
5995
6205
  }
5996
- msgNum = hdr.readUInt8(0) >> 1 & 127;
5997
- ackOptions = hdr.readUInt8(0) & 1;
6206
+ msgNum = hdr[0] >> 1 & 127;
6207
+ ackOptions = hdr[0] & 1;
5998
6208
  hdr = hdr.subarray(1);
5999
- pduCompression = (hdr.readUInt8(0) << 2 | hdr.readUInt8(1) >> 6 & 3) & 7;
6000
- pduEncoding = hdr.readUInt8(1) >> 4 & 3;
6001
- pduAppType = hdr.readUInt8(1) & 15;
6209
+ pduCompression = (hdr[0] << 2 | hdr[1] >> 6 & 3) & 7;
6210
+ pduEncoding = hdr[1] >> 4 & 3;
6211
+ pduAppType = hdr[1] & 15;
6002
6212
  hdr = hdr.subarray(2);
6003
6213
  let appIdLen;
6004
6214
  if (isMIAMCoreApp(pduAppType)) {
@@ -6024,12 +6234,12 @@ var MIAMCoreUtils = class {
6024
6234
  error: "Header too short for v" + version + " appType: " + pduAppType
6025
6235
  };
6026
6236
  }
6027
- pduAppId = hdr.subarray(0, appIdLen).toString("ascii");
6237
+ pduAppId = textDecoder2.decode(hdr.subarray(0, appIdLen));
6028
6238
  hdr = hdr.subarray(appIdLen);
6029
6239
  if (crcLen === 4) {
6030
- pduCrc = hdr.readUInt8(0) << 24 | hdr.readUInt8(1) << 16 | hdr.readUInt8(2) << 8 | hdr.readUInt8(3);
6240
+ pduCrc = hdr[0] << 24 | hdr[1] << 16 | hdr[2] << 8 | hdr[3];
6031
6241
  } else if (crcLen === 2) {
6032
- pduCrc = hdr.readUInt8(0) << 8 | hdr.readUInt8(1);
6242
+ pduCrc = hdr[0] << 8 | hdr[1];
6033
6243
  }
6034
6244
  hdr = hdr.subarray(crcLen);
6035
6245
  if (body !== void 0 && body.length > 0) {
@@ -6037,10 +6247,12 @@ var MIAMCoreUtils = class {
6037
6247
  pduCompression
6038
6248
  ) >= 0) {
6039
6249
  try {
6040
- const decompress = new zlib2.InflateRaw({});
6041
- decompress.write(body);
6042
- decompress.flush(zlib2.constants.Z_SYNC_FLUSH);
6043
- pduData = decompress.read();
6250
+ const inflated = inflateData(body, true);
6251
+ if (inflated === void 0) {
6252
+ pduErrors.push("Inflation produced no output for body");
6253
+ } else {
6254
+ pduData = inflated;
6255
+ }
6044
6256
  } catch (e) {
6045
6257
  pduErrors.push("Inflation failed for body: " + e);
6046
6258
  }
@@ -6098,12 +6310,12 @@ var MIAMCoreUtils = class {
6098
6310
  label,
6099
6311
  ...sublabel ? { sublabel } : {},
6100
6312
  ...mfi ? { mfi } : {},
6101
- ...pduData ? { text: pduData.toString("ascii") } : {}
6313
+ ...pduData ? { text: textDecoder2.decode(pduData) } : {}
6102
6314
  };
6103
6315
  } else {
6104
6316
  pdu.non_acars = {
6105
6317
  appId: pduAppId,
6106
- ...pduData ? { text: pduData.toString("ascii") } : {}
6318
+ ...pduData ? { text: textDecoder2.decode(pduData) } : {}
6107
6319
  };
6108
6320
  }
6109
6321
  return {
@@ -6479,6 +6691,7 @@ var pluginClasses = [
6479
6691
  Label_13Through18_Slash,
6480
6692
  Label_15,
6481
6693
  Label_15_FST,
6694
+ Label_16_AUTPOS,
6482
6695
  Label_16_Honeywell,
6483
6696
  Label_16_N_Space,
6484
6697
  Label_16_POSA1,
@@ -6538,10 +6751,12 @@ var MessageDecoder = class {
6538
6751
  name;
6539
6752
  plugins;
6540
6753
  debug;
6541
- /** Maps a label string to the plugins registered for it, preserving registration order. */
6542
- labelIndex = /* @__PURE__ */ new Map();
6543
- /** Plugins that match all labels (qualifier label '*'). */
6544
- wildcardPlugins = [];
6754
+ /** Maps a label string to the candidate entries (wildcard + label-specific) in registration order. */
6755
+ candidatesByLabel = /* @__PURE__ */ new Map();
6756
+ /** Wildcard entries (plugins that register the '*' label). */
6757
+ wildcardEntries = [];
6758
+ /** Membership set for wildcard entries to dedupe when a plugin also registers a specific label. */
6759
+ wildcardSet = /* @__PURE__ */ new Set();
6545
6760
  constructor() {
6546
6761
  this.name = "acars-decoder-typescript";
6547
6762
  this.plugins = [];
@@ -6553,40 +6768,41 @@ var MessageDecoder = class {
6553
6768
  registerPlugin(plugin) {
6554
6769
  this.plugins.push(plugin);
6555
6770
  const qualifiers = plugin.qualifiers();
6771
+ const entry = {
6772
+ plugin,
6773
+ preambles: qualifiers.preambles && qualifiers.preambles.length > 0 ? qualifiers.preambles : void 0
6774
+ };
6556
6775
  for (const label of qualifiers.labels) {
6557
6776
  if (label === "*") {
6558
- this.wildcardPlugins.push(plugin);
6777
+ if (!this.wildcardSet.has(plugin)) {
6778
+ this.wildcardEntries.push(entry);
6779
+ this.wildcardSet.add(plugin);
6780
+ const wildcardInsertIndex = this.wildcardEntries.length - 1;
6781
+ for (const bucket of this.candidatesByLabel.values()) {
6782
+ bucket.splice(wildcardInsertIndex, 0, entry);
6783
+ }
6784
+ }
6559
6785
  } else {
6560
- let bucket = this.labelIndex.get(label);
6786
+ let bucket = this.candidatesByLabel.get(label);
6561
6787
  if (!bucket) {
6562
- bucket = [];
6563
- this.labelIndex.set(label, bucket);
6788
+ bucket = this.wildcardEntries.slice();
6789
+ this.candidatesByLabel.set(label, bucket);
6790
+ }
6791
+ if (!this.wildcardSet.has(plugin)) {
6792
+ bucket.push(entry);
6564
6793
  }
6565
- bucket.push(plugin);
6566
6794
  }
6567
6795
  }
6568
6796
  return true;
6569
6797
  }
6570
6798
  decode(message, options = {}) {
6571
- const labelPlugins = this.labelIndex.get(message.label) ?? [];
6572
- const seen = /* @__PURE__ */ new Set();
6573
- const candidates = [];
6574
- for (const plugin of [...this.wildcardPlugins, ...labelPlugins]) {
6575
- if (!seen.has(plugin)) {
6576
- seen.add(plugin);
6577
- candidates.push(plugin);
6578
- }
6579
- }
6580
- const usablePlugins = candidates.filter((plugin) => {
6581
- const preambles = plugin.qualifiers().preambles;
6582
- if (!preambles || preambles.length === 0) {
6583
- return true;
6584
- }
6585
- return preambles.some((p) => message.text.startsWith(p));
6586
- });
6799
+ const text = message.text;
6800
+ const candidates = this.candidatesByLabel.get(message.label) ?? this.wildcardEntries;
6587
6801
  if (options.debug) {
6588
6802
  console.log("Usable plugins");
6589
- console.log(usablePlugins);
6803
+ console.log(
6804
+ candidates.filter((e) => this.matchesPreambles(text, e.preambles)).map((e) => e.plugin)
6805
+ );
6590
6806
  }
6591
6807
  let result = {
6592
6808
  decoded: false,
@@ -6598,7 +6814,7 @@ var MessageDecoder = class {
6598
6814
  },
6599
6815
  message,
6600
6816
  remaining: {
6601
- text: message.text
6817
+ text
6602
6818
  },
6603
6819
  raw: {},
6604
6820
  formatted: {
@@ -6606,10 +6822,14 @@ var MessageDecoder = class {
6606
6822
  items: []
6607
6823
  }
6608
6824
  };
6609
- for (let i = 0; i < usablePlugins.length; i++) {
6610
- const plugin = usablePlugins[i];
6611
- result = plugin.decode(message, options);
6612
- if (result.decoded) {
6825
+ for (let i = 0; i < candidates.length; i++) {
6826
+ const entry = candidates[i];
6827
+ if (!this.matchesPreambles(text, entry.preambles)) {
6828
+ continue;
6829
+ }
6830
+ const pluginResult = entry.plugin.decode(message, options);
6831
+ if (pluginResult.decoded) {
6832
+ result = pluginResult;
6613
6833
  break;
6614
6834
  }
6615
6835
  }
@@ -6619,6 +6839,17 @@ var MessageDecoder = class {
6619
6839
  }
6620
6840
  return result;
6621
6841
  }
6842
+ matchesPreambles(text, preambles) {
6843
+ if (!preambles) {
6844
+ return true;
6845
+ }
6846
+ for (let i = 0; i < preambles.length; i++) {
6847
+ if (text.startsWith(preambles[i])) {
6848
+ return true;
6849
+ }
6850
+ }
6851
+ return false;
6852
+ }
6622
6853
  };
6623
6854
  export {
6624
6855
  IcaoDecoder,