427 changes: 107 additions & 320 deletions src/FileIO/FitRideFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "RideItem.h"
#include "Specification.h"
#include "DataProcessor.h"
#include "MainWindow.h" // for gcroot
#include <QSharedPointer>
#include <QMap>
#include <QSet>
Expand Down Expand Up @@ -54,6 +55,87 @@
#define HRV_MSG_NUM 78
#define SEGMENT_MSG_NUM 142

// Fit types metadata
struct prod { int manu, prod; QString name; };
struct manu { int manu; QString name; };

// arrays of manu and prod
QList<prod> FITproducts;
QList<manu> FITmanufacturers;

// load the FITmetadata file, called the first time a FIT file
// is parsed, so may not ever be called by the user
bool loaded=false;
static void loadMetadata()
{
// only do it the first time
if (loaded) return;
loaded=true;

// get locally cached version- or fall back to baked in version
// XXX todo retrieve from website (www.../defaults/3.6/FITmetadata.json)
QString filename = QDir(gcroot).canonicalPath()+"/FITmetadata.json";
if (!QFile(filename).exists()) filename = ":/json/FITmetadata.json";

// read the file
QFile file(filename);
QString content;
if (file.open(QIODevice::ReadOnly)) {
content = file.readAll();
file.close();
} else return;

// parse the content
QJsonDocument metajson = QJsonDocument::fromJson(content.toUtf8());
if (metajson.isEmpty() || metajson.isNull()) goto badconfig;
else {

// lets setup the structures
QJsonObject root = metajson.object();

if (!root.contains("PRODUCTS")) goto badconfig;
QJsonObject products = root["PRODUCTS"].toObject();
QJsonArray PRODUCTS = root["PRODUCTS"].toArray();
foreach(const QJsonValue val, PRODUCTS) {

// convert so we can inspect
QJsonObject obj = val.toObject();

prod add;

add.name = obj["name"].toString();
add.prod = obj["prod"].toInt();
add.manu = obj["manu"].toInt();

FITproducts << add;
//fprintf(stderr, "FITprod: %d:%d %s\n", add.manu, add.prod, add.name.toStdString().c_str()); fflush(stderr);
}

if (!root.contains("MANUFACTURERS")) goto badconfig;
QJsonObject manufacturers = root["MANUFACTURERS"].toObject();
QJsonArray MANUFACTURERS = root["MANUFACTURERS"].toArray();
foreach(const QJsonValue val, MANUFACTURERS) {

// convert so we can inspect
QJsonObject obj = val.toObject();

manu add;

add.name = obj["name"].toString();
add.manu = obj["manu"].toInt();

FITmanufacturers << add;
//fprintf(stderr, "FITmanu: %d %s\n", add.manu, add.name.toStdString().c_str()); fflush(stderr);
}

return;
}

badconfig:
fprintf(stderr, "FITRideFile: FITmetadata.json parse error\n");
return;
}

static int fitFileReaderRegistered =
RideFileFactory::instance().registerReader(
"fit", "Garmin FIT", new FitFileReader());
Expand Down Expand Up @@ -352,330 +434,32 @@ struct FitFileReaderState
}
}

// return a name for the manufacturer, product combintion
// uses the config from FITmetadata.json initialised above
QString getManuProd(int manu, int prod) {
if (manu == 1) {
// Garmin
// Product IDs can be found in c/fit_example.h in the FIT SDK.
// Multiple product IDs refer to different regions e.g. China, Japan etc.
switch (prod) {
case -1: return "Garmin";
case 16: case 20: return "Garmin Cadence Sensor 2";
case 473: case 474: case 475: case 494: return "Garmin FR301";
case 717: case 987: return "Garmin FR405";
case 782: return "Garmin FR50";
case 988: return "Garmin FR60";
case 1018: return "Garmin FR310XT";
case 1036: case 1199: case 1213: case 1387: return "Garmin Edge 500";
case 1124: case 1274: return "Garmin FR110";
case 1169: case 1333: case 1334: case 1386: return "Garmin Edge 800";
case 1325: return "Garmin Edge 200";
case 1328: return "Garmin FR910XT";
case 1345: case 1410: return "Garmin FR610";
case 1360: return "Garmin FR210";
case 1436: return "Garmin FR70";
case 1446: return "Garmin FR310XT 4T";
case 1482: case 1688: return "Garmin FR10";
case 1499: return "Garmin Swim";
case 1551: return "Garmin Fenix";
case 1561: case 1742: case 1821: return "Garmin Edge 510";
case 1567: return "Garmin Edge 810";
case 1623: case 2173: return "Garmin FR620";
case 1632: case 2174: return "Garmin FR220";
case 1743: return "Garmin HRM-Tri";
case 1752: return "Garmin HRM-Run";
case 1765: case 2130: case 2131: case 2132: return "Garmin FR920XT";
case 1836: case 2052: case 2053: case 2070: case 2100: return "Garmin Edge 1000";
case 1903: return "Garmin FR15";
case 1907: return "Garmin Vivoactive";
case 1967: return "Garmin Fenix 2";
case 2050: case 2188: case 2189: return "Garmin Fenix 3";
case 2067: case 2260: return "Garmin Edge 520";
case 2147: return "Garmin Edge 25";
case 2148: return "Garmin FR25";
case 2153: case 2219: return "Garmin FR225";
case 2156: return "Garmin FR630";
case 2157: return "Garmin FR230";
case 2158: return "Garmin FR735XT";
case 2204: return "Garmin Edge 1000 Explore";
case 2327: return "Garmin HRM4 Run";
case 2238: return "Garmin Edge 20";
case 2337: return "Garmin Vivoactive HR";
case 2347: return "Garmin Vivosmart HR+";
case 2348: return "Garmin Vivosmart HR";
case 2413: return "Garmin Fenix 3 HR";
case 2431: return "Garmin FR235";
case 2530: return "Garmin Edge 820";
case 2531: return "Garmin Edge 820 Explore";
case 2544: return "Garmin Fenix 5s";
case 2604: return "Garmin Fenix 5x";
case 2691: return "Garmin FR935";
case 2697: return "Garmin Fenix 5";
case 2713: return "Garmin Edge 1030";
case 2787: return "Garmin Vector 3";
case 2886: case 2888: return "Garmin FR645";
case 2900: return "Garmin Fenix 5s +";
case 2909: case 3092: return "Garmin Edge 130";
case 3028: return "Garmin GPSMap 66";
case 3110: return "Garmin Fenix 5 +";
case 3111: return "Garmin Fenix 5x +";
case 3112: return "Garmin Edge 520 +";
case 3113: return "Garmin FR945";
case 3121: return "Garmin Edge 530";
case 3122: return "Garmin Edge 830";
case 3126: return "Garmin Instinct";
case 3192: return "Garmin Speed Sensor 2";
case 3287: case 3288: case 3512: case 3513: return "Garmin Fenix 6s";
case 3289: case 3290: case 3514: case 3515: return "Garmin Fenix 6";
case 3291: case 3516: return "Garmin Fenix 6x";
case 3299: return "Garmin HRM-Dual";
case 3300: return "Garmin HRM-Pro";
case 3405: case 3639: return "Garmin Swim 2";
case 3558: return "Garmin Edge 130 Plus";
case 3570: return "Garmin Edge 1030 Plus";
case 3578: return "Garmin Rally 100/200";
case 3589: return "Garmin FR745";
case 3592: return "Garmin Varia RTL515";
case 3843: return "Garmin Edge 1040 Solar";
case 3905: case 3908: return "Garmin Fenix 7s";
case 3906: case 3909: return "Garmin Fenix 7";
case 3907: case 3910: return "Garmin Fenix 7x";
case 3990 : return "Garmin FR255";
case 4024 : return "Garmin FR955";
case 20119: return "Garmin Training Center";
case 65532: return "Android ANT+ Plugin";
case 65534: return "Garmin Connect Website";
default: return QString("Garmin %1").arg(prod);
}
} else if (manu == 6 ) {
// SRM
// powercontrol now uses FIT files from PC8
switch (prod) {
case -1: return "SRM";
case 6: return "SRM PC6";
case 7: return "SRM PC7";
case 8: return "SRM PC8";
default: return "SRM Powercontrol";
}
} else if (manu == 7 ) {
// Quarq
switch (prod) {
case -1: return "Quarq";
case 1: return "Quarq Cinqo";
case 9479: return "Quarq DZERO";
default: return QString("Quarq %1").arg(prod);
}
} else if (manu == 8 ) {
// iBike
switch (prod) {
case -1: return "iBike";
case 2054: return "iBike AeroPod";
default: return QString("iBike %1").arg(prod);
}
} else if (manu == 9 ) {
// Powertap
switch (prod) {
case -1: return "Powertap";
case 14: return "Joule 2.0";
case 18: return "Joule";
case 19: return "Joule GPS";
case 22: return "Joule GPS+";
case 272: return "Powertap C1";
case 288: return "Powertap P1";
case 4096: return "Powertap G3";
case 4353: return "Powercal";

default: return QString("Powertap Device %1").arg(prod);
}
} else if (manu == 13 ) {
// dynastream_oem
switch (prod) {
case -1: return "Dynastream";
default: return QString("Dynastream %1").arg(prod);
}
} else if (manu == 29 ) {
// saxonar
switch (prod) {
case -1: return "Power2max";
case 1031: return "Power2max S";
default: return QString("Power2max %1").arg(prod);
}
} else if (manu == 32) {
// wahoo
switch (prod) {
case -1: return "Wahoo";
case 0: return "Wahoo fitness";
case 28: return "Wahoo ELEMNT";
case 31: return "Wahoo ELEMNT BOLT";
default: return QString("Wahoo fitness %1").arg(prod);
}
} else if (manu == 38) {
// o_synce
switch (prod) {
case -1: return "o_synce";
case 1: return "o_synce navi2coach";
default: return QString("o_synce %1").arg(prod);
}
} else if (manu == 48) {
// Pioneer
switch (prod) {
case -1: return "Pioneer";
case 2: return "Pioneer SGX-CA500";
default: return QString("Pioneer %1").arg(prod);
}
} else if (manu == 54) {
// ifor_powell
switch (prod) {
case -1: return "Ifor powell";
case 1: return "IpBike";
default: return QString("Ifor powell %1").arg(prod);

QString returning;

// is it a known or defaulted product?
foreach(struct prod x, FITproducts) {

if (x.manu == manu && x.prod == prod) {
// garmin devices special case (could also fix in FITmetadata.json)
// we have been inconsistent on this in the past e.g. Powertap, not SARIS Powertap
if (manu == 1) return QString("Garmin %1").arg(x.name);
else return x.name;
}
if (x.manu == manu && x.prod == -1) returning = x.name;
}
else if (manu == 69) {
// Stages Cycling
switch (prod) {
case -1: return "Stages Cycling";
case 1: return "Stages Power Gen 1";
case 2: return "Stages Power Gen 2";
case 3: return "Stages Power Gen 3";
default: return QString("Stages Cycling %1").arg(prod);
}
} else if (manu == 70) {
// SIGMA SPORT Germany
switch (prod) {
case 15: return "SIGMA ROX 10.0";
case 18: return "SIGMA ROX 7.0";
case 41: return "SIGMA ROX 11.0";
case 42: return "SIGMA iD.RUN";
case 43: return "SIGMA iD.RUN HR";
case 44: return "SIGMA ROX 12.0";
case 45: return "SIGMA iD.FREE";
case 46: return "SIGMA iD.TRI";
case 47: return "SIGMA PURE GPS";
case 49: return "SIGMA ROX 11.1";
case 51: return "SIGMA ROX 2.0";
case 52: return "SIGMA ROX 4.0";
default: return QString("SIGMA SPORT %1").arg(prod);
}
} else if (manu == 76) {
// Moxy
return "Moxy Monitor";
} else if (manu == 83) {
// Scosche
switch (prod) {
case -1: return "Scosche";
case 3: return "Scosche Rythm+";
default: return QString("Scosche %1").arg(prod);
}
} else if (manu == 89) {
// Tacx
switch (prod) {
case 2800: return "Tacx Neo";
case 2850: return "Tacx Neo 2 Smart";
default: return QString("Tacx %1").arg(prod);
}
} else if (manu == 95) {
// Stryd
return "Stryd";
} else if (manu == 98) {
// BSX
switch(prod) {
case -1: return "BSX";
case 2: return "BSX Insight 2";
default: return QString("BSX %1").arg(prod);
}
} else if (manu == 107) {
// Magene
switch(prod) {
case -1: return "Magene";
default: return QString("Magene %1").arg(prod);
}
} else if (manu == 108) {
// Giant
switch(prod) {
case -1: return "Giant";
case 21845 : return "Giant Power Pro";
default: return QString("Giant %1").arg(prod);
}
} else if (manu == 115) {
// igpsport
switch(prod) {
case -1: return "iGPSPORT";
default: return QString("iGPSPORT %1").arg(prod);
}
} else if (manu == 116) {
// thinkrider
switch(prod) {
case -1: return "Thinkrider";
default: return QString("Thinkrider %1").arg(prod);
}
} else if (manu == 123) {
// Polar
switch(prod) {
case 2: return "Polar H10";
case 3: return "Polar H9";
case -1: return "Polar";
default: return QString("Polar %1").arg(prod);
}
} else if (manu == 132) {
// cycplus
switch(prod) {
case -1: return "Cycplus";
default: return QString("Cycplus %1").arg(prod);
}
} else if (manu == 258) {
// Lezyne
switch (prod) {
case -1: return "Lezyne";
case 4: return "Lezyne Super GPS";
case 6: return "Lezyne Micro-GPS";
case 11: return "Lezyne MegaXL";
default: return QString("Lezyne %1").arg(prod);
}
} else if (manu == 260) {
// Zwift
return "Zwift";
} else if (manu == 263) {
// Favero
switch (prod) {
case -1: return "Favero";
case 12: return "Favero Assioma Duo";
default: return QString("Favero %1").arg(prod);
}
} else if (manu == 267) {
// Bryton
return "Bryton";
} else if (manu == 268) {
// SRAM
switch (prod) {
case -1: return "SRAM";
case 1037: return "SRAM Rival eTap AXS";
case 1052: return "SRAM Rival AXS";
default: return QString("SRAM %1").arg(prod);
}
} else if (manu == 282) {
// Sufferfest
return "The Sufferfest";
} else if (manu == 284) {
// Rouvy
return "Rouvy";
} else if (manu == 289) {
// Hammerhead
// currently not setting product ids
switch (prod) {
case -1: return "Hammerhead";
default: return QString("Hammerhead %1").arg(prod);
}
} else if (manu == 255) {
// Development
switch (prod) {
case -1: return "Development";
case 0: return "Development";
default: return QString("Development %1").arg(prod);
}
} else {
QString name = "Unknown FIT Device";
return name + QString(" %1:%2").arg(manu).arg(prod);
if (returning != "") return returning;

// ok, then lets just return manufacturer and prod number
foreach(struct manu x, FITmanufacturers) {
if (x.manu == manu) return QString ("%1 Device (%2)").arg(x.name).arg(prod);
}

// don't even recognise the manufacturer!
return QString("Unknown FIT Device %1:%2").arg(manu).arg(prod);
}

QString getDeviceType(int device_type) {
Expand Down Expand Up @@ -3748,6 +3532,9 @@ struct FitFileReaderState

RideFile *FitFileReader::openRideFile(QFile &file, QStringList &errors, QList<RideFile*> *rides) const
{
// prepare the metadata first
loadMetadata();

QSharedPointer<FitFileReaderState> state(new FitFileReaderState(file, errors));
RideFile* ret = state->run();
// Split sessions, only if we have a valid RideFile
Expand Down
1 change: 1 addition & 0 deletions src/Resources/application.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@
<file>translations/gc_zh-tw.qm</file>
<file>translations/gc_nl.qm</file>
<file>translations/gc_sv.qm</file>
<file>json/FITmetadata.json</file>
<file>xml/charts.xml</file>
<file>xml/metadata.xml</file>
<file>xml/train-perspectives.xml</file>
Expand Down
666 changes: 666 additions & 0 deletions src/Resources/json/FITmetadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,666 @@
{
"VERSION":1659206075,
"PRODUCTS":[
{ "manu":6, "prod":6, "name":"SRM PC6" },
{ "manu":6, "prod":7, "name":"SRM PC7" },
{ "manu":6, "prod":8, "name":"SRM PC8" },
{ "manu":6, "prod":-1, "name":"SRM Powercontrol" },
{ "manu":7, "prod":1, "name":"Quarq Cinqo" },
{ "manu":7, "prod":9479, "name":"Quarq DZERO" },
{ "manu":8, "prod":2054, "name":"iBike AeroPod" },
{ "manu":9, "prod":-1, "name":"Powertap" },
{ "manu":9, "prod":14, "name":"Joule 2.0" },
{ "manu":9, "prod":18, "name":"Joule" },
{ "manu":9, "prod":19, "name":"Joule GPS" },
{ "manu":9, "prod":22, "name":"Joule GPS+" },
{ "manu":9, "prod":272, "name":"Powertap C1" },
{ "manu":9, "prod":288, "name":"Powertap P1" },
{ "manu":9, "prod":4096, "name":"Powertap G3" },
{ "manu":9, "prod":4353, "name":"Powercal" },
{ "manu":29, "prod":1031, "name":"Power2max S" },
{ "manu":32, "prod":0, "name":"Wahoo fitness" },
{ "manu":32, "prod":28, "name":"Wahoo ELEMNT" },
{ "manu":32, "prod":31, "name":"Wahoo ELEMNT BOLT" },
{ "manu":38, "prod":1, "name":"o_synce navi2coach" },
{ "manu":48, "prod":2, "name":"Pioneer SGX-CA500" },
{ "manu":54, "prod":1, "name":"IpBike" },
{ "manu":69, "prod":1, "name":"Stages Power Gen 1" },
{ "manu":69, "prod":2, "name":"Stages Power Gen 2" },
{ "manu":69, "prod":3, "name":"Stages Power Gen 3" },
{ "manu":70, "prod":15, "name":"SIGMA ROX 10.0" },
{ "manu":70, "prod":18, "name":"SIGMA ROX 7.0" },
{ "manu":70, "prod":41, "name":"SIGMA ROX 11.0" },
{ "manu":70, "prod":42, "name":"SIGMA iD.RUN" },
{ "manu":70, "prod":43, "name":"SIGMA iD.RUN HR" },
{ "manu":70, "prod":44, "name":"SIGMA ROX 12.0" },
{ "manu":70, "prod":45, "name":"SIGMA iD.FREE" },
{ "manu":70, "prod":46, "name":"SIGMA iD.TRI" },
{ "manu":70, "prod":47, "name":"SIGMA PURE GPS" },
{ "manu":70, "prod":49, "name":"SIGMA ROX 11.1" },
{ "manu":70, "prod":51, "name":"SIGMA ROX 2.0" },
{ "manu":70, "prod":52, "name":"SIGMA ROX 4.0" },
{ "manu":76, "prod":-1, "name":"Moxy Monitor" },
{ "manu":83, "prod":3, "name":"Scosche Rythm+" },
{ "manu":89, "prod":2800, "name":"Tacx Neo" },
{ "manu":89, "prod":2850, "name":"Tacx Neo 2 Smart" },
{ "manu":95, "prod":-1, "name":"Stryd" },
{ "manu":98, "prod":-1, "name":"BSX" },
{ "manu":98, "prod":2, "name":"BSX Insight 2" },
{ "manu":107, "prod":-1, "name":"Magene" },
{ "manu":108, "prod":-1, "name":"Giant" },
{ "manu":108, "prod":21845, "name":"Giant Power Pro" },
{ "manu":115, "prod":-1, "name":"iGPSPORT" },
{ "manu":116, "prod":-1, "name":"Thinkrider" },
{ "manu":123, "prod":2, "name":"Polar H10" },
{ "manu":123, "prod":3, "name":"Polar H9" },
{ "manu":123, "prod":-1, "name":"Polar" },
{ "manu":132, "prod":-1, "name":"Cycplus" },
{ "manu":258, "prod":-1, "name":"Lezyne" },
{ "manu":258, "prod":4, "name":"Lezyne Super GPS" },
{ "manu":258, "prod":6, "name":"Lezyne Micro-GPS" },
{ "manu":258, "prod":11, "name":"Lezyne MegaXL" },
{ "manu":260, "prod":-1, "name":"Zwift" },
{ "manu":263, "prod":-1, "name":"Favero" },
{ "manu":263, "prod":12, "name":"Favero Assioma Duo" },
{ "manu":267, "prod":-1, "name":"Bryton" },
{ "manu":268, "prod":-1, "name":"SRAM" },
{ "manu":268, "prod":1037, "name":"SRAM Rival eTap AXS" },
{ "manu":268, "prod":1052, "name":"SRAM Rival AXS" },
{ "manu":282, "prod":-1, "name":"The Sufferfest" },
{ "manu":284, "prod":-1, "name":"Rouvy" },
{ "manu":289, "prod":-1, "name":"Hammerhead" },
{ "manu":255, "prod":-1, "name":"Development" },
{ "manu":1, "prod":1, "name":"Hrm1" },
{ "manu":1, "prod":2, "name":"Axh01" },
{ "manu":1, "prod":3, "name":"Axb01" },
{ "manu":1, "prod":4, "name":"Axb02" },
{ "manu":1, "prod":5, "name":"Hrm2Ss" },
{ "manu":1, "prod":6, "name":"Dsi Alf02" },
{ "manu":1, "prod":7, "name":"Hrm3Ss" },
{ "manu":1, "prod":8, "name":"Hrm Run Single Byte Product Id" },
{ "manu":1, "prod":9, "name":"Bsm" },
{ "manu":1, "prod":10, "name":"Bcm" },
{ "manu":1, "prod":11, "name":"Axs01" },
{ "manu":1, "prod":12, "name":"Hrm Tri Single Byte Product Id" },
{ "manu":1, "prod":13, "name":"Hrm4 Run Single Byte Product Id" },
{ "manu":1, "prod":14, "name":"Fr225 Single Byte Product Id" },
{ "manu":1, "prod":15, "name":"Gen3 Bsm Single Byte Product Id" },
{ "manu":1, "prod":16, "name":"Gen3 Bcm Single Byte Product Id" },
{ "manu":1, "prod":255, "name":"Ohr" },
{ "manu":1, "prod":473, "name":"Fr301 China" },
{ "manu":1, "prod":474, "name":"Fr301 Japan" },
{ "manu":1, "prod":475, "name":"Fr301 Korea" },
{ "manu":1, "prod":494, "name":"Fr301 Taiwan" },
{ "manu":1, "prod":717, "name":"Fr405" },
{ "manu":1, "prod":782, "name":"Fr50" },
{ "manu":1, "prod":987, "name":"Fr405 Japan" },
{ "manu":1, "prod":988, "name":"Fr60" },
{ "manu":1, "prod":1011, "name":"Dsi Alf01" },
{ "manu":1, "prod":1018, "name":"Fr310Xt" },
{ "manu":1, "prod":1036, "name":"Edge500" },
{ "manu":1, "prod":1124, "name":"Fr110" },
{ "manu":1, "prod":1169, "name":"Edge800" },
{ "manu":1, "prod":1199, "name":"Edge500 Taiwan" },
{ "manu":1, "prod":1213, "name":"Edge500 Japan" },
{ "manu":1, "prod":1253, "name":"Chirp" },
{ "manu":1, "prod":1274, "name":"Fr110 Japan" },
{ "manu":1, "prod":1325, "name":"Edge200" },
{ "manu":1, "prod":1328, "name":"Fr910Xt" },
{ "manu":1, "prod":1333, "name":"Edge800 Taiwan" },
{ "manu":1, "prod":1334, "name":"Edge800 Japan" },
{ "manu":1, "prod":1341, "name":"Alf04" },
{ "manu":1, "prod":1345, "name":"Fr610" },
{ "manu":1, "prod":1360, "name":"Fr210 Japan" },
{ "manu":1, "prod":1380, "name":"Vector Ss" },
{ "manu":1, "prod":1381, "name":"Vector Cp" },
{ "manu":1, "prod":1386, "name":"Edge800 China" },
{ "manu":1, "prod":1387, "name":"Edge500 China" },
{ "manu":1, "prod":1405, "name":"Approach G10" },
{ "manu":1, "prod":1410, "name":"Fr610 Japan" },
{ "manu":1, "prod":1422, "name":"Edge500 Korea" },
{ "manu":1, "prod":1436, "name":"Fr70" },
{ "manu":1, "prod":1446, "name":"Fr310Xt 4T" },
{ "manu":1, "prod":1461, "name":"Amx" },
{ "manu":1, "prod":1482, "name":"Fr10" },
{ "manu":1, "prod":1497, "name":"Edge800 Korea" },
{ "manu":1, "prod":1499, "name":"Swim" },
{ "manu":1, "prod":1537, "name":"Fr910Xt China" },
{ "manu":1, "prod":1551, "name":"Fenix" },
{ "manu":1, "prod":1555, "name":"Edge200 Taiwan" },
{ "manu":1, "prod":1561, "name":"Edge510" },
{ "manu":1, "prod":1567, "name":"Edge810" },
{ "manu":1, "prod":1570, "name":"Tempe" },
{ "manu":1, "prod":1600, "name":"Fr910Xt Japan" },
{ "manu":1, "prod":1623, "name":"Fr620" },
{ "manu":1, "prod":1632, "name":"Fr220" },
{ "manu":1, "prod":1664, "name":"Fr910Xt Korea" },
{ "manu":1, "prod":1688, "name":"Fr10 Japan" },
{ "manu":1, "prod":1721, "name":"Edge810 Japan" },
{ "manu":1, "prod":1735, "name":"Virb Elite" },
{ "manu":1, "prod":1736, "name":"Edge Touring" },
{ "manu":1, "prod":1742, "name":"Edge510 Japan" },
{ "manu":1, "prod":1743, "name":"Hrm Tri" },
{ "manu":1, "prod":1752, "name":"Hrm Run" },
{ "manu":1, "prod":1765, "name":"Fr920Xt" },
{ "manu":1, "prod":1821, "name":"Edge510 Asia" },
{ "manu":1, "prod":1822, "name":"Edge810 China" },
{ "manu":1, "prod":1823, "name":"Edge810 Taiwan" },
{ "manu":1, "prod":1836, "name":"Edge1000" },
{ "manu":1, "prod":1837, "name":"Vivo Fit" },
{ "manu":1, "prod":1853, "name":"Virb Remote" },
{ "manu":1, "prod":1885, "name":"Vivo Ki" },
{ "manu":1, "prod":1903, "name":"Fr15" },
{ "manu":1, "prod":1907, "name":"Vivo Active" },
{ "manu":1, "prod":1918, "name":"Edge510 Korea" },
{ "manu":1, "prod":1928, "name":"Fr620 Japan" },
{ "manu":1, "prod":1929, "name":"Fr620 China" },
{ "manu":1, "prod":1930, "name":"Fr220 Japan" },
{ "manu":1, "prod":1931, "name":"Fr220 China" },
{ "manu":1, "prod":1936, "name":"Approach S6" },
{ "manu":1, "prod":1956, "name":"Vivo Smart" },
{ "manu":1, "prod":1967, "name":"Fenix2" },
{ "manu":1, "prod":1988, "name":"Epix" },
{ "manu":1, "prod":2050, "name":"Fenix3" },
{ "manu":1, "prod":2052, "name":"Edge1000 Taiwan" },
{ "manu":1, "prod":2053, "name":"Edge1000 Japan" },
{ "manu":1, "prod":2061, "name":"Fr15 Japan" },
{ "manu":1, "prod":2067, "name":"Edge520" },
{ "manu":1, "prod":2070, "name":"Edge1000 China" },
{ "manu":1, "prod":2072, "name":"Fr620 Russia" },
{ "manu":1, "prod":2073, "name":"Fr220 Russia" },
{ "manu":1, "prod":2079, "name":"Vector S" },
{ "manu":1, "prod":2100, "name":"Edge1000 Korea" },
{ "manu":1, "prod":2130, "name":"Fr920Xt Taiwan" },
{ "manu":1, "prod":2131, "name":"Fr920Xt China" },
{ "manu":1, "prod":2132, "name":"Fr920Xt Japan" },
{ "manu":1, "prod":2134, "name":"Virbx" },
{ "manu":1, "prod":2135, "name":"Vivo Smart Apac" },
{ "manu":1, "prod":2140, "name":"Etrex Touch" },
{ "manu":1, "prod":2147, "name":"Edge25" },
{ "manu":1, "prod":2148, "name":"Fr25" },
{ "manu":1, "prod":2150, "name":"Vivo Fit2" },
{ "manu":1, "prod":2153, "name":"Fr225" },
{ "manu":1, "prod":2156, "name":"Fr630" },
{ "manu":1, "prod":2157, "name":"Fr230" },
{ "manu":1, "prod":2158, "name":"Fr735Xt" },
{ "manu":1, "prod":2160, "name":"Vivo Active Apac" },
{ "manu":1, "prod":2161, "name":"Vector 2" },
{ "manu":1, "prod":2162, "name":"Vector 2S" },
{ "manu":1, "prod":2172, "name":"Virbxe" },
{ "manu":1, "prod":2173, "name":"Fr620 Taiwan" },
{ "manu":1, "prod":2174, "name":"Fr220 Taiwan" },
{ "manu":1, "prod":2175, "name":"Truswing" },
{ "manu":1, "prod":2187, "name":"D2Airvenu" },
{ "manu":1, "prod":2188, "name":"Fenix3 China" },
{ "manu":1, "prod":2189, "name":"Fenix3 Twn" },
{ "manu":1, "prod":2192, "name":"Varia Headlight" },
{ "manu":1, "prod":2193, "name":"Varia Taillight Old" },
{ "manu":1, "prod":2204, "name":"Edge Explore 1000" },
{ "manu":1, "prod":2219, "name":"Fr225 Asia" },
{ "manu":1, "prod":2225, "name":"Varia Radar Taillight" },
{ "manu":1, "prod":2226, "name":"Varia Radar Display" },
{ "manu":1, "prod":2238, "name":"Edge20" },
{ "manu":1, "prod":2260, "name":"Edge520 Asia" },
{ "manu":1, "prod":2261, "name":"Edge520 Japan" },
{ "manu":1, "prod":2262, "name":"D2 Bravo" },
{ "manu":1, "prod":2266, "name":"Approach S20" },
{ "manu":1, "prod":2271, "name":"Vivo Smart2" },
{ "manu":1, "prod":2274, "name":"Edge1000 Thai" },
{ "manu":1, "prod":2276, "name":"Varia Remote" },
{ "manu":1, "prod":2288, "name":"Edge25 Asia" },
{ "manu":1, "prod":2289, "name":"Edge25 Jpn" },
{ "manu":1, "prod":2290, "name":"Edge20 Asia" },
{ "manu":1, "prod":2292, "name":"Approach X40" },
{ "manu":1, "prod":2293, "name":"Fenix3 Japan" },
{ "manu":1, "prod":2294, "name":"Vivo Smart Emea" },
{ "manu":1, "prod":2310, "name":"Fr630 Asia" },
{ "manu":1, "prod":2311, "name":"Fr630 Jpn" },
{ "manu":1, "prod":2313, "name":"Fr230 Jpn" },
{ "manu":1, "prod":2327, "name":"Hrm4 Run" },
{ "manu":1, "prod":2332, "name":"Epix Japan" },
{ "manu":1, "prod":2337, "name":"Vivo Active Hr" },
{ "manu":1, "prod":2347, "name":"Vivo Smart Gps Hr" },
{ "manu":1, "prod":2348, "name":"Vivo Smart Hr" },
{ "manu":1, "prod":2361, "name":"Vivo Smart Hr Asia" },
{ "manu":1, "prod":2362, "name":"Vivo Smart Gps Hr Asia" },
{ "manu":1, "prod":2368, "name":"Vivo Move" },
{ "manu":1, "prod":2379, "name":"Varia Taillight" },
{ "manu":1, "prod":2396, "name":"Fr235 Asia" },
{ "manu":1, "prod":2397, "name":"Fr235 Japan" },
{ "manu":1, "prod":2398, "name":"Varia Vision" },
{ "manu":1, "prod":2406, "name":"Vivo Fit3" },
{ "manu":1, "prod":2407, "name":"Fenix3 Korea" },
{ "manu":1, "prod":2408, "name":"Fenix3 Sea" },
{ "manu":1, "prod":2413, "name":"Fenix3 Hr" },
{ "manu":1, "prod":2417, "name":"Virb Ultra 30" },
{ "manu":1, "prod":2429, "name":"Index Smart Scale" },
{ "manu":1, "prod":2431, "name":"Fr235" },
{ "manu":1, "prod":2432, "name":"Fenix3 Chronos" },
{ "manu":1, "prod":2441, "name":"Oregon7Xx" },
{ "manu":1, "prod":2444, "name":"Rino7Xx" },
{ "manu":1, "prod":2457, "name":"Epix Korea" },
{ "manu":1, "prod":2473, "name":"Fenix3 Hr Chn" },
{ "manu":1, "prod":2474, "name":"Fenix3 Hr Twn" },
{ "manu":1, "prod":2475, "name":"Fenix3 Hr Jpn" },
{ "manu":1, "prod":2476, "name":"Fenix3 Hr Sea" },
{ "manu":1, "prod":2477, "name":"Fenix3 Hr Kor" },
{ "manu":1, "prod":2496, "name":"Nautix" },
{ "manu":1, "prod":2497, "name":"Vivo Active Hr Apac" },
{ "manu":1, "prod":2512, "name":"Oregon7Xx Ww" },
{ "manu":1, "prod":2530, "name":"Edge 820" },
{ "manu":1, "prod":2531, "name":"Edge Explore 820" },
{ "manu":1, "prod":2533, "name":"Fr735Xt Apac" },
{ "manu":1, "prod":2534, "name":"Fr735Xt Japan" },
{ "manu":1, "prod":2544, "name":"Fenix5S" },
{ "manu":1, "prod":2547, "name":"D2 Bravo Titanium" },
{ "manu":1, "prod":2567, "name":"Varia Ut800" },
{ "manu":1, "prod":2593, "name":"Running Dynamics Pod" },
{ "manu":1, "prod":2599, "name":"Edge 820 China" },
{ "manu":1, "prod":2600, "name":"Edge 820 Japan" },
{ "manu":1, "prod":2604, "name":"Fenix5X" },
{ "manu":1, "prod":2606, "name":"Vivo Fit Jr" },
{ "manu":1, "prod":2622, "name":"Vivo Smart3" },
{ "manu":1, "prod":2623, "name":"Vivo Sport" },
{ "manu":1, "prod":2628, "name":"Edge 820 Taiwan" },
{ "manu":1, "prod":2629, "name":"Edge 820 Korea" },
{ "manu":1, "prod":2630, "name":"Edge 820 Sea" },
{ "manu":1, "prod":2650, "name":"Fr35 Hebrew" },
{ "manu":1, "prod":2656, "name":"Approach S60" },
{ "manu":1, "prod":2667, "name":"Fr35 Apac" },
{ "manu":1, "prod":2668, "name":"Fr35 Japan" },
{ "manu":1, "prod":2675, "name":"Fenix3 Chronos Asia" },
{ "manu":1, "prod":2687, "name":"Virb 360" },
{ "manu":1, "prod":2691, "name":"Fr935" },
{ "manu":1, "prod":2697, "name":"Fenix5" },
{ "manu":1, "prod":2700, "name":"Vivoactive3" },
{ "manu":1, "prod":2733, "name":"Fr235 China Nfc" },
{ "manu":1, "prod":2769, "name":"Foretrex 601 701" },
{ "manu":1, "prod":2772, "name":"Vivo Move Hr" },
{ "manu":1, "prod":2713, "name":"Edge 1030" },
{ "manu":1, "prod":2787, "name":"Vector 3" },
{ "manu":1, "prod":2796, "name":"Fenix5 Asia" },
{ "manu":1, "prod":2797, "name":"Fenix5S Asia" },
{ "manu":1, "prod":2798, "name":"Fenix5X Asia" },
{ "manu":1, "prod":2806, "name":"Approach Z80" },
{ "manu":1, "prod":2814, "name":"Fr35 Korea" },
{ "manu":1, "prod":2819, "name":"D2Charlie" },
{ "manu":1, "prod":2831, "name":"Vivo Smart3 Apac" },
{ "manu":1, "prod":2832, "name":"Vivo Sport Apac" },
{ "manu":1, "prod":2833, "name":"Fr935 Asia" },
{ "manu":1, "prod":2859, "name":"Descent" },
{ "manu":1, "prod":2878, "name":"Vivo Fit4" },
{ "manu":1, "prod":2886, "name":"Fr645" },
{ "manu":1, "prod":2888, "name":"Fr645M" },
{ "manu":1, "prod":2891, "name":"Fr30" },
{ "manu":1, "prod":2900, "name":"Fenix5S Plus" },
{ "manu":1, "prod":2909, "name":"Edge 130" },
{ "manu":1, "prod":2924, "name":"Edge 1030 Asia" },
{ "manu":1, "prod":2927, "name":"Vivosmart 4" },
{ "manu":1, "prod":2945, "name":"Vivo Move Hr Asia" },
{ "manu":1, "prod":2962, "name":"Approach X10" },
{ "manu":1, "prod":2977, "name":"Fr30 Asia" },
{ "manu":1, "prod":2988, "name":"Vivoactive3M W" },
{ "manu":1, "prod":3003, "name":"Fr645 Asia" },
{ "manu":1, "prod":3004, "name":"Fr645M Asia" },
{ "manu":1, "prod":3011, "name":"Edge Explore" },
{ "manu":1, "prod":3028, "name":"Gpsmap66" },
{ "manu":1, "prod":3049, "name":"Approach S10" },
{ "manu":1, "prod":3066, "name":"Vivoactive3M L" },
{ "manu":1, "prod":3085, "name":"Approach G80" },
{ "manu":1, "prod":3092, "name":"Edge 130 Asia" },
{ "manu":1, "prod":3095, "name":"Edge 1030 Bontrager" },
{ "manu":1, "prod":3110, "name":"Fenix5 Plus" },
{ "manu":1, "prod":3111, "name":"Fenix5X Plus" },
{ "manu":1, "prod":3112, "name":"Edge 520 Plus" },
{ "manu":1, "prod":3113, "name":"Fr945" },
{ "manu":1, "prod":3121, "name":"Edge 530" },
{ "manu":1, "prod":3122, "name":"Edge 830" },
{ "manu":1, "prod":3126, "name":"Instinct Esports" },
{ "manu":1, "prod":3134, "name":"Fenix5S Plus Apac" },
{ "manu":1, "prod":3135, "name":"Fenix5X Plus Apac" },
{ "manu":1, "prod":3142, "name":"Edge 520 Plus Apac" },
{ "manu":1, "prod":3144, "name":"Fr235L Asia" },
{ "manu":1, "prod":3145, "name":"Fr245 Asia" },
{ "manu":1, "prod":3163, "name":"Vivo Active3M Apac" },
{ "manu":1, "prod":3192, "name":"Gen3 Bsm" },
{ "manu":1, "prod":3193, "name":"Gen3 Bcm" },
{ "manu":1, "prod":3218, "name":"Vivo Smart4 Asia" },
{ "manu":1, "prod":3224, "name":"Vivoactive4 Small" },
{ "manu":1, "prod":3225, "name":"Vivoactive4 Large" },
{ "manu":1, "prod":3226, "name":"Venu" },
{ "manu":1, "prod":3246, "name":"Marq Driver" },
{ "manu":1, "prod":3247, "name":"Marq Aviator" },
{ "manu":1, "prod":3248, "name":"Marq Captain" },
{ "manu":1, "prod":3249, "name":"Marq Commander" },
{ "manu":1, "prod":3250, "name":"Marq Expedition" },
{ "manu":1, "prod":3251, "name":"Marq Athlete" },
{ "manu":1, "prod":3258, "name":"Descent Mk2" },
{ "manu":1, "prod":3284, "name":"Gpsmap66I" },
{ "manu":1, "prod":3287, "name":"Fenix6S Sport" },
{ "manu":1, "prod":3288, "name":"Fenix6S" },
{ "manu":1, "prod":3289, "name":"Fenix6 Sport" },
{ "manu":1, "prod":3290, "name":"Fenix6" },
{ "manu":1, "prod":3291, "name":"Fenix6X" },
{ "manu":1, "prod":3299, "name":"Hrm Dual" },
{ "manu":1, "prod":3300, "name":"Hrm Pro" },
{ "manu":1, "prod":3308, "name":"Vivo Move3 Premium" },
{ "manu":1, "prod":3314, "name":"Approach S40" },
{ "manu":1, "prod":3321, "name":"Fr245M Asia" },
{ "manu":1, "prod":3349, "name":"Edge 530 Apac" },
{ "manu":1, "prod":3350, "name":"Edge 830 Apac" },
{ "manu":1, "prod":3378, "name":"Vivo Move3" },
{ "manu":1, "prod":3387, "name":"Vivo Active4 Small Asia" },
{ "manu":1, "prod":3388, "name":"Vivo Active4 Large Asia" },
{ "manu":1, "prod":3389, "name":"Vivo Active4 Oled Asia" },
{ "manu":1, "prod":3405, "name":"Swim2" },
{ "manu":1, "prod":3420, "name":"Marq Driver Asia" },
{ "manu":1, "prod":3421, "name":"Marq Aviator Asia" },
{ "manu":1, "prod":3422, "name":"Vivo Move3 Asia" },
{ "manu":1, "prod":3441, "name":"Fr945 Asia" },
{ "manu":1, "prod":3446, "name":"Vivo Active3T Chn" },
{ "manu":1, "prod":3448, "name":"Marq Captain Asia" },
{ "manu":1, "prod":3449, "name":"Marq Commander Asia" },
{ "manu":1, "prod":3450, "name":"Marq Expedition Asia" },
{ "manu":1, "prod":3451, "name":"Marq Athlete Asia" },
{ "manu":1, "prod":3466, "name":"Instinct Solar" },
{ "manu":1, "prod":3469, "name":"Fr45 Asia" },
{ "manu":1, "prod":3473, "name":"Vivoactive3 Daimler" },
{ "manu":1, "prod":3498, "name":"Legacy Rey" },
{ "manu":1, "prod":3499, "name":"Legacy Darth Vader" },
{ "manu":1, "prod":3500, "name":"Legacy Captain Marvel" },
{ "manu":1, "prod":3501, "name":"Legacy First Avenger" },
{ "manu":1, "prod":3512, "name":"Fenix6S Sport Asia" },
{ "manu":1, "prod":3513, "name":"Fenix6S Asia" },
{ "manu":1, "prod":3514, "name":"Fenix6 Sport Asia" },
{ "manu":1, "prod":3515, "name":"Fenix6 Asia" },
{ "manu":1, "prod":3516, "name":"Fenix6X Asia" },
{ "manu":1, "prod":3535, "name":"Legacy Captain Marvel Asia" },
{ "manu":1, "prod":3536, "name":"Legacy First Avenger Asia" },
{ "manu":1, "prod":3537, "name":"Legacy Rey Asia" },
{ "manu":1, "prod":3538, "name":"Legacy Darth Vader Asia" },
{ "manu":1, "prod":3542, "name":"Descent Mk2S" },
{ "manu":1, "prod":3558, "name":"Edge 130 Plus" },
{ "manu":1, "prod":3570, "name":"Edge 1030 Plus" },
{ "manu":1, "prod":3578, "name":"Rally 200" },
{ "manu":1, "prod":3589, "name":"Fr745" },
{ "manu":1, "prod":3600, "name":"Venusq" },
{ "manu":1, "prod":3615, "name":"Lily" },
{ "manu":1, "prod":3624, "name":"Marq Adventurer" },
{ "manu":1, "prod":3638, "name":"Enduro" },
{ "manu":1, "prod":3639, "name":"Swim2 Apac" },
{ "manu":1, "prod":3648, "name":"Marq Adventurer Asia" },
{ "manu":1, "prod":3652, "name":"Fr945 Lte" },
{ "manu":1, "prod":3702, "name":"Descent Mk2 Asia" },
{ "manu":1, "prod":3703, "name":"Venu2" },
{ "manu":1, "prod":3704, "name":"Venu2S" },
{ "manu":1, "prod":3737, "name":"Venu Daimler Asia" },
{ "manu":1, "prod":3739, "name":"Marq Golfer" },
{ "manu":1, "prod":3740, "name":"Venu Daimler" },
{ "manu":1, "prod":3794, "name":"Fr745 Asia" },
{ "manu":1, "prod":3809, "name":"Lily Asia" },
{ "manu":1, "prod":3812, "name":"Edge 1030 Plus Asia" },
{ "manu":1, "prod":3813, "name":"Edge 130 Plus Asia" },
{ "manu":1, "prod":3823, "name":"Approach S12" },
{ "manu":1, "prod":3872, "name":"Enduro Asia" },
{ "manu":1, "prod":3837, "name":"Venusq Asia" },
{ "manu":1, "prod":3850, "name":"Marq Golfer Asia" },
{ "manu":1, "prod":3851, "name":"Venu2 Plus" },
{ "manu":1, "prod":3869, "name":"Fr55" },
{ "manu":1, "prod":3888, "name":"Instinct 2" },
{ "manu":1, "prod":3905, "name":"Fenix7S" },
{ "manu":1, "prod":3906, "name":"Fenix7" },
{ "manu":1, "prod":3907, "name":"Fenix7X" },
{ "manu":1, "prod":3908, "name":"Fenix7S Apac" },
{ "manu":1, "prod":3909, "name":"Fenix7 Apac" },
{ "manu":1, "prod":3910, "name":"Fenix7X Apac" },
{ "manu":1, "prod":3927, "name":"Approach G12" },
{ "manu":1, "prod":3930, "name":"Descent Mk2S Asia" },
{ "manu":1, "prod":3934, "name":"Approach S42" },
{ "manu":1, "prod":3943, "name":"Epix Gen2" },
{ "manu":1, "prod":3944, "name":"Epix Gen2 Apac" },
{ "manu":1, "prod":3949, "name":"Venu2S Asia" },
{ "manu":1, "prod":3950, "name":"Venu2 Asia" },
{ "manu":1, "prod":3978, "name":"Fr945 Lte Asia" },
{ "manu":1, "prod":3986, "name":"Approach S12 Asia" },
{ "manu":1, "prod":4001, "name":"Approach G12 Asia" },
{ "manu":1, "prod":4002, "name":"Approach S42 Asia" },
{ "manu":1, "prod":4005, "name":"Descent G1" },
{ "manu":1, "prod":4017, "name":"Venu2 Plus Asia" },
{ "manu":1, "prod":4033, "name":"Fr55 Asia" },
{ "manu":1, "prod":4071, "name":"Instinct 2 Asia" },
{ "manu":1, "prod":4125, "name":"D2 Air X10" },
{ "manu":1, "prod":4132, "name":"Descent G1 Asia" },
{ "manu":1, "prod":4265, "name":"Tacx Neo Smart" },
{ "manu":1, "prod":4266, "name":"Tacx Neo2 Smart" },
{ "manu":1, "prod":4267, "name":"Tacx Neo2 T Smart" },
{ "manu":1, "prod":4268, "name":"Tacx Neo Smart Bike" },
{ "manu":1, "prod":4269, "name":"Tacx Satori Smart" },
{ "manu":1, "prod":4270, "name":"Tacx Flow Smart" },
{ "manu":1, "prod":4271, "name":"Tacx Vortex Smart" },
{ "manu":1, "prod":4272, "name":"Tacx Bushido Smart" },
{ "manu":1, "prod":4273, "name":"Tacx Genius Smart" },
{ "manu":1, "prod":4274, "name":"Tacx Flux Flux S Smart" },
{ "manu":1, "prod":4275, "name":"Tacx Flux2 Smart" },
{ "manu":1, "prod":4276, "name":"Tacx Magnum" },
{ "manu":1, "prod":4135, "name":"Tactix7" },
{ "manu":1, "prod":10007, "name":"Sdm4" },
{ "manu":1, "prod":10014, "name":"Edge Remote" },
{ "manu":1, "prod":20533, "name":"Tacx Training App Win" },
{ "manu":1, "prod":20534, "name":"Tacx Training App Mac" },
{ "manu":1, "prod":20565, "name":"Tacx Training App Mac Catalyst" },
{ "manu":1, "prod":20119, "name":"Training Center" },
{ "manu":1, "prod":30045, "name":"Tacx Training App Android" },
{ "manu":1, "prod":30046, "name":"Tacx Training App Ios" },
{ "manu":1, "prod":30047, "name":"Tacx Training App Legacy" },
{ "manu":1, "prod":65531, "name":"Connectiq Simulator" },
{ "manu":1, "prod":65532, "name":"Android Antplus Plugin" },
{ "manu":1, "prod":65534, "name":"Connect" }
],

"MANUFACTURERS":[
{ "manu":1, "name":"Garmin" },
{ "manu":2, "name":"Garmin Fr405 Antfs" },
{ "manu":3, "name":"Zephyr" },
{ "manu":4, "name":"Dayton" },
{ "manu":5, "name":"Idt" },
{ "manu":6, "name":"Srm" },
{ "manu":7, "name":"Quarq" },
{ "manu":8, "name":"Ibike" },
{ "manu":9, "name":"Saris" },
{ "manu":10, "name":"Spark Hk" },
{ "manu":11, "name":"Tanita" },
{ "manu":12, "name":"Echowell" },
{ "manu":13, "name":"Dynastream Oem" },
{ "manu":14, "name":"Nautilus" },
{ "manu":15, "name":"Dynastream" },
{ "manu":16, "name":"Timex" },
{ "manu":17, "name":"Metrigear" },
{ "manu":18, "name":"Xelic" },
{ "manu":19, "name":"Beurer" },
{ "manu":20, "name":"Cardiosport" },
{ "manu":21, "name":"A And D" },
{ "manu":22, "name":"Hmm" },
{ "manu":23, "name":"Suunto" },
{ "manu":24, "name":"Thita Elektronik" },
{ "manu":25, "name":"Gpulse" },
{ "manu":26, "name":"Clean Mobile" },
{ "manu":27, "name":"Pedal Brain" },
{ "manu":28, "name":"Peaksware" },
{ "manu":29, "name":"Saxonar" },
{ "manu":30, "name":"Lemond Fitness" },
{ "manu":31, "name":"Dexcom" },
{ "manu":32, "name":"Wahoo Fitness" },
{ "manu":33, "name":"Octane Fitness" },
{ "manu":34, "name":"Archinoetics" },
{ "manu":35, "name":"The Hurt Box" },
{ "manu":36, "name":"Citizen Systems" },
{ "manu":37, "name":"Magellan" },
{ "manu":38, "name":"Osynce" },
{ "manu":39, "name":"Holux" },
{ "manu":40, "name":"Concept2" },
{ "manu":41, "name":"Shimano" },
{ "manu":42, "name":"One Giant Leap" },
{ "manu":43, "name":"Ace Sensor" },
{ "manu":44, "name":"Brim Brothers" },
{ "manu":45, "name":"Xplova" },
{ "manu":46, "name":"Perception Digital" },
{ "manu":47, "name":"Bf1Systems" },
{ "manu":48, "name":"Pioneer" },
{ "manu":49, "name":"Spantec" },
{ "manu":50, "name":"Metalogics" },
{ "manu":51, "name":"4Iiiis" },
{ "manu":52, "name":"Seiko Epson" },
{ "manu":53, "name":"Seiko Epson Oem" },
{ "manu":54, "name":"Ifor Powell" },
{ "manu":55, "name":"Maxwell Guider" },
{ "manu":56, "name":"Star Trac" },
{ "manu":57, "name":"Breakaway" },
{ "manu":58, "name":"Alatech Technology Ltd" },
{ "manu":59, "name":"Mio Technology Europe" },
{ "manu":60, "name":"Rotor" },
{ "manu":61, "name":"Geonaute" },
{ "manu":62, "name":"Id Bike" },
{ "manu":63, "name":"Specialized" },
{ "manu":64, "name":"Wtek" },
{ "manu":65, "name":"Physical Enterprises" },
{ "manu":66, "name":"North Pole Engineering" },
{ "manu":67, "name":"Bkool" },
{ "manu":68, "name":"Cateye" },
{ "manu":69, "name":"Stages Cycling" },
{ "manu":70, "name":"Sigmasport" },
{ "manu":71, "name":"Tomtom" },
{ "manu":72, "name":"Peripedal" },
{ "manu":73, "name":"Wattbike" },
{ "manu":76, "name":"Moxy" },
{ "manu":77, "name":"Ciclosport" },
{ "manu":78, "name":"Powerbahn" },
{ "manu":79, "name":"Acorn Projects Aps" },
{ "manu":80, "name":"Lifebeam" },
{ "manu":81, "name":"Bontrager" },
{ "manu":82, "name":"Wellgo" },
{ "manu":83, "name":"Scosche" },
{ "manu":84, "name":"Magura" },
{ "manu":85, "name":"Woodway" },
{ "manu":86, "name":"Elite" },
{ "manu":87, "name":"Nielsen Kellerman" },
{ "manu":88, "name":"Dk City" },
{ "manu":89, "name":"Tacx" },
{ "manu":90, "name":"Direction Technology" },
{ "manu":91, "name":"Magtonic" },
{ "manu":92, "name":"1Partcarbon" },
{ "manu":93, "name":"Inside Ride Technologies" },
{ "manu":94, "name":"Sound Of Motion" },
{ "manu":95, "name":"Stryd" },
{ "manu":96, "name":"Icg" },
{ "manu":97, "name":"Mipulse" },
{ "manu":98, "name":"Bsx Athletics" },
{ "manu":99, "name":"Look" },
{ "manu":100, "name":"Campagnolo Srl" },
{ "manu":101, "name":"Body Bike Smart" },
{ "manu":102, "name":"Praxisworks" },
{ "manu":103, "name":"Limits Technology" },
{ "manu":104, "name":"Topaction Technology" },
{ "manu":105, "name":"Cosinuss" },
{ "manu":106, "name":"Fitcare" },
{ "manu":107, "name":"Magene" },
{ "manu":108, "name":"Giant Manufacturing Co" },
{ "manu":109, "name":"Tigrasport" },
{ "manu":110, "name":"Salutron" },
{ "manu":111, "name":"Technogym" },
{ "manu":112, "name":"Bryton Sensors" },
{ "manu":113, "name":"Latitude Limited" },
{ "manu":114, "name":"Soaring Technology" },
{ "manu":115, "name":"Igpsport" },
{ "manu":116, "name":"Thinkrider" },
{ "manu":117, "name":"Gopher Sport" },
{ "manu":118, "name":"Waterrower" },
{ "manu":119, "name":"Orangetheory" },
{ "manu":120, "name":"Inpeak" },
{ "manu":121, "name":"Kinetic" },
{ "manu":122, "name":"Johnson Health Tech" },
{ "manu":123, "name":"Polar Electro" },
{ "manu":124, "name":"Seesense" },
{ "manu":125, "name":"Nci Technology" },
{ "manu":126, "name":"Iqsquare" },
{ "manu":127, "name":"Leomo" },
{ "manu":128, "name":"Ifit Com" },
{ "manu":129, "name":"Coros Byte" },
{ "manu":130, "name":"Versa Design" },
{ "manu":131, "name":"Chileaf" },
{ "manu":132, "name":"Cycplus" },
{ "manu":133, "name":"Gravaa Byte" },
{ "manu":134, "name":"Sigeyi" },
{ "manu":135, "name":"Coospo" },
{ "manu":136, "name":"Geoid" },
{ "manu":137, "name":"Bosch" },
{ "manu":138, "name":"Kyto" },
{ "manu":139, "name":"Kinetic Sports" },
{ "manu":140, "name":"Decathlon Byte" },
{ "manu":141, "name":"Tq Systems" },
{ "manu":142, "name":"Tag Heuer" },
{ "manu":255, "name":"Development" },
{ "manu":257, "name":"Healthandlife" },
{ "manu":258, "name":"Lezyne" },
{ "manu":259, "name":"Scribe Labs" },
{ "manu":260, "name":"Zwift" },
{ "manu":261, "name":"Watteam" },
{ "manu":262, "name":"Recon" },
{ "manu":263, "name":"Favero Electronics" },
{ "manu":264, "name":"Dynovelo" },
{ "manu":265, "name":"Strava" },
{ "manu":266, "name":"Precor" },
{ "manu":267, "name":"Bryton" },
{ "manu":268, "name":"Sram" },
{ "manu":269, "name":"Navman" },
{ "manu":270, "name":"Cobi" },
{ "manu":271, "name":"Spivi" },
{ "manu":272, "name":"Mio Magellan" },
{ "manu":273, "name":"Evesports" },
{ "manu":274, "name":"Sensitivus Gauge" },
{ "manu":275, "name":"Podoon" },
{ "manu":276, "name":"Life Time Fitness" },
{ "manu":277, "name":"Falco E Motors" },
{ "manu":278, "name":"Minoura" },
{ "manu":279, "name":"Cycliq" },
{ "manu":280, "name":"Luxottica" },
{ "manu":281, "name":"Trainer Road" },
{ "manu":282, "name":"The Sufferfest" },
{ "manu":283, "name":"Fullspeedahead" },
{ "manu":284, "name":"Virtualtraining" },
{ "manu":285, "name":"Feedbacksports" },
{ "manu":286, "name":"Omata" },
{ "manu":287, "name":"Vdo" },
{ "manu":288, "name":"Magneticdays" },
{ "manu":289, "name":"Hammerhead" },
{ "manu":290, "name":"Kinetic By Kurt" },
{ "manu":291, "name":"Shapelog" },
{ "manu":292, "name":"Dabuziduo" },
{ "manu":293, "name":"Jetblack" },
{ "manu":294, "name":"Coros" },
{ "manu":295, "name":"Virtugo" },
{ "manu":296, "name":"Velosense" },
{ "manu":297, "name":"Cycligentinc" },
{ "manu":298, "name":"Trailforks" },
{ "manu":299, "name":"Mahle Ebikemotion" },
{ "manu":300, "name":"Nurvv" },
{ "manu":301, "name":"Microprogram" },
{ "manu":302, "name":"Zone5Cloud" },
{ "manu":303, "name":"Greenteg" },
{ "manu":304, "name":"Yamaha Motors" },
{ "manu":305, "name":"Whoop" },
{ "manu":306, "name":"Gravaa" },
{ "manu":307, "name":"Onelap" },
{ "manu":308, "name":"Monark Exercise" },
{ "manu":309, "name":"Form" },
{ "manu":310, "name":"Decathlon" },
{ "manu":311, "name":"Syncros" },
{ "manu":312, "name":"Heatup" },
{ "manu":313, "name":"Cannondale" },
{ "manu":314, "name":"True Fitness" },
{ "manu":315, "name":"Rgt Cycling" },
{ "manu":316, "name":"Vasa" },
{ "manu":317, "name":"Race Republic" },
{ "manu":318, "name":"Fazua" },
{ "manu":5759, "name":"Actigraphcorp" }
]
}