This commit is contained in:
James Wilson 2017-01-24 17:12:14 -06:00
commit bbfdd45cc3
269 changed files with 1560 additions and 1074 deletions

View file

@ -28,10 +28,10 @@ all: dump1090 view1090
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@ $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
dump1090: dump1090.o anet.o interactive.o mode_ac.o mode_s.o net_io.o crc.o demod_2400.o stats.o cpr.o icao_filter.o track.o util.o convert.o $(COMPAT) dump1090: dump1090.o anet.o interactive.o mode_ac.o mode_s.o net_io.o crc.o demod_2400.o stats.o cpr.o icao_filter.o track.o util.o convert.o $(COMPAT)
$(CC) -g -o $@ $^ $(LDFLAGS) $(LIBS) $(LIBS_RTLSDR) $(CC) -g -o $@ $^ $(LDFLAGS) $(LIBS) $(LIBS_RTLSDR) -lncurses
view1090: view1090.o anet.o interactive.o mode_ac.o mode_s.o net_io.o crc.o stats.o cpr.o icao_filter.o track.o util.o $(COMPAT) view1090: view1090.o anet.o interactive.o mode_ac.o mode_s.o net_io.o crc.o stats.o cpr.o icao_filter.o track.o util.o $(COMPAT)
$(CC) -g -o $@ $^ $(LDFLAGS) $(LIBS) $(CC) -g -o $@ $^ $(LDFLAGS) $(LIBS) -lncurses
faup1090: faup1090.o anet.o mode_ac.o mode_s.o net_io.o crc.o stats.o cpr.o icao_filter.o track.o util.o $(COMPAT) faup1090: faup1090.o anet.o mode_ac.o mode_s.o net_io.o crc.o stats.o cpr.o icao_filter.o track.o util.o $(COMPAT)
$(CC) -g -o $@ $^ $(LDFLAGS) $(LIBS) $(CC) -g -o $@ $^ $(LDFLAGS) $(LIBS)

View file

@ -30,11 +30,13 @@ static void convert_uc8_nodc(void *iq_data,
uint16_t *mag_data, uint16_t *mag_data,
unsigned nsamples, unsigned nsamples,
struct converter_state *state, struct converter_state *state,
double *out_power) double *out_mean_level,
double *out_mean_power)
{ {
uint16_t *in = iq_data; uint16_t *in = iq_data;
unsigned i; unsigned i;
uint64_t power = 0; uint64_t sum_level = 0;
uint64_t sum_power = 0;
uint16_t mag; uint16_t mag;
MODES_NOTUSED(state); MODES_NOTUSED(state);
@ -43,45 +45,58 @@ static void convert_uc8_nodc(void *iq_data,
for (i = 0; i < (nsamples>>3); ++i) { for (i = 0; i < (nsamples>>3); ++i) {
mag = Modes.maglut[*in++]; mag = Modes.maglut[*in++];
*mag_data++ = mag; *mag_data++ = mag;
power += (uint32_t)mag * (uint32_t)mag; sum_level += mag;
sum_power += (uint32_t)mag * (uint32_t)mag;
mag = Modes.maglut[*in++]; mag = Modes.maglut[*in++];
*mag_data++ = mag; *mag_data++ = mag;
power += (uint32_t)mag * (uint32_t)mag; sum_level += mag;
sum_power += (uint32_t)mag * (uint32_t)mag;
mag = Modes.maglut[*in++]; mag = Modes.maglut[*in++];
*mag_data++ = mag; *mag_data++ = mag;
power += (uint32_t)mag * (uint32_t)mag; sum_level += mag;
sum_power += (uint32_t)mag * (uint32_t)mag;
mag = Modes.maglut[*in++]; mag = Modes.maglut[*in++];
*mag_data++ = mag; *mag_data++ = mag;
power += (uint32_t)mag * (uint32_t)mag; sum_level += mag;
sum_power += (uint32_t)mag * (uint32_t)mag;
mag = Modes.maglut[*in++]; mag = Modes.maglut[*in++];
*mag_data++ = mag; *mag_data++ = mag;
power += (uint32_t)mag * (uint32_t)mag; sum_level += mag;
sum_power += (uint32_t)mag * (uint32_t)mag;
mag = Modes.maglut[*in++]; mag = Modes.maglut[*in++];
*mag_data++ = mag; *mag_data++ = mag;
power += (uint32_t)mag * (uint32_t)mag; sum_level += mag;
sum_power += (uint32_t)mag * (uint32_t)mag;
mag = Modes.maglut[*in++]; mag = Modes.maglut[*in++];
*mag_data++ = mag; *mag_data++ = mag;
power += (uint32_t)mag * (uint32_t)mag; sum_level += mag;
sum_power += (uint32_t)mag * (uint32_t)mag;
mag = Modes.maglut[*in++]; mag = Modes.maglut[*in++];
*mag_data++ = mag; *mag_data++ = mag;
power += (uint32_t)mag * (uint32_t)mag; sum_level += mag;
sum_power += (uint32_t)mag * (uint32_t)mag;
} }
for (i = 0; i < (nsamples&7); ++i) { for (i = 0; i < (nsamples&7); ++i) {
mag = Modes.maglut[*in++]; mag = Modes.maglut[*in++];
*mag_data++ = mag; *mag_data++ = mag;
power += (uint32_t)mag * (uint32_t)mag; sum_level += mag;
sum_power += (uint32_t)mag * (uint32_t)mag;
} }
if (out_power) { if (out_mean_level) {
*out_power = power / 65535.0 / 65535.0; *out_mean_level = sum_level / 65536.0 / nsamples;
}
if (out_mean_power) {
*out_mean_power = sum_power / 65535.0 / 65535.0 / nsamples;
} }
} }
@ -89,10 +104,10 @@ static void convert_uc8_generic(void *iq_data,
uint16_t *mag_data, uint16_t *mag_data,
unsigned nsamples, unsigned nsamples,
struct converter_state *state, struct converter_state *state,
double *out_power) double *out_mean_level,
double *out_mean_power)
{ {
uint8_t *in = iq_data; uint8_t *in = iq_data;
float power = 0.0;
float z1_I = state->z1_I; float z1_I = state->z1_I;
float z1_Q = state->z1_Q; float z1_Q = state->z1_Q;
const float dc_a = state->dc_a; const float dc_a = state->dc_a;
@ -101,6 +116,7 @@ static void convert_uc8_generic(void *iq_data,
unsigned i; unsigned i;
uint8_t I, Q; uint8_t I, Q;
float fI, fQ, magsq; float fI, fQ, magsq;
float sum_level = 0, sum_power = 0;
for (i = 0; i < nsamples; ++i) { for (i = 0; i < nsamples; ++i) {
I = *in++; I = *in++;
@ -118,25 +134,32 @@ static void convert_uc8_generic(void *iq_data,
if (magsq > 1) if (magsq > 1)
magsq = 1; magsq = 1;
power += magsq; float mag = sqrtf(magsq);
*mag_data++ = (uint16_t)(sqrtf(magsq) * 65535.0 + 0.5); sum_power += magsq;
sum_level += mag;
*mag_data++ = (uint16_t)(mag * 65535.0 + 0.5);
} }
state->z1_I = z1_I; state->z1_I = z1_I;
state->z1_Q = z1_Q; state->z1_Q = z1_Q;
if (out_power) if (out_mean_level) {
*out_power = power; *out_mean_level = sum_level / nsamples;
}
if (out_mean_power) {
*out_mean_power = sum_power / nsamples;
}
} }
static void convert_sc16_generic(void *iq_data, static void convert_sc16_generic(void *iq_data,
uint16_t *mag_data, uint16_t *mag_data,
unsigned nsamples, unsigned nsamples,
struct converter_state *state, struct converter_state *state,
double *out_power) double *out_mean_level,
double *out_mean_power)
{ {
uint16_t *in = iq_data; uint16_t *in = iq_data;
float power = 0.0;
float z1_I = state->z1_I; float z1_I = state->z1_I;
float z1_Q = state->z1_Q; float z1_Q = state->z1_Q;
const float dc_a = state->dc_a; const float dc_a = state->dc_a;
@ -145,6 +168,7 @@ static void convert_sc16_generic(void *iq_data,
unsigned i; unsigned i;
int16_t I, Q; int16_t I, Q;
float fI, fQ, magsq; float fI, fQ, magsq;
float sum_level = 0, sum_power = 0;
for (i = 0; i < nsamples; ++i) { for (i = 0; i < nsamples; ++i) {
I = (int16_t)le16toh(*in++); I = (int16_t)le16toh(*in++);
@ -162,25 +186,32 @@ static void convert_sc16_generic(void *iq_data,
if (magsq > 1) if (magsq > 1)
magsq = 1; magsq = 1;
power += magsq; float mag = sqrtf(magsq);
*mag_data++ = (uint16_t)(sqrtf(magsq) * 65535.0 + 0.5); sum_power += magsq;
sum_level += mag;
*mag_data++ = (uint16_t)(mag * 65535.0 + 0.5);
} }
state->z1_I = z1_I; state->z1_I = z1_I;
state->z1_Q = z1_Q; state->z1_Q = z1_Q;
if (out_power) if (out_mean_level) {
*out_power = power; *out_mean_level = sum_level / nsamples;
}
if (out_mean_power) {
*out_mean_power = sum_power / nsamples;
}
} }
static void convert_sc16q11_generic(void *iq_data, static void convert_sc16q11_generic(void *iq_data,
uint16_t *mag_data, uint16_t *mag_data,
unsigned nsamples, unsigned nsamples,
struct converter_state *state, struct converter_state *state,
double *out_power) double *out_mean_level,
double *out_mean_power)
{ {
uint16_t *in = iq_data; uint16_t *in = iq_data;
float power = 0.0;
float z1_I = state->z1_I; float z1_I = state->z1_I;
float z1_Q = state->z1_Q; float z1_Q = state->z1_Q;
const float dc_a = state->dc_a; const float dc_a = state->dc_a;
@ -189,6 +220,7 @@ static void convert_sc16q11_generic(void *iq_data,
unsigned i; unsigned i;
int16_t I, Q; int16_t I, Q;
float fI, fQ, magsq; float fI, fQ, magsq;
float sum_level = 0, sum_power = 0;
for (i = 0; i < nsamples; ++i) { for (i = 0; i < nsamples; ++i) {
I = (int16_t)le16toh(*in++); I = (int16_t)le16toh(*in++);
@ -206,15 +238,22 @@ static void convert_sc16q11_generic(void *iq_data,
if (magsq > 1) if (magsq > 1)
magsq = 1; magsq = 1;
power += magsq; float mag = sqrtf(magsq);
sum_power += magsq;
sum_level += mag;
*mag_data++ = (uint16_t)(sqrtf(magsq) * 65535.0 + 0.5); *mag_data++ = (uint16_t)(sqrtf(magsq) * 65535.0 + 0.5);
} }
state->z1_I = z1_I; state->z1_I = z1_I;
state->z1_Q = z1_Q; state->z1_Q = z1_Q;
if (out_power) if (out_mean_level) {
*out_power = power; *out_mean_level = sum_level / nsamples;
}
if (out_mean_power) {
*out_mean_power = sum_power / nsamples;
}
} }
static struct { static struct {

View file

@ -27,7 +27,8 @@ typedef void (*iq_convert_fn)(void *iq_data,
uint16_t *mag_data, uint16_t *mag_data,
unsigned nsamples, unsigned nsamples,
struct converter_state *state, struct converter_state *state,
double *out_power); double *out_mean_level,
double *out_mean_power);
iq_convert_fn init_converter(input_format_t format, iq_convert_fn init_converter(input_format_t format,
double sample_rate, double sample_rate,

View file

@ -2,7 +2,7 @@ Source: dump1090-fa
Section: embedded Section: embedded
Priority: extra Priority: extra
Maintainer: Oliver Jowett <oliver@mutability.co.uk> Maintainer: Oliver Jowett <oliver@mutability.co.uk>
Build-Depends: debhelper(>=9), libusb-1.0-0-dev, pkg-config, cmake Build-Depends: debhelper(>=9), libusb-1.0-0-dev, pkg-config, cmake, libncurses5-dev
Standards-Version: 3.9.3 Standards-Version: 3.9.3
Homepage: https://github.com/mutability/dump1090 Homepage: https://github.com/mutability/dump1090
Vcs-Git: https://github.com/mutability/dump1090.git Vcs-Git: https://github.com/mutability/dump1090.git

39
debian/changelog vendored
View file

@ -1,3 +1,42 @@
dump1090-fa (3.3.0) stable; urgency=medium
* Improvements to the Mode A/C demodulator.
* Automatically enable Mode A/C if a Beast command requesting it is received.
(disable with --no-modeac-auto)
* Process the radarcape position message, emit it from faup1090.
* If view1090 is started with --modeac, request Mode A/C data from dump1090.
* Remove the last traces of the internal webserver.
* Updated the FlightAware aircraft data export.
* Updated the default package-based maximum range to 360NM to match what
piaware-support configured for sdcard installs.
* Remove internal webserver code entirely (previously, it was just disabled
at compile time).
* Tweak the timing reported for Mode S and Mode A/C messages to match how
the Beast/Radarcape does it. This affects the interval between Mode S
and Mode A/C messages only; intervals between Mode S messages and other
Mode S messages, or A/C and other A/C, are unchanged.
-- Oliver Jowett <oliver@mutability.co.uk> Sun, 15 Jan 2017 13:35:56 +0000
dump1090-fa (3.2.0) stable; urgency=medium
* Fix a stray extra comma in port 30003 output if only GNSS altitude
was available
* Track CPR encoding type directly rather than inferring it from airground;
using airground meant some position messages that should be usable were
not used
* Mode A/C aircraft association tuning, allows dump1090 to handle much
higher A/C rates without chewing tons of CPU
* Map: Decrease the maximum marker size shown
* Map: Show additional datasource information (TIS-B etc) in table mode
* Map: Move the datablock so it doesn't overlap the zoom control
* Map: Allow skipping the history load by adding a #nohistory fragment
to the URL (e.g. for high latency connections)
* view1090-fa: Use ncurses to reduce flicker on remote connections
* view1090-fa: Fix knots -> km/h conversion in interactive mode
-- Oliver Jowett <oliver@mutability.co.uk> Tue, 25 Oct 2016 23:40:01 +0100
dump1090-fa (3.1.0) stable; urgency=medium dump1090-fa (3.1.0) stable; urgency=medium
* Update to latest dump1090-mutability master * Update to latest dump1090-mutability master

2
debian/control vendored
View file

@ -2,7 +2,7 @@ Source: dump1090-fa
Section: embedded Section: embedded
Priority: extra Priority: extra
Maintainer: Oliver Jowett <oliver@mutability.co.uk> Maintainer: Oliver Jowett <oliver@mutability.co.uk>
Build-Depends: debhelper(>=9), librtlsdr-dev, libusb-1.0-0-dev, pkg-config, dh-systemd Build-Depends: debhelper(>=9), librtlsdr-dev, libusb-1.0-0-dev, pkg-config, dh-systemd, libncurses5-dev
Standards-Version: 3.9.3 Standards-Version: 3.9.3
Homepage: https://github.com/mutability/dump1090 Homepage: https://github.com/mutability/dump1090
Vcs-Git: https://github.com/mutability/dump1090.git Vcs-Git: https://github.com/mutability/dump1090.git

View file

@ -7,6 +7,6 @@
# file will be lost. # file will be lost.
RECEIVER_OPTIONS="--device-index 0 --gain -10 --ppm 0 --net-bo-port 30005" RECEIVER_OPTIONS="--device-index 0 --gain -10 --ppm 0 --net-bo-port 30005"
DECODER_OPTIONS="--max-range 300" DECODER_OPTIONS="--max-range 360"
NET_OPTIONS="--net --net-heartbeat 60 --net-ro-size 1000 --net-ro-interval 1 --net-ri-port 0 --net-ro-port 30002 --net-sbs-port 30003 --net-bi-port 30004,30104 --net-bo-port 30005" NET_OPTIONS="--net --net-heartbeat 60 --net-ro-size 1000 --net-ro-interval 1 --net-ri-port 0 --net-ro-port 30002 --net-sbs-port 30003 --net-bi-port 30004,30104 --net-bo-port 30005"
JSON_OPTIONS="--json-location-accuracy 1" JSON_OPTIONS="--json-location-accuracy 1"

View file

@ -19,6 +19,12 @@
#include "dump1090.h" #include "dump1090.h"
#include <assert.h>
#ifdef MODEAC_DEBUG
#include <gd.h>
#endif
// 2.4MHz sampling rate version // 2.4MHz sampling rate version
// //
// When sampling at 2.4MHz we have exactly 6 samples per 5 symbols. // When sampling at 2.4MHz we have exactly 6 samples per 5 symbols.
@ -298,7 +304,11 @@ void demodulate2400(struct mag_buf *mag)
// Set initial mm structure details // Set initial mm structure details
mm = zeroMessage; mm = zeroMessage;
mm.timestampMsg = mag->sampleTimestamp + (j*5) + bestphase;
// For consistency with how the Beast / Radarcape does it,
// we report the timestamp at the end of bit 56 (even if
// the frame is a 112-bit frame)
mm.timestampMsg = mag->sampleTimestamp + j*5 + (8 + 56) * 12 + bestphase;
// compute message receive time as block-start-time + difference in the 12MHz clock // compute message receive time as block-start-time + difference in the 12MHz clock
mm.sysTimestampMsg = mag->sysTimestamp; // start of block time mm.sysTimestampMsg = mag->sysTimestamp; // start of block time
@ -360,12 +370,91 @@ void demodulate2400(struct mag_buf *mag)
/* update noise power */ /* update noise power */
{ {
double sum_signal_power = sum_scaled_signal_power / 65535.0 / 65535.0; double sum_signal_power = sum_scaled_signal_power / 65535.0 / 65535.0;
Modes.stats_current.noise_power_sum += (mag->total_power - sum_signal_power); Modes.stats_current.noise_power_sum += (mag->mean_power * mag->length - sum_signal_power);
Modes.stats_current.noise_power_count += mag->length; Modes.stats_current.noise_power_count += mag->length;
} }
} }
#ifdef MODEAC_DEBUG
static int yscale(unsigned signal)
{
return (int) (299 - 299.0 * signal / 65536.0);
}
static void draw_modeac(uint16_t *m, unsigned modeac, unsigned f1_clock, unsigned noise_threshold, unsigned signal_threshold, unsigned bits, unsigned noisy_bits, unsigned uncertain_bits)
{
// 25 bits at 87*60MHz
// use 1 pixel = 30MHz = 1087 pixels
gdImagePtr im = gdImageCreate(1088, 300);
int red = gdImageColorAllocate(im, 255, 0, 0);
int brightgreen = gdImageColorAllocate(im, 0, 255, 0);
int darkgreen = gdImageColorAllocate(im, 0, 180, 0);
int blue = gdImageColorAllocate(im, 0, 0, 255);
int grey = gdImageColorAllocate(im, 200, 200, 200);
int white = gdImageColorAllocate(im, 255, 255, 255);
int black = gdImageColorAllocate(im, 0, 0, 0);
gdImageFilledRectangle(im, 0, 0, 1087, 299, white);
// draw samples
for (unsigned pixel = 0; pixel < 1088; ++pixel) {
int clock_offset = (pixel - 150) * 2;
int bit = clock_offset / 87;
int sample = (f1_clock + clock_offset) / 25;
int bitoffset = clock_offset % 87;
int color;
if (sample < 0)
continue;
if (clock_offset < 0 || bit >= 20) {
color = grey;
} else if (bitoffset < 27 && (uncertain_bits & (1 << (19-bit)))) {
color = red;
} else if (bitoffset >= 27 && (noisy_bits & (1 << (19-bit)))) {
color = red;
} else if (bitoffset >= 27) {
color = grey;
} else if (bits & (1 << (19-bit))) {
color = brightgreen;
} else {
color = darkgreen;
}
gdImageLine(im, pixel, 299, pixel, yscale(m[sample]), color);
}
// draw bit boundaries
for (unsigned bit = 0; bit < 20; ++bit) {
unsigned clock = 87 * bit;
unsigned pixel0 = clock / 2 + 150;
unsigned pixel1 = (clock + 27) / 2 + 150;
gdImageLine(im, pixel0, 0, pixel0, 299, (bit == 0 || bit == 14) ? black : grey);
gdImageLine(im, pixel1, 0, pixel1, 299, (bit == 0 || bit == 14) ? black : grey);
}
// draw thresholds
gdImageLine(im, 0, yscale(noise_threshold), 1087, yscale(noise_threshold), blue);
gdImageLine(im, 0, yscale(signal_threshold), 1087, yscale(signal_threshold), blue);
// save it
static int file_counter;
char filename[PATH_MAX];
sprintf(filename, "modeac_%04X_%04d.png", modeac, ++file_counter);
fprintf(stderr, "writing %s\n", filename);
FILE *pngout = fopen(filename, "wb");
gdImagePng(im, pngout);
fclose(pngout);
gdImageDestroy(im);
}
#endif
////////// //////////
////////// MODE A/C ////////// MODE A/C
@ -389,6 +478,9 @@ void demodulate2400AC(struct mag_buf *mag)
memset(&mm, 0, sizeof(mm)); memset(&mm, 0, sizeof(mm));
double noise_stddev = sqrt(mag->mean_power - mag->mean_level * mag->mean_level); // Var(X) = E[(X-E[X])^2] = E[X^2] - (E[X])^2
unsigned noise_level = (unsigned) ((mag->mean_power + noise_stddev) * 65535 + 0.5);
for (f1_sample = 1; f1_sample < mlen; ++f1_sample) { for (f1_sample = 1; f1_sample < mlen; ++f1_sample) {
// Mode A/C messages should match this bit sequence: // Mode A/C messages should match this bit sequence:
@ -414,10 +506,6 @@ void demodulate2400AC(struct mag_buf *mag)
// 17 SPI // 17 SPI
// 18 0 quiet zone (X4) // 18 0 quiet zone (X4)
// 19 0 quiet zone (X5) // 19 0 quiet zone (X5)
// 20 0 quiet zone (X6)
// 21 0 quiet zone (X7)
// 22 0 quiet zone (X8)
// 23 0 quiet zone (X9)
// Look for a F1 and F2 pair, // Look for a F1 and F2 pair,
// with F1 starting at offset f1_sample. // with F1 starting at offset f1_sample.
@ -447,26 +535,26 @@ void demodulate2400AC(struct mag_buf *mag)
if (m[f1_sample+2] > m[f1_sample+0] || m[f1_sample+2] > m[f1_sample+1]) if (m[f1_sample+2] > m[f1_sample+0] || m[f1_sample+2] > m[f1_sample+1])
continue; // quiet part of bit wasn't sufficiently quiet continue; // quiet part of bit wasn't sufficiently quiet
unsigned f1_noise = (m[f1_sample-1] + m[f1_sample+2]) / 2; unsigned f1_level = (m[f1_sample+0] + m[f1_sample+1]) / 2;
unsigned f1_signal = (m[f1_sample+0] + m[f1_sample+1]) / 2;
if (f1_noise * 4 > f1_signal) { if (noise_level * 2 > f1_level) {
// require 12dB SNR // require 6dB above noise
continue; continue;
} }
// estimate initial clock phase based on the amount of power // estimate initial clock phase based on the amount of power
// that ended up in the second sample // that ended up in the second sample
unsigned f1_clock = 25 * f1_sample;
if (m[f1_sample+1] > f1_noise) { float f1a_power = (float)m[f1_sample] * m[f1_sample];
f1_clock += 25 * (m[f1_sample+1] - f1_noise) / (2*(f1_signal - f1_noise)); float f1b_power = (float)m[f1_sample+1] * m[f1_sample+1];
} float fraction = f1b_power / (f1a_power + f1b_power);
unsigned f1_clock = (unsigned) (25 * (f1_sample + fraction * fraction) + 0.5);
// same again for F2 // same again for F2
// F2 is 20.3us / 14 bit periods after F1 // F2 is 20.3us / 14 bit periods after F1
unsigned f2_clock = f1_clock + (87 * 14); unsigned f2_clock = f1_clock + (87 * 14);
unsigned f2_sample = f2_clock / 25; unsigned f2_sample = f2_clock / 25;
assert(f2_sample < mlen + Modes.trailing_samples);
if (!(m[f2_sample-1] < m[f2_sample+0])) if (!(m[f2_sample-1] < m[f2_sample+0]))
continue; continue;
@ -474,179 +562,90 @@ void demodulate2400AC(struct mag_buf *mag)
if (m[f2_sample+2] > m[f2_sample+0] || m[f2_sample+2] > m[f2_sample+1]) if (m[f2_sample+2] > m[f2_sample+0] || m[f2_sample+2] > m[f2_sample+1])
continue; // quiet part of bit wasn't sufficiently quiet continue; // quiet part of bit wasn't sufficiently quiet
unsigned f2_noise = (m[f2_sample-1] + m[f2_sample+2]) / 2; unsigned f2_level = (m[f2_sample+0] + m[f2_sample+1]) / 2;
unsigned f2_signal = (m[f2_sample+0] + m[f2_sample+1]) / 2;
if (f2_noise * 4 > f2_signal) { if (noise_level * 2 > f2_level) {
// require 12dB SNR // require 6dB above noise
continue; continue;
} }
unsigned f1f2_signal = (f1_signal + f2_signal) / 2; unsigned f1f2_level = (f1_level > f2_level ? f1_level : f2_level);
// look at X1, X2, X3 which should be quiet float midpoint = sqrtf(noise_level * f1f2_level); // geometric mean of the two levels
// (sample 0 may have part of the previous bit, but unsigned signal_threshold = (unsigned) (midpoint * M_SQRT2 + 0.5); // +3dB
// it always covers the quiet part of it) unsigned noise_threshold = (unsigned) (midpoint / M_SQRT2 + 0.5); // -3dB
unsigned x1_clock = f1_clock + (87 * 7);
unsigned x1_sample = x1_clock / 25;
unsigned x1_noise = (m[x1_sample + 0] + m[x1_sample + 1] + m[x1_sample + 2]) / 3;
if (x1_noise * 4 >= f1f2_signal)
continue;
unsigned x2_clock = f1_clock + (87 * 15);
unsigned x2_sample = x2_clock / 25;
unsigned x2_noise = (m[x2_sample + 0] + m[x2_sample + 1] + m[x2_sample + 2]) / 3;
if (x2_noise * 4 >= f1f2_signal)
continue;
unsigned x3_clock = f1_clock + (87 * 16);
unsigned x3_sample = x3_clock / 25;
unsigned x3_noise = (m[x3_sample + 0] + m[x3_sample + 1] + m[x3_sample + 2]) / 3;
if (x3_noise * 4 >= f1f2_signal)
continue;
unsigned x1x2x3_noise = (x1_noise + x2_noise + x3_noise) / 3;
if (x1x2x3_noise * 4 >= f1f2_signal) // require 12dB separation
continue;
// ----- F1/F2 average signal
// ^
// | at least 3dB
// v
// ----- minimum signal level we accept as "on"
// ^
// | 3dB
// v
// ---- midpoint between F1/F2 and X1/X2/X3
// ^
// | 3dB
// v
// ----- maximum signal level we accept as "off"
// ^
// | at least 3dB
// v
// ----- X1/X2/X3 average noise
float midpoint = sqrtf(x1x2x3_noise * f1f2_signal); // so that signal/midpoint == midpoint/noise
unsigned quiet_threshold = (unsigned) midpoint;
unsigned noise_threshold = (unsigned) (midpoint * 0.707107 + 0.5); // -3dB from midpoint
unsigned signal_threshold = (unsigned) (midpoint * 1.414214 + 0.5); // +3dB from midpoint
#if 0
fprintf(stderr, "f1f2 %u x1x2x3 %u midpoint %.0f noise_threshold %u signal_threshold %u\n",
f1f2_signal, x1x2x3_noise, midpoint, noise_threshold, signal_threshold);
fprintf(stderr, "f1 %u f2 %u x1 %u x2 %u x3 %u\n",
f1_signal, f2_signal, x1_noise, x2_noise, x3_noise);
#endif
// recheck F/X bits just in case
if (f1_signal < signal_threshold)
continue;
if (f2_signal < signal_threshold)
continue;
if (x1_noise > noise_threshold)
continue;
if (x2_noise > noise_threshold)
continue;
if (x3_noise > noise_threshold)
continue;
// Looks like a real signal. Demodulate all the bits. // Looks like a real signal. Demodulate all the bits.
unsigned uncertain_bits = 0;
unsigned noisy_bits = 0; unsigned noisy_bits = 0;
unsigned bits = 0; unsigned bits = 0;
unsigned bit; unsigned bit;
unsigned clock; unsigned clock;
for (bit = 0, clock = f1_clock; bit < 24; ++bit, clock += 87) { for (bit = 0, clock = f1_clock; bit < 20; ++bit, clock += 87) {
unsigned sample = clock / 25; unsigned sample = clock / 25;
bits <<= 1; bits <<= 1;
noisy_bits <<= 1; noisy_bits <<= 1;
uncertain_bits <<= 1;
// check for excessive noise in the quiet period // check for excessive noise in the quiet period
if (m[sample+2] >= quiet_threshold) { if (m[sample+2] >= signal_threshold) {
//fprintf(stderr, "bit %u was not quiet (%u > %u)\n", bit, m[sample+2], quiet_threshold);
noisy_bits |= 1; noisy_bits |= 1;
continue;
} }
// decide if this bit is on or off // decide if this bit is on or off
unsigned bit_signal = (m[sample+0] + m[sample+1]) / 2; if (m[sample+0] >= signal_threshold || m[sample+1] >= signal_threshold) {
if (bit_signal >= signal_threshold) {
bits |= 1; bits |= 1;
} else if (bit_signal > noise_threshold) { } else if (m[sample+0] > noise_threshold && m[sample+1] > noise_threshold) {
/* not certain about this bit */ /* not certain about this bit */
//fprintf(stderr, "bit %u was uncertain (%u < %u < %u)\n", bit, noise_threshold, bit_signal, signal_threshold); uncertain_bits |= 1;
noisy_bits |= 1;
} else { } else {
/* this bit is off */ /* this bit is off */
} }
} }
#if 0
fprintf(stderr, "bits: %06X noisy: %06X\n", bits, noisy_bits);
unsigned j, sample;
static const char *names[24] = {
"F1", "C1", "A1", "C2",
"A2", "C4", "A4", "X1",
"B1", "D1", "B2", "D2",
"B4", "D4", "F2", "X2",
"X3", "SPI", "X4", "X5",
"X6", "X7", "X8", "X9"
};
fprintf(stderr, "-1 ... %6u\n", m[f1_sample-1]);
for (j = 0; j < 24; ++j) {
clock = f1_clock + 87 * j;
sample = clock / 25;
fprintf(stderr, "%2u %-3s %6u %6u %6u %6u ", j, names[j], m[sample+0], m[sample+1], m[sample+2], m[sample+3]);
if ((m[sample+0] + m[sample+1])/2 >= signal_threshold) {
fprintf(stderr, "ON\n");
} else if ((m[sample+0] + m[sample+1])/2 <= noise_threshold) {
fprintf(stderr, "OFF\n");
} else {
fprintf(stderr, "UNCERTAIN\n");
}
}
#endif
if (noisy_bits) {
/* XX debug */
continue;
}
// framing bits must be on // framing bits must be on
if ((bits & 0x800200) != 0x800200) { if ((bits & 0x80020) != 0x80020) {
continue; continue;
} }
// quiet bits must be off // quiet bits must be off
if ((bits & 0x0101BF) != 0) { if ((bits & 0x0101B) != 0) {
continue;
}
if (noisy_bits || uncertain_bits) {
continue; continue;
} }
// Convert to the form that we use elsewhere: // Convert to the form that we use elsewhere:
// 00 A4 A2 A1 00 B4 B2 B1 SPI C4 C2 C1 00 D4 D2 D1 // 00 A4 A2 A1 00 B4 B2 B1 SPI C4 C2 C1 00 D4 D2 D1
unsigned modeac = unsigned modeac =
((bits & 0x400000) ? 0x0010 : 0) | // C1 ((bits & 0x40000) ? 0x0010 : 0) | // C1
((bits & 0x200000) ? 0x1000 : 0) | // A1 ((bits & 0x20000) ? 0x1000 : 0) | // A1
((bits & 0x100000) ? 0x0020 : 0) | // C2 ((bits & 0x10000) ? 0x0020 : 0) | // C2
((bits & 0x080000) ? 0x2000 : 0) | // A2 ((bits & 0x08000) ? 0x2000 : 0) | // A2
((bits & 0x040000) ? 0x0040 : 0) | // C4 ((bits & 0x04000) ? 0x0040 : 0) | // C4
((bits & 0x020000) ? 0x4000 : 0) | // A4 ((bits & 0x02000) ? 0x4000 : 0) | // A4
((bits & 0x008000) ? 0x0100 : 0) | // B1 ((bits & 0x00800) ? 0x0100 : 0) | // B1
((bits & 0x004000) ? 0x0001 : 0) | // D1 ((bits & 0x00400) ? 0x0001 : 0) | // D1
((bits & 0x002000) ? 0x0200 : 0) | // B2 ((bits & 0x00200) ? 0x0200 : 0) | // B2
((bits & 0x001000) ? 0x0002 : 0) | // D2 ((bits & 0x00100) ? 0x0002 : 0) | // D2
((bits & 0x000800) ? 0x0400 : 0) | // B4 ((bits & 0x00080) ? 0x0400 : 0) | // B4
((bits & 0x000400) ? 0x0004 : 0) | // D4 ((bits & 0x00040) ? 0x0004 : 0) | // D4
((bits & 0x000040) ? 0x0080 : 0); // SPI ((bits & 0x00004) ? 0x0080 : 0); // SPI
#ifdef MODEAC_DEBUG
draw_modeac(m, modeac, f1_clock, noise_threshold, signal_threshold, bits, noisy_bits, uncertain_bits);
#endif
// This message looks good, submit it // This message looks good, submit it
// For consistency with how the Beast / Radarcape does it,
// we report the timestamp at the second framing pulse (F2)
mm.timestampMsg = mag->sampleTimestamp + f2_clock / 5; // 60MHz -> 12MHz
// compute message receive time as block-start-time + difference in the 12MHz clock // compute message receive time as block-start-time + difference in the 12MHz clock
mm.timestampMsg = mag->sampleTimestamp + f1_clock / 5; // 60MHz -> 12MHz
mm.sysTimestampMsg = mag->sysTimestamp; // start of block time mm.sysTimestampMsg = mag->sysTimestamp; // start of block time
mm.sysTimestampMsg.tv_nsec += receiveclock_ns_elapsed(mag->sampleTimestamp, mm.timestampMsg); mm.sysTimestampMsg.tv_nsec += receiveclock_ns_elapsed(mag->sampleTimestamp, mm.timestampMsg);
normalize_timespec(&mm.sysTimestampMsg); normalize_timespec(&mm.sysTimestampMsg);
@ -656,7 +655,7 @@ void demodulate2400AC(struct mag_buf *mag)
// Pass data to the next layer // Pass data to the next layer
useModesMessage(&mm); useModesMessage(&mm);
f1_sample += (24*87 / 25); f1_sample += (20*87 / 25);
Modes.stats_current.demod_modeac++; Modes.stats_current.demod_modeac++;
} }
} }

View file

@ -95,27 +95,6 @@ static void sigtermHandler(int dummy) {
Modes.exit = 1; // Signal to threads that we are done Modes.exit = 1; // Signal to threads that we are done
log_with_timestamp("Caught SIGTERM, shutting down..\n"); log_with_timestamp("Caught SIGTERM, shutting down..\n");
} }
//
// =============================== Terminal handling ========================
//
#ifndef _WIN32
// Get the number of rows after the terminal changes size.
int getTermRows() {
struct winsize w;
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
return (w.ws_row);
}
// Handle resizing terminal
void sigWinchCallback() {
signal(SIGWINCH, SIG_IGN);
Modes.interactive_rows = getTermRows();
interactiveShowData();
signal(SIGWINCH, sigWinchCallback);
}
#else
int getTermRows() { return MODES_INTERACTIVE_ROWS;}
#endif
static void start_cpu_timing(struct timespec *start_time) static void start_cpu_timing(struct timespec *start_time)
{ {
@ -132,6 +111,13 @@ static void end_cpu_timing(const struct timespec *start_time, struct timespec *a
add_to->tv_nsec = add_to->tv_nsec % 1000000000L; add_to->tv_nsec = add_to->tv_nsec % 1000000000L;
} }
void receiverPositionChanged(float lat, float lon, float alt)
{
log_with_timestamp("Autodetected receiver location: %.5f, %.5f at %.0fm AMSL", lat, lon, alt);
writeJsonToFile("receiver.json", generateReceiverJson); // location changed
}
// //
// =============================== Initialization =========================== // =============================== Initialization ===========================
// //
@ -150,15 +136,12 @@ void modesInitConfig(void) {
Modes.net_output_sbs_ports = strdup("30003"); Modes.net_output_sbs_ports = strdup("30003");
Modes.net_input_beast_ports = strdup("30004,30104"); Modes.net_input_beast_ports = strdup("30004,30104");
Modes.net_output_beast_ports = strdup("30005"); Modes.net_output_beast_ports = strdup("30005");
#ifdef ENABLE_WEBSERVER
Modes.net_http_ports = strdup("8080");
#endif
Modes.interactive_rows = getTermRows();
Modes.interactive_display_ttl = MODES_INTERACTIVE_DISPLAY_TTL; Modes.interactive_display_ttl = MODES_INTERACTIVE_DISPLAY_TTL;
Modes.html_dir = HTMLPATH; Modes.html_dir = HTMLPATH;
Modes.json_interval = 1000; Modes.json_interval = 1000;
Modes.json_location_accuracy = 1; Modes.json_location_accuracy = 1;
Modes.maxRange = 1852 * 300; // 300NM default max range Modes.maxRange = 1852 * 300; // 300NM default max range
Modes.mode_ac_auto = 1;
} }
// //
//========================================================================= //=========================================================================
@ -243,6 +226,8 @@ void modesInit(void) {
// Prepare error correction tables // Prepare error correction tables
modesChecksumInit(Modes.nfix_crc); modesChecksumInit(Modes.nfix_crc);
icaoFilterInit(); icaoFilterInit();
modeACInit();
interactiveInit();
if (Modes.show_only) if (Modes.show_only)
icaoFilterAdd(Modes.show_only); icaoFilterAdd(Modes.show_only);
@ -266,9 +251,10 @@ void modesInit(void) {
static void convert_samples(void *iq, static void convert_samples(void *iq,
uint16_t *mag, uint16_t *mag,
unsigned nsamples, unsigned nsamples,
double *power) double *mean_level,
double *mean_power)
{ {
Modes.converter_function(iq, mag, nsamples, Modes.converter_state, power); Modes.converter_function(iq, mag, nsamples, Modes.converter_state, mean_level, mean_power);
} }
// //
@ -465,7 +451,7 @@ void rtlsdrCallback(unsigned char *buf, uint32_t len, void *ctx) {
// Convert the new data // Convert the new data
outbuf->length = slen; outbuf->length = slen;
convert_samples(buf, &outbuf->data[Modes.trailing_samples], slen, &outbuf->total_power); convert_samples(buf, &outbuf->data[Modes.trailing_samples], slen, &outbuf->mean_level, &outbuf->mean_power);
// Push the new data to the demodulation thread // Push the new data to the demodulation thread
pthread_mutex_lock(&Modes.data_mutex); pthread_mutex_lock(&Modes.data_mutex);
@ -558,7 +544,7 @@ void readDataFromFile(void) {
slen = outbuf->length = MODES_MAG_BUF_SAMPLES - toread/bytes_per_sample; slen = outbuf->length = MODES_MAG_BUF_SAMPLES - toread/bytes_per_sample;
// Convert the new data // Convert the new data
convert_samples(readbuf, &outbuf->data[Modes.trailing_samples], slen, &outbuf->total_power); convert_samples(readbuf, &outbuf->data[Modes.trailing_samples], slen, &outbuf->mean_level, &outbuf->mean_power);
if (Modes.throttle) { if (Modes.throttle) {
// Wait until we are allowed to release this buffer to the main thread // Wait until we are allowed to release this buffer to the main thread
@ -674,17 +660,13 @@ void showHelp(void) {
"--iformat <format> Sample format for --ifile: UC8 (default), SC16, or SC16Q11\n" "--iformat <format> Sample format for --ifile: UC8 (default), SC16, or SC16Q11\n"
"--throttle When reading from a file, play back in realtime, not at max speed\n" "--throttle When reading from a file, play back in realtime, not at max speed\n"
"--interactive Interactive mode refreshing data on screen. Implies --throttle\n" "--interactive Interactive mode refreshing data on screen. Implies --throttle\n"
"--interactive-rows <num> Max number of rows in interactive mode (default: 15)\n"
"--interactive-ttl <sec> Remove from list if idle for <sec> (default: 60)\n" "--interactive-ttl <sec> Remove from list if idle for <sec> (default: 60)\n"
"--interactive-rtl1090 Display flight table in RTL1090 format\n"
"--raw Show only messages hex values\n" "--raw Show only messages hex values\n"
"--net Enable networking\n" "--net Enable networking\n"
"--modeac Enable decoding of SSR Modes 3/A & 3/C\n" "--modeac Enable decoding of SSR Modes 3/A & 3/C\n"
"--no-modeac-auto Don't enable Mode A/C if requested by a Beast connection\n"
"--net-only Enable just networking, no RTL device or file used\n" "--net-only Enable just networking, no RTL device or file used\n"
"--net-bind-address <ip> IP address to bind to (default: Any; Use 127.0.0.1 for private)\n" "--net-bind-address <ip> IP address to bind to (default: Any; Use 127.0.0.1 for private)\n"
#ifdef ENABLE_WEBSERVER
"--net-http-port <ports> HTTP server ports (default: 8080)\n"
#endif
"--net-ri-port <ports> TCP raw input listen ports (default: 30001)\n" "--net-ri-port <ports> TCP raw input listen ports (default: 30001)\n"
"--net-ro-port <ports> TCP raw output listen ports (default: 30002)\n" "--net-ro-port <ports> TCP raw output listen ports (default: 30002)\n"
"--net-sbs-port <ports> TCP BaseStation output listen ports (default: 30003)\n" "--net-sbs-port <ports> TCP BaseStation output listen ports (default: 30003)\n"
@ -968,6 +950,9 @@ int main(int argc, char **argv) {
Modes.net = 1; Modes.net = 1;
} else if (!strcmp(argv[j],"--modeac")) { } else if (!strcmp(argv[j],"--modeac")) {
Modes.mode_ac = 1; Modes.mode_ac = 1;
Modes.mode_ac_auto = 0;
} else if (!strcmp(argv[j],"--no-modeac-auto")) {
Modes.mode_ac_auto = 0;
} else if (!strcmp(argv[j],"--net-beast")) { } else if (!strcmp(argv[j],"--net-beast")) {
fprintf(stderr, "--net-beast ignored, use --net-bo-port to control where Beast output is generated\n"); fprintf(stderr, "--net-beast ignored, use --net-bo-port to control where Beast output is generated\n");
} else if (!strcmp(argv[j],"--net-only")) { } else if (!strcmp(argv[j],"--net-only")) {
@ -997,14 +982,9 @@ int main(int argc, char **argv) {
free(Modes.net_bind_address); free(Modes.net_bind_address);
Modes.net_bind_address = strdup(argv[++j]); Modes.net_bind_address = strdup(argv[++j]);
} else if (!strcmp(argv[j],"--net-http-port") && more) { } else if (!strcmp(argv[j],"--net-http-port") && more) {
#ifdef ENABLE_WEBSERVER
free(Modes.net_http_ports);
Modes.net_http_ports = strdup(argv[++j]);
#else
if (strcmp(argv[++j], "0")) { if (strcmp(argv[++j], "0")) {
fprintf(stderr, "warning: --net-http-port not supported in this build, option ignored.\n"); fprintf(stderr, "warning: --net-http-port not supported in this build, option ignored.\n");
} }
#endif
} else if (!strcmp(argv[j],"--net-sbs-port") && more) { } else if (!strcmp(argv[j],"--net-sbs-port") && more) {
free(Modes.net_output_sbs_ports); free(Modes.net_output_sbs_ports);
Modes.net_output_sbs_ports = strdup(argv[++j]); Modes.net_output_sbs_ports = strdup(argv[++j]);
@ -1030,8 +1010,6 @@ int main(int argc, char **argv) {
Modes.interactive = Modes.throttle = 1; Modes.interactive = Modes.throttle = 1;
} else if (!strcmp(argv[j],"--throttle")) { } else if (!strcmp(argv[j],"--throttle")) {
Modes.throttle = 1; Modes.throttle = 1;
} else if (!strcmp(argv[j],"--interactive-rows") && more) {
Modes.interactive_rows = atoi(argv[++j]);
} else if (!strcmp(argv[j],"--interactive-ttl") && more) { } else if (!strcmp(argv[j],"--interactive-ttl") && more) {
Modes.interactive_display_ttl = (uint64_t)(1000 * atof(argv[++j])); Modes.interactive_display_ttl = (uint64_t)(1000 * atof(argv[++j]));
} else if (!strcmp(argv[j],"--lat") && more) { } else if (!strcmp(argv[j],"--lat") && more) {
@ -1079,9 +1057,6 @@ int main(int argc, char **argv) {
Modes.show_only = (uint32_t) strtoul(argv[++j], NULL, 16); Modes.show_only = (uint32_t) strtoul(argv[++j], NULL, 16);
} else if (!strcmp(argv[j],"--mlat")) { } else if (!strcmp(argv[j],"--mlat")) {
Modes.mlat = 1; Modes.mlat = 1;
} else if (!strcmp(argv[j],"--interactive-rtl1090")) {
Modes.interactive = 1;
Modes.interactive_rtl1090 = 1;
} else if (!strcmp(argv[j],"--oversample")) { } else if (!strcmp(argv[j],"--oversample")) {
// Ignored // Ignored
} else if (!strcmp(argv[j], "--html-dir") && more) { } else if (!strcmp(argv[j], "--html-dir") && more) {
@ -1110,11 +1085,6 @@ int main(int argc, char **argv) {
if (!Modes.quiet) {showCopyright();} if (!Modes.quiet) {showCopyright();}
#endif #endif
#ifndef _WIN32
// Setup for SIGWINCH for handling lines
if (Modes.interactive) {signal(SIGWINCH, sigWinchCallback);}
#endif
// Initialization // Initialization
log_with_timestamp("%s %s starting up.", MODES_DUMP1090_VARIANT, MODES_DUMP1090_VERSION); log_with_timestamp("%s %s starting up.", MODES_DUMP1090_VARIANT, MODES_DUMP1090_VERSION);
modesInit(); modesInit();
@ -1251,6 +1221,8 @@ int main(int argc, char **argv) {
pthread_mutex_destroy(&Modes.data_mutex); pthread_mutex_destroy(&Modes.data_mutex);
} }
interactiveCleanup();
// If --stats were given, print statistics // If --stats were given, print statistics
if (Modes.stats) { if (Modes.stats) {
display_total_stats(); display_total_stats();

View file

@ -105,12 +105,6 @@ typedef struct rtlsdr_dev rtlsdr_dev_t;
#define MODEAC_MSG_SAMPLES (25 * 2) // include up to the SPI bit #define MODEAC_MSG_SAMPLES (25 * 2) // include up to the SPI bit
#define MODEAC_MSG_BYTES 2 #define MODEAC_MSG_BYTES 2
#define MODEAC_MSG_SQUELCH_LEVEL 0x07FF // Average signal strength limit #define MODEAC_MSG_SQUELCH_LEVEL 0x07FF // Average signal strength limit
#define MODEAC_MSG_FLAG (1<<0)
#define MODEAC_MSG_MODES_HIT (1<<1)
#define MODEAC_MSG_MODEA_HIT (1<<2)
#define MODEAC_MSG_MODEC_HIT (1<<3)
#define MODEAC_MSG_MODEA_ONLY (1<<4)
#define MODEAC_MSG_MODEC_OLD (1<<5)
#define MODES_PREAMBLE_US 8 // microseconds = bits #define MODES_PREAMBLE_US 8 // microseconds = bits
#define MODES_PREAMBLE_SAMPLES (MODES_PREAMBLE_US * 2) #define MODES_PREAMBLE_SAMPLES (MODES_PREAMBLE_US * 2)
@ -142,6 +136,7 @@ typedef struct rtlsdr_dev rtlsdr_dev_t;
/* Where did a bit of data arrive from? In order of increasing priority */ /* Where did a bit of data arrive from? In order of increasing priority */
typedef enum { typedef enum {
SOURCE_INVALID, /* data is not valid */ SOURCE_INVALID, /* data is not valid */
SOURCE_MODE_AC, /* A/C message */
SOURCE_MLAT, /* derived from mlat */ SOURCE_MLAT, /* derived from mlat */
SOURCE_MODE_S, /* data from a Mode S message, no full CRC */ SOURCE_MODE_S, /* data from a Mode S message, no full CRC */
SOURCE_MODE_S_CHECKED, /* data from a Mode S message with full CRC */ SOURCE_MODE_S_CHECKED, /* data from a Mode S message with full CRC */
@ -163,6 +158,8 @@ typedef enum {
ADDR_TISB_TRACKFILE, /* TIS-B, Mode A code + track file number */ ADDR_TISB_TRACKFILE, /* TIS-B, Mode A code + track file number */
ADDR_TISB_OTHER, /* TIS-B, other address format */ ADDR_TISB_OTHER, /* TIS-B, other address format */
ADDR_MODE_A, /* Mode A */
ADDR_UNKNOWN /* unknown address format */ ADDR_UNKNOWN /* unknown address format */
} addrtype_t; } addrtype_t;
@ -198,6 +195,10 @@ typedef enum {
SIL_PER_SAMPLE, SIL_PER_HOUR SIL_PER_SAMPLE, SIL_PER_HOUR
} sil_type_t; } sil_type_t;
typedef enum {
CPR_SURFACE, CPR_AIRBORNE, CPR_COARSE
} cpr_type_t;
#define MODES_NON_ICAO_ADDRESS (1<<24) // Set on addresses to indicate they are not ICAO addresses #define MODES_NON_ICAO_ADDRESS (1<<24) // Set on addresses to indicate they are not ICAO addresses
#define MODES_DEBUG_DEMOD (1<<0) #define MODES_DEBUG_DEMOD (1<<0)
@ -213,7 +214,6 @@ typedef enum {
#define MODES_DEBUG_NOPREAMBLE_LEVEL 25 #define MODES_DEBUG_NOPREAMBLE_LEVEL 25
#define MODES_INTERACTIVE_REFRESH_TIME 250 // Milliseconds #define MODES_INTERACTIVE_REFRESH_TIME 250 // Milliseconds
#define MODES_INTERACTIVE_ROWS 22 // Rows on screen
#define MODES_INTERACTIVE_DISPLAY_TTL 60000 // Delete from display after 60 seconds #define MODES_INTERACTIVE_DISPLAY_TTL 60000 // Delete from display after 60 seconds
#define MODES_NET_HEARTBEAT_INTERVAL 60000 // milliseconds #define MODES_NET_HEARTBEAT_INTERVAL 60000 // milliseconds
@ -255,7 +255,8 @@ struct mag_buf {
uint64_t sampleTimestamp; // Clock timestamp of the start of this block, 12MHz clock uint64_t sampleTimestamp; // Clock timestamp of the start of this block, 12MHz clock
struct timespec sysTimestamp; // Estimated system time at start of block struct timespec sysTimestamp; // Estimated system time at start of block
uint32_t dropped; // Number of dropped samples preceding this buffer uint32_t dropped; // Number of dropped samples preceding this buffer
double total_power; // Sum of per-sample input power (in the range [0.0,1.0] per sample), or 0 if not measured double mean_level; // Mean of normalized (0..1) signal level
double mean_power; // Mean of normalized (0..1) power level
}; };
// Program global state // Program global state
@ -312,6 +313,7 @@ struct { // Internal state
int check_crc; // Only display messages with good CRC int check_crc; // Only display messages with good CRC
int raw; // Raw output format int raw; // Raw output format
int mode_ac; // Enable decoding of SSR Modes A & C int mode_ac; // Enable decoding of SSR Modes A & C
int mode_ac_auto; // allow toggling of A/C by Beast commands
int debug; // Debugging mode int debug; // Debugging mode
int net; // Enable networking int net; // Enable networking
int net_only; // Enable just networking int net_only; // Enable just networking
@ -323,9 +325,6 @@ struct { // Internal state
char *net_output_sbs_ports; // List of SBS output TCP ports char *net_output_sbs_ports; // List of SBS output TCP ports
char *net_input_beast_ports; // List of Beast input TCP ports char *net_input_beast_ports; // List of Beast input TCP ports
char *net_output_beast_ports; // List of Beast output TCP ports char *net_output_beast_ports; // List of Beast output TCP ports
#ifdef ENABLE_WEBSERVER
char *net_http_ports; // List of HTTP ports
#endif
char *net_bind_address; // Bind address char *net_bind_address; // Bind address
int net_sndbuf_size; // TCP output buffer size (64Kb * 2^n) int net_sndbuf_size; // TCP output buffer size (64Kb * 2^n)
int net_verbatim; // if true, send the original message, not the CRC-corrected one int net_verbatim; // if true, send the original message, not the CRC-corrected one
@ -333,7 +332,6 @@ struct { // Internal state
int quiet; // Suppress stdout int quiet; // Suppress stdout
uint32_t show_only; // Only show messages from this ICAO uint32_t show_only; // Only show messages from this ICAO
int interactive; // Interactive mode int interactive; // Interactive mode
int interactive_rows; // Interactive mode: max number of rows
uint64_t interactive_display_ttl;// Interactive mode: TTL display uint64_t interactive_display_ttl;// Interactive mode: TTL display
uint64_t stats; // Interval (millis) between stats dumps, uint64_t stats; // Interval (millis) between stats dumps,
int stats_range_histo; // Collect/show a range histogram? int stats_range_histo; // Collect/show a range histogram?
@ -341,7 +339,6 @@ struct { // Internal state
int metric; // Use metric units int metric; // Use metric units
int use_gnss; // Use GNSS altitudes with H suffix ("HAE", though it isn't always) when available int use_gnss; // Use GNSS altitudes with H suffix ("HAE", though it isn't always) when available
int mlat; // Use Beast ascii format for raw data output, i.e. @...; iso *...; int mlat; // Use Beast ascii format for raw data output, i.e. @...; iso *...;
int interactive_rtl1090; // flight table in interactive mode is formatted like RTL1090
char *json_dir; // Path to json base directory, or NULL not to write json. char *json_dir; // Path to json base directory, or NULL not to write json.
uint64_t json_interval; // Interval between rewriting the json aircraft file, in milliseconds; also the advertised map refresh interval uint64_t json_interval; // Interval between rewriting the json aircraft file, in milliseconds; also the advertised map refresh interval
char *html_dir; // Path to www base directory. char *html_dir; // Path to www base directory.
@ -461,6 +458,7 @@ struct modesMessage {
// valid if category_valid // valid if category_valid
unsigned category; // A0 - D7 encoded as a single hex byte unsigned category; // A0 - D7 encoded as a single hex byte
// valid if cpr_valid // valid if cpr_valid
cpr_type_t cpr_type; // The encoding type used (surface, airborne, coarse TIS-B)
unsigned cpr_lat; // Non decoded latitude. unsigned cpr_lat; // Non decoded latitude.
unsigned cpr_lon; // Non decoded longitude. unsigned cpr_lon; // Non decoded longitude.
unsigned cpr_nucp; // NUCp/NIC value implied by message type unsigned cpr_nucp; // NUCp/NIC value implied by message type
@ -547,7 +545,9 @@ extern "C" {
// //
int detectModeA (uint16_t *m, struct modesMessage *mm); int detectModeA (uint16_t *m, struct modesMessage *mm);
void decodeModeAMessage(struct modesMessage *mm, int ModeA); void decodeModeAMessage(struct modesMessage *mm, int ModeA);
int ModeAToModeC (unsigned int ModeA); void modeACInit();
int modeAToModeC (unsigned int modeA);
unsigned modeCToModeA (int modeC);
// //
// Functions exported from mode_s.c // Functions exported from mode_s.c
@ -560,7 +560,12 @@ void useModesMessage (struct modesMessage *mm);
// //
// Functions exported from interactive.c // Functions exported from interactive.c
// //
void interactiveInit(void);
void interactiveShowData(void); void interactiveShowData(void);
void interactiveCleanup(void);
// Provided by dump1090.c / view1090.c / faup1090.c
void receiverPositionChanged(float lat, float lon, float alt);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -51,6 +51,14 @@
#include <stdarg.h> #include <stdarg.h>
void receiverPositionChanged(float lat, float lon, float alt)
{
/* nothing */
(void) lat;
(void) lon;
(void) alt;
}
// //
// =============================== Initialization =========================== // =============================== Initialization ===========================
// //
@ -95,6 +103,7 @@ static void faupInit(void) {
// Prepare error correction tables // Prepare error correction tables
modesChecksumInit(1); modesChecksumInit(1);
icaoFilterInit(); icaoFilterInit();
modeACInit();
} }
// //
@ -109,7 +118,6 @@ static void showHelp(void) {
"--net-bo-port <port> Port to connect for Beast data (default: 30005)\n" "--net-bo-port <port> Port to connect for Beast data (default: 30005)\n"
"--lat <latitude> Reference/receiver latitude for surface posn (opt)\n" "--lat <latitude> Reference/receiver latitude for surface posn (opt)\n"
"--lon <longitude> Reference/receiver longitude for surface posn (opt)\n" "--lon <longitude> Reference/receiver longitude for surface posn (opt)\n"
"--max-range <distance> Absolute maximum range for position decoding (in nm, default: 360)\n"
"--stdout REQUIRED. Write results to stdout.\n" "--stdout REQUIRED. Write results to stdout.\n"
"--help Show this help\n" "--help Show this help\n"
"\n", "\n",
@ -130,22 +138,6 @@ static void backgroundTasks(void) {
modesNetPeriodicWork(); modesNetPeriodicWork();
} }
static void sendBeastSettings(struct client *c, const char *settings) {
int len;
char *buf, *p;
len = strlen(settings) * 3;
buf = p = alloca(len);
while (*settings) {
*p++ = 0x1a;
*p++ = '1';
*p++ = *settings++;
}
anetWrite(c->fd, buf, len);
}
// //
//========================================================================= //=========================================================================
// //
@ -172,8 +164,6 @@ int main(int argc, char **argv) {
Modes.fUserLat = atof(argv[++j]); Modes.fUserLat = atof(argv[++j]);
} else if (!strcmp(argv[j],"--lon") && more) { } else if (!strcmp(argv[j],"--lon") && more) {
Modes.fUserLon = atof(argv[++j]); Modes.fUserLon = atof(argv[++j]);
} else if (!strcmp(argv[j],"--max-range") && more) {
Modes.maxRange = atof(argv[++j]) * 1852.0; // convert to metres
} else if (!strcmp(argv[j],"--help")) { } else if (!strcmp(argv[j],"--help")) {
showHelp(); showHelp();
exit(0); exit(0);

View file

@ -49,6 +49,8 @@
#include "dump1090.h" #include "dump1090.h"
#include <curses.h>
// //
//========================= Interactive mode =============================== //========================= Interactive mode ===============================
@ -64,7 +66,7 @@ static int convert_altitude(int ft)
static int convert_speed(int kts) static int convert_speed(int kts)
{ {
if (Modes.metric) if (Modes.metric)
return (kts / 1.852); return (kts * 1.852);
else else
return kts; return kts;
} }
@ -74,11 +76,29 @@ static int convert_speed(int kts)
// //
// Show the currently captured interactive data on screen. // Show the currently captured interactive data on screen.
// //
void interactiveInit() {
if (!Modes.interactive)
return;
initscr();
clear();
refresh();
mvprintw(0, 0, " Hex Mode Sqwk Flight Alt Spd Hdg Lat Long RSSI Msgs Ti");
mvhline(1, 0, ACS_HLINE, 80);
}
void interactiveCleanup(void) {
if (Modes.interactive) {
endwin();
}
}
void interactiveShowData(void) { void interactiveShowData(void) {
struct aircraft *a = Modes.aircrafts; struct aircraft *a = Modes.aircrafts;
static uint64_t next_update; static uint64_t next_update;
uint64_t now = mstime(); uint64_t now = mstime();
int count = 0;
char progress; char progress;
char spinner[4] = "|/-\\"; char spinner[4] = "|/-\\";
@ -89,34 +109,18 @@ void interactiveShowData(void) {
next_update = now + MODES_INTERACTIVE_REFRESH_TIME; next_update = now + MODES_INTERACTIVE_REFRESH_TIME;
progress = spinner[(now/1000)%4]; progress = spinner[(now/1000)%4];
mvaddch(0, 79, progress);
#ifndef _WIN32 int rows = getmaxy(stdscr);
printf("\x1b[H\x1b[2J"); // Clear the screen int row = 2;
#else
cls();
#endif
if (Modes.interactive_rtl1090 == 0) { while (a && row < rows) {
printf (
" Hex Mode Sqwk Flight Alt Spd Hdg Lat Long RSSI Msgs Ti%c\n", progress);
} else {
printf (
" Hex Flight Alt V/S GS TT SSR G*456^ Msgs Seen %c\n", progress);
}
printf(
"-------------------------------------------------------------------------------\n");
while(a && (count < Modes.interactive_rows)) {
if ((now - a->seen) < Modes.interactive_display_ttl) if ((now - a->seen) < Modes.interactive_display_ttl)
{ {
int msgs = a->messages; int msgs = a->messages;
int flags = a->modeACflags;
if ( (((flags & (MODEAC_MSG_FLAG )) == 0 ) && (msgs > 1 ) ) if (msgs > 1) {
|| (((flags & (MODEAC_MSG_MODES_HIT | MODEAC_MSG_MODEA_ONLY)) == MODEAC_MSG_MODEA_ONLY) && (msgs > 4 ) )
|| (((flags & (MODEAC_MSG_MODES_HIT | MODEAC_MSG_MODEC_OLD )) == 0 ) && (msgs > 127) )
) {
char strSquawk[5] = " "; char strSquawk[5] = " ";
char strFl[7] = " "; char strFl[7] = " ";
char strTt[5] = " "; char strTt[5] = " ";
@ -138,52 +142,75 @@ void interactiveShowData(void) {
msgs = 99999; msgs = 99999;
} }
if (Modes.interactive_rtl1090) { // RTL1090 display mode char strMode[5] = " ";
if (trackDataValid(&a->altitude_valid)) { char strLat[8] = " ";
snprintf(strFl,6,"F%03d",((a->altitude+50)/100)); char strLon[9] = " ";
} double * pSig = a->signalLevel;
printf("%06x %-8s %-4s %-3s %-3s %4s %-6d %-2.0f\n", double signalAverage = (pSig[0] + pSig[1] + pSig[2] + pSig[3] +
a->addr, a->callsign, strFl, strGs, strTt, strSquawk, msgs, (now - a->seen)/1000.0); pSig[4] + pSig[5] + pSig[6] + pSig[7]) / 8.0;
} else { // Dump1090 display mode strMode[0] = 'S';
char strMode[5] = " "; if (a->modeA_hit) {strMode[2] = 'a';}
char strLat[8] = " "; if (a->modeC_hit) {strMode[3] = 'c';}
char strLon[9] = " ";
double * pSig = a->signalLevel;
double signalAverage = (pSig[0] + pSig[1] + pSig[2] + pSig[3] +
pSig[4] + pSig[5] + pSig[6] + pSig[7]) / 8.0;
if ((flags & MODEAC_MSG_FLAG) == 0) { if (trackDataValid(&a->position_valid)) {
strMode[0] = 'S'; snprintf(strLat, 8,"%7.03f", a->lat);
} else if (flags & MODEAC_MSG_MODEA_ONLY) { snprintf(strLon, 9,"%8.03f", a->lon);
strMode[0] = 'A';
}
if (flags & MODEAC_MSG_MODEA_HIT) {strMode[2] = 'a';}
if (flags & MODEAC_MSG_MODEC_HIT) {strMode[3] = 'c';}
if (trackDataValid(&a->position_valid)) {
snprintf(strLat, 8,"%7.03f", a->lat);
snprintf(strLon, 9,"%8.03f", a->lon);
}
if (trackDataValid(&a->airground_valid) && a->airground == AG_GROUND) {
snprintf(strFl, 7," grnd");
} else if (Modes.use_gnss && trackDataValid(&a->altitude_gnss_valid)) {
snprintf(strFl, 7, "%5dH", convert_altitude(a->altitude_gnss));
} else if (trackDataValid(&a->altitude_valid)) {
snprintf(strFl, 7, "%5d ", convert_altitude(a->altitude));
}
printf("%s%06X %-4s %-4s %-8s %6s %3s %3s %7s %8s %5.1f %5d %2.0f\n",
(a->addr & MODES_NON_ICAO_ADDRESS) ? "~" : " ", (a->addr & 0xffffff),
strMode, strSquawk, a->callsign, strFl, strGs, strTt,
strLat, strLon, 10 * log10(signalAverage), msgs, (now - a->seen)/1000.0);
} }
count++;
if (trackDataValid(&a->airground_valid) && a->airground == AG_GROUND) {
snprintf(strFl, 7," grnd");
} else if (Modes.use_gnss && trackDataValid(&a->altitude_gnss_valid)) {
snprintf(strFl, 7, "%5dH", convert_altitude(a->altitude_gnss));
} else if (trackDataValid(&a->altitude_valid)) {
snprintf(strFl, 7, "%5d ", convert_altitude(a->altitude));
}
mvprintw(row, 0, "%s%06X %-4s %-4s %-8s %6s %3s %3s %7s %8s %5.1f %5d %2.0f",
(a->addr & MODES_NON_ICAO_ADDRESS) ? "~" : " ", (a->addr & 0xffffff),
strMode, strSquawk, a->callsign, strFl, strGs, strTt,
strLat, strLon, 10 * log10(signalAverage), msgs, (now - a->seen)/1000.0);
++row;
} }
} }
a = a->next; a = a->next;
} }
if (Modes.mode_ac) {
for (unsigned i = 1; i < 4096 && row < rows; ++i) {
if (modeAC_match[i] || modeAC_count[i] < 50 || modeAC_age[i] > 5)
continue;
char strMode[5] = " A ";
char strFl[7] = " ";
unsigned modeA = indexToModeA(i);
int modeC = modeAToModeC(modeA);
if (modeC != INVALID_ALTITUDE) {
strMode[3] = 'C';
snprintf(strFl, 7, "%5d ", convert_altitude(modeC * 100));
}
mvprintw(row, 0,
"%7s %-4s %04x %-8s %6s %3s %3s %7s %8s %5s %5d %2d\n",
"", /* address */
strMode, /* mode */
modeA, /* squawk */
"", /* callsign */
strFl, /* altitude */
"", /* gs */
"", /* heading */
"", /* lat */
"", /* lon */
"", /* signal */
modeAC_count[i], /* messages */
modeAC_age[i]); /* age */
++row;
}
}
move(row, 0);
clrtobot();
refresh();
} }
// //

View file

@ -29,15 +29,59 @@
// //
#include "dump1090.h" #include "dump1090.h"
#include <assert.h>
// //
//========================================================================= //=========================================================================
// //
// Input format is : 00:A4:A2:A1:00:B4:B2:B1:00:C4:C2:C1:00:D4:D2:D1 // Input format is : 00:A4:A2:A1:00:B4:B2:B1:00:C4:C2:C1:00:D4:D2:D1
// //
int ModeAToModeC(unsigned int ModeA)
static int modeAToCTable[4096];
static unsigned modeCToATable[4096];
static int internalModeAToModeC(unsigned int ModeA);
void modeACInit()
{ {
unsigned int FiveHundreds = 0; for (unsigned i = 0; i < 4096; ++i) {
unsigned int OneHundreds = 0; unsigned modeA = indexToModeA(i);
int modeC = internalModeAToModeC(modeA);
modeAToCTable[i] = modeC;
modeC += 13;
if (modeC >= 0 && modeC < 4096) {
assert(modeCToATable[modeC] == 0);
modeCToATable[modeC] = modeA;
}
}
}
// Given a mode A value (hex-encoded, see above)
// return the mode C value (signed multiple of 100s of feet)
// or INVALID_ALITITUDE if not a valid mode C value
int modeAToModeC(unsigned modeA)
{
unsigned i = modeAToIndex(modeA);
if (i >= 4096)
return INVALID_ALTITUDE;
return modeAToCTable[i];
}
// Given a mode C value (signed multiple of 100s of feet)
// return the mode A value, or 0 if not a valid mode C value
unsigned modeCToModeA(int modeC)
{
modeC += 13;
if (modeC < 0 || modeC >= 4096)
return 0;
return modeCToATable[modeC];
}
static int internalModeAToModeC(unsigned int ModeA)
{
unsigned int FiveHundreds = 0;
unsigned int OneHundreds = 0;
if ((ModeA & 0xFFFF8889) != 0 || // check zero bits are zero, D1 set is illegal if ((ModeA & 0xFFFF8889) != 0 || // check zero bits are zero, D1 set is illegal
(ModeA & 0x000000F0) == 0) { // C1,,C4 cannot be Zero (ModeA & 0x000000F0) == 0) { // C1,,C4 cannot be Zero
@ -78,6 +122,8 @@ int ModeAToModeC(unsigned int ModeA)
// //
void decodeModeAMessage(struct modesMessage *mm, int ModeA) void decodeModeAMessage(struct modesMessage *mm, int ModeA)
{ {
mm->source = SOURCE_MODE_AC;
mm->addrtype = ADDR_MODE_A;
mm->msgtype = 32; // Valid Mode S DF's are DF-00 to DF-31. mm->msgtype = 32; // Valid Mode S DF's are DF-00 to DF-31.
// so use 32 to indicate Mode A/C // so use 32 to indicate Mode A/C
@ -98,7 +144,7 @@ void decodeModeAMessage(struct modesMessage *mm, int ModeA)
// Decode an altitude if this looks like a possible mode C // Decode an altitude if this looks like a possible mode C
if (!mm->spi) { if (!mm->spi) {
int modeC = ModeAToModeC(ModeA); int modeC = modeAToModeC(ModeA);
if (modeC != INVALID_ALTITUDE) { if (modeC != INVALID_ALTITUDE) {
mm->altitude = modeC * 100; mm->altitude = modeC * 100;
mm->altitude_unit = UNIT_FEET; mm->altitude_unit = UNIT_FEET;

View file

@ -134,7 +134,7 @@ static int decodeAC13Field(int AC13Field, altitude_unit_t *unit) {
return ((n * 25) - 1000); return ((n * 25) - 1000);
} else { } else {
// N is an 11 bit Gillham coded altitude // N is an 11 bit Gillham coded altitude
int n = ModeAToModeC(decodeID13Field(AC13Field)); int n = modeAToModeC(decodeID13Field(AC13Field));
if (n < -12) { if (n < -12) {
return INVALID_ALTITUDE; return INVALID_ALTITUDE;
} }
@ -167,7 +167,7 @@ static int decodeAC12Field(int AC12Field, altitude_unit_t *unit) {
// Make N a 13 bit Gillham coded altitude by inserting M=0 at bit 6 // Make N a 13 bit Gillham coded altitude by inserting M=0 at bit 6
int n = ((AC12Field & 0x0FC0) << 1) | int n = ((AC12Field & 0x0FC0) << 1) |
(AC12Field & 0x003F); (AC12Field & 0x003F);
n = ModeAToModeC(decodeID13Field(n)); n = modeAToModeC(decodeID13Field(n));
if (n < -12) { if (n < -12) {
return INVALID_ALTITUDE; return INVALID_ALTITUDE;
} }
@ -903,6 +903,7 @@ static void decodeESSurfacePosition(struct modesMessage *mm, int check_imf)
mm->cpr_odd = getbit(me, 22); mm->cpr_odd = getbit(me, 22);
mm->cpr_nucp = (14 - mm->metype); mm->cpr_nucp = (14 - mm->metype);
mm->cpr_valid = 1; mm->cpr_valid = 1;
mm->cpr_type = CPR_SURFACE;
unsigned movement = getbits(me, 6, 12); unsigned movement = getbits(me, 6, 12);
if (movement > 0 && movement < 125) { if (movement > 0 && movement < 125) {
@ -948,6 +949,7 @@ static void decodeESAirbornePosition(struct modesMessage *mm, int check_imf)
} else { } else {
// Otherwise, assume it's valid. // Otherwise, assume it's valid.
mm->cpr_valid = 1; mm->cpr_valid = 1;
mm->cpr_type = CPR_AIRBORNE;
mm->cpr_odd = getbit(me, 22); mm->cpr_odd = getbit(me, 22);
if (mm->metype == 18 || mm->metype == 22) if (mm->metype == 18 || mm->metype == 22)
@ -1381,11 +1383,26 @@ static const char *addrtype_to_string(addrtype_t type) {
return "ADS-R"; return "ADS-R";
case ADDR_ADSR_OTHER: case ADDR_ADSR_OTHER:
return "ADS-R, other addressing scheme"; return "ADS-R, other addressing scheme";
case ADDR_MODE_A:
return "Mode A";
default: default:
return "unknown addressing scheme"; return "unknown addressing scheme";
} }
} }
static const char *cpr_type_to_string(cpr_type_t type) {
switch (type) {
case CPR_SURFACE:
return "Surface";
case CPR_AIRBORNE:
return "Airborne";
case CPR_COARSE:
return "TIS-B Coarse";
default:
return "unknown CPR type";
}
}
static void print_hex_bytes(unsigned char *data, size_t len) { static void print_hex_bytes(unsigned char *data, size_t len) {
size_t i; size_t i;
for (i = 0; i < len; ++i) { for (i = 0; i < len; ++i) {
@ -1676,12 +1693,11 @@ void displayModesMessage(struct modesMessage *mm) {
mm->category); mm->category);
} }
if (mm->msgtype == 17 || mm->msgtype == 18) {
}
if (mm->cpr_valid) { if (mm->cpr_valid) {
printf(" CPR odd flag: %s\n" printf(" CPR type: %s\n"
" CPR odd flag: %s\n"
" CPR NUCp/NIC: %u\n", " CPR NUCp/NIC: %u\n",
cpr_type_to_string(mm->cpr_type),
mm->cpr_odd ? "odd" : "even", mm->cpr_odd ? "odd" : "even",
mm->cpr_nucp); mm->cpr_nucp);
@ -1804,7 +1820,7 @@ void useModesMessage(struct modesMessage *mm) {
// If this is the second message, and we // If this is the second message, and we
// squelched the first message, then re-emit the // squelched the first message, then re-emit the
// first message now. // first message now.
if (!Modes.net_verbatim && a->messages == 2) { if (!Modes.net_verbatim && a && a->messages == 2) {
modesQueueOutput(&a->first_message, a); modesQueueOutput(&a->first_message, a);
} }
modesQueueOutput(mm, a); modesQueueOutput(mm, a);

598
net_io.c
View file

@ -67,17 +67,18 @@
// handled via non-blocking I/O and manually polling clients to see if // handled via non-blocking I/O and manually polling clients to see if
// they have something new to share with us when reading is needed. // they have something new to share with us when reading is needed.
static int handleBeastCommand(struct client *c, char *p);
static int decodeBinMessage(struct client *c, char *p); static int decodeBinMessage(struct client *c, char *p);
static int decodeHexMessage(struct client *c, char *hex); static int decodeHexMessage(struct client *c, char *hex);
#ifdef ENABLE_WEBSERVER
static int handleHTTPRequest(struct client *c, char *p);
#endif
static void send_raw_heartbeat(struct net_service *service); static void send_raw_heartbeat(struct net_service *service);
static void send_beast_heartbeat(struct net_service *service); static void send_beast_heartbeat(struct net_service *service);
static void send_sbs_heartbeat(struct net_service *service); static void send_sbs_heartbeat(struct net_service *service);
static void writeFATSVEvent(struct modesMessage *mm, struct aircraft *a); static void writeFATSVEvent(struct modesMessage *mm, struct aircraft *a);
static void writeFATSVPositionUpdate(float lat, float lon, float alt);
static void autoset_modeac();
// //
//========================================================================= //=========================================================================
@ -87,7 +88,7 @@ static void writeFATSVEvent(struct modesMessage *mm, struct aircraft *a);
// Init a service with the given read/write characteristics, return the new service. // Init a service with the given read/write characteristics, return the new service.
// Doesn't arrange for the service to listen or connect // Doesn't arrange for the service to listen or connect
struct net_service *serviceInit(const char *descr, struct net_writer *writer, heartbeat_fn hb, const char *sep, read_fn handler) struct net_service *serviceInit(const char *descr, struct net_writer *writer, heartbeat_fn hb, read_mode_t mode, const char *sep, read_fn handler)
{ {
struct net_service *service; struct net_service *service;
@ -104,6 +105,7 @@ struct net_service *serviceInit(const char *descr, struct net_writer *writer, he
service->connections = 0; service->connections = 0;
service->writer = writer; service->writer = writer;
service->read_sep = sep; service->read_sep = sep;
service->read_mode = mode;
service->read_handler = handler; service->read_handler = handler;
if (service->writer) { if (service->writer) {
@ -144,6 +146,7 @@ struct client *createGenericClient(struct net_service *service, int fd)
c->next = Modes.clients; c->next = Modes.clients;
c->fd = fd; c->fd = fd;
c->buflen = 0; c->buflen = 0;
c->modeac_requested = 0;
Modes.clients = c; Modes.clients = c;
++service->connections; ++service->connections;
@ -231,12 +234,12 @@ void serviceListen(struct net_service *service, char *bind_addr, char *bind_port
struct net_service *makeBeastInputService(void) struct net_service *makeBeastInputService(void)
{ {
return serviceInit("Beast TCP input", NULL, NULL, NULL, decodeBinMessage); return serviceInit("Beast TCP input", NULL, NULL, READ_MODE_BEAST, NULL, decodeBinMessage);
} }
struct net_service *makeFatsvOutputService(void) struct net_service *makeFatsvOutputService(void)
{ {
return serviceInit("FATSV TCP output", &Modes.fatsv_out, NULL, NULL, NULL); return serviceInit("FATSV TCP output", &Modes.fatsv_out, NULL, READ_MODE_IGNORE, NULL, NULL);
} }
void modesInitNet(void) { void modesInitNet(void) {
@ -247,25 +250,20 @@ void modesInitNet(void) {
Modes.services = NULL; Modes.services = NULL;
// set up listeners // set up listeners
s = serviceInit("Raw TCP output", &Modes.raw_out, send_raw_heartbeat, NULL, NULL); s = serviceInit("Raw TCP output", &Modes.raw_out, send_raw_heartbeat, READ_MODE_IGNORE, NULL, NULL);
serviceListen(s, Modes.net_bind_address, Modes.net_output_raw_ports); serviceListen(s, Modes.net_bind_address, Modes.net_output_raw_ports);
s = serviceInit("Beast TCP output", &Modes.beast_out, send_beast_heartbeat, NULL, NULL); s = serviceInit("Beast TCP output", &Modes.beast_out, send_beast_heartbeat, READ_MODE_BEAST_COMMAND, NULL, handleBeastCommand);
serviceListen(s, Modes.net_bind_address, Modes.net_output_beast_ports); serviceListen(s, Modes.net_bind_address, Modes.net_output_beast_ports);
s = serviceInit("Basestation TCP output", &Modes.sbs_out, send_sbs_heartbeat, NULL, NULL); s = serviceInit("Basestation TCP output", &Modes.sbs_out, send_sbs_heartbeat, READ_MODE_IGNORE, NULL, NULL);
serviceListen(s, Modes.net_bind_address, Modes.net_output_sbs_ports); serviceListen(s, Modes.net_bind_address, Modes.net_output_sbs_ports);
s = serviceInit("Raw TCP input", NULL, NULL, "\n", decodeHexMessage); s = serviceInit("Raw TCP input", NULL, NULL, READ_MODE_ASCII, "\n", decodeHexMessage);
serviceListen(s, Modes.net_bind_address, Modes.net_input_raw_ports); serviceListen(s, Modes.net_bind_address, Modes.net_input_raw_ports);
s = makeBeastInputService(); s = makeBeastInputService();
serviceListen(s, Modes.net_bind_address, Modes.net_input_beast_ports); serviceListen(s, Modes.net_bind_address, Modes.net_input_beast_ports);
#ifdef ENABLE_WEBSERVER
s = serviceInit("HTTP server", NULL, NULL, "\r\n\r\n", handleHTTPRequest);
serviceListen(s, Modes.net_bind_address, Modes.net_http_ports);
#endif
} }
// //
//========================================================================= //=========================================================================
@ -310,6 +308,9 @@ static void modesCloseClient(struct client *c) {
// mark it as inactive and ready to be freed // mark it as inactive and ready to be freed
c->fd = -1; c->fd = -1;
c->service = NULL; c->service = NULL;
c->modeac_requested = 0;
autoset_modeac();
} }
// //
//========================================================================= //=========================================================================
@ -594,7 +595,7 @@ static void modesSendSBSOutput(struct modesMessage *mm, struct aircraft *a) {
} else if (trackDataValid(&a->gnss_delta_valid)) { } else if (trackDataValid(&a->gnss_delta_valid)) {
p += sprintf(p, ",%d", mm->altitude - a->gnss_delta); p += sprintf(p, ",%d", mm->altitude - a->gnss_delta);
} else { } else {
p += sprintf(p, ",,"); p += sprintf(p, ",");
} }
} }
} else { } else {
@ -710,7 +711,7 @@ static void send_sbs_heartbeat(struct net_service *service)
void modesQueueOutput(struct modesMessage *mm, struct aircraft *a) { void modesQueueOutput(struct modesMessage *mm, struct aircraft *a) {
int is_mlat = (mm->source == SOURCE_MLAT); int is_mlat = (mm->source == SOURCE_MLAT);
if (!is_mlat && mm->correctedbits < 2) { if (a && !is_mlat && mm->correctedbits < 2) {
// Don't ever forward 2-bit-corrected messages via SBS output. // Don't ever forward 2-bit-corrected messages via SBS output.
// Don't ever forward mlat messages via SBS output. // Don't ever forward mlat messages via SBS output.
modesSendSBSOutput(mm, a); modesSendSBSOutput(mm, a);
@ -728,10 +729,119 @@ void modesQueueOutput(struct modesMessage *mm, struct aircraft *a) {
modesSendBeastOutput(mm); modesSendBeastOutput(mm);
} }
if (!is_mlat) { if (a && !is_mlat) {
writeFATSVEvent(mm, a); writeFATSVEvent(mm, a);
} }
} }
// Decode a little-endian IEEE754 float (binary32)
float ieee754_binary32_le_to_float(uint8_t *data)
{
double sign = (data[3] & 0x80) ? -1.0 : 1.0;
int16_t raw_exponent = ((data[3] & 0x7f) << 1) | ((data[2] & 0x80) >> 7);
uint32_t raw_significand = ((data[2] & 0x7f) << 16) | (data[1] << 8) | data[0];
if (raw_exponent == 0) {
if (raw_significand == 0) {
/* -0 is treated like +0 */
return 0;
} else {
/* denormal */
return ldexp(sign * raw_significand, -126 - 23);
}
}
if (raw_exponent == 255) {
if (raw_significand == 0) {
/* +/-infinity */
return sign < 0 ? -INFINITY : INFINITY;
} else {
/* NaN */
#ifdef NAN
return NAN;
#else
return 0.0f;
#endif
}
}
/* normalized value */
return ldexp(sign * ((1 << 23) | raw_significand), raw_exponent - 127 - 23);
}
static void handle_radarcape_position(float lat, float lon, float alt)
{
if (!isfinite(lat) || lat < -90 || lat > 90 || !isfinite(lon) || lon < -180 || lon > 180 || !isfinite(alt))
return;
writeFATSVPositionUpdate(lat, lon, alt);
if (!(Modes.bUserFlags & MODES_USER_LATLON_VALID)) {
Modes.fUserLat = lat;
Modes.fUserLon = lon;
Modes.bUserFlags |= MODES_USER_LATLON_VALID;
receiverPositionChanged(lat, lon, alt);
}
}
// recompute global Mode A/C setting
static void autoset_modeac() {
struct client *c;
if (!Modes.mode_ac_auto)
return;
Modes.mode_ac = 0;
for (c = Modes.clients; c; c = c->next) {
if (c->modeac_requested) {
Modes.mode_ac = 1;
break;
}
}
}
// Send some Beast settings commands to a client
void sendBeastSettings(struct client *c, const char *settings)
{
int len;
char *buf, *p;
len = strlen(settings) * 3;
buf = p = alloca(len);
while (*settings) {
*p++ = 0x1a;
*p++ = '1';
*p++ = *settings++;
}
anetWrite(c->fd, buf, len);
}
//
// Handle a Beast command message.
// Currently, we just look for the Mode A/C command message
// and ignore everything else.
//
static int handleBeastCommand(struct client *c, char *p) {
if (p[0] != '1') {
// huh?
return 0;
}
switch (p[1]) {
case 'j':
c->modeac_requested = 0;
break;
case 'J':
c->modeac_requested = 1;
break;
}
autoset_modeac();
return 0;
}
// //
//========================================================================= //=========================================================================
// //
@ -749,21 +859,37 @@ static int decodeBinMessage(struct client *c, char *p) {
int msgLen = 0; int msgLen = 0;
int j; int j;
char ch; char ch;
unsigned char msg[MODES_LONG_MSG_BYTES]; unsigned char msg[MODES_LONG_MSG_BYTES + 7];
static struct modesMessage zeroMessage; static struct modesMessage zeroMessage;
struct modesMessage mm; struct modesMessage mm;
MODES_NOTUSED(c); MODES_NOTUSED(c);
memset(&mm, 0, sizeof(mm)); memset(&mm, 0, sizeof(mm));
ch = *p++; /// Get the message type ch = *p++; /// Get the message type
if (0x1A == ch) {p++;}
if ((ch == '1') && (Modes.mode_ac)) { // skip ModeA/C unless user enables --modes-ac if (ch == '1' && Modes.mode_ac) {
msgLen = MODEAC_MSG_BYTES; msgLen = MODEAC_MSG_BYTES;
} else if (ch == '2') { } else if (ch == '2') {
msgLen = MODES_SHORT_MSG_BYTES; msgLen = MODES_SHORT_MSG_BYTES;
} else if (ch == '3') { } else if (ch == '3') {
msgLen = MODES_LONG_MSG_BYTES; msgLen = MODES_LONG_MSG_BYTES;
} else if (ch == '5') {
// Special case for Radarcape position messages.
float lat, lon, alt;
for (j = 0; j < 21; j++) { // and the data
msg[j] = ch = *p++;
if (0x1A == ch) {p++;}
}
lat = ieee754_binary32_le_to_float(msg + 4);
lon = ieee754_binary32_le_to_float(msg + 8);
alt = ieee754_binary32_le_to_float(msg + 12);
handle_radarcape_position(lat, lon, alt);
} else {
// Ignore this.
return 0;
} }
if (msgLen) { if (msgLen) {
@ -1027,10 +1153,6 @@ char *generateAircraftJson(const char *url_path, int *len) {
Modes.stats_current.messages_total + Modes.stats_alltime.messages_total); Modes.stats_current.messages_total + Modes.stats_alltime.messages_total);
for (a = Modes.aircrafts; a; a = a->next) { for (a = Modes.aircrafts; a; a = a->next) {
if (a->modeACflags & MODEAC_MSG_FLAG) { // skip any fudged ICAO records Mode A/C
continue;
}
if (a->messages < 2) { // basic filter for bad decodes if (a->messages < 2) { // basic filter for bad decodes
continue; continue;
} }
@ -1149,10 +1271,6 @@ static char * appendStatsJson(char *p,
} }
p += snprintf(p, end-p, "]}"); p += snprintf(p, end-p, "]}");
#ifdef ENABLE_WEBSERVER
p += snprintf(p, end-p, ",\"http_requests\":%u", st->http_requests);
#endif
} }
{ {
@ -1344,205 +1462,6 @@ void writeJsonToFile(const char *file, char * (*generator) (const char *,int*))
} }
#ifdef ENABLE_WEBSERVER
//
//=========================================================================
//
#define MODES_CONTENT_TYPE_HTML "text/html;charset=utf-8"
#define MODES_CONTENT_TYPE_CSS "text/css;charset=utf-8"
#define MODES_CONTENT_TYPE_JSON "application/json;charset=utf-8"
#define MODES_CONTENT_TYPE_JS "application/javascript;charset=utf-8"
#define MODES_CONTENT_TYPE_GIF "image/gif"
static struct {
char *path;
char * (*handler)(const char*,int*);
char *content_type;
int prefix;
} url_handlers[] = {
{ "/data/aircraft.json", generateAircraftJson, MODES_CONTENT_TYPE_JSON, 0 },
{ "/data/receiver.json", generateReceiverJson, MODES_CONTENT_TYPE_JSON, 0 },
{ "/data/stats.json", generateStatsJson, MODES_CONTENT_TYPE_JSON, 0 },
{ "/data/history_", generateHistoryJson, MODES_CONTENT_TYPE_JSON, 1 },
{ NULL, NULL, NULL, 0 }
};
//
// Get an HTTP request header and write the response to the client.
// gain here we assume that the socket buffer is enough without doing
// any kind of userspace buffering.
//
// Returns 1 on error to signal the caller the client connection should
// be closed.
//
static int handleHTTPRequest(struct client *c, char *p) {
char hdr[512];
int clen, hdrlen;
int httpver, keepalive;
int statuscode = 500;
const char *statusmsg = "Internal Server Error";
char *url, *content = NULL;
char *ext;
char *content_type = NULL;
int i;
if (Modes.debug & MODES_DEBUG_NET)
printf("\nHTTP request: %s\n", c->buf);
// Minimally parse the request.
httpver = (strstr(p, "HTTP/1.1") != NULL) ? 11 : 10;
if (httpver == 10) {
// HTTP 1.0 defaults to close, unless otherwise specified.
//keepalive = strstr(p, "Connection: keep-alive") != NULL;
} else if (httpver == 11) {
// HTTP 1.1 defaults to keep-alive, unless close is specified.
//keepalive = strstr(p, "Connection: close") == NULL;
}
keepalive = 0;
// Identify he URL.
p = strchr(p,' ');
if (!p) return 1; // There should be the method and a space
url = ++p; // Now this should point to the requested URL
p = strchr(p, ' ');
if (!p) return 1; // There should be a space before HTTP/
*p = '\0';
if (Modes.debug & MODES_DEBUG_NET) {
printf("\nHTTP keep alive: %d\n", keepalive);
printf("HTTP requested URL: %s\n\n", url);
}
// Ditch any trailing query part (AJAX might add one to avoid caching)
p = strchr(url, '?');
if (p) *p = 0;
statuscode = 404;
statusmsg = "Not Found";
for (i = 0; url_handlers[i].path; ++i) {
if ((url_handlers[i].prefix && !strncmp(url, url_handlers[i].path, strlen(url_handlers[i].path))) ||
(!url_handlers[i].prefix && !strcmp(url, url_handlers[i].path))) {
content_type = url_handlers[i].content_type;
content = url_handlers[i].handler(url, &clen);
if (!content)
continue;
statuscode = 200;
statusmsg = "OK";
if (Modes.debug & MODES_DEBUG_NET) {
printf("HTTP: 200: %s -> internal (%d bytes, %s)\n", url, clen, content_type);
}
break;
}
}
if (!content) {
struct stat sbuf;
int fd = -1;
char rp[PATH_MAX], hrp[PATH_MAX];
char getFile[1024];
if (strlen(url) < 2) {
snprintf(getFile, sizeof getFile, "%s/gmap.html", Modes.html_dir); // Default file
} else {
snprintf(getFile, sizeof getFile, "%s/%s", Modes.html_dir, url);
}
if (!realpath(getFile, rp))
rp[0] = 0;
if (!realpath(Modes.html_dir, hrp))
strcpy(hrp, Modes.html_dir);
clen = -1;
content = strdup("Server error occured");
if (!strncmp(hrp, rp, strlen(hrp))) {
if (stat(getFile, &sbuf) != -1 && (fd = open(getFile, O_RDONLY)) != -1) {
content = (char *) realloc(content, sbuf.st_size);
if (read(fd, content, sbuf.st_size) == sbuf.st_size) {
clen = sbuf.st_size;
statuscode = 200;
statusmsg = "OK";
}
}
} else {
errno = ENOENT;
}
if (clen < 0) {
content = realloc(content, 128);
clen = snprintf(content, 128, "Error opening HTML file: %s", strerror(errno));
statuscode = 404;
statusmsg = "Not Found";
}
if (fd != -1) {
close(fd);
}
// Get file extension and content type
content_type = MODES_CONTENT_TYPE_HTML; // Default content type
ext = strrchr(getFile, '.');
if (ext) {
if (!strcmp(ext, ".json")) {
content_type = MODES_CONTENT_TYPE_JSON;
} else if (!strcmp(ext, ".css")) {
content_type = MODES_CONTENT_TYPE_CSS;
} else if (!strcmp(ext, ".js")) {
content_type = MODES_CONTENT_TYPE_JS;
} else if (!strcmp(ext, ".gif")) {
content_type = MODES_CONTENT_TYPE_GIF;
}
}
if (Modes.debug & MODES_DEBUG_NET) {
printf("HTTP: %d %s: %s -> %s (%d bytes, %s)\n", statuscode, statusmsg, url, rp, clen, content_type);
}
}
// Create the header and send the reply
hdrlen = snprintf(hdr, sizeof(hdr),
"HTTP/1.1 %d %s\r\n"
"Server: Dump1090\r\n"
"Content-Type: %s\r\n"
"Connection: %s\r\n"
"Content-Length: %d\r\n"
"Cache-Control: no-cache, must-revalidate\r\n"
"Expires: Sat, 26 Jul 1997 05:00:00 GMT\r\n"
"\r\n",
statuscode, statusmsg,
content_type,
keepalive ? "keep-alive" : "close",
clen);
if (Modes.debug & MODES_DEBUG_NET) {
printf("HTTP Reply header:\n%s", hdr);
}
/* hack hack hack. try to deal with large content */
anetSetSendBuffer(Modes.aneterr, c->fd, clen + hdrlen);
// Send header and content.
#ifndef _WIN32
if ( (write(c->fd, hdr, hdrlen) != hdrlen)
|| (write(c->fd, content, clen) != clen) )
#else
if ( (send(c->fd, hdr, hdrlen, 0) != hdrlen)
|| (send(c->fd, content, clen, 0) != clen) )
#endif
{
free(content);
return 1;
}
free(content);
Modes.stats_current.http_requests++;
return !keepalive;
}
#endif
// //
//========================================================================= //=========================================================================
// //
@ -1561,14 +1480,11 @@ static int handleHTTPRequest(struct client *c, char *p) {
static void modesReadFromClient(struct client *c) { static void modesReadFromClient(struct client *c) {
int left; int left;
int nread; int nread;
int fullmsg;
int bContinue = 1; int bContinue = 1;
char *s, *e, *p;
while(bContinue) { while (bContinue) {
left = MODES_CLIENT_BUF_SIZE - c->buflen - 1; // leave 1 extra byte for NUL termination in the ASCII case
fullmsg = 0;
left = MODES_CLIENT_BUF_SIZE - c->buflen;
// If our buffer is full discard it, this is some badly formatted shit // If our buffer is full discard it, this is some badly formatted shit
if (left <= 0) { if (left <= 0) {
c->buflen = 0; c->buflen = 0;
@ -1608,73 +1524,138 @@ static void modesReadFromClient(struct client *c) {
c->buflen += nread; c->buflen += nread;
// Always null-term so we are free to use strstr() (it won't affect binary case) char *som = c->buf; // first byte of next message
c->buf[c->buflen] = '\0'; char *eod = som + c->buflen; // one byte past end of data
char *p;
e = s = c->buf; // Start with the start of buffer, first message switch (c->service->read_mode) {
case READ_MODE_IGNORE:
// drop the bytes on the floor
som = eod;
break;
if (c->service->read_sep == NULL) { case READ_MODE_BEAST:
// This is the Beast Binary scanning case. // This is the Beast Binary scanning case.
// If there is a complete message still in the buffer, there must be the separator 'sep' // If there is a complete message still in the buffer, there must be the separator 'sep'
// in the buffer, note that we full-scan the buffer at every read for simplicity. // in the buffer, note that we full-scan the buffer at every read for simplicity.
left = c->buflen; // Length of valid search for memchr() while (som < eod && ((p = memchr(som, (char) 0x1a, eod - som)) != NULL)) { // The first byte of buffer 'should' be 0x1a
while (left > 1 && ((s = memchr(e, (char) 0x1a, left)) != NULL)) { // The first byte of buffer 'should' be 0x1a som = p; // consume garbage up to the 0x1a
s++; // skip the 0x1a ++p; // skip 0x1a
if (*s == '1') {
e = s + MODEAC_MSG_BYTES + 8; // point past remainder of message if (p >= eod) {
} else if (*s == '2') { // Incomplete message in buffer, retry later
e = s + MODES_SHORT_MSG_BYTES + 8;
} else if (*s == '3') {
e = s + MODES_LONG_MSG_BYTES + 8;
} else {
e = s; // Not a valid beast message, skip
left = &(c->buf[c->buflen]) - e;
continue;
}
// we need to be careful of double escape characters in the message body
for (p = s; p < e; p++) {
if (0x1A == *p) {
p++; e++;
if (e > &(c->buf[c->buflen])) {
break;
}
}
}
left = &(c->buf[c->buflen]) - e;
if (left < 0) { // Incomplete message in buffer
e = s - 1; // point back at last found 0x1a.
break; break;
} }
// Have a 0x1a followed by 1, 2 or 3 - pass message less 0x1a to handler.
if (c->service->read_handler(c, s)) { char *eom; // one byte past end of message
if (*p == '1') {
eom = p + MODEAC_MSG_BYTES + 8; // point past remainder of message
} else if (*p == '2') {
eom = p + MODES_SHORT_MSG_BYTES + 8;
} else if (*p == '3') {
eom = p + MODES_LONG_MSG_BYTES + 8;
} else if (*p == '4') {
eom = p + MODES_LONG_MSG_BYTES + 8;
} else if (*p == '5') {
eom = p + MODES_LONG_MSG_BYTES + 8;
} else {
// Not a valid beast message, skip 0x1a and try again
++som;
continue;
}
// we need to be careful of double escape characters in the message body
for (p = som + 1; p < eod && p < eom; p++) {
if (0x1A == *p) {
p++;
eom++;
}
}
if (eom > eod) { // Incomplete message in buffer, retry later
break;
}
// Have a 0x1a followed by 1/2/3/4/5 - pass message to handler.
if (c->service->read_handler(c, som + 1)) {
modesCloseClient(c); modesCloseClient(c);
return; return;
} }
fullmsg = 1;
}
s = e; // For the buffer remainder below
} else { // advance to next message
som = eom;
}
break;
case READ_MODE_BEAST_COMMAND:
while (som < eod && ((p = memchr(som, (char) 0x1a, eod - som)) != NULL)) { // The first byte of buffer 'should' be 0x1a
char *eom; // one byte past end of message
som = p; // consume garbage up to the 0x1a
++p; // skip 0x1a
if (p >= eod) {
// Incomplete message in buffer, retry later
break;
}
if (*p == '1') {
eom = p + 2;
} else {
// Not a valid beast command, skip 0x1a and try again
++som;
continue;
}
// we need to be careful of double escape characters in the message body
for (p = som + 1; p < eod && p < eom; p++) {
if (0x1A == *p) {
p++;
eom++;
}
}
if (eom > eod) { // Incomplete message in buffer, retry later
break;
}
// Have a 0x1a followed by 1 - pass message to handler.
if (c->service->read_handler(c, som + 1)) {
modesCloseClient(c);
return;
}
// advance to next message
som = eom;
}
break;
case READ_MODE_ASCII:
// //
// This is the ASCII scanning case, AVR RAW or HTTP at present // This is the ASCII scanning case, AVR RAW or HTTP at present
// If there is a complete message still in the buffer, there must be the separator 'sep' // If there is a complete message still in the buffer, there must be the separator 'sep'
// in the buffer, note that we full-scan the buffer at every read for simplicity. // in the buffer, note that we full-scan the buffer at every read for simplicity.
//
while ((e = strstr(s, c->service->read_sep)) != NULL) { // end of first message if found // Always NUL-terminate so we are free to use strstr()
*e = '\0'; // The handler expects null terminated strings // nb: we never fill the last byte of the buffer with read data (see above) so this is safe
if (c->service->read_handler(c, s)) { // Pass message to handler. *eod = '\0';
while (som < eod && (p = strstr(som, c->service->read_sep)) != NULL) { // end of first message if found
*p = '\0'; // The handler expects null terminated strings
if (c->service->read_handler(c, som)) { // Pass message to handler.
modesCloseClient(c); // Handler returns 1 on error to signal we . modesCloseClient(c); // Handler returns 1 on error to signal we .
return; // should close the client connection return; // should close the client connection
} }
s = e + strlen(c->service->read_sep); // Move to start of next message som = p + strlen(c->service->read_sep); // Move to start of next message
fullmsg = 1;
} }
break;
} }
if (fullmsg) { // We processed something - so if (som > c->buf) { // We processed something - so
c->buflen = &(c->buf[c->buflen]) - s; // Update the unprocessed buffer length c->buflen = eod - som; // Update the unprocessed buffer length
memmove(c->buf, s, c->buflen); // Move what's remaining to the start of the buffer memmove(c->buf, som, c->buflen); // Move what's remaining to the start of the buffer
} else { // If no message was decoded process the next client } else { // If no message was decoded process the next client
return; return;
} }
@ -1683,6 +1664,40 @@ static void modesReadFromClient(struct client *c) {
#define TSV_MAX_PACKET_SIZE 275 #define TSV_MAX_PACKET_SIZE 275
static void writeFATSVPositionUpdate(float lat, float lon, float alt)
{
static float last_lat, last_lon, last_alt;
if (lat == last_lat && lon == last_lon && alt == last_alt)
return;
last_lat = lat;
last_lon = lon;
last_alt = alt;
char *p = prepareWrite(&Modes.fatsv_out, TSV_MAX_PACKET_SIZE);
if (!p)
return;
char *end = p + TSV_MAX_PACKET_SIZE;
# define bufsize(_p,_e) ((_p) >= (_e) ? (size_t)0 : (size_t)((_e) - (_p)))
p += snprintf(p, bufsize(p, end), "clock\t%" PRIu64, mstime() / 1000);
p += snprintf(p, bufsize(p, end), "\ttype\t%s", "location_update");
p += snprintf(p, bufsize(p, end), "\tlat\t%.5f", lat);
p += snprintf(p, bufsize(p, end), "\tlon\t%.5f", lon);
p += snprintf(p, bufsize(p, end), "\talt\t%.0f", alt);
p += snprintf(p, bufsize(p, end), "\taltref\t%s", "egm96_meters");
p += snprintf(p, bufsize(p, end), "\n");
if (p <= end)
completeWrite(&Modes.fatsv_out, p);
else
fprintf(stderr, "fatsv: output too large (max %d, overran by %d)\n", TSV_MAX_PACKET_SIZE, (int) (p - end));
# undef bufsize
}
static void writeFATSVEventMessage(struct modesMessage *mm, const char *datafield, unsigned char *data, size_t len) static void writeFATSVEventMessage(struct modesMessage *mm, const char *datafield, unsigned char *data, size_t len)
{ {
char *p = prepareWrite(&Modes.fatsv_out, TSV_MAX_PACKET_SIZE); char *p = prepareWrite(&Modes.fatsv_out, TSV_MAX_PACKET_SIZE);
@ -1754,10 +1769,10 @@ static void writeFATSVEvent(struct modesMessage *mm, struct aircraft *a)
case 17: case 17:
case 18: case 18:
// DF 17/18: extended squitter // DF 17/18: extended squitter
if (mm->metype == 28 && mm->mesub == 2 && memcmp(&mm->ME[1], &a->fatsv_emitted_bds_30[1], 6) != 0) { if (mm->metype == 28 && mm->mesub == 2 && memcmp(mm->ME, &a->fatsv_emitted_es_acas_ra, 7) != 0) {
// type 28 subtype 2: ACAS RA report // type 28 subtype 2: ACAS RA report
// first byte has the type/subtype, remaining bytes match the BDS 3,0 format // first byte has the type/subtype, remaining bytes match the BDS 3,0 format
memcpy(a->fatsv_emitted_bds_30, &mm->ME[1], 6); memcpy(a->fatsv_emitted_es_acas_ra, mm->ME, 7);
writeFATSVEventMessage(mm, "es_acas_ra", mm->ME, 7); writeFATSVEventMessage(mm, "es_acas_ra", mm->ME, 7);
} else if (mm->metype == 31 && (mm->mesub == 0 || mm->mesub == 1) && memcmp(mm->ME, a->fatsv_emitted_es_status, 7) != 0) { } else if (mm->metype == 31 && (mm->mesub == 0 || mm->mesub == 1) && memcmp(mm->ME, a->fatsv_emitted_es_status, 7) != 0) {
// aircraft operational status // aircraft operational status
@ -1787,6 +1802,17 @@ typedef enum {
TISB_CATEGORY = 2048 TISB_CATEGORY = 2048
} tisb_flags; } tisb_flags;
static inline unsigned unsigned_difference(unsigned v1, unsigned v2)
{
return (v1 > v2) ? (v1 - v2) : (v2 - v1);
}
static inline unsigned heading_difference(unsigned h1, unsigned h2)
{
unsigned d = unsigned_difference(h1, h2);
return (d < 180) ? d : (360 - d);
}
static void writeFATSV() static void writeFATSV()
{ {
struct aircraft *a; struct aircraft *a;
@ -1860,19 +1886,19 @@ static void writeFATSV()
if (altGNSSValid && abs(a->altitude_gnss - a->fatsv_emitted_altitude_gnss) >= 50) { if (altGNSSValid && abs(a->altitude_gnss - a->fatsv_emitted_altitude_gnss) >= 50) {
changed = 1; changed = 1;
} }
if (headingValid && abs(a->heading - a->fatsv_emitted_heading) >= 2) { if (headingValid && heading_difference(a->heading, a->fatsv_emitted_heading) >= 2) {
changed = 1; changed = 1;
} }
if (headingMagValid && abs(a->heading_magnetic - a->fatsv_emitted_heading_magnetic) >= 2) { if (headingMagValid && heading_difference(a->heading_magnetic, a->fatsv_emitted_heading_magnetic) >= 2) {
changed = 1; changed = 1;
} }
if (speedValid && abs(a->speed - a->fatsv_emitted_speed) >= 25) { if (speedValid && unsigned_difference(a->speed, a->fatsv_emitted_speed) >= 25) {
changed = 1; changed = 1;
} }
if (speedIASValid && abs(a->speed_ias - a->fatsv_emitted_speed_ias) >= 25) { if (speedIASValid && unsigned_difference(a->speed_ias, a->fatsv_emitted_speed_ias) >= 25) {
changed = 1; changed = 1;
} }
if (speedTASValid && abs(a->speed_tas - a->fatsv_emitted_speed_tas) >= 25) { if (speedTASValid && unsigned_difference(a->speed_tas, a->fatsv_emitted_speed_tas) >= 25) {
changed = 1; changed = 1;
} }
@ -1997,7 +2023,7 @@ static void writeFATSV()
} }
if (headingMagValid && a->heading_magnetic_valid.updated > a->fatsv_last_emitted) { if (headingMagValid && a->heading_magnetic_valid.updated > a->fatsv_last_emitted) {
p += snprintf(p, bufsize(p,end), "\theading_magnetic\t%d", a->heading); p += snprintf(p, bufsize(p,end), "\theading_magnetic\t%d", a->heading_magnetic);
a->fatsv_emitted_heading_magnetic = a->heading_magnetic; a->fatsv_emitted_heading_magnetic = a->heading_magnetic;
useful = 1; useful = 1;
tisb |= (a->heading_magnetic_valid.source == SOURCE_TISB) ? TISB_HEADING_MAGNETIC : 0; tisb |= (a->heading_magnetic_valid.source == SOURCE_TISB) ? TISB_HEADING_MAGNETIC : 0;

View file

@ -29,6 +29,13 @@ struct net_service;
typedef int (*read_fn)(struct client *, char *); typedef int (*read_fn)(struct client *, char *);
typedef void (*heartbeat_fn)(struct net_service *); typedef void (*heartbeat_fn)(struct net_service *);
typedef enum {
READ_MODE_IGNORE,
READ_MODE_BEAST,
READ_MODE_BEAST_COMMAND,
READ_MODE_ASCII
} read_mode_t;
// Describes one network service (a group of clients with common behaviour) // Describes one network service (a group of clients with common behaviour)
struct net_service { struct net_service {
struct net_service* next; struct net_service* next;
@ -41,6 +48,7 @@ struct net_service {
struct net_writer *writer; // shared writer state struct net_writer *writer; // shared writer state
const char *read_sep; // hander details for input data const char *read_sep; // hander details for input data
read_mode_t read_mode;
read_fn read_handler; read_fn read_handler;
}; };
@ -51,6 +59,7 @@ struct client {
struct net_service *service; // Service this client is part of struct net_service *service; // Service this client is part of
int buflen; // Amount of data on buffer int buflen; // Amount of data on buffer
char buf[MODES_CLIENT_BUF_SIZE+1]; // Read buffer char buf[MODES_CLIENT_BUF_SIZE+1]; // Read buffer
int modeac_requested; // 1 if this Beast output connection has asked for A/C
}; };
// Common writer state for all output sockets of one type // Common writer state for all output sockets of one type
@ -62,7 +71,7 @@ struct net_writer {
heartbeat_fn send_heartbeat; // function that queues a heartbeat if needed heartbeat_fn send_heartbeat; // function that queues a heartbeat if needed
}; };
struct net_service *serviceInit(const char *descr, struct net_writer *writer, heartbeat_fn hb_handler, const char *sep, read_fn read_handler); struct net_service *serviceInit(const char *descr, struct net_writer *writer, heartbeat_fn hb_handler, read_mode_t mode, const char *sep, read_fn read_handler);
struct client *serviceConnect(struct net_service *service, char *addr, int port); struct client *serviceConnect(struct net_service *service, char *addr, int port);
void serviceListen(struct net_service *service, char *bind_addr, char *bind_ports); void serviceListen(struct net_service *service, char *bind_addr, char *bind_ports);
struct client *createSocketClient(struct net_service *service, int fd); struct client *createSocketClient(struct net_service *service, int fd);
@ -72,6 +81,8 @@ struct client *createGenericClient(struct net_service *service, int fd);
struct net_service *makeBeastInputService(void); struct net_service *makeBeastInputService(void);
struct net_service *makeFatsvOutputService(void); struct net_service *makeFatsvOutputService(void);
void sendBeastSettings(struct client *c, const char *settings);
void modesInitNet(void); void modesInitNet(void);
void modesQueueOutput(struct modesMessage *mm, struct aircraft *a); void modesQueueOutput(struct modesMessage *mm, struct aircraft *a);
void modesNetPeriodicWork(void); void modesNetPeriodicWork(void);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
{"01":{"t":"GLF4"},"02":{"t":"SHIP"},"03":{"t":"SR22"},"05":{"desc":"L1P"},"06":{"desc":"L1P"},"07":{"desc":"L1P"},"08":{"t":"PA46"},"09":{"t":"BE40"},"0A":{"desc":"L1P"},"0B":{"desc":"L1P"},"0C":{"t":"C560"},"0D":{"desc":"L2J","t":"GLF6"},"0E":{"t":"GLF5"},"0F":{"desc":"L1P"},"10":{"t":"C750"},"12":{"t":"GLEX"},"13":{"desc":"A2P"},"15":{"desc":"H4E"},"16":{"t":"BE55"},"17":{"t":"BE35"},"18":{"t":"C172"},"19":{"t":"M20P"},"1A":{"t":"GLF4"},"1B":{"desc":"L4J"},"1C":{"desc":"L1P"},"1D":{"t":"GLF4"},"1E":{"t":"C56X"},"1F":{"t":"T34P"},"20":{"t":"BE35"},"21":{"t":"BE55"},"22":{"t":"S76"},"23":{"desc":"H1P","t":"GYRO"},"24":{"desc":"L1P"},"25":{"t":"BE30"},"26":{"t":"C25C"},"27":{"t":"C425"},"28":{"t":"GLF5"},"29":{"t":"C182"},"2A":{"t":"PA32"},"2B":{"t":"C182"},"2C":{"t":"C750"},"2D":{"t":"GLID"},"2E":{"desc":"L1P"},"2F":{"t":"BE55"},"30":{"t":"BE35"},"31":{"t":"GLF4"},"32":{"desc":"L1P"},"33":{"desc":"L1P"},"34":{"t":"F2TH"},"35":{"t":"CL30"},"36":{"t":"C172"},"37":{"t":"GLF2"},"38":{"t":"C337"},"39":{"t":"BE35"},"3A":{"t":"CL30"},"3B":{"t":"FA50"},"3C":{"t":"C25C"},"3D":{"desc":"L1P"},"3E":{"t":"BE33"},"3F":{"desc":"L1J"},"40":{"desc":"L1P"},"41":{"t":"BE55"},"42":{"t":"CL60"},"43":{"t":"AA1"},"44":{"desc":"H1T"},"45":{"t":"NAVI"},"46":{"t":"P337"},"47":{"t":"CL60"},"48":{"desc":"L1P"},"49":{"t":"PC12"},"4A":{"desc":"L1P"},"4B":{"t":"GC1"},"4C":{"t":"C190"},"4D":{"t":"GLF4"},"4E":{"t":"C500"},"4F":{"t":"C421"},"50":{"t":"GLF5"},"51":{"t":"BE36"},"52":{"desc":"L2J","t":"LR31"},"53":{"desc":"L1P"},"54":{"t":"GL5T"},"55":{"t":"CL60"},"56":{"t":"BE33"},"57":{"t":"SR22"},"58":{"t":"GLID"},"59":{"desc":"L2J","t":"C25C"},"5A":{"t":"BE35"},"5B":{"desc":"L1P"},"5C":{"t":"H500"},"5D":{"t":"C414"},"5E":{"t":"GLEX"},"60":{"t":"BE50"},"61":{"t":"T206"},"62":{"t":"GLF4"},"63":{"t":"R66"},"64":{"t":"C310"},"65":{"t":"C182"},"66":{"t":"C172"},"68":{"t":"GLF5"},"69":{"t":"ST75"},"6A":{"desc":"L2J","t":"LR31"},"6B":{"desc":"L1P"},"6C":{"t":"BE58"},"6D":{"t":"PRM1"},"6E":{"t":"C206"},"70":{"desc":"L1P"},"71":{"t":"C510"},"72":{"desc":"L1P"},"74":{"desc":"L1P"},"76":{"t":"DA42"},"77":{"t":"CL60"},"78":{"t":"PA31"},"79":{"desc":"L1P"},"7A":{"t":"BE36"},"7B":{"t":"NAVI"},"7C":{"desc":"L1P"},"7D":{"desc":"L1P"},"7E":{"desc":"L1P"},"7F":{"t":"GLF6"},"80":{"t":"BE35"},"81":{"desc":"L1P"},"82":{"desc":"L2J"},"83":{"t":"TOBA"},"84":{"t":"GLEX"},"85":{"desc":"L1P"},"86":{"t":"T206"},"87":{"t":"C180"},"88":{"t":"C680"},"89":{"t":"PA23"},"8A":{"desc":"H2T"},"8B":{"t":"C550"},"8C":{"desc":"L1P"},"8D":{"desc":"L1P"},"8F":{"t":"C182"},"90":{"t":"GLF5"},"91":{"desc":"L1J"},"92":{"t":"PA31"},"93":{"t":"M20P"},"94":{"desc":"L1P"},"95":{"t":"BE55"},"96":{"t":"AA5"},"97":{"t":"M5"},"98":{"desc":"L1P"},"99":{"t":"O1"},"9A":{"desc":"L1P"},"9B":{"t":"EC35"},"9C":{"desc":"L1P"},"9D":{"desc":"L1P"},"9E":{"t":"BE9L"},"9F":{"t":"C500"},"A0":{"t":"C550"},"A1":{"desc":"L1P"},"A2":{"desc":"H1P"},"A3":{"t":"PA27"},"A4":{"t":"SBR1"},"A5":{"t":"GLF5"},"A6":{"desc":"L1P"},"A7":{"t":"C421"},"A8":{"desc":"L1P"},"A9":{"t":"BE35"},"AA":{"t":"GLF5"},"AB":{"desc":"L1P"},"AC":{"desc":"L1P"},"AD":{"desc":"L1P"},"AE":{"t":"C177"},"AF":{"t":"C150"},"B0":{"desc":"L1P"},"B1":{"t":"C550"},"B2":{"t":"C551"},"B3":{"t":"BE55"},"B4":{"t":"GLF5"},"B6":{"t":"C550"},"B7":{"t":"FA20"},"B8":{"desc":"L1P"},"B9":{"t":"BE33"},"BA":{"desc":"L1P"},"BB":{"desc":"L1P"},"BC":{"t":"C182"},"BD":{"desc":"L1P"},"BE":{"desc":"L1P"},"BF":{"t":"CL30"},"C0":{"desc":"H1P"},"C2":{"t":"F2TH"},"C3":{"desc":"L1P","t":"LA4"},"C4":{"t":"C337"},"C5":{"desc":"L2P"},"C6":{"desc":"L1P"},"C7":{"t":"BE20"},"C8":{"desc":"L1P"},"C9":{"t":"CL60"},"CA":{"t":"PRM1"},"CB":{"t":"P210"},"CC":{"desc":"L2J","t":"LR60"},"CD":{"desc":"L2J"},"CE":{"t":"PA34"},"CF":{"desc":"L1P"},"D0":{"t":"T210"},"D1":{"desc":"L2J","t":"LR55"},"D2":{"t":"C182"},"D3":{"t":"BL17"},"D4":{"t":"F2TH"},"D5":{"t":"PA18"},"D6":{"t":"C750"},"D7":{"t":"GLF4"},"D8":{"t":"BE40"},"D9":{"t":"PA24"},"DA":{"t":"GLEX"},"DB":{"t":"BE35"},"DD":{"desc":"L1P"},"DE":{"desc":"L1P"},"DF":{"t":"FA10"},"E0":{"t":"SBR1"},"E1":{"t":"C182"},"E4":{"t":"C25B"},"E5":{"t":"C150"},"E7":{"desc":"L1P"},"E8":{"t":"GLF6"},"EA":{"t":"GLID"},"EB":{"t":"AA5"},"EC":{"desc":"L1P"},"ED":{"desc":"L1P"},"EE":{"t":"BE35"},"EF":{"t":"BE60"},"F0":{"desc":"L1P"},"F1":{"t":"T210"},"F2":{"t":"B14A"},"F3":{"desc":"L1P"},"F4":{"t":"C150"},"F5":{"t":"WW24"},"F6":{"t":"PA34"},"F7":{"desc":"L1P"},"F8":{"desc":"L1P"},"F9":{"t":"H269"},"FA":{"t":"BE33"},"FB":{"t":"PA18"},"FC":{"desc":"L3J","t":"F900"},"FD":{"t":"GLF5"},"FE":{"t":"P210"},"FF":{"desc":"L1P"}} {"01":{"t":"GLF4"},"02":{"t":"SHIP"},"03":{"t":"SR22"},"05":{"desc":"L1P"},"06":{"desc":"L1P"},"07":{"desc":"L1P"},"08":{"t":"PA46"},"09":{"t":"BE40"},"0A":{"desc":"L1P"},"0B":{"desc":"L1P"},"0C":{"t":"C560"},"0D":{"desc":"L2J","t":"GLF6"},"0E":{"t":"GLF5"},"0F":{"desc":"L1P"},"10":{"t":"C750"},"12":{"t":"GLEX"},"13":{"desc":"A2P"},"15":{"desc":"H4E"},"16":{"t":"BE55"},"17":{"t":"BE35"},"18":{"t":"C172"},"19":{"t":"M20P"},"1A":{"t":"GLF4"},"1B":{"desc":"L4J"},"1C":{"desc":"L1P"},"1D":{"t":"GLF5"},"1E":{"t":"CL30"},"1F":{"t":"T34P"},"20":{"t":"BE35"},"21":{"t":"BE55"},"22":{"t":"S76"},"23":{"desc":"H1P","t":"GYRO"},"24":{"desc":"L1P"},"25":{"t":"BE30"},"26":{"t":"C25C"},"27":{"t":"C425"},"28":{"desc":"L2J","t":"GLF5"},"29":{"t":"C182"},"2A":{"t":"PA32"},"2B":{"t":"C182"},"2C":{"t":"C750"},"2D":{"t":"GLID"},"2E":{"desc":"L1P"},"2F":{"t":"BE55"},"30":{"t":"BE35"},"31":{"t":"GLF4"},"32":{"desc":"L1P"},"33":{"desc":"L1P"},"34":{"t":"F2TH"},"35":{"t":"CL30"},"36":{"t":"C172"},"37":{"t":"GLF2"},"38":{"t":"C337"},"39":{"t":"BE35"},"3A":{"t":"CL30"},"3B":{"t":"FA50"},"3C":{"t":"C25C"},"3D":{"desc":"L1P"},"3E":{"t":"BE33"},"3F":{"desc":"L1J"},"40":{"desc":"L1P"},"41":{"t":"BE55"},"42":{"t":"CL60"},"43":{"t":"AA1"},"44":{"desc":"H1T"},"45":{"t":"NAVI"},"46":{"t":"P337"},"47":{"t":"CL60"},"48":{"desc":"L1P"},"49":{"t":"PC12"},"4A":{"desc":"L1P"},"4B":{"t":"GC1"},"4C":{"t":"C190"},"4D":{"t":"GLF4"},"4E":{"t":"C500"},"4F":{"t":"C421"},"50":{"t":"GLF5"},"51":{"t":"BE36"},"52":{"desc":"L2J","t":"LR31"},"53":{"desc":"L1P"},"54":{"t":"GL5T"},"55":{"t":"CL60"},"56":{"t":"BE33"},"57":{"t":"SR22"},"58":{"t":"GLID"},"59":{"desc":"L2J","t":"C25C"},"5A":{"t":"BE35"},"5B":{"desc":"L1P"},"5C":{"t":"H500"},"5D":{"desc":"L1P"},"5E":{"t":"GLEX"},"60":{"t":"BE50"},"61":{"t":"T206"},"62":{"t":"GLF4"},"63":{"t":"R66"},"64":{"t":"C310"},"65":{"t":"C182"},"66":{"t":"C172"},"68":{"t":"GLF5"},"69":{"t":"ST75"},"6A":{"desc":"L2J"},"6B":{"desc":"L1P"},"6C":{"t":"BE58"},"6D":{"t":"PRM1"},"6E":{"t":"C206"},"70":{"desc":"L1P"},"71":{"t":"C510"},"72":{"desc":"L1P"},"74":{"desc":"L1P"},"76":{"t":"DA42"},"77":{"t":"CL60"},"78":{"t":"PA31"},"79":{"desc":"L1P"},"7A":{"t":"BE36"},"7B":{"t":"NAVI"},"7C":{"desc":"L1P"},"7D":{"desc":"L1P"},"7E":{"desc":"L1P"},"7F":{"t":"GLF6"},"80":{"t":"BE35"},"81":{"desc":"L1P"},"82":{"desc":"L2J"},"83":{"t":"TOBA"},"84":{"t":"GLEX"},"85":{"desc":"L1P"},"86":{"t":"T206"},"87":{"t":"C180"},"88":{"t":"C680"},"89":{"t":"PA23"},"8A":{"desc":"H2T"},"8B":{"t":"C550"},"8C":{"desc":"L1P"},"8D":{"desc":"L1P"},"8F":{"t":"C182"},"90":{"t":"GLF5"},"91":{"desc":"L1J"},"92":{"desc":"H1T"},"93":{"t":"M20P"},"94":{"desc":"L1P"},"95":{"t":"BE55"},"96":{"t":"AA5"},"97":{"t":"M5"},"98":{"desc":"L1P"},"99":{"t":"O1"},"9A":{"desc":"L1P"},"9B":{"t":"EC35"},"9C":{"desc":"L1P"},"9D":{"desc":"L1P"},"9E":{"t":"BE9L"},"9F":{"t":"C500"},"A0":{"t":"C550"},"A1":{"desc":"L1P"},"A2":{"desc":"H1P"},"A3":{"t":"PA27"},"A4":{"t":"SBR1"},"A5":{"t":"GLF5"},"A6":{"desc":"L1P"},"A7":{"t":"C421"},"A8":{"desc":"L1P"},"A9":{"t":"BE35"},"AA":{"t":"GLF5"},"AB":{"desc":"L1P"},"AC":{"desc":"L1P"},"AD":{"desc":"L1P"},"AE":{"t":"C177"},"AF":{"t":"C150"},"B0":{"desc":"L1P"},"B1":{"t":"C550"},"B2":{"t":"C551"},"B3":{"t":"BE55"},"B4":{"t":"GLF5"},"B6":{"t":"C550"},"B7":{"t":"FA20"},"B8":{"desc":"L1P"},"B9":{"t":"BE33"},"BA":{"desc":"L1P"},"BB":{"desc":"L1P"},"BC":{"t":"C182"},"BD":{"desc":"L1P"},"BE":{"desc":"L1P"},"BF":{"t":"CL30"},"C0":{"desc":"H1P"},"C2":{"t":"F2TH"},"C3":{"desc":"L1P","t":"LA4"},"C4":{"t":"C337"},"C5":{"desc":"L2P"},"C6":{"desc":"L1P"},"C7":{"t":"BE20"},"C8":{"desc":"L1P"},"C9":{"t":"CL60"},"CA":{"t":"PRM1"},"CB":{"t":"P210"},"CC":{"desc":"L2J","t":"LR60"},"CD":{"desc":"L2J"},"CE":{"t":"PA34"},"CF":{"desc":"L1P"},"D0":{"t":"T210"},"D1":{"desc":"L2J","t":"LR55"},"D2":{"t":"C182"},"D3":{"t":"BL17"},"D4":{"t":"F2TH"},"D5":{"t":"PA18"},"D6":{"t":"C750"},"D7":{"t":"GLF4"},"D8":{"t":"BE40"},"D9":{"t":"PA24"},"DA":{"t":"GLEX"},"DB":{"t":"BE35"},"DD":{"desc":"L1P"},"DE":{"desc":"L1P"},"DF":{"t":"FA10"},"E0":{"t":"SBR1"},"E1":{"t":"C182"},"E4":{"t":"E55P"},"E5":{"t":"C150"},"E7":{"desc":"L1P"},"E8":{"t":"GLF6"},"EA":{"t":"GLID"},"EB":{"t":"AA5"},"EC":{"desc":"L1P"},"ED":{"desc":"L1P"},"EE":{"desc":"A1T"},"EF":{"t":"BE60"},"F0":{"desc":"L1P"},"F1":{"t":"T210"},"F2":{"t":"B14A"},"F3":{"desc":"L1P"},"F4":{"t":"C150"},"F5":{"t":"WW24"},"F6":{"t":"C172"},"F7":{"desc":"L1P"},"F8":{"desc":"L1P"},"F9":{"t":"H269"},"FA":{"t":"BE33"},"FB":{"t":"PA18"},"FC":{"desc":"L3J","t":"F900"},"FD":{"t":"GLF5"},"FE":{"t":"P210"},"FF":{"desc":"L1P"}}

View file

@ -1 +1 @@
{"00":{"t":"G164"},"01":{"t":"M7"},"02":{"desc":"A1P"},"03":{"t":"G164"},"04":{"t":"B732"},"05":{"t":"C150"},"06":{"t":"C210"},"08":{"t":"BALL"},"09":{"t":"M20P"},"0A":{"desc":"L1P"},"0B":{"t":"CH7A"},"0C":{"t":"PA30"},"0D":{"t":"ULAC"},"0E":{"t":"P28A"},"10":{"t":"PA32"},"11":{"t":"BE60"},"12":{"t":"C182"},"13":{"desc":"L1P"},"14":{"t":"BALL"},"15":{"t":"P28A"},"16":{"desc":"L1P"},"17":{"t":"TBM7"},"18":{"t":"BE35"},"19":{"t":"PA34"},"1A":{"t":"C206"},"1B":{"desc":"L1P"},"1C":{"t":"M7"},"1E":{"desc":"L1P"},"1F":{"t":"M7"},"20":{"desc":"H1T"},"21":{"t":"C210"},"23":{"t":"G164"},"25":{"t":"C150"},"26":{"t":"G164"},"27":{"desc":"H1T"},"28":{"desc":"L1P"},"29":{"desc":"L1P"},"2A":{"t":"AT5T"},"2B":{"t":"C208"},"2C":{"t":"M20P"},"2D":{"t":"C195"},"2E":{"t":"CH7A"},"2F":{"desc":"L2P"},"30":{"desc":"L1P"},"31":{"t":"H269"},"33":{"t":"SHIP"},"34":{"t":"BALL"},"35":{"t":"C182"},"36":{"t":"M7"},"37":{"t":"BE36"},"38":{"t":"P28R"},"39":{"t":"BALL"},"3A":{"t":"PA27"},"3B":{"t":"BE55"},"3C":{"t":"PA34"},"3D":{"t":"C72R"},"3E":{"t":"BE35"},"3F":{"t":"P28A"},"41":{"desc":"L1P","t":"ULAC"},"42":{"t":"G164"},"43":{"desc":"L1P"},"44":{"t":"G164"},"45":{"t":"G164"},"46":{"t":"G164"},"47":{"t":"C150"},"48":{"t":"G164"},"49":{"t":"C150"},"4A":{"t":"G164"},"4B":{"desc":"L1P","t":"ULAC"},"4C":{"desc":"L1P"},"4D":{"t":"M20P"},"4E":{"t":"BE50"},"4F":{"t":"M20T"},"50":{"t":"C190"},"51":{"t":"CH7A"},"52":{"t":"M20P"},"54":{"t":"P28A"},"55":{"desc":"L1P"},"56":{"t":"L8"},"57":{"desc":"A1P"},"58":{"t":"C172"},"59":{"t":"M20P"},"5A":{"t":"PA23"},"5B":{"desc":"L1P","t":"ULAC"},"5C":{"t":"BALL"},"5E":{"t":"BE35"},"5F":{"t":"M20T"},"60":{"t":"C208"},"61":{"t":"BE55"},"62":{"t":"P28A"},"63":{"t":"B412"},"64":{"desc":"H1P"},"65":{"desc":"L1P"},"66":{"t":"G164"},"67":{"t":"C182"},"68":{"t":"G164"},"69":{"t":"G164"},"6A":{"desc":"L1J"},"6B":{"t":"G164"},"6C":{"t":"C150"},"6D":{"t":"G164"},"6F":{"desc":"L1P"},"70":{"t":"PA18"},"71":{"t":"C208"},"72":{"desc":"L1T","t":"BE36"},"73":{"t":"C421"},"74":{"t":"CH7A"},"75":{"t":"PA32"},"76":{"t":"M7"},"77":{"t":"J3"},"78":{"desc":"L1P"},"79":{"desc":"L1P"},"7A":{"desc":"L1P"},"7B":{"t":"C172"},"7C":{"desc":"L4P"},"7D":{"t":"PA23"},"7E":{"t":"C310"},"7F":{"t":"BALL"},"80":{"desc":"L1P"},"81":{"t":"M20P"},"82":{"t":"C182"},"83":{"t":"C208"},"84":{"t":"BALL"},"85":{"t":"C180"},"86":{"desc":"L1P"},"87":{"desc":"L1P"},"88":{"t":"GLID"},"8A":{"desc":"L1P"},"8B":{"desc":"L1P"},"8C":{"t":"C177"},"8D":{"t":"C150"},"8E":{"t":"G164"},"8F":{"t":"G164"},"90":{"t":"G164"},"91":{"desc":"L1P"},"92":{"desc":"L1P"},"93":{"desc":"L1P"},"94":{"desc":"H1P"},"95":{"desc":"L2P"},"96":{"t":"C195"},"97":{"t":"CH7A"},"98":{"t":"C185"},"99":{"t":"C182"},"9A":{"t":"AR15"},"9C":{"t":"C172"},"9D":{"desc":"A1P"},"9E":{"t":"C182"},"9F":{"desc":"L4T"},"A0":{"t":"PA23"},"A1":{"desc":"L1P"},"A2":{"t":"P210"},"A3":{"desc":"L4T"},"A4":{"desc":"L1P","t":"ULAC"},"A5":{"t":"PA34"},"A6":{"desc":"L1P"},"A7":{"t":"BE55"},"A8":{"desc":"L1P"},"A9":{"desc":"L1P"},"AA":{"t":"B407"},"AB":{"t":"G164"},"AC":{"t":"G164"},"AF":{"t":"M7"},"B0":{"desc":"L1P"},"B1":{"t":"G164"},"B2":{"t":"G164"},"B3":{"t":"C150"},"B4":{"t":"G164"},"B5":{"t":"S55P"},"B6":{"t":"PA18"},"B7":{"t":"M20P"},"B8":{"desc":"L1P"},"B9":{"desc":"L1P"},"BA":{"t":"CH7B"},"BB":{"t":"C172"},"BC":{"desc":"A2P"},"BD":{"t":"P28A"},"BE":{"t":"C208"},"BF":{"t":"L8"},"C0":{"desc":"A1P"},"C1":{"t":"M20P"},"C2":{"t":"M7"},"C3":{"t":"ST75"},"C4":{"t":"C310"},"C5":{"t":"BALL"},"C6":{"desc":"L1P"},"C7":{"t":"BALL"},"C8":{"t":"PA34"},"C9":{"desc":"L4P"},"CA":{"desc":"L1P"},"CB":{"t":"PA32"},"CC":{"t":"C208"},"CD":{"t":"COL4"},"CE":{"desc":"L1P"},"CF":{"t":"G164"},"D0":{"desc":"H4E"},"D1":{"desc":"A1P"},"D2":{"t":"G164"},"D3":{"t":"G164"},"D4":{"desc":"L1P"},"D5":{"t":"C150"},"D6":{"t":"G164"},"D7":{"t":"B412"},"D8":{"desc":"L4P"},"D9":{"desc":"A1P"},"DA":{"t":"HUSK"},"DB":{"t":"H269"},"DC":{"t":"BL8"},"DD":{"t":"BE30"},"DE":{"t":"B06"},"DF":{"t":"BE18"},"E0":{"desc":"H4E"},"E1":{"t":"ULAC"},"E2":{"desc":"L1P"},"E4":{"desc":"L1P"},"E5":{"t":"C185"},"E6":{"t":"C208"},"E7":{"t":"BE9L"},"E9":{"t":"C182"},"EA":{"t":"C82R"},"EB":{"t":"PA32"},"ED":{"t":"P28A"},"EE":{"desc":"L1P"},"F2":{"desc":"L1P","t":"ULAC"},"F3":{"desc":"L2P"},"F4":{"t":"HUSK"},"F5":{"t":"BL8"},"F6":{"desc":"A1P"},"F7":{"desc":"L1P"},"F9":{"desc":"H4E"},"FA":{"t":"BALL"},"FB":{"desc":"L1P"},"FC":{"t":"GLID"},"FD":{"t":"BE9L"},"FE":{"t":"PA44"},"FF":{"desc":"H4E"}} {"00":{"t":"G164"},"01":{"t":"M7"},"02":{"desc":"A1P"},"03":{"t":"G164"},"04":{"t":"B732"},"05":{"t":"C150"},"06":{"t":"C210"},"08":{"t":"BALL"},"09":{"t":"M20P"},"0A":{"desc":"L1P"},"0B":{"t":"CH7A"},"0C":{"t":"PA30"},"0D":{"t":"ULAC"},"0E":{"t":"P28A"},"10":{"t":"PA32"},"11":{"t":"BE60"},"12":{"t":"C182"},"13":{"desc":"L1P"},"14":{"t":"BALL"},"15":{"t":"P28A"},"16":{"desc":"L1P"},"17":{"t":"TBM7"},"18":{"t":"BE35"},"19":{"t":"PA34"},"1A":{"t":"C206"},"1B":{"desc":"L1P"},"1C":{"t":"M7"},"1E":{"desc":"L1P"},"1F":{"t":"M7"},"20":{"desc":"H1T"},"21":{"t":"C210"},"23":{"t":"G164"},"25":{"t":"C150"},"26":{"t":"G164"},"27":{"desc":"H1T"},"28":{"desc":"L1P"},"29":{"desc":"L1P"},"2A":{"t":"AT5T"},"2B":{"t":"C208"},"2C":{"t":"M20P"},"2D":{"t":"C195"},"2E":{"t":"CH7A"},"2F":{"desc":"L2P"},"30":{"desc":"L1P"},"31":{"t":"H269"},"33":{"t":"SHIP"},"34":{"t":"BALL"},"35":{"t":"C182"},"36":{"t":"M7"},"37":{"t":"BE36"},"38":{"t":"P28R"},"39":{"t":"BALL"},"3A":{"t":"PA27"},"3B":{"t":"BE55"},"3C":{"t":"PA34"},"3D":{"t":"C72R"},"3E":{"t":"BE35"},"3F":{"t":"P28A"},"41":{"desc":"L1P","t":"ULAC"},"42":{"t":"G164"},"43":{"desc":"L1P"},"44":{"t":"G164"},"45":{"t":"G164"},"46":{"t":"G164"},"47":{"t":"C150"},"48":{"t":"G164"},"49":{"t":"C150"},"4A":{"t":"G164"},"4B":{"desc":"L1P","t":"ULAC"},"4C":{"desc":"L1P"},"4D":{"t":"M20P"},"4E":{"t":"BE50"},"4F":{"t":"M20T"},"50":{"t":"C190"},"51":{"t":"CH7A"},"52":{"t":"M20P"},"54":{"t":"P28A"},"55":{"desc":"L1P"},"56":{"t":"L8"},"57":{"desc":"A1P"},"58":{"t":"C172"},"59":{"t":"M20P"},"5A":{"t":"PA23"},"5B":{"desc":"L1P","t":"ULAC"},"5C":{"t":"BALL"},"5E":{"t":"BE35"},"5F":{"t":"M20T"},"60":{"t":"C208"},"61":{"t":"BE55"},"62":{"t":"P28A"},"63":{"t":"B412"},"64":{"desc":"H1P"},"65":{"desc":"L1P"},"66":{"t":"G164"},"67":{"t":"C182"},"68":{"t":"G164"},"69":{"t":"G164"},"6A":{"desc":"L1J"},"6B":{"t":"G164"},"6C":{"t":"C150"},"6D":{"t":"G164"},"6F":{"desc":"L1P"},"70":{"t":"PA18"},"71":{"t":"C208"},"72":{"t":"BE36"},"73":{"t":"C421"},"74":{"t":"CH7A"},"75":{"t":"PA32"},"76":{"t":"M7"},"77":{"t":"J3"},"78":{"desc":"L1P"},"79":{"desc":"L1P"},"7A":{"desc":"L1P"},"7B":{"t":"C172"},"7C":{"desc":"L4P"},"7D":{"t":"PA23"},"7E":{"t":"C310"},"7F":{"t":"BALL"},"80":{"desc":"L1P"},"81":{"t":"M20P"},"82":{"t":"C182"},"83":{"t":"C208"},"84":{"t":"BALL"},"85":{"t":"C180"},"86":{"desc":"L1P"},"87":{"desc":"L1P"},"88":{"t":"GLID"},"8A":{"desc":"L1P"},"8B":{"desc":"L1P"},"8C":{"t":"C177"},"8D":{"t":"C150"},"8E":{"t":"G164"},"8F":{"t":"G164"},"90":{"t":"G164"},"91":{"desc":"L1P"},"92":{"desc":"L1P"},"93":{"desc":"L1P"},"94":{"desc":"H1P"},"95":{"desc":"L2P"},"96":{"t":"C195"},"97":{"t":"CH7A"},"98":{"t":"C185"},"99":{"t":"C182"},"9A":{"t":"AR15"},"9C":{"t":"C172"},"9D":{"desc":"A1P"},"9E":{"t":"C182"},"9F":{"desc":"L4T"},"A0":{"t":"PA23"},"A1":{"desc":"L1P"},"A2":{"t":"P210"},"A3":{"desc":"L4T"},"A4":{"desc":"L1P","t":"ULAC"},"A5":{"t":"PA34"},"A6":{"desc":"L1P"},"A7":{"t":"BE55"},"A8":{"desc":"L1P"},"A9":{"desc":"L1P"},"AA":{"t":"B407"},"AB":{"t":"G164"},"AC":{"t":"G164"},"AF":{"t":"M7"},"B0":{"desc":"L1P"},"B1":{"t":"G164"},"B2":{"t":"G164"},"B3":{"t":"C150"},"B4":{"t":"G164"},"B5":{"t":"S55P"},"B6":{"t":"PA18"},"B7":{"t":"M20P"},"B8":{"desc":"L1P"},"B9":{"desc":"L1P"},"BA":{"t":"CH7B"},"BB":{"t":"C172"},"BC":{"desc":"A2P"},"BD":{"t":"P28A"},"BE":{"t":"C208"},"BF":{"t":"L8"},"C0":{"desc":"A1P"},"C1":{"t":"M20P"},"C2":{"t":"M7"},"C3":{"t":"ST75"},"C4":{"t":"C310"},"C5":{"t":"BALL"},"C6":{"desc":"L1P"},"C7":{"t":"BALL"},"C8":{"t":"PA34"},"C9":{"desc":"L4P"},"CA":{"desc":"L1P"},"CB":{"t":"PA32"},"CC":{"t":"C208"},"CD":{"t":"COL4"},"CE":{"desc":"L1P"},"CF":{"t":"G164"},"D0":{"desc":"H4E"},"D1":{"desc":"A1P"},"D2":{"t":"G164"},"D3":{"t":"G164"},"D4":{"desc":"L1P"},"D5":{"t":"C150"},"D6":{"t":"G164"},"D7":{"t":"B412"},"D8":{"desc":"L4P"},"D9":{"desc":"A1P"},"DA":{"t":"HUSK"},"DB":{"t":"H269"},"DC":{"t":"BL8"},"DD":{"t":"BE30"},"DE":{"t":"B06"},"DF":{"t":"BE18"},"E0":{"desc":"H4E"},"E1":{"t":"ULAC"},"E2":{"desc":"L1P"},"E4":{"desc":"L1P"},"E5":{"t":"C185"},"E6":{"t":"C208"},"E7":{"t":"BE9L"},"E9":{"t":"C182"},"EA":{"t":"C82R"},"EB":{"t":"PA32"},"ED":{"t":"P28A"},"EE":{"desc":"L1P"},"F2":{"desc":"L1P","t":"ULAC"},"F3":{"desc":"L2P"},"F4":{"t":"HUSK"},"F5":{"t":"BL8"},"F6":{"desc":"A1P"},"F7":{"desc":"L1P"},"F9":{"desc":"H4E"},"FA":{"t":"BALL"},"FB":{"desc":"L1P"},"FC":{"t":"GLID"},"FD":{"t":"BE9L"},"FE":{"t":"PA44"},"FF":{"desc":"H4E"}}

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
{"00":{"desc":"L1P"},"01":{"t":"C150"},"02":{"t":"C150"},"03":{"desc":"L1P"},"04":{"t":"C150"},"05":{"t":"PA18"},"06":{"desc":"L4P"},"09":{"t":"PA34"},"0B":{"desc":"L2P"},"0C":{"t":"PA18"},"0D":{"desc":"H1T","t":"B47G"},"0E":{"t":"M20T"},"0F":{"t":"TAYB"},"10":{"desc":"L1P"},"11":{"desc":"L2T"},"12":{"t":"M20T"},"13":{"t":"P32R"},"14":{"desc":"L1P"},"15":{"t":"L8"},"16":{"t":"C208"},"17":{"t":"C182"},"18":{"desc":"L1P"},"19":{"desc":"L1P"},"1A":{"t":"P28A"},"1B":{"t":"BALL"},"1C":{"t":"C172"},"1D":{"desc":"L1P"},"1E":{"desc":"L1P"},"1F":{"desc":"L1P"},"20":{"desc":"L1P"},"21":{"t":"P28A"},"22":{"t":"H269"},"23":{"desc":"L1P"},"24":{"t":"C177"},"25":{"t":"H269"},"26":{"t":"M20P"},"27":{"t":"CH7A"},"28":{"desc":"H1P"},"29":{"t":"H269"},"2A":{"t":"J4"},"2B":{"t":"BE35"},"2C":{"t":"BALL"},"2D":{"t":"T210"},"2E":{"t":"GLID"},"2F":{"t":"PA18"},"30":{"t":"B25"},"31":{"desc":"H1P"},"32":{"desc":"L1P"},"33":{"t":"CH7A"},"34":{"t":"C185"},"35":{"t":"C172"},"36":{"t":"PA34"},"37":{"t":"M7"},"38":{"t":"L8"},"39":{"t":"M7"},"3A":{"t":"ST75"},"3B":{"t":"H500"},"3C":{"t":"H269"},"3D":{"t":"BALL"},"3E":{"t":"BE55"},"3F":{"t":"C172"},"40":{"t":"BE58"},"41":{"t":"PA34"},"42":{"desc":"L4P"},"43":{"t":"H269"},"44":{"t":"P28R"},"45":{"desc":"H2T"},"46":{"t":"M7"},"47":{"t":"C177"},"48":{"t":"M7"},"49":{"t":"M20P"},"4A":{"t":"T6"},"4B":{"t":"C150"},"4C":{"t":"C150"},"4E":{"t":"COL4"},"4F":{"t":"C150"},"50":{"t":"TNAV"},"51":{"desc":"L1P"},"53":{"t":"M7"},"54":{"t":"T6"},"55":{"t":"C195"},"56":{"t":"CH7A"},"57":{"t":"C185"},"58":{"t":"GLID"},"59":{"t":"M20T"},"5A":{"desc":"L1P"},"5B":{"t":"PA18"},"5C":{"t":"UH12"},"5D":{"desc":"L2P"},"5E":{"desc":"L1P"},"5F":{"t":"PA23"},"60":{"t":"P28R"},"61":{"t":"BALL"},"62":{"t":"C172"},"63":{"t":"S61"},"64":{"t":"GC1"},"65":{"desc":"L2P"},"66":{"t":"BE33"},"67":{"t":"P28R"},"68":{"t":"C414"},"69":{"t":"M20P"},"6A":{"t":"BALL"},"6B":{"t":"C150"},"6C":{"t":"UH1"},"6D":{"t":"C170"},"6E":{"t":"T6"},"6F":{"t":"C150"},"70":{"t":"BALL"},"71":{"desc":"L2P"},"72":{"t":"M7"},"73":{"t":"C150"},"74":{"desc":"A1E"},"75":{"desc":"L1P"},"76":{"t":"M20P"},"77":{"t":"T6"},"78":{"t":"C190"},"79":{"t":"CH7A"},"7A":{"t":"M7"},"7B":{"t":"C140"},"7C":{"t":"PA34"},"7D":{"desc":"L1P"},"7E":{"desc":"L1P"},"7F":{"t":"M7"},"80":{"desc":"L2T"},"81":{"t":"M7"},"83":{"t":"UH1"},"84":{"t":"BALL"},"85":{"t":"C180"},"86":{"t":"J5"},"87":{"t":"PA34"},"88":{"t":"M20P"},"89":{"t":"BE35"},"8A":{"t":"PA34"},"8B":{"t":"C180"},"8C":{"t":"C150"},"8D":{"t":"J3"},"8E":{"t":"T34P"},"8F":{"t":"O1"},"90":{"desc":"L1P"},"91":{"t":"O1"},"92":{"t":"O1"},"93":{"t":"C172"},"94":{"t":"C150"},"95":{"t":"CH7A"},"96":{"t":"C150"},"97":{"desc":"L1P"},"98":{"t":"PA18"},"99":{"t":"M20P"},"9A":{"t":"B06"},"9B":{"desc":"H1P"},"9C":{"t":"CH7A"},"9D":{"t":"M20P"},"9E":{"desc":"L2P"},"9F":{"desc":"S1P","t":"AR15"},"A0":{"desc":"L1P"},"A1":{"t":"L8"},"A2":{"desc":"A1P"},"A3":{"t":"C337"},"A4":{"desc":"L2P"},"A5":{"t":"PA23"},"A6":{"t":"C310"},"A7":{"t":"M7"},"A8":{"t":"TAYD"},"A9":{"desc":"L1P"},"AA":{"t":"PA34"},"AB":{"t":"C206"},"AC":{"t":"BE55"},"AD":{"t":"M20P"},"AE":{"t":"C182"},"AF":{"t":"M20T"},"B0":{"t":"CH7A"},"B1":{"t":"CH7A"},"B2":{"t":"C150"},"B3":{"desc":"L1P"},"B4":{"t":"C150"},"B5":{"t":"C150"},"B6":{"t":"CH7A"},"B7":{"t":"C206"},"B8":{"t":"VALI"},"B9":{"t":"C150"},"BA":{"desc":"L1P"},"BB":{"t":"PA18"},"BC":{"t":"M20P"},"BF":{"t":"BL8"},"C0":{"t":"C172"},"C1":{"t":"BALL"},"C2":{"t":"P28A"},"C4":{"t":"L8"},"C5":{"t":"M20P"},"C6":{"t":"ST75"},"C7":{"t":"J3"},"C8":{"t":"M20T"},"C9":{"t":"C310"},"CA":{"t":"BALL"},"CB":{"t":"M20P"},"CC":{"desc":"L2P"},"CD":{"t":"M20P"},"CE":{"t":"T206"},"CF":{"t":"NAVI"},"D0":{"t":"P28A"},"D1":{"desc":"L1P"},"D2":{"desc":"L1P"},"D3":{"desc":"L1P"},"D4":{"desc":"L2P"},"D5":{"desc":"L1P"},"D7":{"t":"C140"},"D8":{"t":"T34P"},"D9":{"t":"C150"},"DA":{"t":"C150"},"DB":{"t":"C172"},"DC":{"t":"M20P"},"DD":{"desc":"L1P"},"DE":{"t":"M20T"},"DF":{"t":"BE18"},"E0":{"t":"T6"},"E1":{"t":"C195"},"E2":{"t":"CH7B"},"E3":{"t":"C185"},"E4":{"t":"DC3"},"E5":{"t":"P28A"},"E6":{"desc":"L1P"},"E7":{"desc":"L1P"},"E8":{"t":"M20P"},"E9":{"t":"P28A"},"EA":{"t":"M7"},"EB":{"desc":"L1P"},"EC":{"t":"P28S"},"ED":{"t":"P32R"},"EE":{"desc":"L1P"},"EF":{"t":"M7"},"F0":{"t":"M7"},"F1":{"desc":"L1P"},"F2":{"t":"BE55"},"F3":{"t":"AA1"},"F4":{"t":"M7"},"F5":{"t":"GLID"},"F6":{"desc":"L1P"},"F7":{"desc":"L1P"},"F8":{"t":"B06"},"F9":{"t":"C150"},"FA":{"t":"C150"},"FB":{"t":"H269"},"FD":{"desc":"L2P"},"FE":{"t":"C150"},"FF":{"t":"C150"}} {"00":{"desc":"L1P"},"01":{"t":"C150"},"02":{"t":"C150"},"03":{"desc":"L1P"},"04":{"t":"C150"},"05":{"t":"PA18"},"06":{"desc":"L4P"},"09":{"t":"PA34"},"0B":{"desc":"L2P"},"0C":{"t":"PA18"},"0D":{"desc":"H1T","t":"B47G"},"0E":{"t":"M20T"},"0F":{"t":"TAYB"},"10":{"desc":"L1P"},"11":{"desc":"L2T"},"12":{"t":"M20T"},"13":{"t":"P32R"},"14":{"desc":"L1P"},"15":{"t":"L8"},"16":{"t":"C208"},"17":{"t":"C182"},"18":{"desc":"L1P"},"19":{"desc":"L1P"},"1A":{"t":"P28A"},"1B":{"t":"BALL"},"1C":{"t":"C172"},"1D":{"desc":"L1P"},"1E":{"desc":"L1P"},"1F":{"desc":"L1P"},"20":{"desc":"L1P"},"21":{"t":"P28A"},"22":{"t":"H269"},"23":{"desc":"L1P"},"24":{"t":"C177"},"25":{"t":"H269"},"26":{"t":"M20P"},"27":{"t":"CH7A"},"28":{"desc":"H1P"},"29":{"t":"H269"},"2A":{"t":"J4"},"2B":{"t":"BE35"},"2C":{"t":"BALL"},"2D":{"t":"T210"},"2E":{"t":"GLID"},"2F":{"t":"PA18"},"30":{"t":"B25"},"31":{"desc":"H1P"},"32":{"desc":"L1P"},"33":{"t":"CH7A"},"34":{"t":"C185"},"35":{"t":"C172"},"36":{"desc":"L2T"},"37":{"t":"M7"},"38":{"t":"L8"},"39":{"t":"M7"},"3A":{"t":"ST75"},"3B":{"t":"H500"},"3C":{"t":"H269"},"3D":{"t":"BALL"},"3E":{"t":"BE55"},"3F":{"t":"C172"},"40":{"t":"BE58"},"41":{"t":"PA34"},"42":{"desc":"L4P"},"43":{"t":"H269"},"44":{"t":"P28R"},"45":{"desc":"H2T"},"46":{"t":"M7"},"47":{"t":"C177"},"48":{"t":"M7"},"49":{"t":"M20P"},"4A":{"t":"T6"},"4B":{"t":"C150"},"4C":{"t":"C150"},"4E":{"t":"COL4"},"4F":{"t":"C150"},"50":{"t":"TNAV"},"51":{"desc":"L1P"},"53":{"t":"M7"},"54":{"t":"T6"},"55":{"t":"C195"},"56":{"t":"CH7A"},"57":{"t":"C185"},"58":{"t":"GLID"},"59":{"t":"M20T"},"5A":{"desc":"L1P"},"5B":{"t":"PA18"},"5C":{"t":"UH12"},"5D":{"desc":"L2P"},"5E":{"desc":"L1P"},"5F":{"t":"PA23"},"60":{"t":"P28R"},"61":{"t":"BALL"},"62":{"t":"C172"},"63":{"t":"S61"},"64":{"t":"GC1"},"65":{"desc":"L2P"},"66":{"t":"BE33"},"67":{"t":"P28R"},"68":{"t":"C414"},"69":{"t":"M20P"},"6A":{"t":"BALL"},"6B":{"t":"C150"},"6C":{"t":"UH1"},"6D":{"t":"C170"},"6E":{"t":"T6"},"6F":{"t":"C150"},"70":{"t":"BALL"},"71":{"desc":"L2P"},"72":{"t":"M7"},"73":{"t":"C150"},"74":{"desc":"A1E"},"75":{"desc":"L1P"},"76":{"t":"M20P"},"77":{"t":"T6"},"78":{"t":"C190"},"79":{"t":"CH7A"},"7A":{"t":"M7"},"7B":{"t":"C140"},"7C":{"t":"PA34"},"7D":{"desc":"L1P"},"7E":{"desc":"L1P"},"7F":{"t":"M7"},"80":{"desc":"L2T"},"81":{"t":"M7"},"83":{"t":"UH1"},"84":{"t":"BALL"},"85":{"t":"C180"},"86":{"t":"J5"},"87":{"t":"PA34"},"88":{"t":"M20P"},"89":{"t":"BE35"},"8A":{"t":"PA34"},"8B":{"t":"C180"},"8C":{"t":"C150"},"8D":{"t":"J3"},"8E":{"t":"T34P"},"8F":{"t":"O1"},"90":{"desc":"L1P"},"91":{"t":"O1"},"92":{"t":"O1"},"93":{"t":"C172"},"94":{"t":"C150"},"95":{"t":"CH7A"},"96":{"t":"C150"},"97":{"desc":"L1P"},"98":{"t":"PA18"},"99":{"t":"M20P"},"9A":{"t":"B06"},"9B":{"desc":"H1P"},"9C":{"t":"CH7A"},"9D":{"t":"M20P"},"9E":{"desc":"L2P"},"9F":{"desc":"S1P","t":"AR15"},"A0":{"desc":"L1P"},"A1":{"t":"L8"},"A2":{"desc":"A1P"},"A3":{"t":"C337"},"A4":{"desc":"L2P"},"A5":{"t":"PA23"},"A6":{"t":"C310"},"A7":{"t":"M7"},"A8":{"t":"TAYD"},"A9":{"desc":"L1P"},"AA":{"t":"PA34"},"AB":{"desc":"L2T"},"AC":{"t":"BE55"},"AD":{"t":"M20P"},"AE":{"t":"C182"},"AF":{"t":"M20T"},"B0":{"t":"CH7A"},"B1":{"t":"CH7A"},"B2":{"t":"C150"},"B3":{"desc":"L1P"},"B4":{"t":"C150"},"B5":{"t":"C150"},"B6":{"t":"CH7A"},"B7":{"t":"C206"},"B8":{"t":"VALI"},"B9":{"t":"C150"},"BA":{"desc":"L1P"},"BB":{"t":"PA18"},"BC":{"t":"M20P"},"BF":{"t":"BL8"},"C0":{"t":"C172"},"C1":{"t":"BALL"},"C2":{"t":"P28A"},"C4":{"t":"L8"},"C5":{"t":"M20P"},"C6":{"t":"ST75"},"C7":{"t":"J3"},"C8":{"t":"M20T"},"C9":{"t":"C310"},"CA":{"t":"BALL"},"CB":{"t":"M20P"},"CC":{"desc":"L2P"},"CD":{"t":"M20P"},"CE":{"t":"T206"},"CF":{"t":"NAVI"},"D0":{"t":"P28A"},"D1":{"desc":"L1P"},"D2":{"desc":"L1P"},"D3":{"desc":"L1P"},"D4":{"desc":"L2P"},"D5":{"desc":"L1P"},"D7":{"t":"C140"},"D8":{"t":"T34P"},"D9":{"t":"C150"},"DA":{"t":"C150"},"DB":{"t":"C172"},"DC":{"t":"M20P"},"DD":{"desc":"L1P"},"DE":{"t":"M20T"},"DF":{"t":"BE18"},"E0":{"t":"T6"},"E1":{"t":"C195"},"E2":{"t":"CH7B"},"E3":{"t":"C185"},"E4":{"t":"DC3"},"E5":{"t":"P28A"},"E6":{"desc":"L1P"},"E7":{"desc":"L1P"},"E8":{"t":"M20P"},"E9":{"t":"P28A"},"EA":{"t":"M7"},"EB":{"desc":"L1P"},"EC":{"t":"P28S"},"ED":{"t":"P32R"},"EE":{"desc":"L1P"},"EF":{"t":"M7"},"F0":{"t":"M7"},"F1":{"desc":"L1P"},"F2":{"t":"BE55"},"F3":{"t":"AA1"},"F4":{"t":"M7"},"F5":{"t":"GLID"},"F6":{"desc":"L1P"},"F7":{"desc":"L1P"},"F8":{"t":"B06"},"F9":{"t":"C150"},"FA":{"t":"C150"},"FB":{"t":"H269"},"FD":{"desc":"L2P"},"FE":{"t":"C150"},"FF":{"t":"C150"}}

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
{"00":{"t":"C414"},"01":{"desc":"L1P"},"02":{"t":"BALL"},"03":{"desc":"L2J","t":"LR31"},"04":{"desc":"L1P"},"05":{"t":"C182"},"06":{"desc":"L1P","t":"ULAC"},"07":{"t":"F2TH"},"08":{"desc":"L1P"},"09":{"t":"BE33"},"0A":{"t":"COL4"},"0B":{"t":"PA22"},"0C":{"t":"C185"},"0D":{"t":"PA34"},"0E":{"desc":"L1P"},"0F":{"desc":"L1P"},"10":{"desc":"L1J"},"11":{"t":"BE35"},"12":{"t":"BE50"},"13":{"t":"PA24"},"14":{"desc":"L1P"},"15":{"t":"J3"},"16":{"desc":"L1P"},"17":{"desc":"L1P"},"18":{"t":"FA62"},"19":{"t":"GLID"},"1A":{"t":"PA38"},"1B":{"t":"B06"},"1C":{"t":"BL8"},"1E":{"desc":"L2T"},"1F":{"t":"UH12"},"20":{"t":"PA24"},"21":{"t":"P28R"},"22":{"desc":"L1P"},"23":{"t":"AA1"},"24":{"t":"YK11"},"25":{"desc":"L1P"},"26":{"t":"BE18"},"27":{"desc":"L1P"},"28":{"desc":"L1P"},"29":{"desc":"L1P"},"2A":{"t":"C310"},"2B":{"desc":"L1P"},"2C":{"desc":"L1P"},"2D":{"t":"C180"},"2E":{"t":"C421"},"2F":{"desc":"L1P"},"30":{"t":"B06"},"31":{"desc":"L1P"},"32":{"desc":"L2T"},"33":{"desc":"L1P"},"35":{"desc":"L1P"},"36":{"t":"PA22"},"37":{"t":"BE9L"},"38":{"t":"PA22"},"39":{"desc":"L1P"},"3A":{"desc":"L1P"},"3B":{"t":"BE55"},"3C":{"t":"GLID"},"3D":{"t":"C182"},"3E":{"t":"BE35"},"3F":{"t":"CRJ7"},"40":{"desc":"L1P"},"41":{"t":"BE58"},"42":{"t":"BE35"},"43":{"t":"PA22"},"44":{"t":"PA34"},"45":{"t":"PA27"},"46":{"t":"BE9L"},"47":{"t":"B14A"},"48":{"t":"GLID"},"49":{"t":"DC3"},"4A":{"t":"BE35"},"4B":{"t":"M4"},"4C":{"desc":"L1P"},"4D":{"t":"EC30"},"4E":{"desc":"A1P"},"4F":{"t":"GC1"},"50":{"desc":"L1P"},"52":{"t":"BE58"},"53":{"desc":"L1P"},"54":{"t":"E300"},"56":{"desc":"L1P"},"57":{"desc":"L1P"},"58":{"t":"C310"},"59":{"t":"T210"},"5A":{"t":"BE35"},"5B":{"desc":"H1P"},"5C":{"desc":"L1P"},"5D":{"t":"BE55"},"5E":{"desc":"L1P"},"5F":{"t":"B06"},"60":{"t":"C182"},"61":{"desc":"L1P"},"62":{"t":"P28R"},"63":{"desc":"L1P"},"64":{"t":"C150"},"65":{"t":"BE35"},"66":{"t":"EC30"},"67":{"t":"C182"},"68":{"t":"BL8"},"69":{"t":"BE9L"},"6A":{"t":"PA25"},"6B":{"desc":"L2P"},"6C":{"t":"VALI"},"6D":{"desc":"H1T"},"6E":{"desc":"L1P"},"6F":{"t":"NAVI"},"70":{"desc":"L1P"},"71":{"desc":"L1P"},"72":{"t":"C152"},"73":{"desc":"L1P"},"74":{"t":"J3"},"75":{"desc":"L1P"},"76":{"t":"CH7B"},"77":{"t":"BE35"},"78":{"desc":"L1P"},"79":{"desc":"L1P"},"7A":{"t":"P28A"},"7B":{"t":"C337"},"7C":{"t":"BE35"},"7D":{"t":"P28A"},"7E":{"desc":"L1P"},"7F":{"t":"C210"},"80":{"t":"GLID"},"81":{"t":"C150"},"83":{"t":"C680"},"84":{"t":"GLID"},"85":{"desc":"L1P"},"86":{"t":"C310"},"87":{"desc":"L1P"},"88":{"t":"PA34"},"89":{"desc":"L1P"},"8A":{"t":"P28A"},"8B":{"desc":"H1T"},"8C":{"desc":"L1P"},"8D":{"t":"FA7X"},"8E":{"desc":"L1P"},"8F":{"t":"GC1"},"90":{"desc":"L1P"},"91":{"t":"C180"},"92":{"t":"C500"},"93":{"t":"P32R"},"94":{"t":"BE58"},"95":{"desc":"L2T"},"97":{"t":"T6"},"98":{"t":"EC30"},"99":{"t":"PA34"},"9A":{"t":"GLID"},"9B":{"t":"BE18"},"9C":{"t":"HUSK"},"9D":{"desc":"H1T","t":"B47G"},"9E":{"t":"M20T"},"9F":{"desc":"A1P","t":"ULAC"},"A0":{"t":"HUSK"},"A1":{"desc":"H4E"},"A2":{"desc":"L1P"},"A3":{"t":"C340"},"A4":{"t":"BE35"},"A5":{"desc":"L1P"},"A6":{"t":"PA27"},"A7":{"t":"C182"},"A8":{"t":"M20P"},"A9":{"desc":"L1P"},"AA":{"t":"PA18"},"AB":{"t":"BE10"},"AC":{"t":"BE35"},"AD":{"t":"GLID"},"AE":{"desc":"L1P"},"AF":{"t":"GLID"},"B0":{"desc":"L1P"},"B1":{"t":"BE35"},"B2":{"t":"C402"},"B3":{"desc":"L1P"},"B4":{"t":"C150"},"B5":{"t":"P28R"},"B6":{"t":"AA5"},"B7":{"t":"CH7B"},"B8":{"desc":"L1P"},"B9":{"t":"GLID"},"BA":{"desc":"H1P"},"BB":{"t":"P28A"},"BC":{"desc":"L1P"},"BD":{"t":"GLID"},"BE":{"desc":"L1P"},"BF":{"desc":"L1P"},"C0":{"desc":"H1P"},"C1":{"t":"BE55"},"C2":{"t":"BE36"},"C4":{"t":"GLID"},"C5":{"t":"M20T"},"C6":{"desc":"L1P"},"C7":{"t":"BE50"},"C8":{"desc":"L1P"},"C9":{"desc":"H1P"},"CA":{"t":"EC30"},"CB":{"t":"T210"},"CC":{"t":"BE35"},"CD":{"t":"C172"},"CE":{"t":"R22"},"CF":{"desc":"H1T"},"D0":{"t":"T210"},"D1":{"t":"PA32"},"D2":{"t":"PA30"},"D3":{"t":"HUSK"},"D4":{"desc":"L2P"},"D5":{"t":"C210"},"D6":{"t":"C25B"},"D7":{"desc":"L1P"},"D8":{"desc":"L1P"},"D9":{"t":"GLID"},"DA":{"desc":"L1P"},"DB":{"desc":"L1P"},"DC":{"desc":"L1P"},"DD":{"t":"GLID"},"DE":{"desc":"L1P"},"DF":{"desc":"L1P"},"E0":{"desc":"L1P"},"E1":{"t":"WW24"},"E2":{"t":"DA42"},"E3":{"t":"EC30"},"E4":{"desc":"L1P"},"E5":{"t":"BE36"},"E6":{"t":"AA5"},"E7":{"desc":"L1P"},"E8":{"t":"M20P"},"EA":{"t":"SBR1"},"EB":{"t":"P28B"},"EC":{"t":"C404"},"ED":{"desc":"L1P"},"EE":{"desc":"L1P"},"EF":{"t":"C172"},"F0":{"desc":"L1P"},"F1":{"t":"GLID"},"F2":{"desc":"L1P"},"F3":{"t":"BL8"},"F4":{"desc":"L1P"},"F5":{"t":"M20P"},"F6":{"desc":"L1P"},"F7":{"t":"J3"},"F8":{"t":"P28R"},"F9":{"t":"C441"},"FA":{"t":"C500"},"FB":{"t":"C210"},"FC":{"desc":"H1T"},"FD":{"desc":"H1P"},"FE":{"desc":"L1P"},"FF":{"t":"PA24"}} {"00":{"t":"C414"},"01":{"desc":"L1P"},"02":{"t":"BALL"},"03":{"desc":"L2J","t":"LR31"},"04":{"desc":"L1P"},"05":{"t":"C182"},"06":{"desc":"L1P","t":"ULAC"},"07":{"t":"F2TH"},"08":{"desc":"L1P"},"09":{"t":"BE33"},"0A":{"t":"COL4"},"0B":{"t":"PA22"},"0C":{"t":"C185"},"0D":{"t":"PA34"},"0E":{"desc":"L1P"},"0F":{"desc":"L1P"},"10":{"desc":"L1J"},"11":{"t":"BE35"},"12":{"t":"BE50"},"13":{"t":"PA24"},"14":{"desc":"L1P"},"15":{"t":"J3"},"16":{"desc":"L1P"},"17":{"desc":"L1P"},"18":{"t":"FA62"},"19":{"t":"GLID"},"1A":{"t":"PA38"},"1B":{"t":"B06"},"1C":{"t":"BL8"},"1E":{"desc":"L2T"},"1F":{"t":"UH12"},"20":{"t":"PA24"},"21":{"t":"P28R"},"22":{"desc":"L1P"},"23":{"t":"AA1"},"24":{"t":"YK11"},"25":{"desc":"L1P"},"26":{"t":"BE18"},"27":{"desc":"L1P"},"28":{"desc":"L1P"},"29":{"desc":"L1P"},"2A":{"t":"C310"},"2B":{"desc":"L1P"},"2C":{"desc":"L1P"},"2D":{"t":"C180"},"2E":{"t":"C421"},"2F":{"desc":"L1P"},"30":{"t":"B06"},"31":{"desc":"L1P"},"32":{"desc":"L2T"},"33":{"desc":"L1P"},"35":{"desc":"L1P"},"36":{"t":"PA22"},"37":{"t":"BE9L"},"38":{"t":"PA22"},"39":{"desc":"L1P"},"3A":{"desc":"L1P"},"3B":{"t":"BE55"},"3C":{"t":"GLID"},"3D":{"t":"C182"},"3E":{"t":"BE35"},"3F":{"t":"CRJ7"},"40":{"desc":"L1P"},"41":{"t":"BE58"},"42":{"t":"BE35"},"43":{"t":"PA22"},"44":{"t":"PA34"},"45":{"t":"PA27"},"46":{"t":"BE9L"},"47":{"t":"B14A"},"48":{"t":"GLID"},"49":{"t":"DC3"},"4A":{"t":"BE35"},"4B":{"t":"M4"},"4C":{"desc":"L1P"},"4D":{"t":"EC30"},"4E":{"desc":"A1P"},"4F":{"t":"GC1"},"50":{"desc":"L1P"},"52":{"t":"BE58"},"53":{"desc":"L1P"},"54":{"t":"E300"},"56":{"desc":"L1P"},"57":{"desc":"L1P"},"58":{"t":"C310"},"59":{"t":"T210"},"5A":{"t":"BE35"},"5B":{"desc":"H1P"},"5C":{"desc":"L1P"},"5D":{"t":"BE55"},"5E":{"desc":"L1P"},"5F":{"t":"B06"},"60":{"t":"C182"},"61":{"desc":"L1P"},"62":{"t":"P28R"},"63":{"desc":"L1P"},"64":{"t":"C150"},"65":{"t":"BE35"},"66":{"t":"EC30"},"67":{"t":"C182"},"68":{"t":"BL8"},"69":{"t":"BE9L"},"6A":{"t":"PA25"},"6B":{"desc":"L2P"},"6C":{"t":"VALI"},"6D":{"desc":"H1T"},"6E":{"desc":"L1P"},"6F":{"t":"NAVI"},"70":{"desc":"L1P"},"71":{"desc":"L1P"},"72":{"t":"C152"},"73":{"desc":"L1P"},"74":{"t":"J3"},"75":{"desc":"L1P"},"76":{"t":"CH7B"},"77":{"t":"BE35"},"78":{"desc":"L1P"},"79":{"desc":"L1P"},"7A":{"t":"P28A"},"7B":{"t":"C337"},"7C":{"t":"BE35"},"7D":{"t":"P28A"},"7E":{"desc":"L1P"},"7F":{"t":"C210"},"80":{"t":"GLID"},"81":{"t":"C150"},"83":{"t":"C680"},"84":{"t":"GLID"},"85":{"desc":"L1P"},"86":{"t":"C310"},"87":{"desc":"L1P"},"88":{"t":"PA34"},"89":{"desc":"L1P"},"8A":{"t":"P28A"},"8B":{"desc":"H1T"},"8C":{"desc":"L1P"},"8D":{"t":"FA7X"},"8E":{"desc":"L1P"},"8F":{"t":"GC1"},"90":{"desc":"L1P"},"91":{"t":"C180"},"92":{"t":"C500"},"93":{"t":"P32R"},"94":{"t":"BE58"},"95":{"desc":"L2T"},"96":{"t":"R44"},"97":{"t":"T6"},"98":{"t":"EC30"},"99":{"t":"PA34"},"9A":{"t":"GLID"},"9B":{"t":"BE35"},"9C":{"t":"HUSK"},"9D":{"desc":"H1T","t":"B47G"},"9E":{"t":"M20T"},"9F":{"desc":"A1P","t":"ULAC"},"A0":{"t":"HUSK"},"A1":{"desc":"H4E"},"A2":{"desc":"L1P"},"A3":{"t":"C340"},"A4":{"t":"BE35"},"A5":{"desc":"L1P"},"A6":{"t":"PA27"},"A7":{"t":"C182"},"A8":{"t":"M20P"},"A9":{"desc":"L1P"},"AA":{"t":"PA18"},"AB":{"t":"BE10"},"AC":{"t":"BE35"},"AD":{"t":"GLID"},"AE":{"desc":"L1P"},"AF":{"t":"GLID"},"B0":{"desc":"L1P"},"B1":{"t":"BE35"},"B2":{"t":"C402"},"B3":{"desc":"L1P"},"B4":{"t":"C150"},"B5":{"t":"P28R"},"B6":{"t":"AA5"},"B7":{"t":"CH7B"},"B8":{"desc":"L1P"},"B9":{"t":"GLID"},"BA":{"desc":"H1P"},"BB":{"t":"P28A"},"BC":{"desc":"L1P"},"BD":{"t":"GLID"},"BE":{"desc":"L1P"},"BF":{"desc":"L1P"},"C0":{"desc":"H1P"},"C1":{"t":"BE55"},"C2":{"t":"BE36"},"C4":{"t":"GLID"},"C5":{"t":"M20T"},"C6":{"desc":"L1P"},"C7":{"t":"BE50"},"C8":{"desc":"L1P"},"C9":{"desc":"H1P"},"CA":{"t":"EC30"},"CB":{"t":"T210"},"CC":{"t":"BE35"},"CD":{"t":"C172"},"CE":{"t":"R22"},"CF":{"desc":"H1T"},"D0":{"t":"T210"},"D1":{"t":"PA32"},"D2":{"t":"PA30"},"D3":{"t":"HUSK"},"D4":{"desc":"L2P"},"D5":{"t":"C210"},"D6":{"t":"C25B"},"D7":{"desc":"L1P"},"D8":{"desc":"L1P"},"D9":{"t":"GLID"},"DA":{"desc":"L1P"},"DB":{"desc":"L1P"},"DC":{"desc":"L1P"},"DD":{"t":"GLID"},"DE":{"desc":"L1P"},"DF":{"desc":"L1P"},"E0":{"desc":"L1P"},"E1":{"t":"WW24"},"E2":{"t":"DA42"},"E3":{"t":"EC30"},"E4":{"desc":"L1P"},"E5":{"t":"BE36"},"E6":{"t":"AA5"},"E7":{"desc":"L1P"},"E8":{"t":"M20P"},"E9":{"desc":"L1T"},"EA":{"t":"SBR1"},"EB":{"t":"P28B"},"EC":{"t":"C404"},"ED":{"desc":"L1P"},"EE":{"desc":"L1P"},"EF":{"t":"C172"},"F0":{"desc":"L1P"},"F1":{"t":"GLID"},"F2":{"desc":"L1P"},"F3":{"t":"BL8"},"F4":{"desc":"L1P"},"F5":{"t":"M20P"},"F6":{"desc":"L1P"},"F7":{"t":"J3"},"F8":{"t":"P28R"},"F9":{"t":"C441"},"FA":{"t":"C500"},"FB":{"t":"C210"},"FC":{"desc":"H1T"},"FD":{"desc":"H1P"},"FE":{"desc":"L1P"},"FF":{"t":"PA24"}}

View file

@ -1 +1 @@
{"01":{"desc":"L1P"},"02":{"desc":"H1P"},"03":{"desc":"L1P","t":"ULAC"},"05":{"t":"SR22"},"06":{"desc":"L1P"},"07":{"t":"C150"},"08":{"t":"MITE"},"09":{"t":"GLID"},"0A":{"desc":"L1P"},"0B":{"t":"UH1"},"0C":{"desc":"L1P"},"0D":{"t":"BE55"},"0E":{"t":"BL8"},"11":{"desc":"L1P"},"12":{"desc":"L1P"},"13":{"t":"C172"},"14":{"desc":"L1P"},"15":{"desc":"H1T"},"17":{"desc":"L1P","t":"ULAC"},"18":{"t":"P28A"},"1A":{"desc":"H1P"},"1B":{"t":"RC3"},"1C":{"t":"C402"},"1D":{"t":"PC12"},"1E":{"t":"M20P"},"1F":{"t":"SR22"},"20":{"t":"PA22"},"21":{"desc":"L1P"},"22":{"t":"EA50"},"23":{"desc":"L1P"},"24":{"t":"P337"},"25":{"desc":"L1P"},"26":{"desc":"L1P"},"27":{"t":"C182"},"28":{"desc":"L1P"},"29":{"desc":"L1P"},"2A":{"desc":"L1P"},"2C":{"t":"PA31"},"2D":{"desc":"L1P"},"2E":{"desc":"L1P"},"2F":{"t":"SR22"},"30":{"t":"CH7A"},"31":{"t":"T206"},"33":{"t":"J3"},"34":{"desc":"L1P"},"35":{"desc":"L1P"},"36":{"t":"PA30"},"37":{"t":"PA27"},"38":{"desc":"L1P"},"3A":{"desc":"L1P"},"3B":{"t":"EC30"},"3C":{"t":"EC30"},"3D":{"t":"EC30"},"3E":{"t":"EC30"},"3F":{"t":"EC30"},"40":{"t":"EC30"},"42":{"t":"EC30"},"43":{"t":"EC30"},"44":{"t":"EC30"},"45":{"t":"EC30"},"46":{"t":"EC30"},"47":{"t":"BE19"},"48":{"desc":"L2P"},"49":{"t":"GLID"},"4A":{"t":"PA30"},"4B":{"t":"EC30"},"4C":{"t":"EC30"},"4D":{"t":"EC30"},"4E":{"t":"EC30"},"4F":{"t":"EC30"},"51":{"t":"C195"},"52":{"t":"R44"},"53":{"desc":"L1P"},"54":{"t":"B14C"},"55":{"t":"GLID"},"56":{"desc":"L1P"},"57":{"t":"L8"},"58":{"desc":"L1P"},"59":{"desc":"L1P"},"5A":{"t":"PA34"},"5B":{"desc":"L1P"},"5C":{"t":"BT36"},"5D":{"t":"BT36"},"5E":{"desc":"H1P"},"5F":{"t":"C402"},"60":{"t":"GLID"},"61":{"desc":"L1P"},"62":{"desc":"L1P"},"63":{"t":"BE35"},"64":{"desc":"L1P","t":"ULAC"},"65":{"desc":"L1P"},"66":{"desc":"L1P"},"67":{"t":"BE18"},"68":{"t":"M20P"},"69":{"desc":"L1P"},"6A":{"t":"PA11"},"6B":{"t":"GLID"},"6C":{"t":"PA31"},"6D":{"t":"BE95"},"6E":{"desc":"L1P"},"6F":{"desc":"L1P"},"70":{"desc":"L1P"},"71":{"desc":"L1P"},"72":{"t":"T6"},"73":{"desc":"L2T"},"74":{"desc":"L1P"},"75":{"t":"C310"},"76":{"t":"SR22"},"77":{"t":"BE9L"},"78":{"t":"B407"},"79":{"t":"C172"},"7A":{"desc":"L4P"},"7B":{"desc":"L1P"},"7C":{"desc":"L1P"},"7D":{"t":"C550"},"7E":{"desc":"L1P"},"7F":{"t":"GLID"},"80":{"desc":"L1P"},"81":{"t":"BE55"},"82":{"t":"GLID"},"83":{"t":"BE20"},"84":{"t":"GLID"},"85":{"desc":"L1P"},"86":{"t":"T210"},"87":{"t":"PA27"},"88":{"t":"E55P"},"89":{"desc":"L1P"},"8A":{"desc":"L1P"},"8B":{"t":"C25B"},"8C":{"t":"C310"},"8D":{"desc":"L1T"},"8E":{"t":"BALL"},"8F":{"t":"C501"},"90":{"t":"BE9L"},"91":{"desc":"L1P"},"92":{"desc":"H1T"},"93":{"desc":"L2J"},"94":{"desc":"L2J","t":"LR60"},"95":{"t":"AEST"},"96":{"t":"GLID"},"97":{"t":"B06"},"98":{"t":"GLID"},"99":{"t":"GLID"},"9A":{"desc":"L1P"},"9B":{"t":"TAYB"},"9C":{"t":"GLID"},"9D":{"desc":"H1P"},"9E":{"t":"BE40"},"9F":{"desc":"L1P"},"A0":{"t":"C25B"},"A2":{"desc":"L2J","t":"LR35"},"A3":{"t":"M7"},"A4":{"desc":"L1P"},"A5":{"desc":"L2J"},"A6":{"t":"HUSK"},"A7":{"t":"H25B"},"A8":{"t":"BALL"},"A9":{"desc":"L2T"},"AA":{"desc":"L1P"},"AB":{"desc":"H1T"},"AD":{"t":"BALL"},"AE":{"t":"PA31"},"AF":{"t":"GLID"},"B1":{"t":"BALL"},"B5":{"t":"C175"},"B6":{"desc":"L1P"},"B7":{"desc":"L1P"},"B8":{"t":"BE60"},"B9":{"desc":"L1P","t":"TRIN"},"BA":{"t":"GLID"},"BB":{"t":"C421"},"BC":{"t":"BE35"},"BD":{"t":"B47G"},"BE":{"t":"C337"},"BF":{"t":"BE55"},"C0":{"desc":"L1P"},"C1":{"desc":"L2P"},"C2":{"t":"TNAV"},"C3":{"desc":"L1P"},"C4":{"desc":"H1T"},"C5":{"t":"GLID"},"C6":{"t":"C182"},"C7":{"t":"S108"},"C9":{"t":"M20P"},"CA":{"desc":"L1P"},"CB":{"desc":"L1P"},"CC":{"t":"C182"},"CD":{"t":"BE36"},"CE":{"t":"SR22"},"CF":{"t":"FA20"},"D0":{"t":"PA31"},"D1":{"desc":"L1P"},"D2":{"desc":"L1P"},"D3":{"t":"BE95"},"D4":{"t":"BE40"},"D5":{"desc":"L1P"},"D6":{"t":"C182"},"D9":{"t":"BALL"},"DA":{"t":"F900"},"DB":{"t":"BE9T"},"DC":{"t":"BE36"},"DD":{"desc":"L1P"},"DE":{"desc":"L1P"},"DF":{"t":"P337"},"E0":{"desc":"L1P"},"E1":{"t":"UH1"},"E3":{"t":"BE55"},"E4":{"t":"GLID"},"E5":{"desc":"L1P"},"E6":{"t":"PA27"},"E7":{"t":"PT22"},"E8":{"desc":"L1P","t":"SP18"},"E9":{"desc":"L1P"},"EA":{"t":"H269"},"EB":{"desc":"L1P"},"EC":{"desc":"L1P","t":"SP18"},"EE":{"desc":"L1P"},"EF":{"t":"GLID"},"F2":{"desc":"L1P"},"F3":{"desc":"L1P"},"F4":{"t":"L39"},"F5":{"desc":"L1P"},"F6":{"desc":"H1T"},"F7":{"desc":"L1P"},"F8":{"desc":"L1P"},"F9":{"t":"SR20"},"FB":{"desc":"L1P"},"FC":{"desc":"L2P"},"FD":{"t":"CH7B"},"FE":{"desc":"L1P"}} {"01":{"desc":"L1P"},"02":{"desc":"H1P"},"03":{"desc":"L1P","t":"ULAC"},"05":{"t":"SR22"},"06":{"desc":"L1P"},"07":{"t":"C150"},"08":{"t":"MITE"},"09":{"t":"GLID"},"0A":{"desc":"L1P"},"0B":{"t":"UH1"},"0C":{"desc":"L1P"},"0D":{"t":"BE55"},"0E":{"t":"BL8"},"11":{"desc":"L1P"},"12":{"desc":"H2T"},"13":{"t":"C172"},"14":{"desc":"L1P"},"15":{"desc":"H1T"},"17":{"desc":"L1P","t":"ULAC"},"18":{"t":"P28A"},"1A":{"desc":"H1P"},"1B":{"t":"RC3"},"1C":{"t":"C402"},"1D":{"t":"PC12"},"1E":{"t":"M20P"},"1F":{"t":"SR22"},"20":{"t":"PA22"},"21":{"desc":"L1P"},"22":{"t":"EA50"},"23":{"desc":"L1P"},"24":{"t":"P337"},"25":{"desc":"L1P"},"26":{"desc":"L1P"},"27":{"t":"C182"},"28":{"desc":"L1P"},"29":{"desc":"L1P"},"2A":{"desc":"L1P"},"2C":{"t":"PA31"},"2D":{"desc":"L1P"},"2E":{"desc":"L1P"},"2F":{"t":"SR22"},"30":{"t":"CH7A"},"31":{"t":"T206"},"33":{"t":"J3"},"34":{"desc":"L1P"},"35":{"desc":"L1P"},"36":{"t":"PA30"},"37":{"t":"PA27"},"38":{"desc":"L1P"},"39":{"t":"EC30"},"3A":{"desc":"L1P"},"3B":{"t":"EC30"},"3C":{"t":"EC30"},"3D":{"t":"EC30"},"3E":{"t":"EC30"},"3F":{"t":"EC30"},"40":{"t":"EC30"},"42":{"t":"EC30"},"43":{"t":"EC30"},"44":{"t":"EC30"},"45":{"t":"EC30"},"46":{"t":"EC30"},"47":{"t":"BE19"},"48":{"desc":"L2P"},"49":{"t":"GLID"},"4A":{"t":"PA30"},"4B":{"t":"EC30"},"4C":{"desc":"L1P"},"4D":{"t":"EC30"},"4E":{"t":"EC30"},"4F":{"t":"EC30"},"51":{"t":"C195"},"52":{"t":"R44"},"53":{"desc":"L1P"},"54":{"t":"B14C"},"55":{"t":"GLID"},"56":{"desc":"L1P"},"57":{"t":"L8"},"58":{"desc":"L1P"},"59":{"desc":"L1P"},"5A":{"t":"PA34"},"5B":{"desc":"L1P"},"5C":{"t":"BT36"},"5D":{"t":"BT36"},"5E":{"desc":"H1P"},"5F":{"t":"C402"},"60":{"t":"GLID"},"61":{"desc":"L1P"},"62":{"desc":"L1P"},"63":{"t":"BE35"},"64":{"desc":"L1P","t":"ULAC"},"65":{"desc":"L1P"},"66":{"desc":"L1P"},"67":{"t":"BE18"},"68":{"t":"M20P"},"69":{"desc":"L1P"},"6A":{"t":"PA11"},"6B":{"t":"GLID"},"6C":{"t":"PA31"},"6D":{"t":"BE95"},"6E":{"desc":"L1P"},"6F":{"desc":"L1P"},"70":{"desc":"L1P"},"71":{"desc":"L1P"},"72":{"t":"T6"},"73":{"desc":"L2T"},"74":{"desc":"L1P"},"75":{"t":"C310"},"76":{"t":"SR22"},"77":{"t":"BE9L"},"78":{"t":"B407"},"79":{"t":"RV12"},"7A":{"desc":"L4P"},"7B":{"desc":"L1P"},"7C":{"desc":"L1P"},"7D":{"t":"C550"},"7E":{"desc":"L1P"},"7F":{"t":"GLID"},"80":{"desc":"L1P"},"81":{"t":"BE55"},"82":{"t":"GLID"},"83":{"t":"BE20"},"84":{"t":"GLID"},"85":{"desc":"L1P"},"86":{"t":"T210"},"87":{"t":"PA27"},"88":{"t":"E55P"},"89":{"desc":"L1P"},"8A":{"desc":"L1P"},"8B":{"t":"C25B"},"8C":{"t":"C310"},"8D":{"desc":"L1T"},"8E":{"t":"BALL"},"8F":{"t":"C501"},"90":{"t":"BE9L"},"91":{"desc":"L1P"},"92":{"desc":"H1T"},"93":{"desc":"L2J"},"94":{"desc":"L2J","t":"LR60"},"95":{"t":"AEST"},"96":{"t":"GLID"},"97":{"t":"B06"},"98":{"t":"GLID"},"99":{"t":"GLID"},"9A":{"desc":"L1P"},"9B":{"t":"TAYB"},"9C":{"t":"GLID"},"9D":{"desc":"H1P"},"9E":{"t":"BE40"},"9F":{"desc":"L1P"},"A0":{"t":"C25B"},"A2":{"desc":"L2J","t":"LR35"},"A3":{"t":"M7"},"A4":{"desc":"L1P"},"A5":{"desc":"L2J"},"A6":{"t":"HUSK"},"A7":{"t":"H25B"},"A8":{"t":"BALL"},"A9":{"desc":"L2T"},"AA":{"desc":"L1P"},"AB":{"desc":"H1T"},"AD":{"t":"BALL"},"AE":{"t":"PA31"},"AF":{"t":"GLID"},"B1":{"t":"BALL"},"B5":{"t":"C175"},"B6":{"desc":"L1P"},"B7":{"desc":"L1P"},"B8":{"t":"BE60"},"B9":{"desc":"L1P","t":"TRIN"},"BA":{"t":"GLID"},"BB":{"t":"C421"},"BC":{"t":"BE35"},"BD":{"t":"B47G"},"BE":{"t":"C337"},"BF":{"t":"BE55"},"C0":{"desc":"L1P"},"C1":{"desc":"L2P"},"C2":{"t":"TNAV"},"C3":{"desc":"L1P"},"C4":{"desc":"H1T"},"C5":{"t":"GLID"},"C6":{"t":"C182"},"C7":{"t":"S108"},"C9":{"t":"M20P"},"CA":{"desc":"L1P"},"CB":{"desc":"L1P"},"CC":{"t":"C182"},"CD":{"t":"BE36"},"CE":{"t":"SR22"},"CF":{"t":"FA20"},"D0":{"t":"PA31"},"D1":{"desc":"L1P"},"D2":{"desc":"L1P"},"D3":{"t":"BE95"},"D4":{"t":"BE40"},"D5":{"desc":"L1P"},"D6":{"t":"C182"},"D9":{"t":"BALL"},"DA":{"t":"F900"},"DB":{"t":"BE9T"},"DC":{"t":"BE36"},"DD":{"desc":"L1P"},"DE":{"desc":"L1P"},"DF":{"t":"P337"},"E0":{"desc":"L1P"},"E1":{"t":"UH1"},"E3":{"t":"BE55"},"E4":{"t":"GLID"},"E5":{"desc":"L1P"},"E6":{"t":"PA27"},"E7":{"t":"PT22"},"E8":{"desc":"L1P","t":"SP18"},"E9":{"desc":"L1P"},"EA":{"t":"H269"},"EB":{"desc":"L1P"},"EC":{"desc":"L1P","t":"SP18"},"EE":{"desc":"L1P"},"EF":{"t":"GLID"},"F1":{"desc":"L2J"},"F2":{"desc":"L1P"},"F3":{"desc":"L1P"},"F4":{"t":"L39"},"F5":{"desc":"L1P"},"F6":{"desc":"H1T"},"F7":{"desc":"L1P"},"F8":{"desc":"L1P"},"F9":{"t":"SR20"},"FB":{"desc":"L1P"},"FC":{"desc":"L2P"},"FD":{"t":"CH7B"},"FE":{"desc":"L1P"}}

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
{"00":{"t":"B190"},"01":{"desc":"L1P"},"02":{"t":"P28A"},"03":{"desc":"L1P"},"04":{"desc":"L1P"},"05":{"t":"C500"},"06":{"desc":"L2P"},"07":{"desc":"L1P"},"08":{"t":"CH7B"},"09":{"t":"C525"},"0A":{"t":"GLID"},"0B":{"t":"B429"},"0C":{"t":"PC12"},"0D":{"t":"C210"},"0E":{"t":"C185"},"0F":{"t":"COL3"},"10":{"desc":"L1P"},"11":{"t":"FA20"},"13":{"t":"C411"},"14":{"desc":"L1P"},"15":{"desc":"L1P","t":"ULAC"},"17":{"t":"BE76"},"18":{"t":"BE35"},"19":{"t":"C414"},"1C":{"t":"C185"},"1D":{"t":"GLID"},"1E":{"t":"C140"},"1F":{"t":"BE58"},"20":{"t":"SR22"},"21":{"t":"BE35"},"22":{"t":"PA31"},"23":{"desc":"L1P"},"24":{"desc":"L1P"},"25":{"t":"C182"},"26":{"t":"AEST"},"27":{"t":"BE35"},"29":{"t":"C180"},"2A":{"t":"P28R"},"2B":{"t":"GLF4"},"2C":{"t":"GLID"},"2D":{"t":"PA18"},"2E":{"t":"PAY2"},"2F":{"desc":"L1E"},"30":{"t":"BE35"},"31":{"desc":"L1P"},"32":{"t":"BE40"},"33":{"t":"C182"},"34":{"desc":"L2T"},"35":{"desc":"L2P"},"36":{"desc":"L1P"},"37":{"t":"PA18"},"38":{"desc":"L2J"},"39":{"t":"M20P"},"3A":{"t":"C182"},"3B":{"t":"M20P"},"3C":{"desc":"L1T"},"3D":{"desc":"L1P"},"3E":{"t":"P28R"},"3F":{"desc":"L1P"},"40":{"t":"PA27"},"41":{"desc":"L1P"},"42":{"t":"B762"},"43":{"desc":"H1P"},"44":{"desc":"L1P"},"45":{"t":"UH1"},"46":{"t":"AEST"},"47":{"t":"PA24"},"48":{"t":"SR22"},"49":{"desc":"L1P"},"4A":{"desc":"L1P"},"4B":{"t":"B350"},"4C":{"desc":"L1T"},"4D":{"desc":"A1E"},"4E":{"t":"PA24"},"4F":{"t":"C310"},"50":{"desc":"L1P"},"51":{"t":"BE35"},"52":{"desc":"L1P"},"53":{"desc":"H1P"},"54":{"t":"PA31"},"55":{"t":"BE55"},"56":{"desc":"A1P"},"57":{"desc":"L1P"},"58":{"desc":"L1P"},"59":{"t":"BE30"},"5A":{"t":"P28A"},"5B":{"t":"BE9T"},"5C":{"desc":"L1P"},"5D":{"t":"ASTR"},"5E":{"desc":"L2P"},"5F":{"t":"GLF3"},"60":{"t":"SR22"},"61":{"desc":"L1P"},"62":{"desc":"L1P"},"63":{"t":"M20T"},"64":{"t":"C172"},"65":{"t":"C185"},"66":{"t":"C185"},"67":{"t":"C650"},"68":{"t":"GLF3"},"69":{"t":"P28R"},"6A":{"t":"PA32"},"6B":{"t":"BE55"},"6C":{"desc":"L1P"},"6D":{"t":"C82R"},"6E":{"t":"BE55"},"6F":{"t":"B06"},"70":{"t":"BE55"},"71":{"t":"CL60"},"72":{"t":"AC90"},"73":{"t":"GLID"},"74":{"t":"AS50"},"75":{"t":"P28R"},"77":{"t":"P28A"},"78":{"desc":"L1P"},"79":{"t":"AEST"},"7B":{"t":"BE9L"},"7C":{"t":"BE40"},"80":{"t":"C185"},"81":{"t":"PA31"},"82":{"desc":"L1P"},"83":{"t":"YK52"},"84":{"t":"GLF2"},"85":{"t":"P28R"},"86":{"t":"C182"},"87":{"t":"C182"},"88":{"t":"C182"},"89":{"t":"C550"},"8A":{"t":"BE33"},"8B":{"desc":"L1P"},"8C":{"t":"BE35"},"8D":{"desc":"L1P"},"8E":{"t":"M20P"},"90":{"t":"C402"},"91":{"t":"BE35"},"92":{"t":"C340"},"93":{"t":"C56X"},"94":{"desc":"H1P"},"95":{"t":"BL8"},"96":{"desc":"L1P","t":"ULAC"},"98":{"t":"C140"},"99":{"desc":"L1P"},"9A":{"t":"BALL"},"9B":{"desc":"L1P"},"9C":{"t":"GLF3"},"9D":{"t":"BALL"},"9E":{"t":"P210"},"9F":{"desc":"L2T"},"A0":{"t":"B06"},"A1":{"desc":"L1P"},"A2":{"desc":"L2P"},"A3":{"desc":"L1P"},"A4":{"desc":"L1P"},"A5":{"t":"CH7B"},"A6":{"t":"DA40"},"A7":{"t":"C72R"},"A8":{"t":"E170"},"AA":{"t":"C172"},"AB":{"t":"SR22"},"AD":{"t":"C72R"},"AE":{"desc":"L1P"},"B0":{"desc":"L1P"},"B1":{"t":"FA7X"},"B2":{"t":"ERCO"},"B3":{"t":"BE9L"},"B4":{"desc":"L1P"},"B5":{"t":"C310"},"B6":{"t":"SR22"},"B7":{"desc":"L1P"},"B8":{"t":"C320"},"B9":{"t":"B06"},"BA":{"t":"T34P"},"BB":{"t":"C175"},"BC":{"desc":"L1P"},"BD":{"desc":"L2J"},"BE":{"t":"C510"},"BF":{"desc":"L1P"},"C0":{"t":"M20P"},"C1":{"t":"BE55"},"C2":{"desc":"L1P"},"C3":{"t":"B06"},"C4":{"t":"GLID"},"C6":{"t":"BE55"},"C7":{"t":"PA18"},"C8":{"desc":"L2J"},"C9":{"t":"M5"},"CA":{"t":"BE55"},"CB":{"t":"BE35"},"CC":{"t":"BE9L"},"CD":{"t":"C182"},"CE":{"t":"BE9L"},"CF":{"t":"M7"},"D0":{"desc":"H1J"},"D1":{"t":"BE55"},"D2":{"t":"GLID"},"D3":{"t":"B733"},"D4":{"t":"C25B"},"D5":{"desc":"L2J","t":"LR45"},"D6":{"t":"GLID"},"D7":{"t":"NAVI"},"D8":{"desc":"L1P"},"D9":{"t":"GLID"},"DA":{"desc":"A1T"},"DB":{"desc":"L2J","t":"LR35"},"DC":{"t":"C175"},"DD":{"t":"R22"},"DE":{"t":"C425"},"DF":{"t":"PAY2"},"E1":{"desc":"L1P"},"E4":{"t":"C170"},"E5":{"t":"AA5"},"E6":{"desc":"L1P"},"E7":{"desc":"L1P"},"E8":{"desc":"L1P"},"E9":{"desc":"L1P"},"EA":{"t":"PA24"},"EB":{"desc":"L1P"},"EC":{"t":"C172"},"ED":{"t":"BE36"},"EE":{"t":"T34P"},"EF":{"desc":"L1P"},"F0":{"desc":"H1P"},"F1":{"desc":"H1T"},"F2":{"t":"C25C"},"F3":{"t":"PRM1"},"F4":{"desc":"L1P"},"F5":{"t":"BL8"},"F6":{"t":"BALL"},"F7":{"t":"P28B"},"F8":{"desc":"L1P"},"F9":{"desc":"L1P"},"FA":{"t":"C140"},"FB":{"desc":"L1P"},"FC":{"t":"BE20"},"FD":{"t":"B350"},"FE":{"t":"BE55"},"FF":{"t":"P28B"}} {"00":{"t":"B190"},"01":{"desc":"L1P"},"02":{"t":"P28A"},"03":{"desc":"L1P"},"04":{"desc":"L1P"},"05":{"t":"C500"},"06":{"desc":"L2P"},"07":{"desc":"L1P"},"08":{"t":"CH7B"},"09":{"t":"C525"},"0A":{"t":"GLID"},"0B":{"t":"B429"},"0C":{"t":"PC12"},"0D":{"t":"C210"},"0E":{"t":"C185"},"0F":{"t":"COL3"},"10":{"desc":"L1P"},"11":{"t":"FA20"},"13":{"t":"C411"},"14":{"desc":"L1P"},"15":{"desc":"L1P","t":"ULAC"},"17":{"t":"BE76"},"18":{"t":"BE35"},"19":{"t":"C414"},"1C":{"t":"C185"},"1D":{"t":"BE9T"},"1E":{"t":"C140"},"1F":{"t":"BE58"},"20":{"t":"SR22"},"21":{"t":"BE35"},"22":{"t":"PA31"},"23":{"desc":"L1P"},"24":{"desc":"L1P"},"25":{"t":"C182"},"26":{"t":"AEST"},"27":{"t":"BE35"},"29":{"t":"C180"},"2A":{"t":"P28R"},"2B":{"t":"GLF4"},"2C":{"t":"GLID"},"2D":{"t":"PA18"},"2E":{"t":"PAY2"},"2F":{"desc":"L1E"},"30":{"t":"BE35"},"31":{"desc":"L1P"},"32":{"t":"BE40"},"33":{"t":"C182"},"34":{"desc":"L2T"},"35":{"desc":"L2P"},"36":{"desc":"L1P"},"37":{"t":"PA18"},"38":{"desc":"L2J"},"39":{"t":"M20P"},"3A":{"t":"C182"},"3B":{"t":"M20P"},"3C":{"desc":"L1T"},"3D":{"desc":"L1P"},"3E":{"t":"P28R"},"3F":{"desc":"L1P"},"40":{"t":"PA27"},"41":{"desc":"L1P"},"42":{"t":"B762"},"43":{"desc":"H1P"},"44":{"desc":"L1P"},"45":{"t":"UH1"},"46":{"t":"AEST"},"47":{"t":"PA24"},"48":{"t":"SR22"},"49":{"desc":"L1P"},"4A":{"desc":"L1P"},"4B":{"t":"B350"},"4C":{"desc":"L1T"},"4D":{"desc":"A1E"},"4E":{"t":"PA24"},"4F":{"t":"C310"},"50":{"desc":"L1P"},"51":{"t":"BE35"},"52":{"desc":"L1P"},"53":{"desc":"H1P"},"54":{"t":"PA31"},"55":{"t":"BE55"},"56":{"desc":"A1P"},"57":{"desc":"L1P"},"58":{"desc":"L1P"},"59":{"desc":"L2J","t":"LR60"},"5A":{"t":"P28A"},"5B":{"t":"BE9T"},"5C":{"desc":"L1P"},"5D":{"t":"ASTR"},"5E":{"desc":"L2P"},"5F":{"t":"GLF3"},"60":{"t":"SR22"},"61":{"desc":"L1P"},"62":{"desc":"L1P"},"63":{"t":"M20T"},"64":{"t":"C172"},"65":{"t":"C185"},"66":{"t":"C185"},"67":{"t":"C650"},"68":{"t":"GLF3"},"69":{"t":"P28R"},"6A":{"t":"PA32"},"6B":{"t":"BE55"},"6C":{"desc":"L1P"},"6D":{"t":"C82R"},"6E":{"t":"BE55"},"6F":{"t":"B06"},"70":{"t":"BE55"},"71":{"t":"CL60"},"72":{"t":"AC90"},"73":{"t":"GLID"},"74":{"t":"AS50"},"75":{"t":"P28R"},"77":{"t":"P28A"},"78":{"desc":"L1P"},"79":{"t":"AEST"},"7B":{"t":"BE9L"},"7C":{"t":"BE40"},"80":{"t":"C185"},"81":{"t":"PA31"},"82":{"desc":"L1P"},"83":{"t":"YK52"},"84":{"t":"GLF2"},"85":{"t":"P28R"},"86":{"t":"C182"},"87":{"t":"C182"},"88":{"t":"C182"},"89":{"t":"C550"},"8A":{"t":"BE33"},"8B":{"desc":"L1P"},"8C":{"t":"BE35"},"8D":{"desc":"L1P"},"8E":{"t":"M20P"},"90":{"t":"C402"},"91":{"t":"BE35"},"92":{"t":"C340"},"93":{"t":"C56X"},"94":{"desc":"H1P"},"95":{"t":"BL8"},"96":{"desc":"L1P","t":"ULAC"},"98":{"t":"C140"},"99":{"desc":"L1P"},"9A":{"t":"BALL"},"9B":{"desc":"L1P"},"9C":{"t":"GLF3"},"9D":{"t":"BALL"},"9E":{"t":"P210"},"9F":{"desc":"L2T"},"A0":{"t":"B06"},"A1":{"desc":"L1P"},"A2":{"desc":"L2P"},"A3":{"desc":"L1P"},"A4":{"desc":"L1P"},"A5":{"t":"CH7B"},"A6":{"t":"DA40"},"A7":{"t":"C72R"},"A8":{"t":"E170"},"AA":{"t":"C172"},"AB":{"t":"SR22"},"AD":{"t":"C72R"},"AE":{"desc":"L1P"},"B0":{"desc":"L1P"},"B1":{"t":"FA7X"},"B2":{"t":"ERCO"},"B3":{"t":"BE9L"},"B4":{"desc":"L1P"},"B5":{"t":"C310"},"B6":{"t":"SR22"},"B7":{"desc":"L1P"},"B8":{"t":"C320"},"B9":{"t":"B06"},"BA":{"t":"T34P"},"BB":{"t":"C175"},"BC":{"desc":"L1P"},"BD":{"desc":"L2J"},"BE":{"t":"C510"},"BF":{"desc":"L1P"},"C0":{"t":"M20P"},"C1":{"t":"BE55"},"C2":{"desc":"L1P"},"C3":{"t":"B06"},"C4":{"t":"GLID"},"C6":{"t":"BE55"},"C7":{"t":"PA18"},"C8":{"desc":"L2J"},"C9":{"t":"M5"},"CA":{"t":"BE55"},"CB":{"t":"BE35"},"CC":{"t":"BE9L"},"CD":{"t":"C182"},"CE":{"t":"BE9L"},"CF":{"t":"M7"},"D0":{"desc":"H1J"},"D1":{"t":"BE55"},"D2":{"t":"GLID"},"D3":{"t":"B733"},"D4":{"t":"C25B"},"D5":{"desc":"L2J","t":"LR45"},"D6":{"t":"GLID"},"D7":{"t":"NAVI"},"D8":{"desc":"L1P"},"D9":{"t":"GLID"},"DA":{"desc":"A1T"},"DB":{"desc":"L2J","t":"LR35"},"DC":{"t":"C175"},"DD":{"t":"R22"},"DE":{"t":"C425"},"DF":{"t":"PAY2"},"E1":{"desc":"L1P"},"E4":{"t":"C170"},"E5":{"t":"AA5"},"E6":{"t":"PA18"},"E7":{"desc":"L1P"},"E8":{"desc":"L1P"},"E9":{"desc":"L1P"},"EA":{"t":"PA24"},"EB":{"desc":"L1P"},"EC":{"t":"C172"},"ED":{"t":"C550"},"EE":{"t":"T34P"},"EF":{"desc":"L1P"},"F0":{"desc":"H1P"},"F1":{"desc":"H1T"},"F2":{"t":"C25C"},"F3":{"t":"PRM1"},"F4":{"desc":"L1P"},"F5":{"t":"BL8"},"F6":{"t":"BALL"},"F7":{"t":"P28B"},"F8":{"desc":"L1P"},"F9":{"desc":"L1P"},"FA":{"t":"C140"},"FB":{"desc":"L1P"},"FC":{"t":"BE20"},"FD":{"t":"B350"},"FE":{"t":"BE55"},"FF":{"t":"P28B"}}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
{"00":{"t":"M20P"},"01":{"t":"M20P"},"04":{"t":"M20P"},"06":{"t":"M20P"},"08":{"t":"M20P"},"09":{"t":"M20P"},"0B":{"t":"M20P"},"0C":{"t":"M20P"},"0D":{"t":"M20P"},"0E":{"t":"M20P"},"0F":{"t":"M20P"},"10":{"t":"M20P"},"11":{"t":"M20P"},"12":{"desc":"H1P"},"13":{"t":"BE23"},"14":{"t":"L8"},"15":{"t":"BE95"},"16":{"desc":"L1P"},"17":{"t":"C310"},"18":{"t":"BALL"},"19":{"t":"C182"},"1A":{"t":"C208"},"1B":{"t":"BALL"},"1C":{"t":"BALL"},"1D":{"t":"BE23"},"1E":{"t":"J3"},"1F":{"t":"C140"},"20":{"t":"PA23"},"21":{"t":"C77R"},"22":{"t":"BALL"},"23":{"t":"T210"},"24":{"desc":"A1P"},"25":{"t":"M4"},"26":{"t":"C414"},"27":{"t":"BE33"},"28":{"t":"C182"},"29":{"t":"C172"},"2A":{"t":"P28A"},"2B":{"t":"C182"},"2C":{"t":"J2"},"2D":{"t":"C172"},"2E":{"t":"C172"},"30":{"t":"C172"},"31":{"t":"C172"},"32":{"t":"BE76"},"33":{"t":"C82R"},"34":{"t":"C172"},"35":{"t":"M20P"},"36":{"t":"H269"},"37":{"t":"L8"},"38":{"t":"BE95"},"39":{"t":"BE35"},"3A":{"t":"CH7A"},"3B":{"t":"BALL"},"3C":{"desc":"L1P"},"3D":{"desc":"L1P"},"3E":{"t":"BALL"},"3F":{"t":"L8"},"40":{"desc":"L1P"},"41":{"desc":"L1J"},"42":{"t":"C140"},"43":{"desc":"L1P"},"44":{"t":"C77R"},"45":{"t":"C182"},"46":{"t":"T210"},"47":{"desc":"L1P"},"48":{"t":"SSAB"},"49":{"t":"SSAB"},"4A":{"t":"BALL"},"4B":{"t":"C182"},"4C":{"t":"BALL"},"4D":{"t":"C56X"},"4E":{"desc":"L1P"},"4F":{"t":"C172"},"50":{"t":"J2"},"51":{"desc":"L1P"},"52":{"t":"J2"},"53":{"t":"C172"},"54":{"t":"C177"},"55":{"t":"C172"},"56":{"t":"ULAC"},"57":{"t":"BE24"},"58":{"desc":"L1P"},"59":{"t":"BE24"},"5A":{"t":"BE24"},"5B":{"t":"GLEX"},"5C":{"t":"BE35"},"5D":{"t":"C172"},"5E":{"t":"C182"},"5F":{"t":"C182"},"60":{"t":"WACF"},"61":{"t":"BALL"},"62":{"t":"BE19"},"63":{"desc":"A1P"},"64":{"t":"J3"},"65":{"t":"BE23"},"66":{"t":"SHIP"},"67":{"t":"C77R"},"68":{"t":"C182"},"69":{"t":"T210"},"6A":{"t":"C172"},"6B":{"t":"M4"},"6C":{"t":"C140"},"6D":{"t":"BE35"},"6E":{"t":"C182"},"6F":{"t":"C182"},"70":{"t":"BALL"},"71":{"t":"BE23"},"72":{"t":"C172"},"73":{"desc":"L1P"},"74":{"t":"C172"},"75":{"t":"C177"},"76":{"t":"BE76"},"77":{"t":"C182"},"78":{"t":"C177"},"79":{"t":"BALL"},"7A":{"desc":"L2P"},"7B":{"desc":"L1P"},"7C":{"t":"BE19"},"7D":{"t":"L8"},"7E":{"desc":"L1P"},"7F":{"t":"BE35"},"80":{"t":"CH7A"},"81":{"t":"BALL"},"82":{"t":"BE19"},"83":{"t":"ERCO"},"84":{"t":"BALL"},"85":{"desc":"L1P"},"86":{"desc":"A1P"},"87":{"t":"BALL"},"88":{"t":"BE23"},"89":{"t":"PA23"},"8A":{"t":"C208"},"8B":{"t":"C182"},"8C":{"t":"C210"},"8D":{"t":"ERCO"},"8E":{"t":"M4"},"8F":{"t":"BE76"},"90":{"t":"BE35"},"91":{"t":"C182"},"92":{"t":"C172"},"93":{"t":"C208"},"94":{"t":"H269"},"95":{"t":"BE76"},"96":{"t":"C172"},"97":{"t":"C172"},"98":{"t":"T6"},"99":{"t":"BE24"},"9A":{"t":"C172"},"9B":{"desc":"L1P"},"9C":{"t":"ULAC"},"9D":{"t":"C172"},"9E":{"t":"C180"},"9F":{"t":"BALL"},"A0":{"t":"L8"},"A1":{"t":"BE95"},"A2":{"t":"BE23"},"A3":{"t":"C172"},"A4":{"t":"BALL"},"A5":{"t":"BE24"},"A6":{"t":"ERCO"},"A7":{"t":"BALL"},"A8":{"t":"B412"},"A9":{"desc":"A1P"},"AA":{"t":"J3"},"AB":{"t":"C140"},"AC":{"t":"PA18"},"AD":{"t":"C77R"},"AE":{"t":"C182"},"AF":{"t":"C182"},"B0":{"t":"H269"},"B1":{"t":"M20P"},"B2":{"t":"C120"},"B3":{"t":"ULAC"},"B4":{"t":"C182"},"B5":{"t":"SR20"},"B6":{"desc":"L1P"},"B7":{"desc":"H2T"},"B8":{"t":"C172"},"B9":{"t":"C177"},"BA":{"t":"C172"},"BB":{"t":"C172"},"BC":{"t":"C177"},"BD":{"t":"BALL"},"BE":{"t":"J3"},"BF":{"t":"BE55"},"C0":{"t":"J3"},"C1":{"desc":"H4E"},"C2":{"t":"C208"},"C3":{"t":"L8"},"C4":{"t":"BE36"},"C5":{"t":"BE35"},"C6":{"t":"CH7A"},"C7":{"t":"BALL"},"C8":{"desc":"L1P"},"C9":{"t":"ERCO"},"CA":{"t":"BALL"},"CB":{"t":"BE36"},"CC":{"desc":"H1P"},"CD":{"t":"BALL"},"CE":{"desc":"L1P"},"CF":{"t":"C182"},"D0":{"t":"C77R"},"D1":{"t":"C182"},"D2":{"t":"T210"},"D3":{"t":"BE33"},"D4":{"t":"M4"},"D5":{"t":"BE35"},"D6":{"t":"BE35"},"D7":{"t":"C182"},"D8":{"t":"C172"},"D9":{"t":"BALL"},"DA":{"t":"J2"},"DB":{"t":"C177"},"DC":{"t":"C172"},"DD":{"desc":"L1P"},"DE":{"t":"C172"},"DF":{"t":"C172"},"E0":{"t":"J3"},"E1":{"t":"C172"},"E2":{"t":"C172"},"E3":{"t":"C172"},"E4":{"desc":"L1P"},"E5":{"t":"FA7X"},"E6":{"t":"L8"},"E7":{"t":"BE55"},"E8":{"t":"BE35"},"E9":{"t":"CH7A"},"EA":{"t":"AT5T"},"EB":{"desc":"L1T"},"EC":{"t":"BALL"},"ED":{"t":"BALL"},"EE":{"t":"BE55"},"EF":{"t":"BALL"},"F0":{"t":"J3"},"F1":{"t":"BE36"},"F2":{"t":"PA23"},"F3":{"desc":"L1P"},"F4":{"t":"C182"},"F5":{"desc":"A1P"},"F6":{"desc":"H1P"},"F7":{"t":"M4"},"F8":{"t":"C120"},"F9":{"desc":"A1P"},"FA":{"t":"C182"},"FB":{"t":"BE35"},"FC":{"t":"C150"},"FD":{"t":"BE35"},"FE":{"t":"J2"},"FF":{"t":"C310"}} {"00":{"t":"M20P"},"01":{"t":"M20P"},"04":{"t":"M20P"},"06":{"t":"M20P"},"08":{"t":"M20P"},"09":{"t":"M20P"},"0B":{"t":"M20P"},"0C":{"t":"M20P"},"0D":{"t":"M20P"},"0E":{"t":"M20P"},"0F":{"t":"M20P"},"10":{"t":"M20P"},"11":{"t":"M20P"},"12":{"desc":"H1P"},"13":{"t":"BE23"},"14":{"t":"L8"},"15":{"t":"BE95"},"16":{"desc":"L1P"},"17":{"t":"C310"},"18":{"t":"BALL"},"19":{"t":"C182"},"1A":{"t":"C208"},"1B":{"t":"BALL"},"1C":{"t":"BALL"},"1D":{"t":"BE23"},"1E":{"t":"J3"},"1F":{"t":"C140"},"20":{"t":"PA23"},"21":{"t":"C77R"},"22":{"t":"BALL"},"23":{"t":"T210"},"24":{"desc":"A1P"},"25":{"t":"M4"},"26":{"t":"C414"},"27":{"t":"BE33"},"28":{"t":"C182"},"29":{"t":"C172"},"2A":{"t":"P28A"},"2B":{"t":"C182"},"2C":{"t":"J2"},"2D":{"t":"C172"},"2E":{"t":"C172"},"30":{"t":"C172"},"31":{"t":"C172"},"32":{"t":"BE76"},"33":{"t":"C82R"},"34":{"t":"C172"},"35":{"t":"M20P"},"36":{"t":"H269"},"37":{"t":"L8"},"38":{"t":"BE95"},"39":{"t":"BE35"},"3A":{"t":"CH7A"},"3B":{"t":"BALL"},"3C":{"desc":"L1P"},"3D":{"desc":"L1P"},"3E":{"t":"BALL"},"3F":{"t":"L8"},"40":{"desc":"L1P"},"41":{"desc":"L1J"},"42":{"t":"C140"},"43":{"desc":"L1P"},"44":{"t":"C77R"},"45":{"t":"C182"},"46":{"t":"T210"},"47":{"desc":"L1P"},"48":{"t":"SSAB"},"49":{"t":"SSAB"},"4A":{"t":"BALL"},"4B":{"t":"C182"},"4C":{"t":"BALL"},"4D":{"t":"C56X"},"4E":{"desc":"L1P"},"4F":{"t":"C172"},"50":{"t":"J2"},"51":{"desc":"L1P"},"52":{"t":"J2"},"53":{"t":"C172"},"54":{"t":"C177"},"55":{"t":"C172"},"56":{"desc":"L1P"},"57":{"t":"BE24"},"58":{"desc":"L1P"},"59":{"t":"BE24"},"5A":{"t":"BE24"},"5B":{"t":"GLEX"},"5C":{"t":"BE35"},"5D":{"t":"C172"},"5E":{"t":"C182"},"5F":{"t":"C182"},"60":{"t":"WACF"},"61":{"t":"BALL"},"62":{"t":"BE19"},"63":{"desc":"A1P"},"64":{"t":"J3"},"65":{"t":"BE23"},"66":{"t":"SHIP"},"67":{"t":"C77R"},"68":{"t":"C182"},"69":{"t":"T210"},"6A":{"t":"C172"},"6B":{"t":"M4"},"6C":{"t":"C140"},"6D":{"t":"BE35"},"6E":{"t":"C182"},"6F":{"t":"C182"},"70":{"t":"BALL"},"71":{"t":"BE23"},"72":{"t":"C172"},"73":{"desc":"L1P"},"74":{"t":"C172"},"75":{"t":"C177"},"76":{"t":"BE76"},"77":{"t":"C182"},"78":{"t":"C177"},"79":{"t":"BALL"},"7A":{"desc":"L2P"},"7B":{"desc":"L1P"},"7C":{"t":"BE19"},"7D":{"t":"L8"},"7E":{"desc":"L1P"},"7F":{"t":"BE35"},"80":{"t":"CH7A"},"81":{"t":"BALL"},"82":{"t":"BE19"},"83":{"t":"ERCO"},"84":{"t":"BALL"},"85":{"desc":"L1P"},"86":{"desc":"A1P"},"87":{"t":"BALL"},"88":{"t":"BE23"},"89":{"t":"PA23"},"8A":{"t":"C208"},"8B":{"t":"C182"},"8C":{"t":"C210"},"8D":{"t":"ERCO"},"8E":{"t":"M4"},"8F":{"t":"BE76"},"90":{"t":"BE35"},"91":{"t":"C182"},"92":{"t":"C172"},"93":{"t":"C208"},"94":{"t":"H269"},"95":{"t":"BE76"},"96":{"t":"C172"},"97":{"t":"C172"},"98":{"t":"T6"},"99":{"t":"BE24"},"9A":{"t":"C172"},"9B":{"desc":"L1P"},"9C":{"t":"ULAC"},"9D":{"t":"C172"},"9E":{"t":"C180"},"9F":{"t":"BALL"},"A0":{"t":"L8"},"A1":{"t":"BE95"},"A2":{"t":"BE23"},"A3":{"t":"C172"},"A4":{"t":"BALL"},"A5":{"t":"BE24"},"A6":{"t":"ERCO"},"A7":{"t":"BALL"},"A8":{"t":"B412"},"A9":{"desc":"A1P"},"AA":{"t":"J3"},"AB":{"t":"C140"},"AC":{"t":"PA18"},"AD":{"t":"C77R"},"AE":{"t":"C182"},"AF":{"t":"C182"},"B0":{"t":"H269"},"B1":{"t":"M20P"},"B2":{"t":"C120"},"B3":{"t":"ULAC"},"B4":{"t":"C182"},"B5":{"t":"SR20"},"B6":{"desc":"L1P"},"B7":{"desc":"H2T"},"B8":{"t":"C172"},"B9":{"t":"C177"},"BA":{"t":"C172"},"BB":{"t":"C172"},"BC":{"t":"C177"},"BD":{"t":"BALL"},"BE":{"t":"J3"},"BF":{"t":"BE55"},"C0":{"t":"J3"},"C1":{"desc":"H4E"},"C2":{"t":"C208"},"C3":{"t":"L8"},"C4":{"t":"BE36"},"C5":{"t":"BE35"},"C6":{"t":"CH7A"},"C7":{"t":"BALL"},"C8":{"desc":"L1P"},"C9":{"t":"ERCO"},"CA":{"t":"BALL"},"CB":{"t":"BE36"},"CC":{"desc":"H1P"},"CD":{"t":"BALL"},"CE":{"desc":"L1P"},"CF":{"t":"C182"},"D0":{"t":"C77R"},"D1":{"t":"C182"},"D2":{"t":"T210"},"D3":{"t":"BE33"},"D4":{"t":"M4"},"D5":{"t":"BE35"},"D6":{"t":"BE35"},"D7":{"t":"C182"},"D8":{"t":"C172"},"D9":{"t":"BALL"},"DA":{"t":"J2"},"DB":{"t":"C177"},"DC":{"t":"C172"},"DD":{"desc":"L1P"},"DE":{"t":"C172"},"DF":{"t":"C172"},"E0":{"t":"J3"},"E1":{"t":"C172"},"E2":{"t":"C172"},"E3":{"t":"C172"},"E4":{"desc":"L1P"},"E5":{"t":"FA7X"},"E6":{"t":"L8"},"E7":{"t":"BE55"},"E8":{"t":"BE35"},"E9":{"t":"CH7A"},"EA":{"t":"AT5T"},"EB":{"desc":"L1T"},"EC":{"t":"BALL"},"ED":{"t":"BALL"},"EE":{"t":"BE55"},"EF":{"t":"BALL"},"F0":{"t":"J3"},"F1":{"t":"BE36"},"F2":{"t":"PA23"},"F3":{"desc":"L1P"},"F4":{"t":"C182"},"F5":{"desc":"A1P"},"F6":{"desc":"H1P"},"F7":{"t":"M4"},"F8":{"t":"C120"},"F9":{"desc":"A1P"},"FA":{"t":"C182"},"FB":{"t":"BE35"},"FC":{"t":"C150"},"FD":{"desc":"L2J"},"FE":{"t":"J2"},"FF":{"t":"C310"}}

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
{"00":{"t":"BE35"},"01":{"t":"C182"},"02":{"t":"C172"},"03":{"t":"C150"},"04":{"t":"B06"},"05":{"t":"C172"},"06":{"t":"FA24"},"07":{"t":"BALL"},"08":{"t":"FA24"},"09":{"t":"C172"},"0A":{"t":"C172"},"0B":{"desc":"L1P"},"0C":{"t":"FA24"},"0D":{"desc":"L1P"},"0E":{"desc":"A1E"},"0F":{"desc":"A1P"},"10":{"t":"AT5T"},"11":{"t":"BE33"},"12":{"t":"BE35"},"13":{"t":"CH7A"},"14":{"t":"H269"},"15":{"t":"BE58"},"16":{"t":"H269"},"17":{"t":"C188"},"18":{"t":"L8"},"19":{"t":"BE19"},"1A":{"t":"J3"},"1B":{"t":"C140"},"1C":{"t":"C182"},"1D":{"t":"C77R"},"1E":{"t":"P28A"},"1F":{"t":"C82R"},"20":{"t":"T28"},"21":{"t":"M4"},"22":{"t":"BE36"},"23":{"t":"M20T"},"24":{"t":"BE23"},"25":{"t":"C172"},"26":{"t":"AT8T"},"27":{"t":"C172"},"28":{"desc":"L1P"},"29":{"t":"FA24"},"2A":{"t":"FA24"},"2B":{"t":"C172"},"2C":{"t":"C172"},"2D":{"t":"C172"},"2E":{"t":"C172"},"2F":{"t":"FA24"},"30":{"t":"C82R"},"31":{"desc":"L1P"},"32":{"t":"ULAC"},"33":{"t":"L8"},"34":{"t":"BE55"},"35":{"t":"BE35"},"36":{"t":"CH7A"},"37":{"t":"BALL"},"38":{"t":"C182"},"39":{"t":"ERCO"},"3A":{"t":"AT8T"},"3B":{"t":"BE55"},"3C":{"t":"BE23"},"3D":{"t":"AT3P"},"3E":{"t":"C140"},"3F":{"t":"PA23"},"40":{"t":"H269"},"41":{"desc":"H1T","t":"S92"},"42":{"t":"B06"},"43":{"t":"P28R"},"44":{"t":"M4"},"45":{"t":"BE58"},"46":{"t":"BALL"},"47":{"t":"C182"},"48":{"t":"C172"},"49":{"t":"C150"},"4A":{"t":"C180"},"4B":{"desc":"L1P"},"4C":{"t":"GLID"},"4D":{"desc":"H1T","t":"AT5T"},"4E":{"desc":"H1P"},"4F":{"desc":"L1P"},"50":{"t":"GLID"},"51":{"desc":"L1P"},"52":{"t":"C172"},"53":{"t":"BE55"},"54":{"desc":"L1P"},"55":{"desc":"L2P"},"56":{"desc":"L1P"},"57":{"t":"BE95"},"58":{"t":"H269"},"59":{"t":"C172"},"5A":{"t":"T28"},"5B":{"t":"C182"},"5C":{"desc":"L1P"},"5D":{"t":"T28"},"5E":{"desc":"A1P"},"5F":{"t":"BE95"},"60":{"desc":"L1P"},"61":{"t":"AT5T"},"62":{"t":"H269"},"63":{"t":"BE36"},"64":{"t":"T28"},"65":{"t":"AT8T"},"66":{"t":"H269"},"67":{"t":"M4"},"68":{"t":"C140"},"69":{"t":"BE33"},"6A":{"t":"C56X"},"6B":{"t":"BE35"},"6C":{"t":"C150"},"6D":{"t":"C172"},"6E":{"t":"BE36"},"6F":{"t":"C172"},"70":{"t":"AT5T"},"71":{"t":"BE35"},"72":{"t":"C172"},"73":{"t":"L8"},"74":{"t":"L8"},"75":{"t":"C172"},"76":{"t":"L8"},"77":{"desc":"H1P"},"78":{"t":"BE36"},"79":{"t":"L8"},"7A":{"t":"BALL"},"7B":{"t":"BE35"},"7C":{"t":"AT5T"},"7D":{"t":"BALL"},"7E":{"t":"C182"},"7F":{"desc":"L1P"},"80":{"t":"C188"},"81":{"t":"L8"},"82":{"t":"BE23"},"83":{"t":"J3"},"84":{"t":"BE35"},"85":{"t":"PA23"},"86":{"desc":"L1P"},"87":{"desc":"H1P"},"88":{"t":"T210"},"89":{"desc":"L1P"},"8A":{"t":"M4"},"8B":{"t":"C120"},"8C":{"desc":"H1T"},"8D":{"t":"ULAC"},"8E":{"t":"BALL"},"8F":{"t":"C150"},"90":{"t":"C172"},"91":{"t":"ST75"},"92":{"t":"L8"},"93":{"t":"L8"},"94":{"t":"AT3T"},"95":{"t":"C172"},"96":{"t":"C172"},"97":{"t":"C172"},"98":{"t":"C172"},"99":{"t":"C25A"},"9A":{"t":"CH7A"},"9B":{"t":"T28"},"9C":{"desc":"L1T"},"9D":{"t":"BE18"},"9E":{"desc":"L1P"},"9F":{"t":"AT8T"},"A0":{"desc":"L1P","t":"GLID"},"A1":{"t":"C182"},"A2":{"desc":"L1P"},"A3":{"desc":"L1P"},"A4":{"t":"T28"},"A5":{"t":"BE23"},"A6":{"desc":"L1P"},"A7":{"t":"AT8T"},"A8":{"t":"PA23"},"A9":{"t":"BALL"},"AA":{"desc":"L1P"},"AB":{"t":"C82R"},"AC":{"desc":"L1P"},"AD":{"t":"M4"},"AE":{"t":"C56X"},"AF":{"desc":"L1P"},"B0":{"desc":"L1P"},"B1":{"t":"C172"},"B2":{"t":"C150"},"B3":{"t":"C172"},"B4":{"t":"BALL"},"B5":{"desc":"H1T","t":"S92"},"B6":{"desc":"A1P"},"B7":{"desc":"L1P"},"B8":{"t":"C172"},"B9":{"t":"C172"},"BA":{"t":"T28"},"BB":{"t":"C172"},"BC":{"desc":"L1P","t":"ULAC"},"BD":{"t":"GLID"},"BE":{"t":"B06"},"BF":{"desc":"L1T"},"C0":{"t":"T206"},"C1":{"t":"BE35"},"C2":{"desc":"L1P"},"C3":{"t":"BALL"},"C4":{"t":"C750"},"C5":{"t":"ERCO"},"C6":{"t":"AT8T"},"C7":{"t":"L8"},"C8":{"desc":"A1P"},"C9":{"t":"J3"},"CA":{"t":"C140"},"CB":{"desc":"L1P"},"CC":{"desc":"A1P"},"CD":{"t":"C182"},"CE":{"t":"C82R"},"CF":{"t":"P28R"},"D0":{"t":"BALL"},"D1":{"t":"UH12"},"D2":{"desc":"L1T"},"D3":{"t":"B06"},"D4":{"t":"C172"},"D5":{"t":"C150"},"D6":{"t":"C172"},"D7":{"t":"T28"},"D8":{"t":"L8"},"D9":{"t":"B06"},"DA":{"t":"T34P"},"DB":{"t":"T34P"},"DC":{"t":"L8"},"DD":{"t":"L8"},"DE":{"desc":"H1T","t":"S92"},"DF":{"t":"C172"},"E0":{"desc":"L1J"},"E1":{"desc":"L1P"},"E2":{"t":"B407"},"E3":{"t":"BE18"},"E4":{"t":"BE35"},"E5":{"t":"CH7A"},"E6":{"t":"BALL"},"E7":{"desc":"L1P"},"E8":{"t":"ERCO"},"E9":{"t":"BALL"},"EA":{"t":"BE58"},"EB":{"t":"B06"},"EC":{"t":"P28A"},"ED":{"desc":"L1P"},"EE":{"desc":"L1P","t":"ULAC"},"EF":{"t":"AT8T"},"F0":{"t":"C182"},"F1":{"t":"C172"},"F2":{"desc":"L1P"},"F3":{"t":"M4"},"F4":{"desc":"L1P","t":"ULAC"},"F5":{"t":"GLID"},"F6":{"t":"C182"},"F7":{"t":"BE58"},"F8":{"desc":"L1P"},"F9":{"t":"L8"},"FA":{"t":"H269"},"FB":{"t":"L8"},"FC":{"t":"C172"},"FD":{"desc":"L1P"},"FE":{"desc":"L1P"},"FF":{"desc":"L1P"}} {"00":{"t":"BE35"},"01":{"t":"C182"},"02":{"t":"C172"},"03":{"t":"C150"},"04":{"t":"B06"},"05":{"t":"C172"},"06":{"t":"FA24"},"07":{"t":"BALL"},"08":{"t":"FA24"},"09":{"t":"C172"},"0A":{"t":"C172"},"0B":{"desc":"L1P"},"0C":{"t":"FA24"},"0D":{"desc":"L1P"},"0E":{"desc":"A1E"},"0F":{"desc":"A1P"},"10":{"t":"AT5T"},"11":{"t":"BE33"},"12":{"t":"BE35"},"13":{"t":"CH7A"},"14":{"t":"H269"},"15":{"t":"BE58"},"16":{"t":"H269"},"17":{"t":"C188"},"18":{"t":"L8"},"19":{"t":"BE19"},"1A":{"t":"J3"},"1B":{"t":"C140"},"1C":{"t":"C182"},"1D":{"t":"C77R"},"1E":{"t":"P28A"},"1F":{"t":"C82R"},"20":{"t":"T28"},"21":{"t":"M4"},"22":{"t":"BE36"},"23":{"t":"M20T"},"24":{"t":"BE23"},"25":{"t":"C172"},"26":{"t":"AT8T"},"27":{"t":"C172"},"28":{"desc":"L1P"},"29":{"t":"FA24"},"2A":{"t":"FA24"},"2B":{"t":"C172"},"2C":{"desc":"L1P"},"2D":{"t":"C172"},"2E":{"t":"C172"},"2F":{"t":"FA24"},"30":{"t":"C82R"},"31":{"desc":"L1P"},"32":{"t":"ULAC"},"33":{"t":"L8"},"34":{"t":"BE55"},"35":{"t":"BE35"},"36":{"t":"CH7A"},"37":{"t":"BALL"},"38":{"t":"C182"},"39":{"t":"ERCO"},"3A":{"t":"AT8T"},"3B":{"t":"BE55"},"3C":{"t":"BE23"},"3D":{"t":"AT3P"},"3E":{"t":"C140"},"3F":{"t":"PA23"},"40":{"t":"H269"},"41":{"desc":"L1P"},"42":{"t":"B06"},"43":{"t":"P28R"},"44":{"t":"M4"},"45":{"t":"BE58"},"46":{"t":"BALL"},"47":{"t":"C182"},"48":{"t":"C172"},"49":{"t":"C150"},"4A":{"t":"C180"},"4B":{"desc":"L1P"},"4C":{"t":"GLID"},"4D":{"desc":"H1T","t":"AT5T"},"4E":{"desc":"H1P"},"4F":{"desc":"L1P"},"50":{"t":"GLID"},"51":{"desc":"L1P"},"52":{"t":"C172"},"53":{"t":"BE55"},"54":{"desc":"L1P"},"55":{"desc":"L2P"},"56":{"desc":"L1P"},"57":{"t":"BE95"},"58":{"t":"H269"},"59":{"t":"C172"},"5A":{"t":"T28"},"5B":{"t":"C182"},"5C":{"desc":"L1P"},"5D":{"t":"T28"},"5E":{"desc":"A1P"},"5F":{"t":"BE95"},"60":{"desc":"L1P"},"61":{"t":"AT5T"},"62":{"t":"H269"},"63":{"t":"BE36"},"64":{"t":"T28"},"65":{"t":"AT8T"},"66":{"t":"H269"},"67":{"t":"M4"},"68":{"t":"C140"},"69":{"t":"BE33"},"6A":{"desc":"L1P"},"6B":{"t":"BE35"},"6C":{"t":"C150"},"6D":{"t":"C172"},"6E":{"t":"BE36"},"6F":{"t":"C172"},"70":{"t":"AT5T"},"71":{"t":"BE35"},"72":{"t":"C172"},"73":{"t":"L8"},"74":{"t":"L8"},"75":{"t":"C172"},"76":{"t":"L8"},"77":{"desc":"H1P"},"78":{"t":"BE36"},"79":{"t":"L8"},"7A":{"t":"BALL"},"7B":{"t":"BE35"},"7C":{"t":"AT5T"},"7D":{"t":"BALL"},"7E":{"t":"C182"},"7F":{"desc":"L1P"},"80":{"t":"C188"},"81":{"t":"L8"},"82":{"t":"BE23"},"83":{"t":"J3"},"84":{"t":"BE35"},"85":{"t":"PA23"},"86":{"desc":"L1P"},"87":{"desc":"H1P"},"88":{"t":"T210"},"89":{"desc":"L1P"},"8A":{"t":"M4"},"8B":{"t":"C120"},"8C":{"desc":"H1T"},"8D":{"t":"ULAC"},"8E":{"t":"BALL"},"8F":{"t":"C150"},"90":{"t":"C172"},"91":{"t":"ST75"},"92":{"t":"L8"},"93":{"t":"L8"},"94":{"t":"AT3T"},"95":{"t":"C172"},"96":{"t":"C172"},"97":{"t":"C172"},"98":{"t":"C172"},"99":{"desc":"L1T"},"9A":{"t":"CH7A"},"9B":{"t":"T28"},"9C":{"desc":"L1T"},"9D":{"t":"BE18"},"9E":{"desc":"L1P"},"9F":{"t":"AT8T"},"A0":{"desc":"L1P","t":"GLID"},"A1":{"t":"C182"},"A2":{"desc":"L1P"},"A3":{"desc":"L1P"},"A4":{"t":"T28"},"A5":{"t":"BE23"},"A6":{"desc":"L1P"},"A7":{"t":"AT8T"},"A8":{"t":"PA23"},"A9":{"t":"BALL"},"AA":{"desc":"L1P"},"AB":{"t":"C82R"},"AC":{"desc":"L1P"},"AD":{"t":"M4"},"AE":{"t":"C56X"},"AF":{"desc":"L1P"},"B0":{"desc":"L1P"},"B1":{"t":"C172"},"B2":{"desc":"L1T"},"B3":{"t":"C172"},"B4":{"t":"BALL"},"B5":{"desc":"H1T","t":"S92"},"B6":{"desc":"A1P"},"B7":{"desc":"L1P"},"B8":{"t":"C172"},"B9":{"t":"C172"},"BA":{"t":"T28"},"BB":{"t":"C172"},"BC":{"desc":"L1P","t":"ULAC"},"BD":{"t":"GLID"},"BE":{"t":"B06"},"BF":{"desc":"L1T"},"C0":{"t":"T206"},"C1":{"t":"BE35"},"C2":{"desc":"L1P"},"C3":{"t":"BALL"},"C4":{"t":"C750"},"C5":{"t":"ERCO"},"C6":{"t":"AT8T"},"C7":{"t":"L8"},"C8":{"desc":"A1P"},"C9":{"t":"J3"},"CA":{"t":"C140"},"CB":{"desc":"L1P"},"CC":{"desc":"A1P"},"CD":{"t":"C182"},"CE":{"t":"C82R"},"CF":{"t":"P28R"},"D0":{"t":"BALL"},"D1":{"t":"UH12"},"D2":{"desc":"L1T"},"D3":{"t":"B06"},"D4":{"t":"C172"},"D5":{"t":"C150"},"D6":{"t":"C172"},"D7":{"t":"T28"},"D8":{"t":"L8"},"D9":{"t":"B06"},"DA":{"t":"T34P"},"DB":{"t":"T34P"},"DC":{"t":"L8"},"DD":{"t":"L8"},"DE":{"desc":"H1T","t":"S92"},"DF":{"t":"C172"},"E0":{"desc":"L1J"},"E1":{"desc":"L1P"},"E2":{"t":"B407"},"E3":{"t":"BE18"},"E4":{"t":"BE35"},"E5":{"t":"CH7A"},"E6":{"t":"BALL"},"E7":{"desc":"L1P"},"E8":{"t":"ERCO"},"E9":{"t":"BALL"},"EA":{"t":"BE58"},"EB":{"t":"B06"},"EC":{"t":"P28A"},"ED":{"desc":"L1P"},"EE":{"desc":"L1P","t":"ULAC"},"EF":{"t":"AT8T"},"F0":{"t":"C182"},"F1":{"t":"C172"},"F2":{"desc":"L1P"},"F3":{"t":"M4"},"F4":{"desc":"L1P","t":"ULAC"},"F5":{"t":"GLID"},"F6":{"t":"C182"},"F7":{"t":"BE58"},"F8":{"desc":"L1P"},"F9":{"t":"L8"},"FA":{"t":"H269"},"FB":{"t":"L8"},"FC":{"t":"C172"},"FD":{"desc":"L1P"},"FE":{"desc":"L2J"},"FF":{"desc":"L1P"}}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
{"00":{"t":"BE35"},"01":{"t":"CH7A"},"02":{"t":"C206"},"03":{"t":"M20T"},"04":{"t":"BALL"},"05":{"t":"H269"},"06":{"t":"GLID"},"07":{"t":"C172"},"08":{"t":"P28U"},"09":{"t":"C140"},"0A":{"t":"PA23"},"0B":{"t":"C77R"},"0C":{"t":"P28A"},"0D":{"t":"C182"},"0E":{"t":"C172"},"0F":{"t":"C182"},"10":{"desc":"L1P"},"11":{"t":"C182"},"12":{"t":"P28T"},"13":{"t":"P28B"},"14":{"desc":"L1P"},"15":{"t":"C208"},"16":{"t":"C182"},"17":{"t":"C172"},"18":{"t":"P32T"},"19":{"t":"C208"},"1A":{"t":"P32T"},"1B":{"t":"PA44"},"1C":{"t":"ULAC"},"1D":{"t":"P28A"},"1E":{"t":"P28A"},"1F":{"desc":"H1P"},"20":{"t":"PA44"},"21":{"t":"P32T"},"22":{"t":"CH7B"},"23":{"t":"C182"},"24":{"t":"CH7A"},"25":{"t":"C206"},"26":{"t":"P28A"},"27":{"t":"B701"},"28":{"t":"BE58"},"29":{"t":"L8"},"2A":{"t":"BE55"},"2B":{"t":"J3"},"2C":{"t":"C140"},"2D":{"t":"P28B"},"2E":{"t":"C77R"},"2F":{"t":"C182"},"30":{"t":"T210"},"31":{"t":"P28A"},"32":{"desc":"H1P"},"33":{"t":"C140"},"34":{"t":"BALL"},"35":{"t":"C172"},"36":{"t":"P28A"},"37":{"t":"P28B"},"38":{"t":"C310"},"39":{"t":"B06"},"3A":{"t":"J3"},"3B":{"t":"P32T"},"3C":{"t":"M20P"},"3D":{"t":"P32T"},"3E":{"t":"P32T"},"3F":{"t":"PA34"},"40":{"t":"PA44"},"41":{"t":"M20T"},"42":{"desc":"L1P"},"43":{"t":"PA22"},"44":{"t":"L8"},"45":{"t":"P32T"},"46":{"t":"BE35"},"47":{"t":"CH7A"},"48":{"desc":"L4T"},"49":{"t":"C182"},"4A":{"t":"ERCO"},"4B":{"t":"P28U"},"4C":{"t":"L8"},"4D":{"t":"BE36"},"4E":{"t":"P28U"},"4F":{"t":"P28B"},"50":{"t":"M20P"},"51":{"t":"C77R"},"52":{"t":"C182"},"53":{"desc":"L1P"},"54":{"t":"P28A"},"55":{"desc":"H1P"},"56":{"t":"C182"},"57":{"t":"P28A"},"58":{"t":"C337"},"59":{"t":"C172"},"5A":{"t":"C180"},"5B":{"t":"J3"},"5C":{"t":"P28A"},"5D":{"t":"P28A"},"5E":{"t":"P28A"},"5F":{"desc":"L2J"},"60":{"t":"C182"},"61":{"t":"C172"},"62":{"t":"H269"},"63":{"t":"M20T"},"64":{"t":"PA32"},"65":{"desc":"L1P"},"66":{"t":"PA22"},"67":{"t":"L8"},"68":{"desc":"L1P"},"69":{"t":"BE35"},"6A":{"t":"CH7A"},"6B":{"t":"AA5"},"6C":{"t":"C182"},"6D":{"t":"BALL"},"6E":{"t":"C172"},"6F":{"t":"L8"},"70":{"desc":"H1T","t":"S92"},"71":{"t":"P28R"},"72":{"t":"PA32"},"73":{"t":"BALL"},"74":{"t":"C77R"},"75":{"t":"T206"},"76":{"t":"T210"},"77":{"t":"C172"},"78":{"t":"T210"},"79":{"desc":"L2J"},"7A":{"t":"ULAC"},"7B":{"t":"M20P"},"7C":{"t":"C172"},"7D":{"t":"C182"},"7E":{"t":"C182"},"7F":{"t":"BALL"},"80":{"t":"M20P"},"81":{"t":"C182"},"82":{"t":"C182"},"83":{"t":"C172"},"84":{"desc":"L1P"},"85":{"t":"C182"},"86":{"t":"C172"},"87":{"t":"P32T"},"89":{"t":"C182"},"8A":{"t":"BALL"},"8B":{"t":"C182"},"8C":{"t":"BE35"},"8D":{"t":"CH7A"},"8E":{"t":"B06"},"8F":{"desc":"L2J"},"90":{"t":"ERCO"},"91":{"desc":"L2J"},"92":{"t":"L8"},"93":{"t":"BE58"},"94":{"t":"J3"},"95":{"desc":"L1P","t":"ULAC"},"96":{"t":"PA23"},"97":{"t":"C77R"},"98":{"t":"P28A"},"99":{"desc":"L1P"},"9A":{"t":"P28A"},"9B":{"t":"P28U"},"9C":{"t":"C140"},"9D":{"t":"H269"},"9E":{"t":"M20P"},"9F":{"t":"P28A"},"A0":{"t":"C172"},"A1":{"t":"C208"},"A2":{"t":"C182"},"A3":{"t":"C182"},"A4":{"t":"C172"},"A5":{"desc":"L1J"},"A6":{"t":"C182"},"A7":{"t":"B06"},"A8":{"t":"BALL"},"A9":{"t":"GLID"},"AA":{"t":"P32T"},"AB":{"desc":"A1E"},"AC":{"t":"PA22"},"AD":{"t":"BALL"},"AE":{"t":"C195"},"AF":{"t":"P28B"},"B0":{"t":"CH7A"},"B1":{"t":"C206"},"B2":{"t":"P28A"},"B3":{"t":"ERCO"},"B4":{"t":"P28U"},"B5":{"t":"PA32"},"B6":{"t":"BE55"},"B7":{"t":"J3"},"B8":{"t":"PA32"},"B9":{"t":"PA32"},"BA":{"desc":"L1T","t":"T206"},"BB":{"t":"C182"},"BC":{"desc":"L2J"},"BD":{"t":"P28A"},"BE":{"desc":"H1P"},"BF":{"t":"C140"},"C0":{"t":"BE23"},"C1":{"desc":"L1P"},"C2":{"t":"C172"},"C3":{"t":"P28B"},"C4":{"t":"B06"},"C5":{"desc":"L1P"},"C6":{"t":"C182"},"C7":{"t":"C182"},"C8":{"t":"C182"},"C9":{"t":"C182"},"CA":{"desc":"H1P"},"CB":{"t":"C182"},"CC":{"t":"J3"},"CD":{"t":"M20P"},"CE":{"desc":"L1P"},"CF":{"desc":"H1T","t":"S92"},"D0":{"t":"P32T"},"D1":{"t":"M20P"},"D2":{"t":"BE35"},"D3":{"t":"C172"},"D4":{"t":"PA44"},"D5":{"t":"C182"},"D6":{"t":"ERCO"},"D7":{"t":"P28U"},"D8":{"t":"B412"},"D9":{"t":"BE36"},"DA":{"t":"P28R"},"DB":{"t":"P32T"},"DC":{"t":"PA32"},"DD":{"t":"C77R"},"DE":{"t":"C172"},"DF":{"t":"C172"},"E0":{"t":"P28B"},"E1":{"desc":"H1P"},"E2":{"t":"BALL"},"E3":{"t":"T206"},"E4":{"t":"P28U"},"E5":{"t":"P28A"},"E6":{"t":"P28A"},"E7":{"t":"P28A"},"E8":{"t":"P28A"},"E9":{"t":"J3"},"EA":{"t":"C172"},"EB":{"t":"J3"},"EC":{"t":"C172"},"ED":{"t":"J3"},"EE":{"t":"C182"},"EF":{"t":"C182"},"F0":{"t":"P28A"},"F1":{"desc":"L1P"},"F2":{"t":"PA22"},"F3":{"t":"L8"},"F4":{"t":"C195"},"F5":{"t":"P32T"},"F6":{"t":"P28B"},"F7":{"t":"P28A"},"F8":{"t":"C182"},"F9":{"t":"ERCO"},"FA":{"t":"P28B"},"FB":{"t":"L8"},"FC":{"t":"BE36"},"FD":{"t":"J3"},"FE":{"t":"C140"},"FF":{"t":"PA23"}} {"00":{"t":"BE35"},"01":{"t":"CH7A"},"02":{"t":"C206"},"03":{"t":"M20T"},"04":{"t":"BALL"},"05":{"t":"H269"},"06":{"t":"GLID"},"07":{"t":"C172"},"08":{"t":"P28U"},"09":{"t":"C140"},"0A":{"t":"PA23"},"0B":{"t":"C77R"},"0C":{"t":"P28A"},"0D":{"t":"C182"},"0E":{"t":"C172"},"0F":{"t":"B77W"},"10":{"desc":"L1P"},"11":{"t":"C182"},"12":{"t":"P28T"},"13":{"t":"P28B"},"14":{"desc":"L1P"},"15":{"t":"C208"},"16":{"t":"C182"},"17":{"t":"C172"},"18":{"t":"P32T"},"19":{"t":"C208"},"1A":{"t":"P32T"},"1B":{"t":"PA44"},"1C":{"t":"ULAC"},"1D":{"t":"P28A"},"1E":{"t":"P28A"},"1F":{"desc":"H1P"},"20":{"t":"PA44"},"21":{"t":"P32T"},"22":{"t":"CH7B"},"23":{"t":"C182"},"24":{"t":"CH7A"},"25":{"t":"C206"},"26":{"t":"P28A"},"27":{"t":"B701"},"28":{"t":"BE58"},"29":{"t":"L8"},"2A":{"t":"BE55"},"2B":{"t":"J3"},"2C":{"t":"C140"},"2D":{"t":"P28B"},"2E":{"t":"C77R"},"2F":{"t":"C182"},"30":{"t":"T210"},"31":{"t":"P28A"},"32":{"desc":"H1P"},"33":{"t":"C140"},"34":{"t":"BALL"},"35":{"t":"C172"},"36":{"t":"P28A"},"37":{"t":"P28B"},"38":{"t":"C310"},"39":{"t":"B06"},"3A":{"t":"J3"},"3B":{"t":"P32T"},"3C":{"t":"M20P"},"3D":{"t":"P32T"},"3E":{"t":"P32T"},"3F":{"t":"PA34"},"40":{"t":"PA44"},"41":{"t":"M20T"},"42":{"desc":"L1P"},"43":{"t":"PA22"},"44":{"t":"L8"},"45":{"t":"P32T"},"46":{"t":"BE35"},"47":{"t":"CH7A"},"48":{"desc":"L4T"},"49":{"t":"C182"},"4A":{"t":"ERCO"},"4B":{"t":"P28U"},"4C":{"t":"L8"},"4D":{"t":"BE36"},"4E":{"t":"P28U"},"4F":{"t":"P28B"},"50":{"t":"M20P"},"51":{"t":"C77R"},"52":{"t":"C182"},"53":{"desc":"L1P"},"54":{"t":"P28A"},"55":{"desc":"H1P"},"56":{"t":"C182"},"57":{"t":"P28A"},"58":{"t":"C337"},"59":{"t":"C172"},"5A":{"t":"C180"},"5B":{"t":"J3"},"5C":{"t":"P28A"},"5D":{"t":"P28A"},"5E":{"t":"P28A"},"5F":{"desc":"L2J"},"60":{"t":"C182"},"61":{"t":"C172"},"62":{"t":"H269"},"63":{"t":"M20T"},"64":{"t":"PA32"},"65":{"desc":"L1P"},"66":{"t":"PA22"},"67":{"t":"L8"},"68":{"desc":"L1P"},"69":{"t":"BE35"},"6A":{"t":"CH7A"},"6B":{"t":"AA5"},"6C":{"t":"C182"},"6D":{"t":"BALL"},"6E":{"t":"C172"},"6F":{"t":"L8"},"70":{"desc":"H1T","t":"S92"},"71":{"t":"P28R"},"72":{"t":"PA32"},"73":{"t":"BALL"},"74":{"t":"C77R"},"75":{"t":"T206"},"76":{"t":"T210"},"77":{"t":"C172"},"78":{"t":"T210"},"79":{"desc":"L2J"},"7A":{"t":"ULAC"},"7B":{"t":"M20P"},"7C":{"t":"C172"},"7D":{"t":"C182"},"7E":{"t":"C182"},"7F":{"t":"BALL"},"80":{"t":"M20P"},"81":{"t":"C182"},"82":{"t":"C182"},"83":{"t":"C172"},"84":{"desc":"L1P"},"85":{"t":"C182"},"86":{"t":"C172"},"87":{"t":"P32T"},"89":{"t":"C182"},"8A":{"t":"BALL"},"8B":{"t":"C182"},"8C":{"t":"BE35"},"8D":{"t":"CH7A"},"8E":{"t":"B06"},"8F":{"desc":"L2J"},"90":{"t":"ERCO"},"91":{"desc":"L2J"},"92":{"t":"L8"},"93":{"t":"BE58"},"94":{"t":"J3"},"95":{"desc":"L1P","t":"ULAC"},"96":{"t":"PA23"},"97":{"t":"C77R"},"98":{"t":"P28A"},"99":{"desc":"L1P"},"9A":{"t":"P28A"},"9B":{"t":"P28U"},"9C":{"t":"C140"},"9D":{"t":"H269"},"9E":{"t":"M20P"},"9F":{"t":"P28A"},"A0":{"t":"C172"},"A1":{"t":"C208"},"A2":{"t":"C182"},"A3":{"t":"C182"},"A4":{"t":"C172"},"A5":{"desc":"L1J"},"A6":{"t":"C182"},"A7":{"t":"B06"},"A8":{"t":"BALL"},"A9":{"t":"GLID"},"AA":{"t":"P32T"},"AB":{"desc":"A1E"},"AC":{"t":"PA22"},"AD":{"t":"BALL"},"AE":{"t":"C195"},"AF":{"t":"P28B"},"B0":{"t":"CH7A"},"B1":{"t":"C206"},"B2":{"t":"P28A"},"B3":{"t":"ERCO"},"B4":{"t":"P28U"},"B5":{"t":"PA32"},"B6":{"t":"BE55"},"B7":{"t":"J3"},"B8":{"t":"PA32"},"B9":{"t":"PA32"},"BA":{"desc":"L1T","t":"T206"},"BB":{"t":"C182"},"BC":{"desc":"L2J"},"BD":{"t":"P28A"},"BE":{"desc":"H1P"},"BF":{"t":"C140"},"C0":{"t":"BE23"},"C1":{"desc":"L1P"},"C2":{"t":"C172"},"C3":{"t":"P28B"},"C4":{"t":"B06"},"C5":{"desc":"L1P"},"C6":{"t":"C182"},"C7":{"t":"C182"},"C8":{"t":"C182"},"C9":{"t":"C182"},"CA":{"desc":"H1P"},"CB":{"t":"C182"},"CC":{"t":"J3"},"CD":{"t":"M20P"},"CE":{"desc":"L1P"},"CF":{"desc":"H1T","t":"S92"},"D0":{"t":"P32T"},"D1":{"t":"M20P"},"D2":{"t":"BE35"},"D3":{"t":"C172"},"D4":{"t":"PA44"},"D5":{"t":"C182"},"D6":{"t":"ERCO"},"D7":{"t":"P28U"},"D8":{"t":"B412"},"D9":{"t":"BE36"},"DA":{"t":"P28R"},"DB":{"t":"P32T"},"DC":{"t":"PA32"},"DD":{"t":"C77R"},"DE":{"t":"C172"},"DF":{"t":"C172"},"E0":{"t":"P28B"},"E1":{"desc":"H1P"},"E2":{"t":"BALL"},"E3":{"t":"T206"},"E4":{"t":"P28U"},"E5":{"t":"P28A"},"E6":{"t":"P28A"},"E7":{"t":"P28A"},"E8":{"t":"P28A"},"E9":{"t":"J3"},"EA":{"t":"C172"},"EB":{"t":"J3"},"EC":{"t":"C172"},"ED":{"t":"J3"},"EE":{"t":"C182"},"EF":{"t":"C182"},"F0":{"t":"P28A"},"F1":{"desc":"L1P"},"F2":{"t":"PA22"},"F3":{"t":"L8"},"F4":{"t":"C195"},"F5":{"t":"P32T"},"F6":{"t":"P28B"},"F7":{"t":"P28A"},"F8":{"t":"C182"},"F9":{"t":"ERCO"},"FA":{"t":"P28B"},"FB":{"t":"L8"},"FC":{"t":"BE36"},"FD":{"t":"J3"},"FE":{"t":"C140"},"FF":{"t":"PA23"}}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
{"00":{"t":"C182"},"01":{"t":"C177"},"02":{"t":"C185"},"03":{"t":"C150"},"04":{"t":"TAYB"},"05":{"desc":"H3P"},"06":{"t":"P32T"},"07":{"t":"P32T"},"08":{"t":"TAYB"},"09":{"t":"TAYB"},"0A":{"t":"P32T"},"0D":{"t":"TAYD"},"0E":{"t":"PA20"},"0F":{"t":"P28A"},"10":{"t":"PC12"},"11":{"t":"C170"},"12":{"t":"CH7A"},"13":{"t":"C310"},"14":{"t":"C182"},"15":{"t":"ERCO"},"16":{"t":"C140"},"17":{"t":"PA23"},"18":{"t":"B407"},"19":{"t":"C310"},"1A":{"t":"P28A"},"1B":{"t":"PA23"},"1C":{"t":"M20P"},"1D":{"t":"P28A"},"1E":{"desc":"A1P"},"1F":{"t":"P28A"},"20":{"t":"PA34"},"22":{"t":"C170"},"23":{"t":"C337"},"24":{"t":"PA27"},"25":{"t":"PA24"},"26":{"t":"TAYB"},"27":{"desc":"L1P"},"28":{"desc":"L1P"},"29":{"t":"TAYB"},"2A":{"t":"C210"},"2B":{"t":"P28A"},"2C":{"desc":"L1P"},"2D":{"t":"TAYB"},"2E":{"t":"TAYB"},"2F":{"t":"C210"},"30":{"desc":"L1P"},"31":{"desc":"H1P"},"32":{"t":"P28A"},"33":{"t":"C180"},"34":{"t":"C170"},"35":{"desc":"L1P"},"36":{"t":"P28A"},"37":{"t":"C182"},"38":{"t":"BALL"},"39":{"t":"C150"},"3A":{"t":"L8"},"3B":{"t":"BE23"},"3C":{"t":"J3"},"3D":{"t":"P28A"},"3E":{"t":"R22"},"3F":{"t":"P28A"},"40":{"t":"P28A"},"41":{"t":"T210"},"42":{"t":"C185"},"43":{"t":"C182"},"44":{"t":"P28B"},"45":{"t":"P28U"},"46":{"t":"C337"},"47":{"t":"C177"},"48":{"t":"P28U"},"49":{"t":"C172"},"4A":{"t":"TAYB"},"4B":{"t":"T210"},"4C":{"t":"TAYB"},"4E":{"t":"TAYB"},"4F":{"desc":"L1P"},"50":{"t":"C172"},"53":{"t":"PA18"},"55":{"t":"P28B"},"56":{"t":"PA23"},"57":{"t":"BE58"},"58":{"t":"C170"},"59":{"t":"M20P"},"5A":{"t":"C25A"},"5B":{"t":"BALL"},"5C":{"t":"C150"},"5D":{"t":"P28A"},"5E":{"t":"BE23"},"5F":{"t":"J3"},"60":{"desc":"L1P"},"61":{"t":"PA23"},"62":{"t":"C421"},"63":{"desc":"H1P"},"67":{"t":"C140"},"68":{"t":"P28B"},"69":{"t":"C337"},"6A":{"t":"C177"},"6B":{"t":"P28U"},"6C":{"t":"TAYB"},"6D":{"t":"TAYB"},"6E":{"t":"TAYB"},"6F":{"t":"C150"},"70":{"desc":"L1P"},"71":{"t":"C150"},"72":{"t":"TAYB"},"74":{"t":"C150"},"75":{"t":"TAYB"},"76":{"desc":"L1P"},"77":{"t":"C172"},"78":{"t":"L8"},"79":{"desc":"L2P"},"7A":{"t":"P28A"},"7B":{"t":"C182"},"7C":{"t":"C172"},"7D":{"t":"PA44"},"7E":{"t":"BE10"},"80":{"t":"L8"},"81":{"t":"BE24"},"82":{"t":"J3"},"83":{"t":"P28A"},"85":{"t":"P28U"},"86":{"t":"T210"},"87":{"t":"PA32"},"88":{"t":"C82R"},"8A":{"t":"C140"},"8B":{"t":"ULAC"},"8C":{"t":"C337"},"8E":{"t":"P28B"},"8F":{"t":"C150"},"90":{"t":"C150"},"91":{"t":"C150"},"92":{"t":"C150"},"93":{"t":"C150"},"94":{"t":"C150"},"95":{"t":"TAYB"},"96":{"t":"TAYB"},"97":{"t":"TAYB"},"98":{"desc":"L1P"},"99":{"desc":"L1P"},"9A":{"t":"PA22"},"9B":{"t":"C206"},"9C":{"t":"C180"},"9D":{"t":"P28A"},"9E":{"t":"CH7A"},"9F":{"t":"P28A"},"A0":{"t":"C182"},"A1":{"desc":"L1P"},"A2":{"desc":"L1P"},"A3":{"desc":"H1P"},"A4":{"t":"BT36"},"A5":{"t":"J3"},"A6":{"t":"P28A"},"A7":{"t":"PA23"},"A8":{"t":"C172"},"A9":{"t":"T210"},"AA":{"t":"C210"},"AB":{"t":"P28R"},"AC":{"desc":"H1P"},"AD":{"t":"C140"},"AE":{"t":"BALL"},"AF":{"t":"P28A"},"B0":{"t":"C177"},"B1":{"t":"P28A"},"B2":{"t":"C150"},"B3":{"t":"P28R"},"B4":{"t":"PA32"},"B5":{"t":"C150"},"B6":{"t":"C150"},"B7":{"t":"C172"},"B8":{"t":"P28A"},"B9":{"t":"P32T"},"BA":{"t":"TAYB"},"BC":{"desc":"L1P","t":"ULAC"},"BE":{"desc":"H1P"},"BF":{"t":"PA18"},"C0":{"t":"P28A"},"C1":{"t":"CH7A"},"C2":{"t":"C182"},"C3":{"t":"PA44"},"C4":{"t":"PA44"},"C5":{"t":"PA32"},"C6":{"t":"L8"},"C7":{"t":"H500"},"C8":{"t":"J3"},"C9":{"t":"C140"},"CA":{"t":"ULAC"},"CB":{"t":"C421"},"CC":{"t":"P28A"},"CD":{"desc":"L1P"},"CE":{"t":"C185"},"D0":{"t":"C140"},"D1":{"t":"PA34"},"D2":{"t":"P28A"},"D3":{"t":"C177"},"D4":{"t":"P28A"},"D5":{"t":"TAYB"},"D6":{"t":"C172"},"D7":{"t":"TAYB"},"D8":{"desc":"L1P"},"D9":{"t":"C150"},"DA":{"t":"C150"},"DB":{"t":"C150"},"DC":{"t":"C150"},"DD":{"t":"C150"},"DE":{"t":"C182"},"DF":{"desc":"A1P"},"E0":{"t":"PA22"},"E1":{"t":"P32T"},"E2":{"t":"C180"},"E3":{"t":"M20P"},"E4":{"t":"C172"},"E5":{"t":"C310"},"E6":{"t":"C182"},"E8":{"t":"C150"},"E9":{"t":"M20P"},"EA":{"t":"C172"},"EB":{"t":"J3"},"ED":{"t":"PA23"},"EF":{"t":"T210"},"F0":{"t":"C210"},"F1":{"t":"C182"},"F2":{"t":"PA34"},"F3":{"t":"C140"},"F5":{"t":"C337"},"F6":{"desc":"L1P"},"F7":{"t":"P28A"},"F8":{"t":"C150"},"F9":{"desc":"L1P"},"FA":{"t":"TAYB"},"FC":{"t":"C150"},"FD":{"t":"C150"},"FE":{"t":"C182"},"FF":{"t":"TAYB"}} {"00":{"t":"C182"},"01":{"t":"C177"},"02":{"t":"C185"},"03":{"t":"C150"},"04":{"t":"TAYB"},"05":{"desc":"H3P"},"06":{"t":"P32T"},"07":{"t":"P32T"},"08":{"t":"TAYB"},"09":{"t":"TAYB"},"0A":{"t":"P32T"},"0D":{"t":"TAYD"},"0E":{"t":"PA20"},"0F":{"t":"P28A"},"10":{"t":"PC12"},"11":{"t":"C170"},"12":{"t":"CH7A"},"13":{"t":"C310"},"14":{"t":"C182"},"15":{"t":"ERCO"},"16":{"t":"C140"},"17":{"t":"PA23"},"18":{"t":"B407"},"19":{"t":"C310"},"1A":{"t":"P28A"},"1B":{"t":"PA23"},"1C":{"t":"M20P"},"1D":{"t":"P28A"},"1E":{"desc":"A1P"},"1F":{"t":"P28A"},"20":{"t":"PA34"},"22":{"t":"C170"},"23":{"t":"C337"},"24":{"t":"PA27"},"25":{"t":"PA24"},"26":{"t":"TAYB"},"27":{"desc":"L1P"},"28":{"desc":"L1P"},"29":{"t":"TAYB"},"2A":{"t":"C210"},"2B":{"t":"P28A"},"2C":{"desc":"L1P"},"2D":{"t":"TAYB"},"2E":{"t":"TAYB"},"2F":{"t":"C210"},"30":{"desc":"L1P"},"31":{"desc":"H1P"},"32":{"t":"P28A"},"33":{"t":"C180"},"34":{"t":"C170"},"35":{"desc":"L1P"},"36":{"t":"P28A"},"37":{"t":"C182"},"38":{"t":"BALL"},"39":{"t":"C150"},"3A":{"t":"L8"},"3B":{"t":"BE23"},"3C":{"t":"J3"},"3D":{"t":"P28A"},"3E":{"t":"R22"},"3F":{"t":"P28A"},"40":{"t":"P28A"},"41":{"t":"T210"},"42":{"t":"C185"},"43":{"t":"C182"},"44":{"t":"P28B"},"45":{"t":"P28U"},"46":{"t":"C337"},"47":{"t":"C177"},"48":{"t":"P28U"},"49":{"t":"C172"},"4A":{"t":"TAYB"},"4B":{"t":"T210"},"4C":{"t":"TAYB"},"4E":{"t":"TAYB"},"4F":{"desc":"L1P"},"50":{"t":"C172"},"53":{"t":"PA18"},"55":{"t":"P28B"},"56":{"t":"PA23"},"57":{"t":"BE58"},"58":{"t":"C170"},"59":{"t":"M20P"},"5A":{"t":"C25A"},"5B":{"t":"BALL"},"5C":{"t":"C150"},"5D":{"t":"P28A"},"5E":{"t":"BE23"},"5F":{"t":"J3"},"60":{"desc":"L1P"},"61":{"t":"PA23"},"62":{"t":"C421"},"63":{"desc":"H1P"},"67":{"t":"C140"},"68":{"t":"P28B"},"69":{"t":"C337"},"6A":{"t":"C177"},"6B":{"t":"P28U"},"6C":{"t":"TAYB"},"6D":{"t":"TAYB"},"6E":{"t":"TAYB"},"6F":{"t":"C150"},"70":{"desc":"L1P"},"71":{"t":"C150"},"72":{"t":"TAYB"},"74":{"t":"C150"},"75":{"t":"TAYB"},"76":{"desc":"L1P"},"77":{"t":"C172"},"78":{"t":"L8"},"79":{"desc":"L2P"},"7A":{"t":"P28A"},"7B":{"t":"C182"},"7C":{"t":"C172"},"7D":{"t":"PA44"},"7E":{"t":"BE10"},"80":{"t":"L8"},"81":{"t":"BE24"},"82":{"t":"J3"},"83":{"t":"P28A"},"85":{"t":"P28U"},"86":{"t":"T210"},"87":{"t":"PA32"},"88":{"t":"C82R"},"8A":{"t":"C140"},"8B":{"t":"ULAC"},"8C":{"t":"C337"},"8E":{"t":"P28B"},"8F":{"t":"C150"},"90":{"t":"C150"},"91":{"t":"C150"},"92":{"t":"C150"},"93":{"t":"C150"},"94":{"t":"C150"},"95":{"t":"TAYB"},"96":{"t":"TAYB"},"97":{"t":"TAYB"},"98":{"desc":"L1P"},"99":{"desc":"L1P"},"9A":{"t":"PA22"},"9B":{"t":"C206"},"9C":{"t":"C180"},"9D":{"t":"P28A"},"9E":{"t":"CH7A"},"9F":{"t":"P28A"},"A0":{"t":"C182"},"A1":{"desc":"L1P"},"A2":{"desc":"L1P"},"A3":{"desc":"H1P"},"A4":{"t":"BT36"},"A5":{"t":"J3"},"A6":{"t":"P28A"},"A7":{"t":"PA23"},"A8":{"t":"C172"},"A9":{"t":"T210"},"AA":{"t":"C210"},"AB":{"t":"P28R"},"AC":{"desc":"H1P"},"AD":{"t":"C140"},"AE":{"t":"BALL"},"AF":{"t":"P28A"},"B0":{"t":"C177"},"B1":{"t":"P28A"},"B2":{"t":"C150"},"B3":{"t":"P28R"},"B4":{"t":"PA32"},"B5":{"t":"C150"},"B6":{"t":"C150"},"B7":{"t":"C172"},"B8":{"t":"P28A"},"B9":{"t":"P32T"},"BA":{"t":"TAYB"},"BC":{"desc":"L1P","t":"ULAC"},"BE":{"desc":"H1P"},"BF":{"t":"PA18"},"C0":{"t":"P28A"},"C1":{"t":"CH7A"},"C2":{"t":"C182"},"C3":{"desc":"H4E"},"C4":{"t":"PA44"},"C5":{"t":"PA32"},"C6":{"t":"L8"},"C7":{"t":"H500"},"C8":{"t":"J3"},"C9":{"t":"C140"},"CA":{"t":"ULAC"},"CB":{"t":"C421"},"CC":{"t":"P28A"},"CD":{"desc":"L1P"},"CE":{"t":"C185"},"D0":{"t":"C140"},"D1":{"t":"PA34"},"D2":{"t":"P28A"},"D3":{"t":"C177"},"D4":{"t":"P28A"},"D5":{"t":"TAYB"},"D6":{"t":"C172"},"D7":{"t":"TAYB"},"D8":{"desc":"L1P"},"D9":{"t":"C150"},"DA":{"t":"C150"},"DB":{"t":"C150"},"DC":{"t":"C150"},"DD":{"t":"C150"},"DE":{"t":"C182"},"DF":{"desc":"A1P"},"E0":{"t":"PA22"},"E1":{"t":"P32T"},"E2":{"t":"C180"},"E3":{"t":"M20P"},"E4":{"t":"C172"},"E5":{"t":"C310"},"E6":{"t":"C182"},"E8":{"t":"C150"},"E9":{"t":"M20P"},"EA":{"t":"C172"},"EB":{"t":"J3"},"ED":{"t":"PA23"},"EF":{"t":"T210"},"F0":{"t":"C210"},"F1":{"t":"C182"},"F2":{"t":"PA34"},"F3":{"t":"C140"},"F5":{"t":"C337"},"F6":{"desc":"L1P"},"F7":{"t":"P28A"},"F8":{"t":"C150"},"F9":{"desc":"L1P"},"FA":{"t":"TAYB"},"FC":{"t":"C150"},"FD":{"t":"C150"},"FE":{"t":"C182"},"FF":{"t":"TAYB"}}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show more