@airframes/acars-decoder 1.8.13 → 1.8.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -122,56 +122,6 @@ var IcaoDecoder = class _IcaoDecoder {
122
122
  }
123
123
  };
124
124
 
125
- // lib/DecoderPlugin.ts
126
- var DecoderPlugin = class {
127
- decoder;
128
- name = "unknown";
129
- defaultResult() {
130
- return {
131
- decoded: false,
132
- decoder: {
133
- name: "unknown",
134
- type: "pattern-match",
135
- decodeLevel: "none"
136
- },
137
- formatted: {
138
- description: "Unknown",
139
- items: []
140
- },
141
- raw: {},
142
- remaining: {}
143
- };
144
- }
145
- options;
146
- constructor(decoder, options = {}) {
147
- this.decoder = decoder;
148
- this.options = options;
149
- }
150
- id() {
151
- console.log(
152
- "DecoderPlugin subclass has not overriden id() to provide a unique ID for this plugin!"
153
- );
154
- return "abstract_decoder_plugin";
155
- }
156
- meetsStateRequirements() {
157
- return true;
158
- }
159
- // onRegister(store: Store<any>) {
160
- // this.store = store;
161
- // }
162
- qualifiers() {
163
- const labels = [];
164
- return {
165
- labels
166
- };
167
- }
168
- decode(message) {
169
- const decodeResult = this.defaultResult();
170
- decodeResult.remaining.text = message.text;
171
- return decodeResult;
172
- }
173
- };
174
-
175
125
  // lib/utils/coordinate_utils.ts
176
126
  var CoordinateUtils = class _CoordinateUtils {
177
127
  /**
@@ -1029,6 +979,99 @@ var ResultFormatter = class {
1029
979
  }
1030
980
  };
1031
981
 
982
+ // lib/DecoderPlugin.ts
983
+ var DecoderPlugin = class {
984
+ decoder;
985
+ name = "unknown";
986
+ defaultResult() {
987
+ return {
988
+ decoded: false,
989
+ decoder: {
990
+ name: "unknown",
991
+ type: "pattern-match",
992
+ decodeLevel: "none"
993
+ },
994
+ formatted: {
995
+ description: "Unknown",
996
+ items: []
997
+ },
998
+ raw: {},
999
+ remaining: {}
1000
+ };
1001
+ }
1002
+ /**
1003
+ * Creates a DecodeResult pre-populated with the plugin name, description, and message.
1004
+ * Replaces the common boilerplate at the start of every decode() method.
1005
+ */
1006
+ initResult(message, description) {
1007
+ const result = this.defaultResult();
1008
+ result.decoder.name = this.name;
1009
+ result.formatted.description = description;
1010
+ result.message = message;
1011
+ return result;
1012
+ }
1013
+ /**
1014
+ * Sets the decoded flag and decodeLevel on a result.
1015
+ * If decoded is true and no explicit level is given, infers 'full' or 'partial'
1016
+ * based on whether remaining.text is set.
1017
+ */
1018
+ setDecodeLevel(result, decoded, level) {
1019
+ result.decoded = decoded;
1020
+ if (decoded) {
1021
+ result.decoder.decodeLevel = level ?? (result.remaining.text ? "partial" : "full");
1022
+ } else {
1023
+ result.decoder.decodeLevel = "none";
1024
+ }
1025
+ }
1026
+ /**
1027
+ * Logs a debug message prefixed with the plugin name, only if options.debug is true.
1028
+ */
1029
+ debug(options, ...args) {
1030
+ if (options.debug) {
1031
+ console.log(`[${this.name}]`, ...args);
1032
+ }
1033
+ }
1034
+ /**
1035
+ * Marks a result as a failed decode with 'none' level, sets the remaining text
1036
+ * as unknown, and logs a debug message. Returns the result for convenient early return.
1037
+ */
1038
+ failUnknown(result, text, options = {}) {
1039
+ this.debug(options, `Unknown message: ${text}`);
1040
+ ResultFormatter.unknown(result, text);
1041
+ result.decoded = false;
1042
+ result.decoder.decodeLevel = "none";
1043
+ return result;
1044
+ }
1045
+ options;
1046
+ constructor(decoder, options = {}) {
1047
+ this.decoder = decoder;
1048
+ this.options = options;
1049
+ }
1050
+ id() {
1051
+ console.log(
1052
+ "DecoderPlugin subclass has not overriden id() to provide a unique ID for this plugin!"
1053
+ );
1054
+ return "abstract_decoder_plugin";
1055
+ }
1056
+ meetsStateRequirements() {
1057
+ return true;
1058
+ }
1059
+ // onRegister(store: Store<any>) {
1060
+ // this.store = store;
1061
+ // }
1062
+ qualifiers() {
1063
+ const labels = [];
1064
+ return {
1065
+ labels
1066
+ };
1067
+ }
1068
+ decode(message, options = {}) {
1069
+ const decodeResult = this.defaultResult();
1070
+ decodeResult.remaining.text = message.text;
1071
+ return decodeResult;
1072
+ }
1073
+ };
1074
+
1032
1075
  // lib/plugins/CBand.ts
1033
1076
  var CBand = class extends DecoderPlugin {
1034
1077
  name = "c-band";
@@ -2098,19 +2141,10 @@ var Label_10_POS = class extends DecoderPlugin {
2098
2141
  };
2099
2142
  }
2100
2143
  decode(message, options = {}) {
2101
- const decodeResult = this.defaultResult();
2102
- decodeResult.decoder.name = this.name;
2103
- decodeResult.formatted.description = "Position Report";
2104
- decodeResult.message = message;
2144
+ const decodeResult = this.initResult(message, "Position Report");
2105
2145
  const parts = message.text.split(",");
2106
2146
  if (parts.length !== 12) {
2107
- if (options.debug) {
2108
- console.log(`Decoder: Unknown 10 message: ${message.text}`);
2109
- }
2110
- ResultFormatter.unknown(decodeResult, message.text);
2111
- decodeResult.decoded = false;
2112
- decodeResult.decoder.decodeLevel = "none";
2113
- return decodeResult;
2147
+ return this.failUnknown(decodeResult, message.text, options);
2114
2148
  }
2115
2149
  const lat = parts[1].trim();
2116
2150
  const lon = parts[2].trim();
@@ -2125,8 +2159,7 @@ var Label_10_POS = class extends DecoderPlugin {
2125
2159
  ...parts.slice(3, 7),
2126
2160
  ...parts.slice(8)
2127
2161
  ]);
2128
- decodeResult.decoded = true;
2129
- decodeResult.decoder.decodeLevel = "partial";
2162
+ this.setDecodeLevel(decodeResult, true, "partial");
2130
2163
  return decodeResult;
2131
2164
  }
2132
2165
  };
@@ -2253,19 +2286,10 @@ var Label_12_POS = class extends DecoderPlugin {
2253
2286
  };
2254
2287
  }
2255
2288
  decode(message, options = {}) {
2256
- const decodeResult = this.defaultResult();
2257
- decodeResult.decoder.name = this.name;
2258
- decodeResult.formatted.description = "Position Report";
2259
- decodeResult.message = message;
2289
+ const decodeResult = this.initResult(message, "Position Report");
2260
2290
  const data = message.text.substring(3).split(",");
2261
2291
  if (!message.text.startsWith("POS") || data.length !== 12) {
2262
- if (options.debug) {
2263
- console.log(`Decoder: Unknown 12 message: ${message.text}`);
2264
- }
2265
- ResultFormatter.unknown(decodeResult, message.text);
2266
- decodeResult.decoded = false;
2267
- decodeResult.decoder.decodeLevel = "none";
2268
- return decodeResult;
2292
+ return this.failUnknown(decodeResult, message.text, options);
2269
2293
  }
2270
2294
  const lat = data[0].substring(0, 8);
2271
2295
  const lon = data[0].substring(8);
@@ -2299,8 +2323,7 @@ var Label_12_POS = class extends DecoderPlugin {
2299
2323
  ResultFormatter.departureAirport(decodeResult, data[9]);
2300
2324
  ResultFormatter.arrivalAirport(decodeResult, data[10]);
2301
2325
  ResultFormatter.unknown(decodeResult, data[11]);
2302
- decodeResult.decoded = true;
2303
- decodeResult.decoder.decodeLevel = "partial";
2326
+ this.setDecodeLevel(decodeResult, true, "partial");
2304
2327
  return decodeResult;
2305
2328
  }
2306
2329
  };
@@ -2413,10 +2436,7 @@ var Label_15 = class extends DecoderPlugin {
2413
2436
  };
2414
2437
  }
2415
2438
  decode(message, options = {}) {
2416
- const decodeResult = this.defaultResult();
2417
- decodeResult.decoder.name = this.name;
2418
- decodeResult.formatted.description = "Position Report";
2419
- decodeResult.message = message;
2439
+ const decodeResult = this.initResult(message, "Position Report");
2420
2440
  if (message.text.startsWith("(2") && message.text.endsWith("(Z")) {
2421
2441
  const between = message.text.substring(2, message.text.length - 2);
2422
2442
  ResultFormatter.position(
@@ -2454,16 +2474,9 @@ var Label_15 = class extends DecoderPlugin {
2454
2474
  ResultFormatter.unknown(decodeResult, between.substring(26));
2455
2475
  }
2456
2476
  } else {
2457
- if (options.debug) {
2458
- console.log(`Decoder: Unknown 15 message: ${message.text}`);
2459
- }
2460
- ResultFormatter.unknown(decodeResult, message.text);
2461
- decodeResult.decoded = false;
2462
- decodeResult.decoder.decodeLevel = "none";
2463
- return decodeResult;
2477
+ return this.failUnknown(decodeResult, message.text, options);
2464
2478
  }
2465
- decodeResult.decoded = true;
2466
- decodeResult.decoder.decodeLevel = "partial";
2479
+ this.setDecodeLevel(decodeResult, true, "partial");
2467
2480
  return decodeResult;
2468
2481
  }
2469
2482
  };
@@ -2478,10 +2491,7 @@ var Label_15_FST = class extends DecoderPlugin {
2478
2491
  };
2479
2492
  }
2480
2493
  decode(message, options = {}) {
2481
- const decodeResult = this.defaultResult();
2482
- decodeResult.decoder.name = this.name;
2483
- decodeResult.formatted.description = "Position Report";
2484
- decodeResult.message = message;
2494
+ const decodeResult = this.initResult(message, "Position Report");
2485
2495
  const parts = message.text.split(" ");
2486
2496
  const header = parts[0];
2487
2497
  const stringCoords = header.substring(13);
@@ -2497,15 +2507,12 @@ var Label_15_FST = class extends DecoderPlugin {
2497
2507
  Number(stringCoords.substring(15)) * 100
2498
2508
  );
2499
2509
  } else {
2500
- decodeResult.decoded = false;
2501
- decodeResult.decoder.decodeLevel = "none";
2502
- return decodeResult;
2510
+ return this.failUnknown(decodeResult, message.text, options);
2503
2511
  }
2504
2512
  ResultFormatter.departureAirport(decodeResult, header.substring(5, 9));
2505
2513
  ResultFormatter.arrivalAirport(decodeResult, header.substring(9, 13));
2506
2514
  ResultFormatter.unknownArr(decodeResult, parts.slice(1), " ");
2507
- decodeResult.decoded = true;
2508
- decodeResult.decoder.decodeLevel = "partial";
2515
+ this.setDecodeLevel(decodeResult, true, "partial");
2509
2516
  return decodeResult;
2510
2517
  }
2511
2518
  };
@@ -2644,19 +2651,10 @@ var Label_16_POSA1 = class extends DecoderPlugin {
2644
2651
  };
2645
2652
  }
2646
2653
  decode(message, options = {}) {
2647
- const decodeResult = this.defaultResult();
2648
- decodeResult.decoder.name = this.name;
2649
- decodeResult.formatted.description = "Position Report";
2650
- decodeResult.message = message;
2654
+ const decodeResult = this.initResult(message, "Position Report");
2651
2655
  const fields = message.text.split(",");
2652
2656
  if (fields.length !== 11 || !fields[0].startsWith("POSA1")) {
2653
- if (options.debug) {
2654
- console.log(`Decoder: Unknown 16 message: ${message.text}`);
2655
- }
2656
- decodeResult.remaining.text = message.text;
2657
- decodeResult.decoded = false;
2658
- decodeResult.decoder.decodeLevel = "none";
2659
- return decodeResult;
2657
+ return this.failUnknown(decodeResult, message.text, options);
2660
2658
  }
2661
2659
  ResultFormatter.position(
2662
2660
  decodeResult,
@@ -2674,8 +2672,7 @@ var Label_16_POSA1 = class extends DecoderPlugin {
2674
2672
  { name: nextWaypoint, time: nextTime }
2675
2673
  ]
2676
2674
  });
2677
- decodeResult.decoded = true;
2678
- decodeResult.decoder.decodeLevel = "partial";
2675
+ this.setDecodeLevel(decodeResult, true, "partial");
2679
2676
  return decodeResult;
2680
2677
  }
2681
2678
  };
@@ -3057,42 +3054,31 @@ var Label_20_POS = class extends DecoderPlugin {
3057
3054
  };
3058
3055
  }
3059
3056
  decode(message, options = {}) {
3060
- const decodeResult = this.defaultResult();
3061
- decodeResult.decoder.name = this.name;
3062
- decodeResult.formatted.description = "Position Report";
3063
- decodeResult.message = message;
3057
+ const decodeResult = this.initResult(message, "Position Report");
3064
3058
  decodeResult.raw.preamble = message.text.substring(0, 3);
3065
3059
  const content = message.text.substring(3);
3066
3060
  const fields = content.split(",");
3067
3061
  if (fields.length == 11) {
3068
- if (options.debug) {
3069
- console.log(`DEBUG: ${this.name}: Variation 1 detected`);
3070
- }
3062
+ this.debug(options, "Variation 1 detected");
3071
3063
  const rawCoords = fields[0];
3072
3064
  ResultFormatter.position(
3073
3065
  decodeResult,
3074
3066
  CoordinateUtils.decodeStringCoordinates(rawCoords)
3075
3067
  );
3076
- decodeResult.decoded = true;
3077
- decodeResult.decoder.decodeLevel = "full";
3068
+ this.setDecodeLevel(decodeResult, true, "full");
3078
3069
  } else if (fields.length == 5) {
3079
- if (options.debug) {
3080
- console.log(`DEBUG: ${this.name}: Variation 2 detected`);
3081
- }
3070
+ this.debug(options, "Variation 2 detected");
3082
3071
  const position = CoordinateUtils.decodeStringCoordinates(fields[0]);
3083
3072
  if (position) {
3084
3073
  ResultFormatter.position(decodeResult, position);
3085
3074
  }
3086
- decodeResult.decoded = true;
3087
- decodeResult.decoder.decodeLevel = "full";
3075
+ this.setDecodeLevel(decodeResult, true, "full");
3088
3076
  } else {
3089
- if (options.debug) {
3090
- console.log(
3091
- `DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${content}`
3092
- );
3093
- }
3094
- decodeResult.decoded = false;
3095
- decodeResult.decoder.decodeLevel = "none";
3077
+ this.debug(
3078
+ options,
3079
+ `Unknown variation. Field count: ${fields.length}, content: ${content}`
3080
+ );
3081
+ this.setDecodeLevel(decodeResult, false);
3096
3082
  }
3097
3083
  return decodeResult;
3098
3084
  }
@@ -3108,10 +3094,7 @@ var Label_21_POS = class extends DecoderPlugin {
3108
3094
  };
3109
3095
  }
3110
3096
  decode(message, options = {}) {
3111
- const decodeResult = this.defaultResult();
3112
- decodeResult.decoder.name = this.name;
3113
- decodeResult.formatted.description = "Position Report";
3114
- decodeResult.message = message;
3097
+ const decodeResult = this.initResult(message, "Position Report");
3115
3098
  decodeResult.raw.preamble = message.text.substring(0, 3);
3116
3099
  const content = message.text.substring(3);
3117
3100
  const fields = content.split(",");
@@ -3133,16 +3116,13 @@ var Label_21_POS = class extends DecoderPlugin {
3133
3116
  fields[4],
3134
3117
  fields[5]
3135
3118
  ]);
3136
- decodeResult.decoded = true;
3137
- decodeResult.decoder.decodeLevel = "partial";
3119
+ this.setDecodeLevel(decodeResult, true, "partial");
3138
3120
  } else {
3139
- if (options.debug) {
3140
- console.log(
3141
- `DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${content}`
3142
- );
3143
- }
3144
- decodeResult.decoded = false;
3145
- decodeResult.decoder.decodeLevel = "none";
3121
+ this.debug(
3122
+ options,
3123
+ `Unknown variation. Field count: ${fields.length}, content: ${content}`
3124
+ );
3125
+ this.setDecodeLevel(decodeResult, false);
3146
3126
  }
3147
3127
  return decodeResult;
3148
3128
  }
@@ -3170,15 +3150,11 @@ var Label_22_OFF = class extends DecoderPlugin {
3170
3150
  };
3171
3151
  }
3172
3152
  decode(message, options = {}) {
3173
- const decodeResult = this.defaultResult();
3174
- decodeResult.decoder.name = this.name;
3175
- decodeResult.formatted.description = "Takeoff Report";
3176
- decodeResult.message = message;
3153
+ const decodeResult = this.initResult(message, "Takeoff Report");
3177
3154
  if (message.text.startsWith("OFF01")) {
3178
3155
  const fields = message.text.substring(5).split("/");
3179
3156
  if (fields.length != 2) {
3180
- decodeResult.decoded = false;
3181
- decodeResult.decoder.decodeLevel = "none";
3157
+ this.setDecodeLevel(decodeResult, false);
3182
3158
  return decodeResult;
3183
3159
  }
3184
3160
  ResultFormatter.flightNumber(decodeResult, fields[0]);
@@ -3204,13 +3180,11 @@ var Label_22_OFF = class extends DecoderPlugin {
3204
3180
  DateTimeUtils.convertHHMMSSToTod(fields[1].substring(16, 22))
3205
3181
  );
3206
3182
  ResultFormatter.unknown(decodeResult, fields[1].substring(22));
3207
- decodeResult.decoded = true;
3208
- decodeResult.decoder.decodeLevel = "partial";
3183
+ this.setDecodeLevel(decodeResult, true, "partial");
3209
3184
  } else if (message.text.startsWith("OFF02\r\n")) {
3210
3185
  const fields = message.text.substring(7).split(",");
3211
3186
  if (fields.length != 4) {
3212
- decodeResult.decoded = false;
3213
- decodeResult.decoder.decodeLevel = "none";
3187
+ this.setDecodeLevel(decodeResult, false);
3214
3188
  return decodeResult;
3215
3189
  }
3216
3190
  ResultFormatter.departureAirport(decodeResult, fields[0]);
@@ -3220,13 +3194,11 @@ var Label_22_OFF = class extends DecoderPlugin {
3220
3194
  DateTimeUtils.convertHHMMSSToTod(fields[2])
3221
3195
  );
3222
3196
  ResultFormatter.unknown(decodeResult, fields[3]);
3223
- decodeResult.decoded = true;
3224
- decodeResult.decoder.decodeLevel = "partial";
3197
+ this.setDecodeLevel(decodeResult, true, "partial");
3225
3198
  } else if (message.text.startsWith("OFF02")) {
3226
3199
  const fields = message.text.substring(5).split("/");
3227
3200
  if (fields.length != 2) {
3228
- decodeResult.decoded = false;
3229
- decodeResult.decoder.decodeLevel = "none";
3201
+ this.setDecodeLevel(decodeResult, false);
3230
3202
  return decodeResult;
3231
3203
  }
3232
3204
  ResultFormatter.flightNumber(decodeResult, fields[0]);
@@ -3255,14 +3227,10 @@ var Label_22_OFF = class extends DecoderPlugin {
3255
3227
  decodeResult,
3256
3228
  DateTimeUtils.convertHHMMSSToTod(fields[1].substring(36, 40))
3257
3229
  );
3258
- decodeResult.decoded = true;
3259
- decodeResult.decoder.decodeLevel = "partial";
3230
+ this.setDecodeLevel(decodeResult, true, "partial");
3260
3231
  } else {
3261
- if (options.debug) {
3262
- console.log(`DEBUG: ${this.name}: Unknown variation.`);
3263
- }
3264
- decodeResult.decoded = false;
3265
- decodeResult.decoder.decodeLevel = "none";
3232
+ this.debug(options, "Unknown variation.");
3233
+ this.setDecodeLevel(decodeResult, false);
3266
3234
  }
3267
3235
  return decodeResult;
3268
3236
  }
@@ -3278,19 +3246,14 @@ var Label_22_POS = class extends DecoderPlugin {
3278
3246
  };
3279
3247
  }
3280
3248
  decode(message, options = {}) {
3281
- const decodeResult = this.defaultResult();
3282
- decodeResult.decoder.name = this.name;
3283
- decodeResult.formatted.description = "Position Report";
3284
- decodeResult.message = message;
3249
+ const decodeResult = this.initResult(message, "Position Report");
3285
3250
  const fields = message.text.split(",");
3286
3251
  if (fields.length !== 11) {
3287
- if (options.debug) {
3288
- console.log(
3289
- `DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${fields.join(",")}`
3290
- );
3291
- }
3292
- decodeResult.decoded = false;
3293
- decodeResult.decoder.decodeLevel = "none";
3252
+ this.debug(
3253
+ options,
3254
+ `Unknown variation. Field count: ${fields.length}, content: ${fields.join(",")}`
3255
+ );
3256
+ this.setDecodeLevel(decodeResult, false);
3294
3257
  return decodeResult;
3295
3258
  }
3296
3259
  const latStr = fields[0].substring(1, 8);
@@ -3307,8 +3270,7 @@ var Label_22_POS = class extends DecoderPlugin {
3307
3270
  );
3308
3271
  ResultFormatter.altitude(decodeResult, Number(fields[3]));
3309
3272
  ResultFormatter.unknownArr(decodeResult, [fields[1], ...fields.slice(4)]);
3310
- decodeResult.decoded = true;
3311
- decodeResult.decoder.decodeLevel = "partial";
3273
+ this.setDecodeLevel(decodeResult, true, "partial");
3312
3274
  return decodeResult;
3313
3275
  }
3314
3276
  };
@@ -3600,218 +3562,143 @@ var Label_44_ETA = class extends DecoderPlugin {
3600
3562
  };
3601
3563
  }
3602
3564
  decode(message, options = {}) {
3603
- const decodeResult = this.defaultResult();
3604
- decodeResult.decoder.name = this.name;
3605
- decodeResult.formatted.description = "ETA Report";
3606
- decodeResult.message = message;
3565
+ const result = this.initResult(message, "ETA Report");
3607
3566
  const data = message.text.split(",");
3608
- if (data.length >= 9) {
3609
- if (options.debug) {
3610
- console.log("Label 44 ETA Report: groups");
3611
- console.log(data);
3612
- }
3613
- ResultFormatter.position(
3614
- decodeResult,
3615
- CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1])
3616
- );
3617
- ResultFormatter.altitude(decodeResult, 100 * Number(data[2]));
3618
- ResultFormatter.departureAirport(decodeResult, data[3]);
3619
- ResultFormatter.arrivalAirport(decodeResult, data[4]);
3620
- ResultFormatter.month(decodeResult, Number(data[5].substring(0, 2)));
3621
- ResultFormatter.day(decodeResult, Number(data[5].substring(2, 4)));
3622
- ResultFormatter.timestamp(
3623
- decodeResult,
3624
- DateTimeUtils.convertHHMMSSToTod(data[6])
3625
- );
3626
- ResultFormatter.eta(
3627
- decodeResult,
3628
- DateTimeUtils.convertHHMMSSToTod(data[7])
3629
- );
3630
- const fuel = Number(data[8]);
3631
- if (!isNaN(fuel)) {
3632
- ResultFormatter.remainingFuel(decodeResult, Number(fuel));
3633
- }
3634
- if (data.length > 9) {
3635
- ResultFormatter.unknownArr(decodeResult, data.slice(9));
3636
- }
3637
- } else {
3638
- if (options.debug) {
3639
- console.log(`Decoder: Unknown 44 message: ${message.text}`);
3640
- }
3641
- ResultFormatter.unknown(decodeResult, message.text);
3642
- decodeResult.decoded = false;
3643
- decodeResult.decoder.decodeLevel = "none";
3644
- return decodeResult;
3567
+ if (data.length < 9) {
3568
+ return this.failUnknown(result, message.text, options);
3569
+ }
3570
+ this.debug(options, "ETA Report: fields", data);
3571
+ ResultFormatter.position(
3572
+ result,
3573
+ CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1])
3574
+ );
3575
+ ResultFormatter.altitude(result, 100 * Number(data[2]));
3576
+ ResultFormatter.departureAirport(result, data[3]);
3577
+ ResultFormatter.arrivalAirport(result, data[4]);
3578
+ ResultFormatter.month(result, Number(data[5].substring(0, 2)));
3579
+ ResultFormatter.day(result, Number(data[5].substring(2, 4)));
3580
+ ResultFormatter.timestamp(
3581
+ result,
3582
+ DateTimeUtils.convertHHMMSSToTod(data[6])
3583
+ );
3584
+ ResultFormatter.eta(result, DateTimeUtils.convertHHMMSSToTod(data[7]));
3585
+ const fuel = Number(data[8]);
3586
+ if (!isNaN(fuel)) {
3587
+ ResultFormatter.remainingFuel(result, fuel);
3588
+ }
3589
+ if (data.length > 9) {
3590
+ ResultFormatter.unknownArr(result, data.slice(9));
3591
+ }
3592
+ this.setDecodeLevel(result, true, "full");
3593
+ return result;
3594
+ }
3595
+ };
3596
+
3597
+ // lib/plugins/Label_44_Base.ts
3598
+ var Label_44_Base = class extends DecoderPlugin {
3599
+ decode(message, options = {}) {
3600
+ const result = this.initResult(message, this.description);
3601
+ const data = message.text.split(",");
3602
+ if (data.length < this.minFields) {
3603
+ return this.failUnknown(result, message.text, options);
3604
+ }
3605
+ this.debug(options, `${this.description}: fields`, data);
3606
+ ResultFormatter.position(
3607
+ result,
3608
+ CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1])
3609
+ );
3610
+ ResultFormatter.departureAirport(result, data[2]);
3611
+ ResultFormatter.arrivalAirport(result, data[3]);
3612
+ ResultFormatter.month(result, Number(data[4].substring(0, 2)));
3613
+ ResultFormatter.day(result, Number(data[4].substring(2, 4)));
3614
+ this.decodeEventFields(result, data, options);
3615
+ this.setDecodeLevel(result, true, "full");
3616
+ return result;
3617
+ }
3618
+ /**
3619
+ * Helper to parse a fuel value from a CSV field.
3620
+ * Returns undefined if the value is not a valid number.
3621
+ */
3622
+ parseFuel(result, value) {
3623
+ const fuel = Number(value);
3624
+ if (!isNaN(fuel)) {
3625
+ ResultFormatter.remainingFuel(result, fuel);
3626
+ }
3627
+ }
3628
+ /**
3629
+ * Helper to add any remaining fields as unknown.
3630
+ */
3631
+ addRemainingFields(result, data, startIndex) {
3632
+ if (data.length > startIndex) {
3633
+ ResultFormatter.unknownArr(result, data.slice(startIndex));
3645
3634
  }
3646
- decodeResult.decoded = true;
3647
- decodeResult.decoder.decodeLevel = "full";
3648
- return decodeResult;
3649
3635
  }
3650
3636
  };
3651
3637
 
3652
3638
  // lib/plugins/Label_44_IN.ts
3653
- var Label_44_IN = class extends DecoderPlugin {
3639
+ var Label_44_IN = class extends Label_44_Base {
3654
3640
  name = "label-44-in";
3641
+ get description() {
3642
+ return "In Gate Report";
3643
+ }
3644
+ get minFields() {
3645
+ return 7;
3646
+ }
3655
3647
  qualifiers() {
3656
3648
  return {
3657
3649
  labels: ["44"],
3658
3650
  preambles: ["00IN01", "00IN02", "00IN03", "IN01", "IN02", "IN03"]
3659
3651
  };
3660
3652
  }
3661
- decode(message, options = {}) {
3662
- const decodeResult = this.defaultResult();
3663
- decodeResult.decoder.name = this.name;
3664
- decodeResult.formatted.description = "In Air Report";
3665
- decodeResult.message = message;
3666
- const data = message.text.split(",");
3667
- if (data.length >= 7) {
3668
- if (options.debug) {
3669
- console.log("Label 44 In Air Report: groups");
3670
- console.log(data);
3671
- }
3672
- ResultFormatter.position(
3673
- decodeResult,
3674
- CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1])
3675
- );
3676
- ResultFormatter.departureAirport(decodeResult, data[2]);
3677
- ResultFormatter.arrivalAirport(decodeResult, data[3]);
3678
- ResultFormatter.month(decodeResult, Number(data[4].substring(0, 2)));
3679
- ResultFormatter.day(decodeResult, Number(data[4].substring(2, 4)));
3680
- ResultFormatter.in(
3681
- decodeResult,
3682
- DateTimeUtils.convertHHMMSSToTod(data[5])
3683
- );
3684
- const fuel = Number(data[6]);
3685
- if (!isNaN(fuel)) {
3686
- ResultFormatter.remainingFuel(decodeResult, Number(fuel));
3687
- }
3688
- if (data.length > 7) {
3689
- ResultFormatter.unknownArr(decodeResult, data.slice(7));
3690
- }
3691
- } else {
3692
- if (options.debug) {
3693
- console.log(`Decoder: Unknown 44 message: ${message.text}`);
3694
- }
3695
- ResultFormatter.unknown(decodeResult, message.text);
3696
- decodeResult.decoded = false;
3697
- decodeResult.decoder.decodeLevel = "none";
3698
- return decodeResult;
3699
- }
3700
- decodeResult.decoded = true;
3701
- decodeResult.decoder.decodeLevel = "full";
3702
- return decodeResult;
3653
+ decodeEventFields(result, data, _options) {
3654
+ ResultFormatter.in(result, DateTimeUtils.convertHHMMSSToTod(data[5]));
3655
+ this.parseFuel(result, data[6]);
3656
+ this.addRemainingFields(result, data, 7);
3703
3657
  }
3704
3658
  };
3705
3659
 
3706
3660
  // lib/plugins/Label_44_OFF.ts
3707
- var Label_44_OFF = class extends DecoderPlugin {
3661
+ var Label_44_OFF = class extends Label_44_Base {
3708
3662
  name = "label-44-off";
3663
+ get description() {
3664
+ return "Off Runway Report";
3665
+ }
3666
+ get minFields() {
3667
+ return 8;
3668
+ }
3709
3669
  qualifiers() {
3710
3670
  return {
3711
3671
  labels: ["44"],
3712
3672
  preambles: ["00OFF01", "00OFF02", "00OFF03", "OFF01", "OFF02", "OFF03"]
3713
3673
  };
3714
3674
  }
3715
- decode(message, options = {}) {
3716
- const decodeResult = this.defaultResult();
3717
- decodeResult.decoder.name = this.name;
3718
- decodeResult.formatted.description = "Off Runway Report";
3719
- decodeResult.message = message;
3720
- const data = message.text.split(",");
3721
- if (data.length >= 8) {
3722
- if (options.debug) {
3723
- console.log("Label 44 Off Runway Report: groups");
3724
- console.log(data);
3725
- }
3726
- ResultFormatter.position(
3727
- decodeResult,
3728
- CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1])
3729
- );
3730
- ResultFormatter.departureAirport(decodeResult, data[2]);
3731
- ResultFormatter.arrivalAirport(decodeResult, data[3]);
3732
- ResultFormatter.month(decodeResult, Number(data[4].substring(0, 2)));
3733
- ResultFormatter.day(decodeResult, Number(data[4].substring(2, 4)));
3734
- ResultFormatter.off(
3735
- decodeResult,
3736
- DateTimeUtils.convertHHMMSSToTod(data[5])
3737
- );
3738
- ResultFormatter.eta(
3739
- decodeResult,
3740
- DateTimeUtils.convertHHMMSSToTod(data[6])
3741
- );
3742
- const fuel = Number(data[7]);
3743
- if (!isNaN(fuel)) {
3744
- ResultFormatter.remainingFuel(decodeResult, Number(fuel));
3745
- }
3746
- if (data.length > 8) {
3747
- ResultFormatter.unknownArr(decodeResult, data.slice(8));
3748
- }
3749
- } else {
3750
- if (options.debug) {
3751
- console.log(`Decoder: Unknown 44 message: ${message.text}`);
3752
- }
3753
- ResultFormatter.unknown(decodeResult, message.text);
3754
- decodeResult.decoded = false;
3755
- decodeResult.decoder.decodeLevel = "none";
3756
- return decodeResult;
3757
- }
3758
- decodeResult.decoded = true;
3759
- decodeResult.decoder.decodeLevel = "full";
3760
- return decodeResult;
3675
+ decodeEventFields(result, data, _options) {
3676
+ ResultFormatter.off(result, DateTimeUtils.convertHHMMSSToTod(data[5]));
3677
+ ResultFormatter.eta(result, DateTimeUtils.convertHHMMSSToTod(data[6]));
3678
+ this.parseFuel(result, data[7]);
3679
+ this.addRemainingFields(result, data, 8);
3761
3680
  }
3762
3681
  };
3763
3682
 
3764
3683
  // lib/plugins/Label_44_ON.ts
3765
- var Label_44_ON = class extends DecoderPlugin {
3684
+ var Label_44_ON = class extends Label_44_Base {
3766
3685
  name = "label-44-on";
3686
+ get description() {
3687
+ return "On Runway Report";
3688
+ }
3689
+ get minFields() {
3690
+ return 7;
3691
+ }
3767
3692
  qualifiers() {
3768
3693
  return {
3769
3694
  labels: ["44"],
3770
3695
  preambles: ["00ON01", "00ON02", "00ON03", "ON01", "ON02", "ON03"]
3771
3696
  };
3772
3697
  }
3773
- decode(message, options = {}) {
3774
- const decodeResult = this.defaultResult();
3775
- decodeResult.decoder.name = this.name;
3776
- decodeResult.formatted.description = "On Runway Report";
3777
- decodeResult.message = message;
3778
- const data = message.text.split(",");
3779
- if (data.length >= 7) {
3780
- if (options.debug) {
3781
- console.log("Label 44 On Runway Report: groups");
3782
- console.log(data);
3783
- }
3784
- ResultFormatter.position(
3785
- decodeResult,
3786
- CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1])
3787
- );
3788
- ResultFormatter.departureAirport(decodeResult, data[2]);
3789
- ResultFormatter.arrivalAirport(decodeResult, data[3]);
3790
- ResultFormatter.month(decodeResult, Number(data[4].substring(0, 2)));
3791
- ResultFormatter.day(decodeResult, Number(data[4].substring(2, 4)));
3792
- ResultFormatter.on(
3793
- decodeResult,
3794
- DateTimeUtils.convertHHMMSSToTod(data[5])
3795
- );
3796
- const fuel = Number(data[6]);
3797
- if (!isNaN(fuel)) {
3798
- ResultFormatter.remainingFuel(decodeResult, Number(fuel));
3799
- }
3800
- if (data.length > 7) {
3801
- ResultFormatter.unknownArr(decodeResult, data.slice(7));
3802
- }
3803
- } else {
3804
- if (options.debug) {
3805
- console.log(`Decoder: Unknown 44 message: ${message.text}`);
3806
- }
3807
- ResultFormatter.unknown(decodeResult, message.text);
3808
- decodeResult.decoded = false;
3809
- decodeResult.decoder.decodeLevel = "none";
3810
- return decodeResult;
3811
- }
3812
- decodeResult.decoded = true;
3813
- decodeResult.decoder.decodeLevel = "full";
3814
- return decodeResult;
3698
+ decodeEventFields(result, data, _options) {
3699
+ ResultFormatter.on(result, DateTimeUtils.convertHHMMSSToTod(data[5]));
3700
+ this.parseFuel(result, data[6]);
3701
+ this.addRemainingFields(result, data, 7);
3815
3702
  }
3816
3703
  };
3817
3704
 
@@ -3825,17 +3712,11 @@ var Label_44_POS = class extends DecoderPlugin {
3825
3712
  };
3826
3713
  }
3827
3714
  decode(message, options = {}) {
3828
- const decodeResult = this.defaultResult();
3829
- decodeResult.decoder.name = this.name;
3830
- decodeResult.formatted.description = "Position Report";
3831
- decodeResult.message = message;
3715
+ const decodeResult = this.initResult(message, "Position Report");
3832
3716
  const regex = /^.*,(?<unsplit_coords>.*),(?<flight_level_or_ground>.*),(?<departure_icao>.*),(?<arrival_icao>.*),(?<current_date>.*),(?<current_time>.*),(?<eta_time>.*),(?<fuel_in_tons>.*)$/;
3833
3717
  const results = message.text.match(regex);
3834
3718
  if (results?.groups) {
3835
- if (options.debug) {
3836
- console.log("Label 44 Position Report: groups");
3837
- console.log(results.groups);
3838
- }
3719
+ this.debug(options, "Position Report: groups", results.groups);
3839
3720
  ResultFormatter.position(
3840
3721
  decodeResult,
3841
3722
  CoordinateUtils.decodeStringCoordinatesDecimalMinutes(
@@ -3868,10 +3749,10 @@ var Label_44_POS = class extends DecoderPlugin {
3868
3749
  );
3869
3750
  ResultFormatter.arrivalAirport(decodeResult, results.groups.arrival_icao);
3870
3751
  ResultFormatter.altitude(decodeResult, flight_level * 100);
3752
+ this.setDecodeLevel(decodeResult, true, "full");
3753
+ return decodeResult;
3871
3754
  }
3872
- decodeResult.decoded = true;
3873
- decodeResult.decoder.decodeLevel = "full";
3874
- return decodeResult;
3755
+ return this.failUnknown(decodeResult, message.text, options);
3875
3756
  }
3876
3757
  };
3877
3758
 
@@ -3949,10 +3830,7 @@ var Label_4A = class extends DecoderPlugin {
3949
3830
  };
3950
3831
  }
3951
3832
  decode(message, options = {}) {
3952
- const decodeResult = this.defaultResult();
3953
- decodeResult.decoder.name = this.name;
3954
- decodeResult.message = message;
3955
- decodeResult.formatted.description = "Latest New Format";
3833
+ const decodeResult = this.initResult(message, "Latest New Format");
3956
3834
  decodeResult.decoded = true;
3957
3835
  const fields = message.text.split(",");
3958
3836
  if (fields.length === 11) {
@@ -4008,13 +3886,7 @@ var Label_4A = class extends DecoderPlugin {
4008
3886
  decodeResult.decoded = false;
4009
3887
  ResultFormatter.unknown(decodeResult, message.text);
4010
3888
  }
4011
- if (decodeResult.decoded) {
4012
- if (!decodeResult.remaining.text)
4013
- decodeResult.decoder.decodeLevel = "full";
4014
- else decodeResult.decoder.decodeLevel = "partial";
4015
- } else {
4016
- decodeResult.decoder.decodeLevel = "none";
4017
- }
3889
+ this.setDecodeLevel(decodeResult, decodeResult.decoded);
4018
3890
  return decodeResult;
4019
3891
  }
4020
3892
  };
@@ -4029,10 +3901,7 @@ var Label_4A_01 = class extends DecoderPlugin {
4029
3901
  };
4030
3902
  }
4031
3903
  decode(message, options = {}) {
4032
- const decodeResult = this.defaultResult();
4033
- decodeResult.decoder.name = this.name;
4034
- decodeResult.message = message;
4035
- decodeResult.formatted.description = "Latest New Format";
3904
+ const decodeResult = this.initResult(message, "Latest New Format");
4036
3905
  decodeResult.decoded = true;
4037
3906
  let rgx = message.text.match(
4038
3907
  /^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)/
@@ -4053,13 +3922,7 @@ var Label_4A_01 = class extends DecoderPlugin {
4053
3922
  decodeResult.decoded = false;
4054
3923
  ResultFormatter.unknown(decodeResult, message.text);
4055
3924
  }
4056
- if (decodeResult.decoded) {
4057
- if (!decodeResult.remaining.text)
4058
- decodeResult.decoder.decodeLevel = "full";
4059
- else decodeResult.decoder.decodeLevel = "partial";
4060
- } else {
4061
- decodeResult.decoder.decodeLevel = "none";
4062
- }
3925
+ this.setDecodeLevel(decodeResult, decodeResult.decoded);
4063
3926
  return decodeResult;
4064
3927
  }
4065
3928
  };
@@ -4074,10 +3937,7 @@ var Label_4A_DIS = class extends DecoderPlugin {
4074
3937
  };
4075
3938
  }
4076
3939
  decode(message, options = {}) {
4077
- const decodeResult = this.defaultResult();
4078
- decodeResult.decoder.name = this.name;
4079
- decodeResult.message = message;
4080
- decodeResult.formatted.description = "Latest New Format";
3940
+ const decodeResult = this.initResult(message, "Latest New Format");
4081
3941
  decodeResult.decoded = true;
4082
3942
  const fields = message.text.split(",");
4083
3943
  ResultFormatter.timestamp(
@@ -4086,13 +3946,7 @@ var Label_4A_DIS = class extends DecoderPlugin {
4086
3946
  );
4087
3947
  ResultFormatter.callsign(decodeResult, fields[2]);
4088
3948
  ResultFormatter.text(decodeResult, fields.slice(3).join(""));
4089
- if (decodeResult.decoded) {
4090
- if (!decodeResult.remaining.text)
4091
- decodeResult.decoder.decodeLevel = "full";
4092
- else decodeResult.decoder.decodeLevel = "partial";
4093
- } else {
4094
- decodeResult.decoder.decodeLevel = "none";
4095
- }
3949
+ this.setDecodeLevel(decodeResult, decodeResult.decoded);
4096
3950
  return decodeResult;
4097
3951
  }
4098
3952
  };
@@ -4107,10 +3961,7 @@ var Label_4A_DOOR = class extends DecoderPlugin {
4107
3961
  };
4108
3962
  }
4109
3963
  decode(message, options = {}) {
4110
- const decodeResult = this.defaultResult();
4111
- decodeResult.decoder.name = this.name;
4112
- decodeResult.message = message;
4113
- decodeResult.formatted.description = "Latest New Format";
3964
+ const decodeResult = this.initResult(message, "Latest New Format");
4114
3965
  decodeResult.decoded = true;
4115
3966
  const fields = message.text.split(" ");
4116
3967
  if (fields.length === 3) {
@@ -4127,13 +3978,7 @@ var Label_4A_DOOR = class extends DecoderPlugin {
4127
3978
  decodeResult.decoded = false;
4128
3979
  ResultFormatter.unknown(decodeResult, message.text);
4129
3980
  }
4130
- if (decodeResult.decoded) {
4131
- if (!decodeResult.remaining.text)
4132
- decodeResult.decoder.decodeLevel = "full";
4133
- else decodeResult.decoder.decodeLevel = "partial";
4134
- } else {
4135
- decodeResult.decoder.decodeLevel = "none";
4136
- }
3981
+ this.setDecodeLevel(decodeResult, decodeResult.decoded);
4137
3982
  return decodeResult;
4138
3983
  }
4139
3984
  };
@@ -4389,9 +4234,10 @@ var Label_80 = class extends DecoderPlugin {
4389
4234
  };
4390
4235
  }
4391
4236
  decode(message, options = {}) {
4392
- const decodeResult = this.defaultResult();
4393
- decodeResult.decoder.name = this.name;
4394
- decodeResult.formatted.description = "Airline Defined Position Report";
4237
+ const decodeResult = this.initResult(
4238
+ message,
4239
+ "Airline Defined Position Report"
4240
+ );
4395
4241
  const lines = message.text.split(/\r?\n/);
4396
4242
  if (lines.length === 1 && lines[0].includes(",")) {
4397
4243
  this.parseCsvFormat(lines[0], decodeResult);
@@ -4417,8 +4263,7 @@ var Label_80 = class extends DecoderPlugin {
4417
4263
  }
4418
4264
  }
4419
4265
  if (decodeResult.formatted.items.length > 0) {
4420
- decodeResult.decoded = true;
4421
- decodeResult.decoder.decodeLevel = decodeResult.remaining.text === void 0 ? "full" : "partial";
4266
+ this.setDecodeLevel(decodeResult, true);
4422
4267
  }
4423
4268
  return decodeResult;
4424
4269
  }
@@ -4944,10 +4789,7 @@ var Label_H1_FLR = class extends DecoderPlugin {
4944
4789
  };
4945
4790
  }
4946
4791
  decode(message, options = {}) {
4947
- let decodeResult = this.defaultResult();
4948
- decodeResult.decoder.name = this.name;
4949
- decodeResult.formatted.description = "Fault Log Report";
4950
- decodeResult.message = message;
4792
+ const decodeResult = this.initResult(message, "Fault Log Report");
4951
4793
  const parts = message.text.split("/FR");
4952
4794
  if (parts.length > 1) {
4953
4795
  const fields = parts[0].split("/");
@@ -4971,15 +4813,9 @@ var Label_H1_FLR = class extends DecoderPlugin {
4971
4813
  label: "Fault Report",
4972
4814
  value: decodeResult.raw.fault_message
4973
4815
  });
4974
- decodeResult.decoded = true;
4975
- decodeResult.decoder.decodeLevel = "partial";
4816
+ this.setDecodeLevel(decodeResult, true, "partial");
4976
4817
  } else {
4977
- if (options.debug) {
4978
- console.log(`Decoder: Unknown H1 message: ${message.text}`);
4979
- }
4980
- ResultFormatter.unknown(decodeResult, message.text);
4981
- decodeResult.decoded = false;
4982
- decodeResult.decoder.decodeLevel = "none";
4818
+ return this.failUnknown(decodeResult, message.text, options);
4983
4819
  }
4984
4820
  return decodeResult;
4985
4821
  }
@@ -4994,30 +4830,21 @@ var Label_H1_M_POS = class extends DecoderPlugin {
4994
4830
  };
4995
4831
  }
4996
4832
  decode(message, options = {}) {
4997
- let decodeResult = this.defaultResult();
4998
- decodeResult.decoder.name = this.name;
4999
- decodeResult.formatted.description = "M-Series Periodic Position Report";
5000
- decodeResult.message = message;
4833
+ const decodeResult = this.initResult(
4834
+ message,
4835
+ "M-Series Periodic Position Report"
4836
+ );
5001
4837
  const headerRegex = /^M(\d{2})A([A-Z]{2})(\d{4})/;
5002
4838
  const headerMatch = message.text.match(headerRegex);
5003
4839
  if (!headerMatch) {
5004
- if (options.debug) {
5005
- console.log(`Decoder: Unknown H1 M-POS message: ${message.text}`);
5006
- }
5007
- ResultFormatter.unknown(decodeResult, message.text);
5008
- decodeResult.decoded = false;
5009
- decodeResult.decoder.decodeLevel = "none";
5010
- return decodeResult;
4840
+ return this.failUnknown(decodeResult, message.text, options);
5011
4841
  }
5012
4842
  const airline = headerMatch[2];
5013
4843
  const flightNum = headerMatch[3];
5014
4844
  const afterHeader = message.text.substring(headerMatch[0].length);
5015
4845
  const fields = afterHeader.split(",");
5016
4846
  if (fields.length < 7) {
5017
- ResultFormatter.unknown(decodeResult, message.text);
5018
- decodeResult.decoded = false;
5019
- decodeResult.decoder.decodeLevel = "none";
5020
- return decodeResult;
4847
+ return this.failUnknown(decodeResult, message.text, options);
5021
4848
  }
5022
4849
  ResultFormatter.flightNumber(decodeResult, `${airline}${flightNum}`);
5023
4850
  ResultFormatter.departureAirport(decodeResult, fields[0]);
@@ -5041,8 +4868,11 @@ var Label_H1_M_POS = class extends DecoderPlugin {
5041
4868
  if (fields.length > 7) {
5042
4869
  ResultFormatter.unknownArr(decodeResult, fields.slice(7));
5043
4870
  }
5044
- decodeResult.decoded = true;
5045
- decodeResult.decoder.decodeLevel = fields.length > 7 ? "partial" : "full";
4871
+ this.setDecodeLevel(
4872
+ decodeResult,
4873
+ true,
4874
+ fields.length > 7 ? "partial" : "full"
4875
+ );
5046
4876
  return decodeResult;
5047
4877
  }
5048
4878
  };
@@ -5400,10 +5230,7 @@ var Label_H1_WRN = class extends DecoderPlugin {
5400
5230
  };
5401
5231
  }
5402
5232
  decode(message, options = {}) {
5403
- let decodeResult = this.defaultResult();
5404
- decodeResult.decoder.name = this.name;
5405
- decodeResult.formatted.description = "Warning Message";
5406
- decodeResult.message = message;
5233
+ const decodeResult = this.initResult(message, "Warning Message");
5407
5234
  const parts = message.text.split("/WN");
5408
5235
  if (parts.length > 1) {
5409
5236
  const fields = parts[0].split("/");
@@ -5424,15 +5251,9 @@ var Label_H1_WRN = class extends DecoderPlugin {
5424
5251
  label: "Warning Message",
5425
5252
  value: decodeResult.raw.warning_message
5426
5253
  });
5427
- decodeResult.decoded = true;
5428
- decodeResult.decoder.decodeLevel = "partial";
5254
+ this.setDecodeLevel(decodeResult, true, "partial");
5429
5255
  } else {
5430
- if (options.debug) {
5431
- console.log(`Decoder: Unknown H1 message: ${message.text}`);
5432
- }
5433
- ResultFormatter.unknown(decodeResult, message.text);
5434
- decodeResult.decoded = false;
5435
- decodeResult.decoder.decodeLevel = "none";
5256
+ return this.failUnknown(decodeResult, message.text, options);
5436
5257
  }
5437
5258
  return decodeResult;
5438
5259
  }
@@ -6440,12 +6261,11 @@ var Label_SQ = class extends DecoderPlugin {
6440
6261
  };
6441
6262
  }
6442
6263
  decode(message, options = {}) {
6443
- const decodeResult = this.defaultResult();
6444
- decodeResult.decoder.name = this.name;
6264
+ const decodeResult = this.initResult(message, "Ground Station Squitter");
6445
6265
  decodeResult.raw.preamble = message.text.substring(0, 4);
6446
- decodeResult.raw.version = message.text.substring(1, 2);
6266
+ decodeResult.raw.version = Number(message.text.substring(1, 2));
6447
6267
  decodeResult.raw.network = message.text.substring(3, 4);
6448
- if (decodeResult.raw.version === "2") {
6268
+ if (decodeResult.raw.version === 2) {
6449
6269
  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+)\/.*/;
6450
6270
  const result = message.text.match(regex);
6451
6271
  if (result?.groups && result.length >= 8) {
@@ -6461,7 +6281,6 @@ var Label_SQ = class extends DecoderPlugin {
6461
6281
  decodeResult.raw.vdlFrequency = Number(result.groups.vfreq) / 1e3;
6462
6282
  }
6463
6283
  }
6464
- decodeResult.formatted.description = "Ground Station Squitter";
6465
6284
  var formattedNetwork = "Unknown";
6466
6285
  if (decodeResult.raw.network == "A") {
6467
6286
  formattedNetwork = "ARINC";
@@ -6479,7 +6298,7 @@ var Label_SQ = class extends DecoderPlugin {
6479
6298
  type: "version",
6480
6299
  code: "VER",
6481
6300
  label: "Version",
6482
- value: decodeResult.raw.version
6301
+ value: String(decodeResult.raw.version)
6483
6302
  }
6484
6303
  ];
6485
6304
  if (decodeResult.raw.groundStation) {
@@ -6532,8 +6351,7 @@ var Label_SQ = class extends DecoderPlugin {
6532
6351
  value: `${decodeResult.raw.vdlFrequency} MHz`
6533
6352
  });
6534
6353
  }
6535
- decodeResult.decoded = true;
6536
- decodeResult.decoder.decodeLevel = "full";
6354
+ this.setDecodeLevel(decodeResult, true, "full");
6537
6355
  return decodeResult;
6538
6356
  }
6539
6357
  };
@@ -6685,99 +6503,123 @@ var Label_QQ = class extends DecoderPlugin {
6685
6503
  };
6686
6504
 
6687
6505
  // lib/MessageDecoder.ts
6506
+ var pluginClasses = [
6507
+ CBand,
6508
+ Arinc702,
6509
+ Label_ColonComma,
6510
+ Label_5Z_Slash,
6511
+ Label_10_LDR,
6512
+ Label_10_POS,
6513
+ Label_10_Slash,
6514
+ Label_12_N_Space,
6515
+ Label_12_POS,
6516
+ Label_13Through18_Slash,
6517
+ Label_15,
6518
+ Label_15_FST,
6519
+ Label_16_Honeywell,
6520
+ Label_16_N_Space,
6521
+ Label_16_POSA1,
6522
+ Label_16_TOD,
6523
+ Label_1L_3Line,
6524
+ Label_1L_070,
6525
+ Label_1L_660,
6526
+ Label_1L_Slash,
6527
+ Label_20_POS,
6528
+ Label_21_POS,
6529
+ Label_22_OFF,
6530
+ Label_22_POS,
6531
+ Label_24_Slash,
6532
+ Label_2P_FM3,
6533
+ Label_2P_FM4,
6534
+ Label_2P_FM5,
6535
+ Label_30_Slash_EA,
6536
+ Label_44_ETA,
6537
+ Label_44_IN,
6538
+ Label_44_OFF,
6539
+ Label_44_ON,
6540
+ Label_44_POS,
6541
+ Label_44_Slash,
6542
+ Label_4A,
6543
+ Label_4A_01,
6544
+ Label_4A_DIS,
6545
+ Label_4A_DOOR,
6546
+ Label_4A_Slash_01,
6547
+ Label_4N,
6548
+ Label_4T_AGFSR,
6549
+ Label_4T_ETA,
6550
+ Label_B6_Forwardslash,
6551
+ Label_H2_02E,
6552
+ Label_H1_ATIS,
6553
+ Label_H1_EZF,
6554
+ Label_H1_FLR,
6555
+ Label_H1_M_POS,
6556
+ Label_H1_OHMA,
6557
+ Label_H1_OFP,
6558
+ Label_H1_Paren,
6559
+ Label_H1_WRN,
6560
+ Label_H1_StarPOS,
6561
+ Label_HX,
6562
+ Label_58,
6563
+ Label_80,
6564
+ Label_83,
6565
+ Label_8E,
6566
+ Label_1M_Slash,
6567
+ Label_MA,
6568
+ Label_SQ,
6569
+ Label_QP,
6570
+ Label_QQ,
6571
+ Label_QR,
6572
+ Label_QS
6573
+ ];
6688
6574
  var MessageDecoder = class {
6689
6575
  name;
6690
6576
  plugins;
6691
6577
  debug;
6578
+ /** Maps a label string to the plugins registered for it, preserving registration order. */
6579
+ labelIndex = /* @__PURE__ */ new Map();
6580
+ /** Plugins that match all labels (qualifier label '*'). */
6581
+ wildcardPlugins = [];
6692
6582
  constructor() {
6693
6583
  this.name = "acars-decoder-typescript";
6694
6584
  this.plugins = [];
6695
6585
  this.debug = false;
6696
- this.registerPlugin(new CBand(this));
6697
- this.registerPlugin(new Arinc702(this));
6698
- this.registerPlugin(new Label_ColonComma(this));
6699
- this.registerPlugin(new Label_5Z_Slash(this));
6700
- this.registerPlugin(new Label_10_LDR(this));
6701
- this.registerPlugin(new Label_10_POS(this));
6702
- this.registerPlugin(new Label_10_Slash(this));
6703
- this.registerPlugin(new Label_12_N_Space(this));
6704
- this.registerPlugin(new Label_12_POS(this));
6705
- this.registerPlugin(new Label_13Through18_Slash(this));
6706
- this.registerPlugin(new Label_15(this));
6707
- this.registerPlugin(new Label_15_FST(this));
6708
- this.registerPlugin(new Label_16_Honeywell(this));
6709
- this.registerPlugin(new Label_16_N_Space(this));
6710
- this.registerPlugin(new Label_16_POSA1(this));
6711
- this.registerPlugin(new Label_16_TOD(this));
6712
- this.registerPlugin(new Label_1L_3Line(this));
6713
- this.registerPlugin(new Label_1L_070(this));
6714
- this.registerPlugin(new Label_1L_660(this));
6715
- this.registerPlugin(new Label_1L_Slash(this));
6716
- this.registerPlugin(new Label_20_POS(this));
6717
- this.registerPlugin(new Label_21_POS(this));
6718
- this.registerPlugin(new Label_22_OFF(this));
6719
- this.registerPlugin(new Label_22_POS(this));
6720
- this.registerPlugin(new Label_24_Slash(this));
6721
- this.registerPlugin(new Label_2P_FM3(this));
6722
- this.registerPlugin(new Label_2P_FM4(this));
6723
- this.registerPlugin(new Label_2P_FM5(this));
6724
- this.registerPlugin(new Label_30_Slash_EA(this));
6725
- this.registerPlugin(new Label_44_ETA(this));
6726
- this.registerPlugin(new Label_44_IN(this));
6727
- this.registerPlugin(new Label_44_OFF(this));
6728
- this.registerPlugin(new Label_44_ON(this));
6729
- this.registerPlugin(new Label_44_POS(this));
6730
- this.registerPlugin(new Label_44_Slash(this));
6731
- this.registerPlugin(new Label_4A(this));
6732
- this.registerPlugin(new Label_4A_01(this));
6733
- this.registerPlugin(new Label_4A_DIS(this));
6734
- this.registerPlugin(new Label_4A_DOOR(this));
6735
- this.registerPlugin(new Label_4A_Slash_01(this));
6736
- this.registerPlugin(new Label_4N(this));
6737
- this.registerPlugin(new Label_4T_AGFSR(this));
6738
- this.registerPlugin(new Label_4T_ETA(this));
6739
- this.registerPlugin(new Label_B6_Forwardslash(this));
6740
- this.registerPlugin(new Label_H2_02E(this));
6741
- this.registerPlugin(new Label_H1_ATIS(this));
6742
- this.registerPlugin(new Label_H1_EZF(this));
6743
- this.registerPlugin(new Label_H1_FLR(this));
6744
- this.registerPlugin(new Label_H1_M_POS(this));
6745
- this.registerPlugin(new Label_H1_OHMA(this));
6746
- this.registerPlugin(new Label_H1_OFP(this));
6747
- this.registerPlugin(new Label_H1_Paren(this));
6748
- this.registerPlugin(new Label_H1_WRN(this));
6749
- this.registerPlugin(new Label_H1_StarPOS(this));
6750
- this.registerPlugin(new Label_HX(this));
6751
- this.registerPlugin(new Label_58(this));
6752
- this.registerPlugin(new Label_80(this));
6753
- this.registerPlugin(new Label_83(this));
6754
- this.registerPlugin(new Label_8E(this));
6755
- this.registerPlugin(new Label_1M_Slash(this));
6756
- this.registerPlugin(new Label_MA(this));
6757
- this.registerPlugin(new Label_SQ(this));
6758
- this.registerPlugin(new Label_QP(this));
6759
- this.registerPlugin(new Label_QQ(this));
6760
- this.registerPlugin(new Label_QR(this));
6761
- this.registerPlugin(new Label_QS(this));
6586
+ for (const PluginClass of pluginClasses) {
6587
+ this.registerPlugin(new PluginClass(this));
6588
+ }
6762
6589
  }
6763
6590
  registerPlugin(plugin) {
6764
6591
  this.plugins.push(plugin);
6592
+ const qualifiers = plugin.qualifiers();
6593
+ for (const label of qualifiers.labels) {
6594
+ if (label === "*") {
6595
+ this.wildcardPlugins.push(plugin);
6596
+ } else {
6597
+ let bucket = this.labelIndex.get(label);
6598
+ if (!bucket) {
6599
+ bucket = [];
6600
+ this.labelIndex.set(label, bucket);
6601
+ }
6602
+ bucket.push(plugin);
6603
+ }
6604
+ }
6765
6605
  return true;
6766
6606
  }
6767
6607
  decode(message, options = {}) {
6768
- const usablePlugins = this.plugins.filter((plugin) => {
6769
- const qualifiers = plugin.qualifiers();
6770
- if (qualifiers.labels.includes(message.label) || qualifiers.labels.length === 1 && qualifiers.labels[0] === "*") {
6771
- if (qualifiers.preambles && qualifiers.preambles.length > 0) {
6772
- const matching = qualifiers.preambles.filter((preamble) => {
6773
- return message.text.substring(0, preamble.length) === preamble;
6774
- });
6775
- return matching.length >= 1;
6776
- } else {
6777
- return true;
6778
- }
6608
+ const labelPlugins = this.labelIndex.get(message.label) ?? [];
6609
+ const seen = /* @__PURE__ */ new Set();
6610
+ const candidates = [];
6611
+ for (const plugin of [...this.wildcardPlugins, ...labelPlugins]) {
6612
+ if (!seen.has(plugin)) {
6613
+ seen.add(plugin);
6614
+ candidates.push(plugin);
6615
+ }
6616
+ }
6617
+ const usablePlugins = candidates.filter((plugin) => {
6618
+ const preambles = plugin.qualifiers().preambles;
6619
+ if (!preambles || preambles.length === 0) {
6620
+ return true;
6779
6621
  }
6780
- return false;
6622
+ return preambles.some((p) => message.text.startsWith(p));
6781
6623
  });
6782
6624
  if (options.debug) {
6783
6625
  console.log("Usable plugins");
@@ -6803,7 +6645,7 @@ var MessageDecoder = class {
6803
6645
  };
6804
6646
  for (let i = 0; i < usablePlugins.length; i++) {
6805
6647
  const plugin = usablePlugins[i];
6806
- result = plugin.decode(message);
6648
+ result = plugin.decode(message, options);
6807
6649
  if (result.decoded) {
6808
6650
  break;
6809
6651
  }