incyclist-services 1.7.48 → 1.7.49

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.
Files changed (140) hide show
  1. package/lib/cjs/activities/active-rides/service.js +4 -4
  2. package/lib/cjs/activities/base/convert/converter.js +1 -1
  3. package/lib/cjs/activities/base/convert/fit/index.js +1 -0
  4. package/lib/cjs/activities/base/convert/fit/local-fit.js +208 -0
  5. package/lib/cjs/activities/base/convert/tcx/tcx.js +3 -3
  6. package/lib/cjs/activities/base/repo/db.js +1 -1
  7. package/lib/cjs/activities/base/utils/activity.js +2 -3
  8. package/lib/cjs/activities/base/utils/helpers.js +1 -1
  9. package/lib/cjs/activities/ride/duration.js +1 -1
  10. package/lib/cjs/activities/ride/service.js +20 -19
  11. package/lib/cjs/apps/base/api/intervals/api.js +1 -1
  12. package/lib/cjs/apps/komoot/KomootAppConnection.js +1 -1
  13. package/lib/cjs/apps/velohero/VeloHeroAppConnection.js +1 -1
  14. package/lib/cjs/appstate/service.js +2 -1
  15. package/lib/cjs/base/types/observer.js +2 -2
  16. package/lib/cjs/coaches/coach.js +1 -1
  17. package/lib/cjs/coaches/service.js +1 -1
  18. package/lib/cjs/devices/access/service.js +1 -1
  19. package/lib/cjs/devices/configuration/service.js +5 -5
  20. package/lib/cjs/devices/page/service.js +1 -1
  21. package/lib/cjs/devices/pairing/service.js +7 -6
  22. package/lib/cjs/devices/ride/service.js +12 -10
  23. package/lib/cjs/maps/MapArea/MapArea.js +33 -33
  24. package/lib/cjs/maps/MapArea/options.js +27 -27
  25. package/lib/cjs/maps/MapArea/service.js +2 -2
  26. package/lib/cjs/maps/MapArea/utils.js +47 -47
  27. package/lib/cjs/ride/base/base.js +3 -2
  28. package/lib/cjs/ride/display/service.js +2 -2
  29. package/lib/cjs/ride/route/FreeRideDisplayService.js +4 -4
  30. package/lib/cjs/ride/route/GpxDisplayService.js +1 -1
  31. package/lib/cjs/ride/route/RLVDisplayService.js +4 -3
  32. package/lib/cjs/routes/base/model/route.js +1 -1
  33. package/lib/cjs/routes/base/parsers/bikelab.js +1 -1
  34. package/lib/cjs/routes/base/parsers/geometry.js +1 -1
  35. package/lib/cjs/routes/base/parsers/gpx.js +1 -1
  36. package/lib/cjs/routes/base/parsers/incyclist.js +2 -3
  37. package/lib/cjs/routes/base/parsers/utils.js +2 -2
  38. package/lib/cjs/routes/base/parsers/xml.js +10 -10
  39. package/lib/cjs/routes/base/utils/points.js +2 -2
  40. package/lib/cjs/routes/base/utils/route.js +18 -18
  41. package/lib/cjs/routes/download/service.js +2 -1
  42. package/lib/cjs/routes/free-ride/service.js +8 -8
  43. package/lib/cjs/routes/list/cards/RouteCard.js +2 -2
  44. package/lib/cjs/routes/list/lists/myroutes.js +1 -1
  45. package/lib/cjs/routes/list/loaders/StravaActivityLoader.js +3 -3
  46. package/lib/cjs/routes/list/loaders/api.js +0 -1
  47. package/lib/cjs/routes/list/service.js +6 -4
  48. package/lib/cjs/routes/sync/komoot/provider.js +1 -1
  49. package/lib/cjs/settings/bindings/json.js +3 -3
  50. package/lib/cjs/settings/display/user/service.js +2 -3
  51. package/lib/cjs/settings/service/service.js +2 -2
  52. package/lib/cjs/ui/service.js +4 -3
  53. package/lib/cjs/utils/formatting.js +3 -3
  54. package/lib/cjs/utils/geo.js +5 -4
  55. package/lib/cjs/utils/math.js +1 -1
  56. package/lib/cjs/utils/vector.js +10 -10
  57. package/lib/cjs/utils/xml.js +2 -2
  58. package/lib/cjs/video/VideoConversion.js +3 -3
  59. package/lib/cjs/video/VideoSyncHelper.js +14 -14
  60. package/lib/cjs/workouts/base/model/Segment.js +1 -1
  61. package/lib/cjs/workouts/base/model/Workout.js +2 -2
  62. package/lib/cjs/workouts/base/parsers/intervals/parser.js +1 -1
  63. package/lib/cjs/workouts/base/parsers/zwo/zwo.js +6 -5
  64. package/lib/cjs/workouts/calendar/sync/intervals/provider.js +1 -1
  65. package/lib/cjs/workouts/ride/service.js +2 -1
  66. package/lib/esm/activities/active-rides/service.js +4 -4
  67. package/lib/esm/activities/base/convert/converter.js +2 -2
  68. package/lib/esm/activities/base/convert/fit/index.js +1 -0
  69. package/lib/esm/activities/base/convert/fit/local-fit.js +205 -0
  70. package/lib/esm/activities/base/convert/tcx/tcx.js +3 -3
  71. package/lib/esm/activities/base/repo/db.js +1 -1
  72. package/lib/esm/activities/base/utils/activity.js +2 -3
  73. package/lib/esm/activities/base/utils/helpers.js +1 -1
  74. package/lib/esm/activities/ride/duration.js +1 -1
  75. package/lib/esm/activities/ride/service.js +20 -19
  76. package/lib/esm/apps/base/api/intervals/api.js +1 -1
  77. package/lib/esm/apps/komoot/KomootAppConnection.js +1 -1
  78. package/lib/esm/apps/velohero/VeloHeroAppConnection.js +1 -1
  79. package/lib/esm/appstate/service.js +2 -1
  80. package/lib/esm/base/types/observer.js +1 -1
  81. package/lib/esm/coaches/coach.js +1 -1
  82. package/lib/esm/coaches/service.js +1 -1
  83. package/lib/esm/devices/access/service.js +1 -1
  84. package/lib/esm/devices/configuration/service.js +5 -5
  85. package/lib/esm/devices/page/service.js +1 -1
  86. package/lib/esm/devices/pairing/service.js +7 -6
  87. package/lib/esm/devices/ride/service.js +12 -10
  88. package/lib/esm/maps/MapArea/MapArea.js +33 -33
  89. package/lib/esm/maps/MapArea/options.js +27 -27
  90. package/lib/esm/maps/MapArea/service.js +2 -2
  91. package/lib/esm/maps/MapArea/utils.js +47 -47
  92. package/lib/esm/ride/base/base.js +3 -2
  93. package/lib/esm/ride/display/service.js +2 -2
  94. package/lib/esm/ride/route/FreeRideDisplayService.js +4 -4
  95. package/lib/esm/ride/route/GpxDisplayService.js +1 -1
  96. package/lib/esm/ride/route/RLVDisplayService.js +4 -3
  97. package/lib/esm/routes/base/model/route.js +1 -1
  98. package/lib/esm/routes/base/parsers/bikelab.js +1 -1
  99. package/lib/esm/routes/base/parsers/geometry.js +1 -1
  100. package/lib/esm/routes/base/parsers/gpx.js +1 -1
  101. package/lib/esm/routes/base/parsers/incyclist.js +2 -3
  102. package/lib/esm/routes/base/parsers/utils.js +2 -2
  103. package/lib/esm/routes/base/parsers/xml.js +10 -10
  104. package/lib/esm/routes/base/utils/points.js +2 -2
  105. package/lib/esm/routes/base/utils/route.js +18 -18
  106. package/lib/esm/routes/download/service.js +2 -1
  107. package/lib/esm/routes/free-ride/service.js +8 -8
  108. package/lib/esm/routes/list/cards/RouteCard.js +2 -2
  109. package/lib/esm/routes/list/lists/myroutes.js +1 -1
  110. package/lib/esm/routes/list/loaders/StravaActivityLoader.js +2 -2
  111. package/lib/esm/routes/list/loaders/api.js +0 -1
  112. package/lib/esm/routes/list/service.js +6 -4
  113. package/lib/esm/routes/sync/komoot/provider.js +1 -1
  114. package/lib/esm/settings/bindings/json.js +3 -3
  115. package/lib/esm/settings/display/user/service.js +2 -3
  116. package/lib/esm/settings/service/service.js +2 -2
  117. package/lib/esm/ui/service.js +4 -3
  118. package/lib/esm/utils/formatting.js +3 -3
  119. package/lib/esm/utils/geo.js +5 -4
  120. package/lib/esm/utils/math.js +1 -1
  121. package/lib/esm/utils/vector.js +10 -10
  122. package/lib/esm/utils/xml.js +2 -2
  123. package/lib/esm/video/VideoConversion.js +3 -3
  124. package/lib/esm/video/VideoSyncHelper.js +14 -14
  125. package/lib/esm/workouts/base/model/Segment.js +1 -1
  126. package/lib/esm/workouts/base/model/Workout.js +2 -2
  127. package/lib/esm/workouts/base/parsers/intervals/parser.js +1 -1
  128. package/lib/esm/workouts/base/parsers/zwo/zwo.js +6 -5
  129. package/lib/esm/workouts/calendar/sync/intervals/provider.js +1 -1
  130. package/lib/esm/workouts/ride/service.js +2 -1
  131. package/lib/types/activities/base/convert/fit/index.d.ts +1 -0
  132. package/lib/types/activities/base/convert/fit/local-fit.d.ts +12 -0
  133. package/lib/types/api/download/index.d.ts +1 -1
  134. package/lib/types/api/mq/index.d.ts +1 -1
  135. package/lib/types/api/path/index.d.ts +1 -1
  136. package/lib/types/api/video/index.d.ts +1 -1
  137. package/lib/types/ride/base/types.d.ts +1 -1
  138. package/lib/types/routes/list/loaders/StravaActivityLoader.d.ts +1 -1
  139. package/lib/types/routes/page/types.d.ts +1 -2
  140. package/package.json +2 -1
@@ -392,9 +392,9 @@ let ActiveRidesService = (() => {
392
392
  return 'Anonymous';
393
393
  const names = ['Alex', 'Bart', 'Cosmas', 'Dirk', 'Ernesto', 'Frank', 'Guido', 'Hans', 'Irene', 'John', 'Kai', 'Lorenzo', 'Martin', 'Naijb', 'Oswaldo', 'Pete', 'Quentin', 'Rachel', 'Sophia', 'Trevor', 'Ute', 'Vivian', 'Wil', 'Xaver', 'Younes', 'Zoe'];
394
394
  const fnKey = id.charAt(0).toLowerCase();
395
- const idx = !isNaN(parseInt(fnKey)) ? parseInt(fnKey) : fnKey.charCodeAt(0) - 96;
395
+ const idx = !Number.isNaN(Number.parseInt(fnKey)) ? Number.parseInt(fnKey) : (fnKey.codePointAt(0) ?? 0) - 96;
396
396
  const lnKey = id.charAt(0).toUpperCase();
397
- const ln = !isNaN(parseInt(lnKey)) ? '' : lnKey;
397
+ const ln = !Number.isNaN(Number.parseInt(lnKey)) ? '' : lnKey;
398
398
  return `${names[idx]}${ln}`;
399
399
  }
400
400
  addCurrentActivity() {
@@ -567,7 +567,7 @@ let ActiveRidesService = (() => {
567
567
  const logs = this.activity?.logs ?? [];
568
568
  if (!logs.length)
569
569
  return;
570
- const point = logs[logs.length - 1];
570
+ const point = logs.at(-1);
571
571
  const { lat, lng, elevation, slope } = point;
572
572
  return { lat, lng, elevation, slope };
573
573
  }
@@ -807,7 +807,7 @@ let ActiveRidesService = (() => {
807
807
  }
808
808
  this.coaches = coaches.map(c => {
809
809
  const props = c.getRidersListDisplayProperties();
810
- let routeDistance = props.currentRideDistance;
810
+ const routeDistance = props.currentRideDistance;
811
811
  const entry = { ...props,
812
812
  ride: this.current?.ride,
813
813
  };
@@ -9,7 +9,7 @@ class ActivityConverter {
9
9
  static async convert(activity, format) {
10
10
  if (!ActivityConverter.factory) {
11
11
  ActivityConverter.factory = new factory_1.ActivityConverterFactory();
12
- ActivityConverter.factory.add('fit', new fit_1.RemoteFitConverter());
12
+ ActivityConverter.factory.add('fit', new fit_1.LocalFitConverter());
13
13
  ActivityConverter.factory.add('tcx', new tcx_1.TcxConverter());
14
14
  }
15
15
  return await ActivityConverter.factory.convert(activity, format);
@@ -15,3 +15,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./remote-fit"), exports);
18
+ __exportStar(require("./local-fit"), exports);
@@ -0,0 +1,208 @@
1
+ "use strict";
2
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
3
+ var useValue = arguments.length > 2;
4
+ for (var i = 0; i < initializers.length; i++) {
5
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
6
+ }
7
+ return useValue ? value : void 0;
8
+ };
9
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
10
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
11
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
12
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
13
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
14
+ var _, done = false;
15
+ for (var i = decorators.length - 1; i >= 0; i--) {
16
+ var context = {};
17
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
18
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
19
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
20
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
21
+ if (kind === "accessor") {
22
+ if (result === void 0) continue;
23
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
24
+ if (_ = accept(result.get)) descriptor.get = _;
25
+ if (_ = accept(result.set)) descriptor.set = _;
26
+ if (_ = accept(result.init)) initializers.unshift(_);
27
+ }
28
+ else if (_ = accept(result)) {
29
+ if (kind === "field") initializers.unshift(_);
30
+ else descriptor[key] = _;
31
+ }
32
+ }
33
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
34
+ done = true;
35
+ };
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.LocalFitConverter = void 0;
38
+ const fitsdk_1 = require("@garmin/fitsdk");
39
+ const gd_eventlog_1 = require("gd-eventlog");
40
+ const settings_1 = require("../../../../settings");
41
+ const decorators_1 = require("../../../../base/decorators");
42
+ const DEG_TO_SEMICIRCLES = (2 ** 31) / 180;
43
+ let LocalFitConverter = (() => {
44
+ let _instanceExtraInitializers = [];
45
+ let _getUserSettings_decorators;
46
+ return class LocalFitConverter {
47
+ static {
48
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
49
+ _getUserSettings_decorators = [decorators_1.Injectable];
50
+ __esDecorate(this, null, _getUserSettings_decorators, { kind: "method", name: "getUserSettings", static: false, private: false, access: { has: obj => "getUserSettings" in obj, get: obj => obj.getUserSettings }, metadata: _metadata }, null, _instanceExtraInitializers);
51
+ if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
52
+ }
53
+ logger = __runInitializers(this, _instanceExtraInitializers);
54
+ constructor() {
55
+ this.logger = new gd_eventlog_1.EventLogger('LocalFitExporter');
56
+ }
57
+ async convert(activity) {
58
+ try {
59
+ this.logger.logEvent({ message: 'convert start', format: 'FIT' });
60
+ const fitActivity = this.getFitActivity(activity);
61
+ const data = this.encode(fitActivity);
62
+ this.logger.logEvent({ message: 'convert success', format: 'FIT' });
63
+ return data;
64
+ }
65
+ catch (err) {
66
+ this.logger.logEvent({ message: 'convert result', format: 'FIT', result: 'error', reason: err.message });
67
+ throw err;
68
+ }
69
+ }
70
+ getFitActivity(activity) {
71
+ const { id, title, time, timeTotal, timePause, distance } = activity;
72
+ const status = 'created';
73
+ const startTime = new Date(activity.startTime).toISOString();
74
+ const logs = activity.logs.map(this.mapLogToFit.bind(this));
75
+ const screenshots = [];
76
+ const laps = this.mapLapsToFit(activity.laps ?? [], activity.startTime);
77
+ const user = {
78
+ id: this.getUserSettings().get('uuid', undefined),
79
+ weight: activity.user.weight
80
+ };
81
+ return { id, title, status, logs, laps, startTime, time, timeTotal, timePause, distance, user, screenshots };
82
+ }
83
+ mapLapsToFit(laps, activityStartTime) {
84
+ const activityStartMs = new Date(activityStartTime).getTime();
85
+ return laps.map((lap, i) => {
86
+ const prevDistance = i > 0 ? laps[i - 1].distance : 0;
87
+ return {
88
+ lapNo: lap.num,
89
+ startTime: new Date(lap.startTime).toISOString(),
90
+ stopTime: new Date(lap.startTime + lap.rideTime * 1000).toISOString(),
91
+ lapDistance: lap.distance - prevDistance,
92
+ totalDistance: lap.distance,
93
+ lapTime: lap.rideTime,
94
+ totalTime: (lap.startTime - activityStartMs) / 1000 + lap.rideTime,
95
+ };
96
+ });
97
+ }
98
+ mapLogToFit(log) {
99
+ const { time, speed, slope, cadence: cadenceOrg, heartrate: heartrateOrg, distance, power: powerOrg, lat, lng, elevation } = log;
100
+ const cadence = Math.round(cadenceOrg);
101
+ const heartrate = Math.round(heartrateOrg);
102
+ const power = Math.round(powerOrg);
103
+ return { time, speed, slope, cadence, heartrate, distance, power, lat, lon: lng, elevation };
104
+ }
105
+ encode(activity) {
106
+ const encoder = new fitsdk_1.Encoder();
107
+ const startTime = new Date(activity.startTime);
108
+ encoder.onMesg(fitsdk_1.Profile.MesgNum.FILE_ID, {
109
+ type: 'activity',
110
+ manufacturer: 'development',
111
+ product: 0,
112
+ timeCreated: startTime,
113
+ });
114
+ encoder.onMesg(fitsdk_1.Profile.MesgNum.EVENT, {
115
+ timestamp: startTime,
116
+ event: 'timer',
117
+ eventType: 'start',
118
+ data: 0,
119
+ });
120
+ let lastTimestampMs = startTime.getTime();
121
+ activity.logs.forEach((log) => {
122
+ if (log.time != null) {
123
+ lastTimestampMs = startTime.getTime() + log.time * 1000;
124
+ }
125
+ const record = {
126
+ timestamp: new Date(lastTimestampMs),
127
+ };
128
+ if (log.lat != null && log.lon != null) {
129
+ record.positionLat = Math.round(log.lat * DEG_TO_SEMICIRCLES);
130
+ record.positionLong = Math.round(log.lon * DEG_TO_SEMICIRCLES);
131
+ }
132
+ if (log.elevation != null)
133
+ record.altitude = log.elevation;
134
+ if (log.heartrate != null)
135
+ record.heartRate = log.heartrate;
136
+ if (log.cadence != null)
137
+ record.cadence = log.cadence;
138
+ if (log.distance != null)
139
+ record.distance = log.distance;
140
+ if (log.speed != null)
141
+ record.speed = log.speed / 3.6;
142
+ if (log.power != null)
143
+ record.power = log.power;
144
+ if (log.slope != null)
145
+ record.grade = log.slope;
146
+ encoder.onMesg(fitsdk_1.Profile.MesgNum.RECORD, record);
147
+ });
148
+ const endTime = new Date(lastTimestampMs);
149
+ encoder.onMesg(fitsdk_1.Profile.MesgNum.EVENT, {
150
+ timestamp: endTime,
151
+ event: 'timer',
152
+ eventType: 'stopAll',
153
+ data: 0,
154
+ });
155
+ if (activity.laps.length > 0) {
156
+ activity.laps.forEach(lap => {
157
+ const lapStart = new Date(lap.startTime);
158
+ const lapEnd = new Date(lap.stopTime);
159
+ encoder.onMesg(fitsdk_1.Profile.MesgNum.LAP, {
160
+ timestamp: lapEnd,
161
+ startTime: lapStart,
162
+ totalElapsedTime: lap.lapTime,
163
+ totalTimerTime: lap.lapTime,
164
+ totalDistance: lap.lapDistance,
165
+ event: 'lap',
166
+ eventType: 'stop',
167
+ });
168
+ });
169
+ }
170
+ else {
171
+ encoder.onMesg(fitsdk_1.Profile.MesgNum.LAP, {
172
+ timestamp: endTime,
173
+ startTime,
174
+ totalElapsedTime: activity.timeTotal,
175
+ totalTimerTime: activity.time,
176
+ totalDistance: activity.distance,
177
+ event: 'lap',
178
+ eventType: 'stop',
179
+ });
180
+ }
181
+ encoder.onMesg(fitsdk_1.Profile.MesgNum.SESSION, {
182
+ timestamp: endTime,
183
+ startTime,
184
+ totalElapsedTime: activity.timeTotal,
185
+ totalTimerTime: activity.time,
186
+ totalDistance: activity.distance,
187
+ sport: 'cycling',
188
+ subSport: 'virtualActivity',
189
+ event: 'session',
190
+ eventType: 'stopDisableAll',
191
+ });
192
+ encoder.onMesg(fitsdk_1.Profile.MesgNum.ACTIVITY, {
193
+ timestamp: endTime,
194
+ totalTimerTime: activity.time,
195
+ numSessions: 1,
196
+ type: 'manual',
197
+ event: 'activity',
198
+ eventType: 'stop',
199
+ });
200
+ const uint8Array = encoder.close();
201
+ return uint8Array.buffer;
202
+ }
203
+ getUserSettings() {
204
+ return (0, settings_1.useUserSettings)();
205
+ }
206
+ };
207
+ })();
208
+ exports.LocalFitConverter = LocalFitConverter;
@@ -112,7 +112,7 @@ class TcxConverter {
112
112
  const lapEnd = new Date(startTime.valueOf() + end * 1000);
113
113
  const points = trackPoints.filter(p => p.Time >= lapStart && p.Time < lapEnd);
114
114
  const lastPointBeforeLap = trackPoints.filter(p => p.Time < lapStart)?.pop();
115
- const lastPointInLap = points[points.length - 1];
115
+ const lastPointInLap = points.at(-1);
116
116
  const distanceStart = lastPointBeforeLap?.DistanceMeters ?? 0;
117
117
  const DistanceMeters = lastPointInLap?.DistanceMeters ? lastPointInLap.DistanceMeters - distanceStart : 0;
118
118
  const lap = new tcx_builder_1.ActivityLap(lapStart, {
@@ -151,7 +151,7 @@ class TcxConverter {
151
151
  if (!markers.length) {
152
152
  return [{ start: 0, end: activityDuration }];
153
153
  }
154
- const final = steps[steps.length - 1];
154
+ const final = steps.at(-1);
155
155
  if (final.end < activityDuration) {
156
156
  markers.push({ start: final.end, end: activityDuration });
157
157
  }
@@ -189,7 +189,7 @@ class TcxConverter {
189
189
  else {
190
190
  lng = log?.lon;
191
191
  }
192
- if (!isNaN(Number(lat ?? 'XX')) && !isNaN(Number(lng ?? 'XX')))
192
+ if (!Number.isNaN(Number(lat ?? 'XX')) && !Number.isNaN(Number(lng ?? 'XX')))
193
193
  tp.Position = new tcx_builder_1.Position(lat, lng);
194
194
  return tp;
195
195
  });
@@ -148,7 +148,7 @@ let ActivitiesRepository = (() => {
148
148
  }
149
149
  }
150
150
  async migrateDB() {
151
- let deleted = [];
151
+ const deleted = [];
152
152
  try {
153
153
  const promises = [];
154
154
  this.activities.forEach(activity => {
@@ -151,7 +151,7 @@ let Activity = (() => {
151
151
  if (fileName)
152
152
  exports.push({ type: 'json', file: fileName });
153
153
  const formats = ['tcx', 'fit'];
154
- for (let type of formats) {
154
+ for (const type of formats) {
155
155
  const details = this.details ?? {};
156
156
  const file = details[`${type}FileName`] ?? fileName?.replace('.json', `.${type}`);
157
157
  const fs = this.getBindings().fs;
@@ -178,9 +178,8 @@ let Activity = (() => {
178
178
  observer.emit('export', { status: 'started', format });
179
179
  }
180
180
  try {
181
- let data;
182
181
  const converter = this.getActivityConverter();
183
- data = await converter.convert(this.details, format);
182
+ const data = await converter.convert(this.details, format);
184
183
  const fileName = this.details.fileName.replace('.json', `.${format}`);
185
184
  await fs.writeFile(fileName, Buffer.from(data));
186
185
  this.details[`${format}FileName`] = fileName;
@@ -35,7 +35,7 @@ const buildSummary = (activity, proposedName) => {
35
35
  }
36
36
  if (name === undefined && fileName !== undefined) {
37
37
  const parts = fileName.split(/[/\\]/);
38
- const match = /([^\\/]+)\.json/.exec(parts[parts.length - 1]);
38
+ const match = /([^\\/]+)\.json/.exec(parts.at(-1));
39
39
  if (match?.[1])
40
40
  name = match[1];
41
41
  }
@@ -34,7 +34,7 @@ class ActivityDuration {
34
34
  const realityFactor = (this.activity.realityFactor ?? 100) / 100;
35
35
  this.checkIfCacheIsInvalid(routePos, route);
36
36
  if (this.cache) {
37
- let updateFrequency = this.getUpdateFrequency(time);
37
+ const updateFrequency = this.getUpdateFrequency(time);
38
38
  const timeSinceLastUpdate = Date.now() - this.cache.ts;
39
39
  if (timeSinceLastUpdate < updateFrequency) {
40
40
  const timeRemaining = this.cache.remaining.timeRemaining - (Date.now() - this.cache.ts) / 1000;
@@ -254,7 +254,8 @@ let ActivityRideService = (() => {
254
254
  showLog = (showLog || this.current.isAutoResume) && (infoStr !== this.current.info);
255
255
  this.current.info = infoStr;
256
256
  }
257
- catch { }
257
+ catch {
258
+ }
258
259
  if (showLog) {
259
260
  this.logEvent({ message: 'Dashboard update', items: info.map(i => `${i.title}:${i.data[0]?.value ?? ''}:${i.data[1]?.value ?? ''}${i.data[1]?.label ? '(' + i.data[1]?.label + ')' : ''}`).join('|') });
260
261
  }
@@ -318,7 +319,7 @@ let ActivityRideService = (() => {
318
319
  speed = 0;
319
320
  }
320
321
  let distanceRemaining = (this.getTotalDistance() / 1000 - distance);
321
- if (isNaN(distanceRemaining))
322
+ if (Number.isNaN(distanceRemaining))
322
323
  distanceRemaining = undefined;
323
324
  if (distanceRemaining < 0)
324
325
  distanceRemaining = 0;
@@ -355,7 +356,7 @@ let ActivityRideService = (() => {
355
356
  const heartrateDetails = { value: (0, utils_1.formatNumber)(stats?.hrm?.avg, 0), label: 'avg' };
356
357
  const cadenceDetails = { value: (0, utils_1.formatNumber)(stats?.cadence?.avg, 0), label: 'avg' };
357
358
  let elevationGainRemaining = this.getTotalElevation() - (this.current.elevationGainDisplay ?? 0);
358
- if (isNaN(elevationGainRemaining))
359
+ if (Number.isNaN(elevationGainRemaining))
359
360
  elevationGainRemaining = undefined;
360
361
  if (elevationGainRemaining < 0)
361
362
  elevationGainRemaining = 0;
@@ -403,7 +404,7 @@ let ActivityRideService = (() => {
403
404
  if (this.isDonateShown) {
404
405
  return true;
405
406
  }
406
- let trialGroup = 'A';
407
+ const trialGroup = 'A';
407
408
  if (this.saveObserver || this.isSaveDone || trialGroup === 'B') {
408
409
  const lastClicked = this.getUserSettings().getValue('state.donateClicked', 0);
409
410
  if (Date.now() - lastClicked < 1000 * 60 * 60 * 24 * 365) {
@@ -536,7 +537,7 @@ let ActivityRideService = (() => {
536
537
  }
537
538
  this.current.route.details.points = points;
538
539
  (0, route_1.validateRoute)(this.current.route);
539
- this.current.route.details.distance = points[points.length - 1].routeDistance;
540
+ this.current.route.details.distance = points.at(-1).routeDistance;
540
541
  (0, route_1.addDetails)(this.current.route, this.current.route.details);
541
542
  }
542
543
  getPrevRideStats(current) {
@@ -565,7 +566,7 @@ let ActivityRideService = (() => {
565
566
  if (props.length > maxEntries) {
566
567
  const currentIdx = props.findIndex(a => a.title === 'current');
567
568
  if (currentIdx < maxEntries - 1) {
568
- let deleted = props.splice(maxEntries - 1);
569
+ const deleted = props.splice(maxEntries - 1);
569
570
  props.push({ title: `+${deleted.length}`, tsStart: null, distanceGap: '', timeGap: '' });
570
571
  }
571
572
  else if (currentIdx > maxEntries - 1) {
@@ -587,7 +588,7 @@ let ActivityRideService = (() => {
587
588
  props.splice(maxEntries - 2, props.length - maxEntries);
588
589
  }
589
590
  else if (currentIdx === maxEntries - 1) {
590
- let deleted = props.splice(currentIdx + 1, props.length - currentIdx);
591
+ const deleted = props.splice(currentIdx + 1, props.length - currentIdx);
591
592
  props.push({ title: `+${deleted.length}`, tsStart: null, distanceGap: '', timeGap: '' });
592
593
  props.splice(currentIdx - 1, 1);
593
594
  }
@@ -601,7 +602,8 @@ let ActivityRideService = (() => {
601
602
  logInfo = `(${props.length}/${prevRides.length})`
602
603
  + props.map(buildLog).join(',');
603
604
  }
604
- catch { }
605
+ catch {
606
+ }
605
607
  this.logEvent({ message: 'PrevRides', prevRides: logInfo });
606
608
  return props;
607
609
  }
@@ -621,7 +623,7 @@ let ActivityRideService = (() => {
621
623
  const { distanceGap, routeDistance, lat, lng } = this.calculateDistanceGap(ai, sameTime, current);
622
624
  const [C, U] = this.getUnitConversionShortcuts();
623
625
  const speed = { value: C(sameTime.speed, 'speed', { digits: 1 }), unit: U('speed') };
624
- let sameDistance = this.getRecordWithSameOrBiggerDistance(logs, current);
626
+ const sameDistance = this.getRecordWithSameOrBiggerDistance(logs, current);
625
627
  if (!sameDistance)
626
628
  return null;
627
629
  const timeGap = this.calculateTimeGap(sameDistance, current);
@@ -652,7 +654,7 @@ let ActivityRideService = (() => {
652
654
  }
653
655
  }
654
656
  else {
655
- res = (0, clone_1.default)(logs[logs.length - 1]);
657
+ res = (0, clone_1.default)(logs.at(-1));
656
658
  }
657
659
  return res;
658
660
  }
@@ -694,7 +696,7 @@ let ActivityRideService = (() => {
694
696
  const t = v === 0 ? Infinity : s / v;
695
697
  sameDistance.time -= t;
696
698
  const timeDelta = sameDistance.time - current.time;
697
- let prefix = Math.sign(timeDelta) > 0 ? '+' : '-';
699
+ const prefix = Math.sign(timeDelta) > 0 ? '+' : '-';
698
700
  const timeGap = prefix + (Math.abs(timeDelta) < 60 ? `${Math.abs(timeDelta).toFixed(1)}s` : (0, utils_1.formatTime)(Math.abs(timeDelta), true));
699
701
  return timeGap;
700
702
  }
@@ -874,8 +876,7 @@ let ActivityRideService = (() => {
874
876
  const fs = this.getFileSystemBinding();
875
877
  emit('convert.start', format);
876
878
  try {
877
- let data;
878
- data = await base_1.ActivityConverter.convert(this.activity, format);
879
+ const data = await base_1.ActivityConverter.convert(this.activity, format);
879
880
  emit('convert.done', format, true);
880
881
  if (format.toLowerCase() === 'fit') {
881
882
  const fileName = await this.getTargetFileName('fit');
@@ -917,7 +918,7 @@ let ActivityRideService = (() => {
917
918
  }
918
919
  createLogRecord() {
919
920
  const prevLogs = this.activity.logs;
920
- const prev = prevLogs?.length ? prevLogs[prevLogs.length - 1] : undefined;
921
+ const prev = prevLogs?.length ? prevLogs.at(-1) : undefined;
921
922
  const time = this.activity.time;
922
923
  const timeDelta = prev ? time - prev.time : time;
923
924
  const deviceData = this.current?.deviceData;
@@ -934,9 +935,9 @@ let ActivityRideService = (() => {
934
935
  slope: this.current.position?.slope,
935
936
  elevation: this.current.position?.elevation
936
937
  };
937
- if (this.current?.position?.lat && !isNaN(this.current?.position?.lat))
938
+ if (this.current?.position?.lat && !Number.isNaN(this.current?.position?.lat))
938
939
  log.lat = this.current?.position?.lat;
939
- if (this.current?.position?.lng && !isNaN(this.current?.position?.lng)) {
940
+ if (this.current?.position?.lng && !Number.isNaN(this.current?.position?.lng)) {
940
941
  log.lng = this.current?.position?.lng;
941
942
  }
942
943
  return log;
@@ -1080,7 +1081,7 @@ let ActivityRideService = (() => {
1080
1081
  if (!route)
1081
1082
  return 0;
1082
1083
  const isLoop = (0, route_1.checkIsLoop)(route);
1083
- const totalRouteDistance = this.current?.endPos ?? route.distance ?? route.points?.[route.points.length - 1]?.routeDistance;
1084
+ const totalRouteDistance = this.current?.endPos ?? route.distance ?? route.points?.at(-1)?.routeDistance;
1084
1085
  if (isLoop) {
1085
1086
  const currentLap = Math.floor((this.current.routeDistance ?? 0) / totalRouteDistance);
1086
1087
  return totalRouteDistance - (this.activity.startPos ?? 0) + currentLap * totalRouteDistance;
@@ -1100,8 +1101,8 @@ let ActivityRideService = (() => {
1100
1101
  if (!route)
1101
1102
  return 0;
1102
1103
  const isLoop = (0, route_1.checkIsLoop)(route);
1103
- const totalRouteDistance = this.current?.endPos ?? route.distance ?? route.points?.[route.points.length - 1]?.routeDistance;
1104
- let totalElevation = route.points?.[route.points.length - 1]?.elevationGain ?? 0;
1104
+ const totalRouteDistance = this.current?.endPos ?? route.distance ?? route.points?.at(-1)?.routeDistance;
1105
+ let totalElevation = route.points?.at(-1)?.elevationGain ?? 0;
1105
1106
  if (this.current?.endPos !== undefined && route.points) {
1106
1107
  const endPosPoint = route.points.find(p => p.routeDistance >= this.current.endPos);
1107
1108
  if (endPosPoint) {
@@ -57,7 +57,7 @@ class IntervalsApi extends base_1.AppApiBase {
57
57
  Authorization: 'Bearer ' + this.config.accessToken
58
58
  }
59
59
  };
60
- let url = `/athlete/0/activities${this.getUploadParams(request)}`;
60
+ const url = `/athlete/0/activities${this.getUploadParams(request)}`;
61
61
  const form = await this.createForm(url, { file: request.file }, reqOpts);
62
62
  const response = await this.postForm(form);
63
63
  if (response.data && !response.error && !response.data.error) {
@@ -186,7 +186,7 @@ let KomootAppConnection = (() => {
186
186
  this.on('login-failure', () => { this._isConnecting = false; });
187
187
  }
188
188
  getCrypto() {
189
- return (0, api_1.getBindings)().crypto ?? require('crypto');
189
+ return (0, api_1.getBindings)().crypto ?? require('node:crypto');
190
190
  }
191
191
  encrypt(algo) {
192
192
  if (!this.credentials)
@@ -170,7 +170,7 @@ let VeloHeroAppConnection = (() => {
170
170
  this.on('login-failure', () => { this._isConnecting = false; });
171
171
  }
172
172
  getCrypto() {
173
- return (0, api_1.getBindings)().crypto ?? require('crypto');
173
+ return (0, api_1.getBindings)().crypto ?? require('node:crypto');
174
174
  }
175
175
  encrypt(algo) {
176
176
  if (!this.credentials)
@@ -79,7 +79,8 @@ let AppStateService = (() => {
79
79
  try {
80
80
  this.getUserSettings().set(`state.${key}`, value);
81
81
  }
82
- catch { }
82
+ catch {
83
+ }
83
84
  }
84
85
  getState(key) {
85
86
  return this.state[key];
@@ -1,12 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PromiseObserver = exports.Observer = void 0;
4
- const events_1 = require("events");
4
+ const node_events_1 = require("node:events");
5
5
  const utils_1 = require("../../utils");
6
6
  class Observer {
7
7
  emitter;
8
8
  constructor() {
9
- this.emitter = new events_1.EventEmitter();
9
+ this.emitter = new node_events_1.EventEmitter();
10
10
  }
11
11
  on(event, callback) {
12
12
  this.emitter.on(event, callback);
@@ -27,7 +27,7 @@ class Coach {
27
27
  }
28
28
  get lead() {
29
29
  const lead = this.routeDistance - this.riderPosition;
30
- if (isNaN(lead))
30
+ if (Number.isNaN(lead))
31
31
  return 0;
32
32
  return lead;
33
33
  }
@@ -138,7 +138,7 @@ let CoachesService = (() => {
138
138
  if (startSettings.type === 'Route') {
139
139
  pos = startSettings.startPos;
140
140
  }
141
- const lead = (isNaN(c.settings?.lead) ? 0 : c.settings?.lead) ?? 0;
141
+ const lead = (Number.isNaN(c.settings?.lead) ? 0 : c.settings?.lead) ?? 0;
142
142
  c.setRoute(route);
143
143
  c.setProgress(lead + pos);
144
144
  c.setRiderPosition(pos);
@@ -287,7 +287,7 @@ let DeviceAccessService = (() => {
287
287
  const onDataHandlers = {};
288
288
  const { includeKnown = false } = props;
289
289
  const isKnown = (adapters, deviceSettings) => {
290
- if (adapters.find(a => a.isEqual(deviceSettings))) {
290
+ if (adapters.some(a => a.isEqual(deviceSettings))) {
291
291
  return true;
292
292
  }
293
293
  if (filter.profile && deviceSettings.profile !== filter.profile) {
@@ -377,7 +377,7 @@ let DeviceConfigurationService = (() => {
377
377
  const device = devices.find(d => d.udid === udid);
378
378
  if (!device)
379
379
  return;
380
- let mode, settings, isERG, isSIM;
380
+ let mode, settings;
381
381
  let modeObj;
382
382
  let modes = [];
383
383
  const adapter = this.getAdapterFromSetting(device.settings);
@@ -401,8 +401,8 @@ let DeviceConfigurationService = (() => {
401
401
  if (!settings && modeObj) {
402
402
  settings = modeObj.getSettings();
403
403
  }
404
- isERG = modeObj?.isERG() === true;
405
- isSIM = modeObj?.isSIM() === true;
404
+ const isERG = modeObj?.isERG() === true;
405
+ const isSIM = modeObj?.isSIM() === true;
406
406
  return { udid, mode, settings, isERG, isSIM, options };
407
407
  }
408
408
  catch (err) {
@@ -460,7 +460,7 @@ let DeviceConfigurationService = (() => {
460
460
  capabilities.forEach(c => {
461
461
  if (c.disabled || !c.selected)
462
462
  return;
463
- if (!devices.find(d => d.udid === c.selected))
463
+ if (!devices.some(d => d.udid === c.selected))
464
464
  return;
465
465
  const adapter = this.adapters[c.selected];
466
466
  if (!adapter)
@@ -775,7 +775,7 @@ let DeviceConfigurationService = (() => {
775
775
  if (!this.settings.capabilities)
776
776
  this.settings.capabilities = [];
777
777
  target.forEach(capability => {
778
- if (!this.settings.capabilities.find(c => c.capability === capability))
778
+ if (!this.settings.capabilities.some(c => c.capability === capability))
779
779
  this.settings.capabilities.push({ capability, devices: [], selected: undefined, disabled: false });
780
780
  });
781
781
  }
@@ -271,7 +271,7 @@ let DevicesPageService = (() => {
271
271
  isSelected: d.selected,
272
272
  onClick: (addAll) => { this.onDeviceSelected(d, addAll); }
273
273
  }));
274
- const disabled = devices.length > 0 && !devices.find(d => d.isSelected);
274
+ const disabled = devices.length > 0 && !devices.some(d => d.isSelected);
275
275
  return {
276
276
  capability: this.openedCapability,
277
277
  devices,