@sports-alliance/sports-lib 7.0.13 → 7.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/check-metrics.js +30 -0
- package/find-values.js +33 -0
- package/inspect-devices.js +21 -0
- package/inspect-session.js +27 -0
- package/lib/cjs/activities/devices/device.d.ts +1 -0
- package/lib/cjs/activities/devices/device.interface.d.ts +1 -0
- package/lib/cjs/activities/devices/device.js +1 -0
- package/lib/cjs/activities/devices/device.json.interface.d.ts +1 -0
- package/lib/cjs/data/data.age.d.ts +6 -0
- package/lib/cjs/data/data.age.js +12 -0
- package/lib/cjs/data/data.avg-flow.d.ts +5 -0
- package/lib/cjs/data/data.avg-flow.js +9 -0
- package/lib/cjs/data/data.avg-grit.d.ts +5 -0
- package/lib/cjs/data/data.avg-grit.js +9 -0
- package/lib/cjs/data/data.avg-respiration-rate.d.ts +5 -0
- package/lib/cjs/data/data.avg-respiration-rate.js +9 -0
- package/lib/cjs/data/data.avg-vam.d.ts +5 -0
- package/lib/cjs/data/data.avg-vam.js +9 -0
- package/lib/cjs/data/data.est-sweat-loss.d.ts +6 -0
- package/lib/cjs/data/data.est-sweat-loss.js +12 -0
- package/lib/cjs/data/data.flow.d.ts +5 -0
- package/lib/cjs/data/data.flow.js +9 -0
- package/lib/cjs/data/data.gender.d.ts +4 -0
- package/lib/cjs/data/data.gender.js +8 -0
- package/lib/cjs/data/data.grit.d.ts +5 -0
- package/lib/cjs/data/data.grit.js +9 -0
- package/lib/cjs/data/data.height.d.ts +6 -0
- package/lib/cjs/data/data.height.js +12 -0
- package/lib/cjs/data/data.jump-count.d.ts +6 -0
- package/lib/cjs/data/data.jump-count.js +12 -0
- package/lib/cjs/data/data.jump-event.d.ts +12 -0
- package/lib/cjs/data/data.jump-event.js +16 -0
- package/lib/cjs/data/data.left-pedal-smoothness.d.ts +6 -0
- package/lib/cjs/data/data.left-pedal-smoothness.js +12 -0
- package/lib/cjs/data/data.left-torque-effectiveness.d.ts +6 -0
- package/lib/cjs/data/data.left-torque-effectiveness.js +12 -0
- package/lib/cjs/data/data.max-respiration-rate.d.ts +5 -0
- package/lib/cjs/data/data.max-respiration-rate.js +9 -0
- package/lib/cjs/data/data.min-respiration-rate.d.ts +5 -0
- package/lib/cjs/data/data.min-respiration-rate.js +9 -0
- package/lib/cjs/data/data.primary-benefit.d.ts +6 -0
- package/lib/cjs/data/data.primary-benefit.js +12 -0
- package/lib/cjs/data/data.resting-calories.d.ts +5 -0
- package/lib/cjs/data/data.resting-calories.js +9 -0
- package/lib/cjs/data/data.right-pedal-smoothness.d.ts +6 -0
- package/lib/cjs/data/data.right-pedal-smoothness.js +12 -0
- package/lib/cjs/data/data.right-torque-effectiveness.d.ts +6 -0
- package/lib/cjs/data/data.right-torque-effectiveness.js +12 -0
- package/lib/cjs/data/data.store.js +54 -2
- package/lib/cjs/data/data.total-flow.d.ts +5 -0
- package/lib/cjs/data/data.total-flow.js +9 -0
- package/lib/cjs/data/data.total-grit.d.ts +5 -0
- package/lib/cjs/data/data.total-grit.js +9 -0
- package/lib/cjs/data/data.training-load-peak.d.ts +5 -0
- package/lib/cjs/data/data.training-load-peak.js +9 -0
- package/lib/cjs/data/data.weight.d.ts +6 -0
- package/lib/cjs/data/data.weight.js +12 -0
- package/lib/cjs/events/adapters/importers/fit/importer.fit.d.ts +3 -1
- package/lib/cjs/events/adapters/importers/fit/importer.fit.js +211 -6
- package/lib/cjs/events/adapters/importers/fit/importer.fit.mapper.js +42 -0
- package/lib/cjs/events/adapters/importers/fit/importer.fit.mtb.spec.d.ts +1 -0
- package/lib/cjs/events/adapters/importers/fit/importer.fit.mtb.spec.js +217 -0
- package/lib/cjs/events/adapters/importers/fit/importer.fit.road.spec.d.ts +1 -0
- package/lib/cjs/events/adapters/importers/fit/importer.fit.road.spec.js +103 -0
- package/lib/cjs/index.d.ts +4 -0
- package/lib/cjs/index.js +4 -0
- package/lib/esm/activities/devices/device.d.ts +1 -0
- package/lib/esm/activities/devices/device.interface.d.ts +1 -0
- package/lib/esm/activities/devices/device.json.interface.d.ts +1 -0
- package/lib/esm/data/data.age.d.ts +6 -0
- package/lib/esm/data/data.avg-flow.d.ts +5 -0
- package/lib/esm/data/data.avg-grit.d.ts +5 -0
- package/lib/esm/data/data.avg-respiration-rate.d.ts +5 -0
- package/lib/esm/data/data.avg-vam.d.ts +5 -0
- package/lib/esm/data/data.est-sweat-loss.d.ts +6 -0
- package/lib/esm/data/data.flow.d.ts +5 -0
- package/lib/esm/data/data.gender.d.ts +4 -0
- package/lib/esm/data/data.grit.d.ts +5 -0
- package/lib/esm/data/data.height.d.ts +6 -0
- package/lib/esm/data/data.jump-count.d.ts +6 -0
- package/lib/esm/data/data.jump-event.d.ts +12 -0
- package/lib/esm/data/data.left-pedal-smoothness.d.ts +6 -0
- package/lib/esm/data/data.left-torque-effectiveness.d.ts +6 -0
- package/lib/esm/data/data.max-respiration-rate.d.ts +5 -0
- package/lib/esm/data/data.min-respiration-rate.d.ts +5 -0
- package/lib/esm/data/data.primary-benefit.d.ts +6 -0
- package/lib/esm/data/data.resting-calories.d.ts +5 -0
- package/lib/esm/data/data.right-pedal-smoothness.d.ts +6 -0
- package/lib/esm/data/data.right-torque-effectiveness.d.ts +6 -0
- package/lib/esm/data/data.total-flow.d.ts +5 -0
- package/lib/esm/data/data.total-grit.d.ts +5 -0
- package/lib/esm/data/data.training-load-peak.d.ts +5 -0
- package/lib/esm/data/data.weight.d.ts +6 -0
- package/lib/esm/events/adapters/importers/fit/importer.fit.d.ts +3 -1
- package/lib/esm/events/adapters/importers/fit/importer.fit.mtb.spec.d.ts +1 -0
- package/lib/esm/events/adapters/importers/fit/importer.fit.road.spec.d.ts +1 -0
- package/lib/esm/index.d.ts +4 -0
- package/lib/esm/index.js +522 -4
- package/package.json +2 -2
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
const fs = __importStar(require("fs"));
|
|
46
|
+
const path = __importStar(require("path"));
|
|
47
|
+
const importer_fit_1 = require("./importer.fit");
|
|
48
|
+
const data_aerobic_training_effect_1 = require("../../../../data/data-aerobic-training-effect");
|
|
49
|
+
const data_anaerobic_training_effect_1 = require("../../../../data/data-anaerobic-training-effect");
|
|
50
|
+
const data_vo2_max_1 = require("../../../../data/data.vo2-max");
|
|
51
|
+
const data_recovery_time_1 = require("../../../../data/data.recovery-time");
|
|
52
|
+
const data_avg_respiration_rate_1 = require("../../../../data/data.avg-respiration-rate");
|
|
53
|
+
const data_heart_rate_zone_five_duration_1 = require("../../../../data/data.heart-rate-zone-five-duration");
|
|
54
|
+
const data_heart_rate_zone_four_duration_1 = require("../../../../data/data.heart-rate-zone-four-duration");
|
|
55
|
+
const data_heart_rate_zone_one_duration_1 = require("../../../../data/data.heart-rate-zone-one-duration");
|
|
56
|
+
const data_heart_rate_zone_three_duration_1 = require("../../../../data/data.heart-rate-zone-three-duration");
|
|
57
|
+
const data_heart_rate_zone_two_duration_1 = require("../../../../data/data.heart-rate-zone-two-duration");
|
|
58
|
+
const data_jump_count_1 = require("../../../../data/data.jump-count");
|
|
59
|
+
const data_max_respiration_rate_1 = require("../../../../data/data.max-respiration-rate");
|
|
60
|
+
const data_min_respiration_rate_1 = require("../../../../data/data.min-respiration-rate");
|
|
61
|
+
const data_weight_1 = require("../../../../data/data.weight");
|
|
62
|
+
const data_training_load_peak_1 = require("../../../../data/data.training-load-peak");
|
|
63
|
+
const data_resting_calories_1 = require("../../../../data/data.resting-calories");
|
|
64
|
+
const data_est_sweat_loss_1 = require("../../../../data/data.est-sweat-loss");
|
|
65
|
+
const data_primary_benefit_1 = require("../../../../data/data.primary-benefit");
|
|
66
|
+
const data_sport_profile_name_1 = require("../../../../data/data.sport-profile-name");
|
|
67
|
+
const data_total_grit_1 = require("../../../../data/data.total-grit");
|
|
68
|
+
const data_avg_flow_1 = require("../../../../data/data.avg-flow");
|
|
69
|
+
const data_jump_event_1 = require("../../../../data/data.jump-event");
|
|
70
|
+
const data_avg_vam_1 = require("../../../../data/data.avg-vam");
|
|
71
|
+
const data_temperature_max_1 = require("../../../../data/data.temperature-max");
|
|
72
|
+
const data_temperature_min_1 = require("../../../../data/data.temperature-min");
|
|
73
|
+
const data_start_position_1 = require("../../../../data/data.start-position");
|
|
74
|
+
const data_end_position_1 = require("../../../../data/data.end-position");
|
|
75
|
+
const data_energy_1 = require("../../../../data/data.energy");
|
|
76
|
+
const helpers_1 = require("../../../../events/utilities/helpers");
|
|
77
|
+
describe('EventImporterFIT MTB Jumps', () => {
|
|
78
|
+
const samplesDir = path.resolve(__dirname, '../../../../../samples/fit');
|
|
79
|
+
const fitFile = 'jumps-mtb.fit';
|
|
80
|
+
it('should parse jumps-mtb.fit and extract grit, flow and jumps', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
81
|
+
const filePath = path.join(samplesDir, fitFile);
|
|
82
|
+
if (!fs.existsSync(filePath)) {
|
|
83
|
+
console.warn(`Sample file ${fitFile} not found. Skipping test.`);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const fileBuffer = fs.readFileSync(filePath);
|
|
87
|
+
const arrayBuffer = fileBuffer.buffer.slice(fileBuffer.byteOffset, fileBuffer.byteOffset + fileBuffer.byteLength);
|
|
88
|
+
const event = yield importer_fit_1.EventImporterFIT.getFromArrayBuffer(arrayBuffer, undefined, fitFile);
|
|
89
|
+
expect(event).toBeDefined();
|
|
90
|
+
const activities = event.getActivities();
|
|
91
|
+
console.log(`Parsed ${activities.length} activities.`);
|
|
92
|
+
activities.forEach((a, i) => {
|
|
93
|
+
console.log(`Activity ${i}: ${a.startDate.toISOString()} - ${a.endDate.toISOString()}`);
|
|
94
|
+
});
|
|
95
|
+
const activity = activities[0];
|
|
96
|
+
expect(activity).toBeDefined();
|
|
97
|
+
// Check Stats
|
|
98
|
+
const totalGrit = activity.getStat(data_total_grit_1.DataTotalGrit.type);
|
|
99
|
+
expect(totalGrit).toBeDefined();
|
|
100
|
+
expect(totalGrit.getValue()).toBeCloseTo(38.4, 1);
|
|
101
|
+
const avgFlow = activity.getStat(data_avg_flow_1.DataAvgFlow.type);
|
|
102
|
+
expect(avgFlow).toBeDefined();
|
|
103
|
+
expect(avgFlow.getValue()).toBeCloseTo(6.13, 2);
|
|
104
|
+
// Verify Respiration Rate
|
|
105
|
+
const avgResp = activity.getStat(data_avg_respiration_rate_1.DataAvgRespirationRate.type);
|
|
106
|
+
expect(avgResp).toBeDefined();
|
|
107
|
+
expect(avgResp.getValue()).toBeCloseTo(27.56, 1);
|
|
108
|
+
const maxResp = activity.getStat(data_max_respiration_rate_1.DataMaxRespirationRate.type);
|
|
109
|
+
expect(maxResp).toBeDefined();
|
|
110
|
+
expect(maxResp.getValue()).toBeCloseTo(41.43, 2);
|
|
111
|
+
const minResp = activity.getStat(data_min_respiration_rate_1.DataMinRespirationRate.type);
|
|
112
|
+
expect(minResp).toBeDefined();
|
|
113
|
+
expect(minResp.getValue()).toBeCloseTo(15.77, 2);
|
|
114
|
+
// Verify Avg VAM
|
|
115
|
+
const avgVam = activity.getStat(data_avg_vam_1.DataAvgVAM.type);
|
|
116
|
+
expect(avgVam).toBeDefined();
|
|
117
|
+
expect(avgVam.getValue()).toBeCloseTo(100, 1);
|
|
118
|
+
// Verify Jump Count
|
|
119
|
+
const jumpCount = activity.getStat(data_jump_count_1.DataJumpCount.type);
|
|
120
|
+
expect(jumpCount).toBeDefined();
|
|
121
|
+
expect(jumpCount.getValue()).toBe(11);
|
|
122
|
+
// Verify Training Load Peak
|
|
123
|
+
const trainingLoadPeak = activity.getStat(data_training_load_peak_1.DataTrainingLoadPeak.type);
|
|
124
|
+
expect(trainingLoadPeak).toBeDefined();
|
|
125
|
+
expect(trainingLoadPeak.getValue()).toBe(6079174);
|
|
126
|
+
// Verify Resting Calories
|
|
127
|
+
const restingCalories = activity.getStat(data_resting_calories_1.DataRestingCalories.type);
|
|
128
|
+
expect(restingCalories).toBeDefined();
|
|
129
|
+
expect(restingCalories.getValue()).toBe(159);
|
|
130
|
+
// Verify Est Sweat Loss
|
|
131
|
+
const sweatLoss = activity.getStat(data_est_sweat_loss_1.DataEstSweatLoss.type);
|
|
132
|
+
expect(sweatLoss).toBeDefined();
|
|
133
|
+
expect(sweatLoss.getValue()).toBe(790);
|
|
134
|
+
// Verify Primary Benefit
|
|
135
|
+
const primaryBenefit = activity.getStat(data_primary_benefit_1.DataPrimaryBenefit.type);
|
|
136
|
+
expect(primaryBenefit).toBeDefined();
|
|
137
|
+
expect(primaryBenefit.getValue()).toBe(2);
|
|
138
|
+
// Verify Sport Profile Name
|
|
139
|
+
const sportProfileName = activity.getStat(data_sport_profile_name_1.DataSportProfileName.type);
|
|
140
|
+
expect(sportProfileName).toBeDefined();
|
|
141
|
+
expect(sportProfileName.getValue()).toBe('MOUNTAIN');
|
|
142
|
+
// Verify Physiological Metrics
|
|
143
|
+
const aerobic = activity.getStat(data_aerobic_training_effect_1.DataAerobicTrainingEffect.type);
|
|
144
|
+
expect(aerobic).toBeDefined();
|
|
145
|
+
expect(aerobic.getValue()).toBe(3);
|
|
146
|
+
const anaerobic = activity.getStat(data_anaerobic_training_effect_1.DataAnaerobicTrainingEffect.type);
|
|
147
|
+
expect(anaerobic).toBeDefined();
|
|
148
|
+
expect(anaerobic.getValue()).toBe(2);
|
|
149
|
+
// VO2 Max
|
|
150
|
+
const vo2Max = activity.getStat(data_vo2_max_1.DataVO2Max.type);
|
|
151
|
+
expect(vo2Max).toBeDefined();
|
|
152
|
+
expect(vo2Max.getValue()).toBeCloseTo(57.0633, 4);
|
|
153
|
+
expect(activity.getStat(data_temperature_max_1.DataTemperatureMax.type).getValue()).toBe(19);
|
|
154
|
+
expect(activity.getStat(data_temperature_min_1.DataTemperatureMin.type).getValue()).toBe(7);
|
|
155
|
+
// Positions
|
|
156
|
+
const startPos = activity.getStat(data_start_position_1.DataStartPosition.type).getValue();
|
|
157
|
+
expect(startPos.latitudeDegrees).toBeCloseTo(39.664968, 5);
|
|
158
|
+
expect(startPos.longitudeDegrees).toBeCloseTo(20.849827, 5);
|
|
159
|
+
const endPos = activity.getStat(data_end_position_1.DataEndPosition.type).getValue();
|
|
160
|
+
expect(endPos.latitudeDegrees).toBeCloseTo(39.664946, 5);
|
|
161
|
+
expect(endPos.longitudeDegrees).toBeCloseTo(20.849807, 5);
|
|
162
|
+
expect(activity.getStat(data_recovery_time_1.DataRecoveryTime.type)).toBeUndefined();
|
|
163
|
+
// User Profile
|
|
164
|
+
const weight = activity.getStat(data_weight_1.DataWeight.type);
|
|
165
|
+
expect(weight).toBeDefined();
|
|
166
|
+
// Resting Calories
|
|
167
|
+
expect(activity.getStat(data_resting_calories_1.DataRestingCalories.type).getValue()).toBe(159);
|
|
168
|
+
expect(activity.getStat(data_aerobic_training_effect_1.DataAerobicTrainingEffect.type).getValue()).toBe(3);
|
|
169
|
+
expect(activity.getStat(data_anaerobic_training_effect_1.DataAnaerobicTrainingEffect.type).getValue()).toBe(2);
|
|
170
|
+
expect(activity.getStat(data_energy_1.DataEnergy.type).getValue()).toBe(853);
|
|
171
|
+
// HR Zone Durations from time_in_zone (session-level message 216)
|
|
172
|
+
const zone1 = activity.getStat(data_heart_rate_zone_one_duration_1.DataHeartRateZoneOneDuration.type);
|
|
173
|
+
expect(zone1).toBeDefined();
|
|
174
|
+
expect(zone1.getValue()).toBeCloseTo(346.004, 0); // ~346 seconds in zone 1
|
|
175
|
+
const zone2 = activity.getStat(data_heart_rate_zone_two_duration_1.DataHeartRateZoneTwoDuration.type);
|
|
176
|
+
expect(zone2).toBeDefined();
|
|
177
|
+
expect(zone2.getValue()).toBeCloseTo(1831.986, 0); // ~1832 seconds in zone 2
|
|
178
|
+
const zone3 = activity.getStat(data_heart_rate_zone_three_duration_1.DataHeartRateZoneThreeDuration.type);
|
|
179
|
+
expect(zone3).toBeDefined();
|
|
180
|
+
expect(zone3.getValue()).toBeCloseTo(2412.306, 0); // ~2412 seconds in zone 3
|
|
181
|
+
const zone4 = activity.getStat(data_heart_rate_zone_four_duration_1.DataHeartRateZoneFourDuration.type);
|
|
182
|
+
expect(zone4).toBeDefined();
|
|
183
|
+
expect(zone4.getValue()).toBeCloseTo(2160.994, 0); // ~2161 seconds in zone 4
|
|
184
|
+
const zone5 = activity.getStat(data_heart_rate_zone_five_duration_1.DataHeartRateZoneFiveDuration.type);
|
|
185
|
+
expect(zone5).toBeDefined();
|
|
186
|
+
expect(zone5.getValue()).toBeCloseTo(450.999, 0); // ~451 seconds in zone 5
|
|
187
|
+
// Check IntensityZones with boundaries
|
|
188
|
+
const hrIntensityZones = activity.intensityZones.find(iz => iz.type === 'Heart Rate');
|
|
189
|
+
expect(hrIntensityZones).toBeDefined();
|
|
190
|
+
if (hrIntensityZones) {
|
|
191
|
+
expect(hrIntensityZones.zone1Duration).toBeCloseTo(346.004, 0);
|
|
192
|
+
expect(hrIntensityZones.zone2Duration).toBeCloseTo(1831.986, 0);
|
|
193
|
+
// Zone boundaries: hr_zone_high_boundary = [93, 111, 130, 148, 167, 185] (from image)
|
|
194
|
+
// zone2LowerLimit = 93, zone3LowerLimit = 111, zone4LowerLimit = 130, zone5LowerLimit = 148
|
|
195
|
+
expect(hrIntensityZones.zone2LowerLimit).toBe(93);
|
|
196
|
+
expect(hrIntensityZones.zone3LowerLimit).toBe(111);
|
|
197
|
+
expect(hrIntensityZones.zone4LowerLimit).toBe(130);
|
|
198
|
+
expect(hrIntensityZones.zone5LowerLimit).toBe(148);
|
|
199
|
+
}
|
|
200
|
+
// Check Jumps
|
|
201
|
+
const jumpEvents = activity.getAllEvents().filter((e) => e.getType() === data_jump_event_1.DataJumpEvent.type);
|
|
202
|
+
expect(jumpEvents.length).toBeGreaterThan(0);
|
|
203
|
+
const jump = jumpEvents[0];
|
|
204
|
+
expect(jump.jumpData).toBeDefined();
|
|
205
|
+
expect((0, helpers_1.isNumber)(jump.jumpData.distance)).toBeTruthy();
|
|
206
|
+
expect((0, helpers_1.isNumber)(jump.jumpData.height)).toBeTruthy();
|
|
207
|
+
expect((0, helpers_1.isNumber)(jump.jumpData.score)).toBeTruthy();
|
|
208
|
+
console.log(`Found ${jumpEvents.length} jumps.`);
|
|
209
|
+
console.log('First jump:', jump.jumpData);
|
|
210
|
+
// We can check if we can find a sample with Grit.
|
|
211
|
+
// In sports-lib, samples are often accessed via activity.getStream(type) or similar, BUT
|
|
212
|
+
// importer creates `DataPoint`s? Or `DataSample`s?
|
|
213
|
+
// Let's assume we just check if parsing succeeded without error for now for samples,
|
|
214
|
+
// as verifying exact sample values requires knowing the file content deep structure.
|
|
215
|
+
// However, we added mapping for DataGrit/Flow, so they SHOULD be in the data set.
|
|
216
|
+
}));
|
|
217
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
46
|
+
const fs = __importStar(require("fs"));
|
|
47
|
+
const path = __importStar(require("path"));
|
|
48
|
+
const importer_fit_1 = require("./importer.fit");
|
|
49
|
+
const data_left_torque_effectiveness_1 = require("../../../../data/data.left-torque-effectiveness");
|
|
50
|
+
const data_right_torque_effectiveness_1 = require("../../../../data/data.right-torque-effectiveness");
|
|
51
|
+
const data_left_pedal_smoothness_1 = require("../../../../data/data.left-pedal-smoothness");
|
|
52
|
+
const data_right_pedal_smoothness_1 = require("../../../../data/data.right-pedal-smoothness");
|
|
53
|
+
const activity_parsing_options_1 = require("../../../../activities/activity-parsing-options");
|
|
54
|
+
describe('EventImporterFIT Road with Power', () => {
|
|
55
|
+
const fitFilePath = path.join(__dirname, '../../../../../samples/fit/road-with-power.fit');
|
|
56
|
+
it('should parse road-with-power.fit and extract torque effectiveness and pedal smoothness', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
57
|
+
const fileContent = fs.readFileSync(fitFilePath);
|
|
58
|
+
const arrayBuffer = fileContent.buffer.slice(fileContent.byteOffset, fileContent.byteOffset + fileContent.byteLength);
|
|
59
|
+
const options = new activity_parsing_options_1.ActivityParsingOptions({ generateUnitStreams: false });
|
|
60
|
+
const event = yield importer_fit_1.EventImporterFIT.getFromArrayBuffer(arrayBuffer, options, 'Test Road Activity');
|
|
61
|
+
const activity = event.getFirstActivity();
|
|
62
|
+
// Check for Left Torque Effectiveness
|
|
63
|
+
const leftTEStream = activity.getStreamData(data_left_torque_effectiveness_1.DataLeftTorqueEffectiveness.type);
|
|
64
|
+
expect(leftTEStream).toBeDefined();
|
|
65
|
+
expect(leftTEStream.some((val) => val !== null && val > 0)).toBe(true);
|
|
66
|
+
// data contains 82
|
|
67
|
+
expect(leftTEStream.find((val) => val === 82)).toBe(82);
|
|
68
|
+
// Check for Right Torque Effectiveness
|
|
69
|
+
const rightTEStream = activity.getStreamData(data_right_torque_effectiveness_1.DataRightTorqueEffectiveness.type);
|
|
70
|
+
expect(rightTEStream).toBeDefined();
|
|
71
|
+
// Right side having data (can be 0)
|
|
72
|
+
expect(rightTEStream.length).toBeGreaterThan(0);
|
|
73
|
+
// Check for Left Pedal Smoothness
|
|
74
|
+
const leftPSStream = activity.getStreamData(data_left_pedal_smoothness_1.DataLeftPedalSmoothness.type);
|
|
75
|
+
expect(leftPSStream).toBeDefined();
|
|
76
|
+
expect(leftPSStream.some((val) => val !== null && val > 0)).toBe(true);
|
|
77
|
+
// data contains 24.5
|
|
78
|
+
expect(leftPSStream.find((val) => val === 24.5)).toBe(24.5);
|
|
79
|
+
// Check for Right Pedal Smoothness
|
|
80
|
+
const rightPSStream = activity.getStreamData(data_right_pedal_smoothness_1.DataRightPedalSmoothness.type);
|
|
81
|
+
expect(rightPSStream).toBeDefined();
|
|
82
|
+
// Just check we have data points
|
|
83
|
+
expect(rightPSStream.length).toBeGreaterThan(0);
|
|
84
|
+
// Check for Device Infos
|
|
85
|
+
const devices = activity.creator.devices;
|
|
86
|
+
expect(devices).toBeDefined();
|
|
87
|
+
expect(devices.length).toBeGreaterThan(0);
|
|
88
|
+
// Find Stages Cycling (Index 4)
|
|
89
|
+
const stages = devices.find(d => d.index === 4);
|
|
90
|
+
expect(stages).toBeDefined();
|
|
91
|
+
expect(stages === null || stages === void 0 ? void 0 : stages.manufacturer).toBe('stages_cycling');
|
|
92
|
+
expect(stages === null || stages === void 0 ? void 0 : stages.antId).toBe('0-5-0B-31CD');
|
|
93
|
+
// Find Lezyne Bike Light (Index 5)
|
|
94
|
+
const lezyneLight = devices.find(d => d.index === 5);
|
|
95
|
+
expect(lezyneLight).toBeDefined();
|
|
96
|
+
expect(lezyneLight === null || lezyneLight === void 0 ? void 0 : lezyneLight.manufacturer).toBe('lezyne');
|
|
97
|
+
expect(lezyneLight === null || lezyneLight === void 0 ? void 0 : lezyneLight.antId).toBe('E-1-23-B088');
|
|
98
|
+
// Find Lezyne Bike Radar (Index 6)
|
|
99
|
+
const lezyneRadar = devices.find(d => d.index === 6);
|
|
100
|
+
expect(lezyneRadar).toBeDefined();
|
|
101
|
+
expect(lezyneRadar === null || lezyneRadar === void 0 ? void 0 : lezyneRadar.antId).toBe('E-1-28-B088');
|
|
102
|
+
}));
|
|
103
|
+
});
|
package/lib/cjs/index.d.ts
CHANGED
|
@@ -74,6 +74,8 @@ export * from './data/data.ibi';
|
|
|
74
74
|
export * from './data/data.interface';
|
|
75
75
|
export * from './data/data.latitude-degrees';
|
|
76
76
|
export * from './data/data.left-balance';
|
|
77
|
+
export * from './data/data.left-pedal-smoothness';
|
|
78
|
+
export * from './data/data.left-torque-effectiveness';
|
|
77
79
|
export * from './data/data.longitude-degrees';
|
|
78
80
|
export * from './data/data.moving-time';
|
|
79
81
|
export * from './data/data.pace';
|
|
@@ -89,6 +91,8 @@ export * from './data/data.power-min';
|
|
|
89
91
|
export * from './data/data.power-right';
|
|
90
92
|
export * from './data/data.recovery-time';
|
|
91
93
|
export * from './data/data.right-balance';
|
|
94
|
+
export * from './data/data.right-pedal-smoothness';
|
|
95
|
+
export * from './data/data.right-torque-effectiveness';
|
|
92
96
|
export * from './data/data.rpe';
|
|
93
97
|
export * from './data/data.sea-level-pressure';
|
|
94
98
|
export * from './data/data.speed';
|
package/lib/cjs/index.js
CHANGED
|
@@ -104,6 +104,8 @@ __exportStar(require("./data/data.ibi"), exports);
|
|
|
104
104
|
__exportStar(require("./data/data.interface"), exports);
|
|
105
105
|
__exportStar(require("./data/data.latitude-degrees"), exports);
|
|
106
106
|
__exportStar(require("./data/data.left-balance"), exports);
|
|
107
|
+
__exportStar(require("./data/data.left-pedal-smoothness"), exports);
|
|
108
|
+
__exportStar(require("./data/data.left-torque-effectiveness"), exports);
|
|
107
109
|
__exportStar(require("./data/data.longitude-degrees"), exports);
|
|
108
110
|
__exportStar(require("./data/data.moving-time"), exports);
|
|
109
111
|
__exportStar(require("./data/data.pace"), exports);
|
|
@@ -119,6 +121,8 @@ __exportStar(require("./data/data.power-min"), exports);
|
|
|
119
121
|
__exportStar(require("./data/data.power-right"), exports);
|
|
120
122
|
__exportStar(require("./data/data.recovery-time"), exports);
|
|
121
123
|
__exportStar(require("./data/data.right-balance"), exports);
|
|
124
|
+
__exportStar(require("./data/data.right-pedal-smoothness"), exports);
|
|
125
|
+
__exportStar(require("./data/data.right-torque-effectiveness"), exports);
|
|
122
126
|
__exportStar(require("./data/data.rpe"), exports);
|
|
123
127
|
__exportStar(require("./data/data.sea-level-pressure"), exports);
|
|
124
128
|
__exportStar(require("./data/data.speed"), exports);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { DataEvent } from './data.event';
|
|
2
|
+
export interface JumpEventInterface {
|
|
3
|
+
distance: number;
|
|
4
|
+
height: number;
|
|
5
|
+
score: number;
|
|
6
|
+
}
|
|
7
|
+
export declare class DataJumpEvent extends DataEvent {
|
|
8
|
+
jumpData: JumpEventInterface;
|
|
9
|
+
static type: string;
|
|
10
|
+
constructor(timestamp: number, jumpData: JumpEventInterface);
|
|
11
|
+
toJSON(): any;
|
|
12
|
+
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { EventInterface } from '../../../event.interface';
|
|
2
2
|
import { CreatorInterface } from '../../../../creators/creator.interface';
|
|
3
|
+
import { ActivityInterface } from '../../../../activities/activity.interface';
|
|
4
|
+
import { DataInterface } from '../../../../data/data.interface';
|
|
3
5
|
import { ActivityParsingOptions } from '../../../../activities/activity-parsing-options';
|
|
4
6
|
import { Buffer } from 'buffer';
|
|
5
7
|
export declare class EventImporterFIT {
|
|
@@ -27,7 +29,7 @@ export declare class EventImporterFIT {
|
|
|
27
29
|
*/
|
|
28
30
|
private static swapTimesIfRequired;
|
|
29
31
|
private static getActivityTypeFromSessionObject;
|
|
30
|
-
|
|
32
|
+
static getStatsFromObject(object: any, activity: ActivityInterface, isLap: boolean): DataInterface[];
|
|
31
33
|
static getCreatorFromFitDataObject(fitDataObject: any): CreatorInterface;
|
|
32
34
|
}
|
|
33
35
|
export interface FITFileActivityEvent {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/lib/esm/index.d.ts
CHANGED
|
@@ -74,6 +74,8 @@ export * from './data/data.ibi';
|
|
|
74
74
|
export * from './data/data.interface';
|
|
75
75
|
export * from './data/data.latitude-degrees';
|
|
76
76
|
export * from './data/data.left-balance';
|
|
77
|
+
export * from './data/data.left-pedal-smoothness';
|
|
78
|
+
export * from './data/data.left-torque-effectiveness';
|
|
77
79
|
export * from './data/data.longitude-degrees';
|
|
78
80
|
export * from './data/data.moving-time';
|
|
79
81
|
export * from './data/data.pace';
|
|
@@ -89,6 +91,8 @@ export * from './data/data.power-min';
|
|
|
89
91
|
export * from './data/data.power-right';
|
|
90
92
|
export * from './data/data.recovery-time';
|
|
91
93
|
export * from './data/data.right-balance';
|
|
94
|
+
export * from './data/data.right-pedal-smoothness';
|
|
95
|
+
export * from './data/data.right-torque-effectiveness';
|
|
92
96
|
export * from './data/data.rpe';
|
|
93
97
|
export * from './data/data.sea-level-pressure';
|
|
94
98
|
export * from './data/data.speed';
|