incyclist-services 1.7.65 → 1.7.67
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/lib/cjs/activities/base/utils/activity.js +13 -1
- package/lib/cjs/services/overpass/overpass.js +165 -13
- package/lib/esm/activities/base/utils/activity.js +13 -1
- package/lib/esm/package.json +68 -0
- package/lib/esm/services/overpass/overpass.js +165 -13
- package/lib/esm/src/activities/active-rides/service.js +4 -4
- package/lib/esm/src/activities/active-rides/sessions.js +0 -1
- package/lib/esm/src/activities/base/convert/converter.js +2 -2
- package/lib/esm/src/activities/base/convert/fit/index.js +1 -0
- package/lib/esm/src/activities/base/convert/fit/local-fit.js +237 -0
- package/lib/esm/src/activities/base/convert/fit/remote-fit.js +2 -2
- package/lib/esm/src/activities/base/convert/tcx/tcx.js +13 -4
- package/lib/esm/src/activities/base/model/index.js +5 -0
- package/lib/esm/src/activities/base/repo/db.js +2 -2
- package/lib/esm/src/activities/base/utils/activity.js +5 -5
- package/lib/esm/src/activities/base/utils/helpers.js +4 -3
- package/lib/esm/src/activities/list/utils.js +1 -1
- package/lib/esm/src/activities/ride/duration.js +1 -1
- package/lib/esm/src/activities/ride/service.js +102 -62
- package/lib/esm/src/api/repository/json/index.js +33 -6
- package/lib/esm/src/api/rest/api.js +4 -1
- package/lib/esm/src/api/rest/incyclist.js +1 -0
- package/lib/esm/src/apps/base/api/intervals/api.js +1 -1
- package/lib/esm/src/apps/intervals/index.js +0 -1
- package/lib/esm/src/apps/komoot/KomootAppConnection.js +1 -1
- package/lib/esm/src/apps/service.js +1 -0
- package/lib/esm/src/apps/velohero/VeloHeroAppConnection.js +1 -1
- package/lib/esm/src/appstate/service.js +2 -1
- package/lib/esm/src/base/types/observer.js +1 -1
- package/lib/esm/src/coaches/coach.js +1 -1
- package/lib/esm/src/coaches/service.js +1 -1
- package/lib/esm/src/devices/access/service.js +2 -2
- package/lib/esm/src/devices/configuration/service.js +11 -7
- package/lib/esm/src/devices/page/service.js +14 -2
- package/lib/esm/src/devices/pairing/service.js +14 -8
- package/lib/esm/src/devices/ride/service.js +34 -12
- package/lib/esm/src/i18n/countries/index.js +1 -115
- package/lib/esm/src/i18n/countries/service.js +118 -0
- package/lib/esm/src/maps/MapArea/MapArea.js +33 -33
- package/lib/esm/src/maps/MapArea/options.js +68 -60
- package/lib/esm/src/maps/MapArea/service.js +31 -15
- package/lib/esm/src/maps/MapArea/utils.js +55 -53
- package/lib/esm/src/ride/base/base.js +3 -2
- package/lib/esm/src/ride/display/service.js +35 -11
- package/lib/esm/src/ride/page/service.js +29 -15
- package/lib/esm/src/ride/route/FreeRideDisplayService.js +36 -18
- package/lib/esm/src/ride/route/GpxDisplayService.js +9 -6
- package/lib/esm/src/ride/route/RLVDisplayService.js +19 -6
- package/lib/esm/src/ride/route/RouteDisplayService.js +24 -17
- package/lib/esm/src/routes/base/model/route.js +2 -5
- package/lib/esm/src/routes/base/parsers/bikelab.js +2 -2
- package/lib/esm/src/routes/base/parsers/epm.js +19 -16
- package/lib/esm/src/routes/base/parsers/factory.js +5 -0
- package/lib/esm/src/routes/base/parsers/geometry.js +10 -5
- package/lib/esm/src/routes/base/parsers/gpx.js +7 -1
- package/lib/esm/src/routes/base/parsers/incyclist.js +6 -7
- package/lib/esm/src/routes/base/parsers/index.js +6 -2
- package/lib/esm/src/routes/base/parsers/multixml.js +9 -1
- package/lib/esm/src/routes/base/parsers/tacx/TacxParser.js +300 -223
- package/lib/esm/src/routes/base/parsers/utils.js +119 -14
- package/lib/esm/src/routes/base/parsers/xml.js +25 -13
- package/lib/esm/src/routes/base/utils/points.js +2 -2
- package/lib/esm/src/routes/base/utils/route.js +18 -18
- package/lib/esm/src/routes/download/service.js +52 -21
- package/lib/esm/src/routes/free-ride/service.js +77 -39
- package/lib/esm/src/routes/library/service.js +635 -0
- package/lib/esm/src/routes/list/cards/RouteCard.js +53 -23
- package/lib/esm/src/routes/list/lists/myroutes.js +1 -1
- package/lib/esm/src/routes/list/loaders/StravaActivityLoader.js +2 -2
- package/lib/esm/src/routes/list/loaders/api.js +0 -1
- package/lib/esm/src/routes/list/loaders/db.js +1 -0
- package/lib/esm/src/routes/list/service.js +69 -16
- package/lib/esm/src/routes/page/service.js +113 -88
- package/lib/esm/src/routes/sync/komoot/provider.js +1 -1
- package/lib/esm/src/services/overpass/overpass.js +115 -11
- package/lib/esm/src/settings/bindings/json.js +3 -3
- package/lib/esm/src/settings/display/user/service.js +2 -3
- package/lib/esm/src/settings/service/service.js +2 -2
- package/lib/esm/src/ui/service.js +33 -8
- package/lib/esm/src/utils/fileinfo.js +1 -1
- package/lib/esm/src/utils/formatting.js +3 -3
- package/lib/esm/src/utils/geo.js +5 -4
- package/lib/esm/src/utils/math.js +1 -1
- package/lib/esm/src/utils/vector.js +10 -10
- package/lib/esm/src/utils/xml.js +2 -2
- package/lib/esm/src/video/VideoConversion.js +3 -3
- package/lib/esm/src/video/VideoSyncHelper.js +29 -18
- package/lib/esm/src/workouts/base/model/Segment.js +1 -1
- package/lib/esm/src/workouts/base/model/Workout.js +2 -2
- package/lib/esm/src/workouts/base/parsers/incyclist/Json.js +3 -1
- package/lib/esm/src/workouts/base/parsers/intervals/parser.js +4 -2
- package/lib/esm/src/workouts/base/parsers/zwo/zwo.js +9 -6
- package/lib/esm/src/workouts/calendar/sync/intervals/provider.js +1 -1
- package/lib/esm/src/workouts/ride/service.js +2 -1
- package/lib/types/activities/base/utils/activity.d.ts +1 -0
- package/lib/types/services/overpass/overpass.d.ts +25 -0
- package/lib/types/src/activities/active-rides/mq.d.ts +2 -2
- package/lib/types/src/activities/active-rides/service.d.ts +5 -5
- package/lib/types/src/activities/base/convert/fit/index.d.ts +1 -0
- package/lib/types/src/activities/base/convert/fit/local-fit.d.ts +16 -0
- package/lib/types/src/activities/base/convert/tcx/tcx.d.ts +3 -1
- package/lib/types/src/activities/base/model/index.d.ts +4 -0
- package/lib/types/src/activities/base/repo/db.d.ts +2 -2
- package/lib/types/src/activities/base/utils/activity.d.ts +3 -3
- package/lib/types/src/activities/page/service.d.ts +1 -1
- package/lib/types/src/activities/ride/duration.d.ts +1 -1
- package/lib/types/src/activities/ride/service.d.ts +32 -64
- package/lib/types/src/activities/ride/stats.d.ts +1 -1
- package/lib/types/src/activities/ride/types.d.ts +16 -0
- package/lib/types/src/activities/upload/intervals.d.ts +2 -2
- package/lib/types/src/activities/upload/strava.d.ts +2 -2
- package/lib/types/src/activities/upload/velohero.d.ts +2 -2
- package/lib/types/src/api/download/index.d.ts +2 -1
- package/lib/types/src/api/fs/index.d.ts +13 -2
- package/lib/types/src/api/mq/index.d.ts +3 -1
- package/lib/types/src/api/path/index.d.ts +1 -1
- package/lib/types/src/api/repository/json/index.d.ts +5 -4
- package/lib/types/src/api/repository/types.d.ts +1 -2
- package/lib/types/src/api/rest/types.d.ts +1 -0
- package/lib/types/src/api/ui/index.d.ts +1 -0
- package/lib/types/src/api/video/index.d.ts +1 -1
- package/lib/types/src/apps/base/api/base.d.ts +1 -1
- package/lib/types/src/apps/base/api/strava/api.d.ts +1 -1
- package/lib/types/src/apps/base/app/index.d.ts +1 -1
- package/lib/types/src/apps/googleMaps/service.d.ts +1 -1
- package/lib/types/src/apps/intervals/IntervalsAppConnection.d.ts +1 -1
- package/lib/types/src/apps/komoot/KomootAppConnection.d.ts +2 -2
- package/lib/types/src/apps/service.d.ts +4 -4
- package/lib/types/src/apps/strava/StravaAppConnection.d.ts +3 -3
- package/lib/types/src/apps/velohero/VeloHeroAppConnection.d.ts +2 -3
- package/lib/types/src/autoupdate/autoupdate.d.ts +1 -1
- package/lib/types/src/base/decorators/Injection.d.ts +1 -1
- package/lib/types/src/base/service.d.ts +1 -1
- package/lib/types/src/base/types/observer.d.ts +1 -2
- package/lib/types/src/coaches/coach.d.ts +1 -1
- package/lib/types/src/devices/configuration/service.d.ts +1 -1
- package/lib/types/src/devices/page/service.d.ts +1 -0
- package/lib/types/src/devices/pairing/service.d.ts +12 -12
- package/lib/types/src/devices/ride/service.d.ts +10 -9
- package/lib/types/src/devices/types.d.ts +2 -0
- package/lib/types/src/i18n/countries/index.d.ts +1 -17
- package/lib/types/src/i18n/countries/model.d.ts +6 -3
- package/lib/types/src/i18n/countries/service.d.ts +18 -0
- package/lib/types/src/i18n/units/converter.d.ts +4 -4
- package/lib/types/src/index.d.ts +1 -1
- package/lib/types/src/maps/MapArea/MapArea.d.ts +1 -1
- package/lib/types/src/maps/MapArea/options.d.ts +6 -6
- package/lib/types/src/maps/MapArea/service.d.ts +10 -9
- package/lib/types/src/maps/MapArea/types.d.ts +6 -2
- package/lib/types/src/maps/MapArea/utils.d.ts +8 -8
- package/lib/types/src/ride/base/types.d.ts +5 -3
- package/lib/types/src/ride/display/service.d.ts +11 -9
- package/lib/types/src/ride/page/service.d.ts +6 -8
- package/lib/types/src/ride/page/types.d.ts +1 -0
- package/lib/types/src/ride/route/FreeRideDisplayService.d.ts +7 -5
- package/lib/types/src/ride/route/GpxDisplayService.d.ts +10 -5
- package/lib/types/src/ride/route/RLVDisplayService.d.ts +10 -8
- package/lib/types/src/ride/route/RouteDisplayService.d.ts +20 -16
- package/lib/types/src/routes/base/model/route.d.ts +1 -1
- package/lib/types/src/routes/base/parsers/epm.d.ts +3 -1
- package/lib/types/src/routes/base/parsers/factory.d.ts +2 -1
- package/lib/types/src/routes/base/parsers/geometry.d.ts +5 -2
- package/lib/types/src/routes/base/parsers/gpx.d.ts +2 -0
- package/lib/types/src/routes/base/parsers/index.d.ts +1 -1
- package/lib/types/src/routes/base/parsers/multixml.d.ts +4 -2
- package/lib/types/src/routes/base/parsers/tacx/TacxParser.d.ts +11 -3
- package/lib/types/src/routes/base/parsers/types.d.ts +14 -0
- package/lib/types/src/routes/base/parsers/utils.d.ts +4 -0
- package/lib/types/src/routes/base/parsers/xml.d.ts +4 -1
- package/lib/types/src/routes/base/types/index.d.ts +1 -11
- package/lib/types/src/routes/base/utils/localization.d.ts +1 -1
- package/lib/types/src/routes/base/utils/points.d.ts +2 -2
- package/lib/types/src/routes/base/utils/route.d.ts +2 -2
- package/lib/types/src/routes/download/service.d.ts +6 -4
- package/lib/types/src/routes/free-ride/service.d.ts +5 -1
- package/lib/types/src/routes/library/service.d.ts +44 -0
- package/lib/types/src/routes/library/types.d.ts +73 -0
- package/lib/types/src/routes/list/cards/ActiveImportCard.d.ts +3 -3
- package/lib/types/src/routes/list/cards/FreeRideCard.d.ts +1 -1
- package/lib/types/src/routes/list/cards/RouteCard.d.ts +12 -10
- package/lib/types/src/routes/list/cards/RouteImportCard.d.ts +1 -1
- package/lib/types/src/routes/list/cards/types.d.ts +4 -2
- package/lib/types/src/routes/list/loaders/StravaActivityLoader.d.ts +3 -3
- package/lib/types/src/routes/list/loaders/api.d.ts +1 -1
- package/lib/types/src/routes/list/loaders/db.d.ts +1 -0
- package/lib/types/src/routes/list/service.d.ts +13 -4
- package/lib/types/src/routes/page/service.d.ts +18 -12
- package/lib/types/src/routes/page/types.d.ts +5 -9
- package/lib/types/src/routes/sync/komoot/provider.d.ts +1 -1
- package/lib/types/src/routes/types.d.ts +2 -0
- package/lib/types/src/services/overpass/overpass.d.ts +19 -3
- package/lib/types/src/ui/service.d.ts +8 -4
- package/lib/types/src/utils/fileinfo.d.ts +1 -1
- package/lib/types/src/utils/formatting.d.ts +2 -2
- package/lib/types/src/utils/logging.d.ts +1 -1
- package/lib/types/src/utils/math.d.ts +1 -1
- package/lib/types/src/utils/string.d.ts +1 -1
- package/lib/types/src/utils/vector.d.ts +1 -1
- package/lib/types/src/utils/xml.d.ts +1 -1
- package/lib/types/src/video/VideoConversion.d.ts +1 -1
- package/lib/types/src/video/VideoSyncHelper.d.ts +1 -1
- package/lib/types/src/workouts/base/model/Segment.d.ts +1 -1
- package/lib/types/src/workouts/base/parsers/intervals/parser.d.ts +1 -1
- package/lib/types/src/workouts/base/parsers/zwo/zwo.d.ts +1 -1
- package/lib/types/src/workouts/calendar/service.d.ts +1 -1
- package/lib/types/src/workouts/list/cards/ActiveImportCard.d.ts +3 -3
- package/lib/types/src/workouts/list/cards/WorkoutCreateCard.d.ts +1 -1
- package/lib/types/src/workouts/list/cards/WorkoutImportCard.d.ts +1 -1
- package/lib/types/src/workouts/ride/service.d.ts +4 -4
- package/package.json +1 -1
- package/lib/cjs/api/form/index.js +0 -2
- package/lib/types/api/form/index.d.ts +0 -6
- /package/lib/esm/{api/form/index.js → src/routes/library/types.js} +0 -0
|
@@ -181,7 +181,7 @@ let Activity = (() => {
|
|
|
181
181
|
try {
|
|
182
182
|
const converter = this.getActivityConverter();
|
|
183
183
|
const data = await converter.convert(this.details, format);
|
|
184
|
-
const fileName = this.
|
|
184
|
+
const fileName = await this.getExportFileName(format);
|
|
185
185
|
await fs.writeFile(fileName, Buffer.from(data));
|
|
186
186
|
this.details[`${format}FileName`] = fileName;
|
|
187
187
|
await this.save(true);
|
|
@@ -197,6 +197,18 @@ let Activity = (() => {
|
|
|
197
197
|
}
|
|
198
198
|
return success;
|
|
199
199
|
}
|
|
200
|
+
async getExportFileName(format) {
|
|
201
|
+
let fileName = this.details.fileName.replace('json', format);
|
|
202
|
+
if (fileName.startsWith('mmkv:/')) {
|
|
203
|
+
const fs = this.getBindings().fs;
|
|
204
|
+
const appDir = this.getBindings().appInfo.getAppDir();
|
|
205
|
+
const activitiesDir = this.getBindings().path.join(appDir, 'activities');
|
|
206
|
+
await fs.ensureDir(activitiesDir);
|
|
207
|
+
const baseName = fileName.split('/').pop();
|
|
208
|
+
fileName = this.getBindings().path.join(activitiesDir, baseName);
|
|
209
|
+
}
|
|
210
|
+
return fileName;
|
|
211
|
+
}
|
|
200
212
|
async upload(connectedApp, observer) {
|
|
201
213
|
let success = false;
|
|
202
214
|
let error;
|
|
@@ -1,4 +1,11 @@
|
|
|
1
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
|
+
};
|
|
2
9
|
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
3
10
|
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
4
11
|
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
@@ -26,13 +33,6 @@ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn,
|
|
|
26
33
|
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
27
34
|
done = true;
|
|
28
35
|
};
|
|
29
|
-
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
30
|
-
var useValue = arguments.length > 2;
|
|
31
|
-
for (var i = 0; i < initializers.length; i++) {
|
|
32
|
-
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
33
|
-
}
|
|
34
|
-
return useValue ? value : void 0;
|
|
35
|
-
};
|
|
36
36
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
37
37
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
38
38
|
};
|
|
@@ -43,6 +43,9 @@ const types_1 = require("../../base/types");
|
|
|
43
43
|
const sleep_1 = require("../../utils/sleep");
|
|
44
44
|
const base_1 = require("../../apps/base/api/base");
|
|
45
45
|
const gd_eventlog_1 = require("gd-eventlog");
|
|
46
|
+
const decorators_1 = require("../../base/decorators");
|
|
47
|
+
const api_1 = require("../../api");
|
|
48
|
+
const settings_1 = require("../../settings");
|
|
46
49
|
const OVERPASS_URL_ALT1 = 'https://overpass.kumi.systems/api/interpreter';
|
|
47
50
|
const OVERPASS_URL_ALT2 = 'https://lz4.overpass-api.de/api/interpreter';
|
|
48
51
|
const OVERPASS_URL_ALT3 = 'https://z.overpass-api.de/api/interpreter';
|
|
@@ -53,16 +56,23 @@ let OverpassApi = (() => {
|
|
|
53
56
|
let _classExtraInitializers = [];
|
|
54
57
|
let _classThis;
|
|
55
58
|
let _classSuper = base_1.AppApiBase;
|
|
59
|
+
let _instanceExtraInitializers = [];
|
|
60
|
+
let _getUserSettings_decorators;
|
|
61
|
+
let _getBindings_decorators;
|
|
56
62
|
var OverpassApi = class extends _classSuper {
|
|
57
63
|
static { _classThis = this; }
|
|
58
64
|
static {
|
|
59
65
|
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
66
|
+
_getUserSettings_decorators = [decorators_1.Injectable];
|
|
67
|
+
_getBindings_decorators = [decorators_1.Injectable];
|
|
68
|
+
__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);
|
|
69
|
+
__esDecorate(this, null, _getBindings_decorators, { kind: "method", name: "getBindings", static: false, private: false, access: { has: obj => "getBindings" in obj, get: obj => obj.getBindings }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
60
70
|
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
61
71
|
OverpassApi = _classThis = _classDescriptor.value;
|
|
62
72
|
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
63
73
|
__runInitializers(_classThis, _classExtraInitializers);
|
|
64
74
|
}
|
|
65
|
-
url;
|
|
75
|
+
url = __runInitializers(this, _instanceExtraInitializers);
|
|
66
76
|
mirrors = [];
|
|
67
77
|
logger;
|
|
68
78
|
constructor(props) {
|
|
@@ -76,6 +86,70 @@ let OverpassApi = (() => {
|
|
|
76
86
|
}
|
|
77
87
|
}
|
|
78
88
|
}
|
|
89
|
+
getOverpassHeaders() {
|
|
90
|
+
const version = this.getAppVersion();
|
|
91
|
+
const userId = this.getUserId();
|
|
92
|
+
let userAgent = `Incyclist/${version}`;
|
|
93
|
+
if (userId) {
|
|
94
|
+
try {
|
|
95
|
+
const crypto = this.getBindings()?.crypto;
|
|
96
|
+
const hashedId = crypto ? crypto.createHash('sha256').update('OAPI:' + userId).digest('hex').substring(0, 8) : undefined;
|
|
97
|
+
if (hashedId) {
|
|
98
|
+
userAgent += ` (${hashedId})`;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
this.logger.logEvent({ message: 'failed to hash userId', error: err.message });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
'User-Agent': userAgent,
|
|
107
|
+
'Referer': 'https://incyclist.com'
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
async post(url, data, conf) {
|
|
111
|
+
try {
|
|
112
|
+
const https = require('https');
|
|
113
|
+
return await this.postViaNodeHttps(https, url, data);
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
const cfg = conf ?? {};
|
|
117
|
+
const config = {
|
|
118
|
+
...cfg,
|
|
119
|
+
headers: this.getOverpassHeaders()
|
|
120
|
+
};
|
|
121
|
+
return await super.post(url, data, config);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
async postViaNodeHttps(https, url, data) {
|
|
125
|
+
return new Promise((resolve, reject) => {
|
|
126
|
+
const reqUrl = new URL(url);
|
|
127
|
+
const headers = this.getOverpassHeaders();
|
|
128
|
+
const queryData = typeof data === 'string' ? data : JSON.stringify(data);
|
|
129
|
+
const options = {
|
|
130
|
+
method: 'POST',
|
|
131
|
+
headers: {
|
|
132
|
+
...headers,
|
|
133
|
+
'Content-Length': Buffer.byteLength(queryData)
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
const req = https.request(reqUrl, options, (res) => {
|
|
137
|
+
let body = '';
|
|
138
|
+
res.on('data', (chunk) => body += chunk);
|
|
139
|
+
res.on('end', () => {
|
|
140
|
+
resolve({
|
|
141
|
+
data: body,
|
|
142
|
+
status: res.statusCode,
|
|
143
|
+
statusText: res.statusMessage,
|
|
144
|
+
headers: res.headers
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
req.on('error', reject);
|
|
149
|
+
req.write(queryData);
|
|
150
|
+
req.end();
|
|
151
|
+
});
|
|
152
|
+
}
|
|
79
153
|
async query(queryOL, timeout) {
|
|
80
154
|
const ts = Date.now();
|
|
81
155
|
this.logger.logEvent({ message: 'query', queryOL, queryId: ts, timeout });
|
|
@@ -96,24 +170,102 @@ let OverpassApi = (() => {
|
|
|
96
170
|
getBaseUrl() {
|
|
97
171
|
return '';
|
|
98
172
|
}
|
|
173
|
+
extractErrorInfo(err, mirror) {
|
|
174
|
+
return {
|
|
175
|
+
mirror,
|
|
176
|
+
status: err?.response?.status,
|
|
177
|
+
statusText: err?.response?.statusText,
|
|
178
|
+
error: err?.message ?? 'overpass query failed'
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
logUnexpectedErrors(fn, errors) {
|
|
182
|
+
const unexpectedErrors = errors.filter(e => {
|
|
183
|
+
const status = e.status;
|
|
184
|
+
if (!status || status === 408 || status === 504)
|
|
185
|
+
return false;
|
|
186
|
+
return status >= 406 && status < 500;
|
|
187
|
+
});
|
|
188
|
+
if (unexpectedErrors.length > 0 && unexpectedErrors.length === errors.length) {
|
|
189
|
+
unexpectedErrors.forEach(err => {
|
|
190
|
+
this.logger.logEvent({
|
|
191
|
+
message: 'error',
|
|
192
|
+
fn,
|
|
193
|
+
mirror: err.mirror,
|
|
194
|
+
status: err.status,
|
|
195
|
+
statusText: err.statusText,
|
|
196
|
+
error: err.error ?? 'all mirrors failed with 4xx error'
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
}
|
|
99
201
|
async bulkQuery(query, timeout) {
|
|
202
|
+
const errors = [];
|
|
100
203
|
const promises = [];
|
|
101
204
|
this.mirrors.forEach(mirror => {
|
|
102
|
-
promises.push(this.post(mirror, query)
|
|
205
|
+
promises.push(this.post(mirror, query)
|
|
206
|
+
.then((res) => res?.data)
|
|
207
|
+
.catch(err => {
|
|
208
|
+
errors.push(this.extractErrorInfo(err, mirror));
|
|
209
|
+
throw err;
|
|
210
|
+
}));
|
|
103
211
|
});
|
|
104
212
|
if (timeout !== undefined && timeout !== null) {
|
|
105
213
|
promises.push((0, sleep_1.sleep)(timeout).then(() => 'timeout'));
|
|
106
214
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
215
|
+
try {
|
|
216
|
+
const res = await (0, promise_any_1.default)(promises);
|
|
217
|
+
if (res === 'timeout') {
|
|
218
|
+
return undefined;
|
|
219
|
+
}
|
|
220
|
+
return res;
|
|
221
|
+
}
|
|
222
|
+
catch (err) {
|
|
223
|
+
this.logUnexpectedErrors('bulkQuery', errors);
|
|
224
|
+
throw err;
|
|
110
225
|
}
|
|
111
|
-
|
|
226
|
+
}
|
|
227
|
+
async sequentialQuery(query, timeout) {
|
|
228
|
+
const startTime = Date.now();
|
|
229
|
+
const errors = [];
|
|
230
|
+
let lastError;
|
|
231
|
+
for (const mirror of this.mirrors) {
|
|
232
|
+
if (timeout !== undefined && timeout !== null) {
|
|
233
|
+
const elapsed = Date.now() - startTime;
|
|
234
|
+
if (elapsed >= timeout) {
|
|
235
|
+
return undefined;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
try {
|
|
239
|
+
const res = await this.post(mirror, query);
|
|
240
|
+
return res?.data;
|
|
241
|
+
}
|
|
242
|
+
catch (err) {
|
|
243
|
+
lastError = err;
|
|
244
|
+
errors.push(this.extractErrorInfo(err, mirror));
|
|
245
|
+
if (mirror !== this.mirrors[this.mirrors.length - 1]) {
|
|
246
|
+
await (0, sleep_1.sleep)(100);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
this.logUnexpectedErrors('sequentialQuery', errors);
|
|
251
|
+
throw lastError;
|
|
112
252
|
}
|
|
113
253
|
reset() {
|
|
114
254
|
this.mirrors = [OVERPASS_URL_ALT1, OVERPASS_URL_ALT2, OVERPASS_URL_ALT3];
|
|
115
255
|
this.url = this.mirrors[0];
|
|
116
256
|
}
|
|
257
|
+
getAppVersion() {
|
|
258
|
+
return this.getBindings()?.appInfo?.getAppVersion() ?? '';
|
|
259
|
+
}
|
|
260
|
+
getUserId() {
|
|
261
|
+
return this.getUserSettings().getValue('uuid', '');
|
|
262
|
+
}
|
|
263
|
+
getUserSettings() {
|
|
264
|
+
return (0, settings_1.useUserSettings)();
|
|
265
|
+
}
|
|
266
|
+
getBindings() {
|
|
267
|
+
return (0, api_1.getBindings)();
|
|
268
|
+
}
|
|
117
269
|
};
|
|
118
270
|
return OverpassApi = _classThis;
|
|
119
271
|
})();
|
|
@@ -178,7 +178,7 @@ let Activity = (() => {
|
|
|
178
178
|
try {
|
|
179
179
|
const converter = this.getActivityConverter();
|
|
180
180
|
const data = await converter.convert(this.details, format);
|
|
181
|
-
const fileName = this.
|
|
181
|
+
const fileName = await this.getExportFileName(format);
|
|
182
182
|
await fs.writeFile(fileName, Buffer.from(data));
|
|
183
183
|
this.details[`${format}FileName`] = fileName;
|
|
184
184
|
await this.save(true);
|
|
@@ -194,6 +194,18 @@ let Activity = (() => {
|
|
|
194
194
|
}
|
|
195
195
|
return success;
|
|
196
196
|
}
|
|
197
|
+
async getExportFileName(format) {
|
|
198
|
+
let fileName = this.details.fileName.replace('json', format);
|
|
199
|
+
if (fileName.startsWith('mmkv:/')) {
|
|
200
|
+
const fs = this.getBindings().fs;
|
|
201
|
+
const appDir = this.getBindings().appInfo.getAppDir();
|
|
202
|
+
const activitiesDir = this.getBindings().path.join(appDir, 'activities');
|
|
203
|
+
await fs.ensureDir(activitiesDir);
|
|
204
|
+
const baseName = fileName.split('/').pop();
|
|
205
|
+
fileName = this.getBindings().path.join(activitiesDir, baseName);
|
|
206
|
+
}
|
|
207
|
+
return fileName;
|
|
208
|
+
}
|
|
197
209
|
async upload(connectedApp, observer) {
|
|
198
210
|
let success = false;
|
|
199
211
|
let error;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "incyclist-services",
|
|
3
|
+
"version": "1.7.65",
|
|
4
|
+
"peerDependencies": {
|
|
5
|
+
"gd-eventlog": "^0.1.27"
|
|
6
|
+
},
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"@garmin/fitsdk": "^21.200.0",
|
|
9
|
+
"axios": "^1.15.2",
|
|
10
|
+
"incyclist-devices": "^3.0.21",
|
|
11
|
+
"promise.any": "^2.0.6",
|
|
12
|
+
"semver": "^7.7.4",
|
|
13
|
+
"tcx-builder": "^1.1.1",
|
|
14
|
+
"uuid": "^14.0.0",
|
|
15
|
+
"xml2js": "^0.6.2"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@serialport/binding-mock": "^10.2.2",
|
|
19
|
+
"@serialport/bindings-interface": "^1.2.2",
|
|
20
|
+
"@types/jest": "^30.0.0",
|
|
21
|
+
"@types/node": "^25.6.0",
|
|
22
|
+
"@typescript-eslint/eslint-plugin": "^8.58.2",
|
|
23
|
+
"@typescript-eslint/parser": "^8.58.2",
|
|
24
|
+
"dotenv": "^17.4.2",
|
|
25
|
+
"eslint": "^9.39.4",
|
|
26
|
+
"formdata-node": "^6.0.3",
|
|
27
|
+
"jest": "^30.3.0",
|
|
28
|
+
"jsdoc": "^4.0.5",
|
|
29
|
+
"ts-jest": "^29.4.9",
|
|
30
|
+
"typedoc": "^0.28.19",
|
|
31
|
+
"typedoc-plugin-markdown": "^4.11.0",
|
|
32
|
+
"typedoc-plugin-no-inherit": "^1.6.1",
|
|
33
|
+
"typescript": "^5.9.3",
|
|
34
|
+
"typescript-eslint": "^8.58.2"
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"lint": "eslint . --quiet",
|
|
38
|
+
"buildx": "npm run lint && tsc",
|
|
39
|
+
"build": "npm run build:esm && npm run build:cjs",
|
|
40
|
+
"build:esm": "tsc -p tsconfig.esm.json",
|
|
41
|
+
"build:cjs": "tsc -p tsconfig.cjs.json",
|
|
42
|
+
"test:all": "npx jest",
|
|
43
|
+
"test:e2e": "npx jest --coverage -c jest.e2e-config.cjs --coverageDirectory coverage.e2e",
|
|
44
|
+
"test:unit": "npx jest --coverage -c jest.unit-config.cjs ",
|
|
45
|
+
"test": "npx jest --coverage -c jest.unit-config.cjs ",
|
|
46
|
+
"dev": "tsc -p tsconfig.esm.json --watch",
|
|
47
|
+
"docgen": "typedoc --options typedoc.json",
|
|
48
|
+
"docgen1": "typedoc --readme none --excludeProtected --excludePrivate --plugin typedoc-plugin-no-inherit --plugin typedoc-plugin-markdown src/index.ts",
|
|
49
|
+
"postversion": "git push --tags"
|
|
50
|
+
},
|
|
51
|
+
"files": [
|
|
52
|
+
"lib/"
|
|
53
|
+
],
|
|
54
|
+
"module": "./lib/esm/index.js",
|
|
55
|
+
"main": "./lib/cjs/index.js",
|
|
56
|
+
"types": "./lib/types/index.d.ts",
|
|
57
|
+
"exports": {
|
|
58
|
+
".": {
|
|
59
|
+
"types": "./lib/types/index.d.ts",
|
|
60
|
+
"import": "./lib/esm/index.js",
|
|
61
|
+
"require": "./lib/cjs/index.js"
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
"directories": {
|
|
65
|
+
"example": "./sample",
|
|
66
|
+
"lib": "./src"
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
2
|
+
var useValue = arguments.length > 2;
|
|
3
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
4
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
5
|
+
}
|
|
6
|
+
return useValue ? value : void 0;
|
|
7
|
+
};
|
|
1
8
|
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
2
9
|
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
3
10
|
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
@@ -25,18 +32,14 @@ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn,
|
|
|
25
32
|
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
26
33
|
done = true;
|
|
27
34
|
};
|
|
28
|
-
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
29
|
-
var useValue = arguments.length > 2;
|
|
30
|
-
for (var i = 0; i < initializers.length; i++) {
|
|
31
|
-
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
32
|
-
}
|
|
33
|
-
return useValue ? value : void 0;
|
|
34
|
-
};
|
|
35
35
|
import any from 'promise.any';
|
|
36
36
|
import { Singleton } from '../../base/types';
|
|
37
37
|
import { sleep } from '../../utils/sleep';
|
|
38
38
|
import { AppApiBase } from '../../apps/base/api/base';
|
|
39
39
|
import { EventLogger } from 'gd-eventlog';
|
|
40
|
+
import { Injectable } from '../../base/decorators';
|
|
41
|
+
import { getBindings } from '../../api';
|
|
42
|
+
import { useUserSettings } from '../../settings';
|
|
40
43
|
const OVERPASS_URL_ALT1 = 'https://overpass.kumi.systems/api/interpreter';
|
|
41
44
|
const OVERPASS_URL_ALT2 = 'https://lz4.overpass-api.de/api/interpreter';
|
|
42
45
|
const OVERPASS_URL_ALT3 = 'https://z.overpass-api.de/api/interpreter';
|
|
@@ -47,16 +50,23 @@ let OverpassApi = (() => {
|
|
|
47
50
|
let _classExtraInitializers = [];
|
|
48
51
|
let _classThis;
|
|
49
52
|
let _classSuper = AppApiBase;
|
|
53
|
+
let _instanceExtraInitializers = [];
|
|
54
|
+
let _getUserSettings_decorators;
|
|
55
|
+
let _getBindings_decorators;
|
|
50
56
|
var OverpassApi = class extends _classSuper {
|
|
51
57
|
static { _classThis = this; }
|
|
52
58
|
static {
|
|
53
59
|
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
60
|
+
_getUserSettings_decorators = [Injectable];
|
|
61
|
+
_getBindings_decorators = [Injectable];
|
|
62
|
+
__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);
|
|
63
|
+
__esDecorate(this, null, _getBindings_decorators, { kind: "method", name: "getBindings", static: false, private: false, access: { has: obj => "getBindings" in obj, get: obj => obj.getBindings }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
54
64
|
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
55
65
|
OverpassApi = _classThis = _classDescriptor.value;
|
|
56
66
|
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
57
67
|
__runInitializers(_classThis, _classExtraInitializers);
|
|
58
68
|
}
|
|
59
|
-
url;
|
|
69
|
+
url = __runInitializers(this, _instanceExtraInitializers);
|
|
60
70
|
mirrors = [];
|
|
61
71
|
logger;
|
|
62
72
|
constructor(props) {
|
|
@@ -70,6 +80,70 @@ let OverpassApi = (() => {
|
|
|
70
80
|
}
|
|
71
81
|
}
|
|
72
82
|
}
|
|
83
|
+
getOverpassHeaders() {
|
|
84
|
+
const version = this.getAppVersion();
|
|
85
|
+
const userId = this.getUserId();
|
|
86
|
+
let userAgent = `Incyclist/${version}`;
|
|
87
|
+
if (userId) {
|
|
88
|
+
try {
|
|
89
|
+
const crypto = this.getBindings()?.crypto;
|
|
90
|
+
const hashedId = crypto ? crypto.createHash('sha256').update('OAPI:' + userId).digest('hex').substring(0, 8) : undefined;
|
|
91
|
+
if (hashedId) {
|
|
92
|
+
userAgent += ` (${hashedId})`;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
this.logger.logEvent({ message: 'failed to hash userId', error: err.message });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
'User-Agent': userAgent,
|
|
101
|
+
'Referer': 'https://incyclist.com'
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
async post(url, data, conf) {
|
|
105
|
+
try {
|
|
106
|
+
const https = require('https');
|
|
107
|
+
return await this.postViaNodeHttps(https, url, data);
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
const cfg = conf ?? {};
|
|
111
|
+
const config = {
|
|
112
|
+
...cfg,
|
|
113
|
+
headers: this.getOverpassHeaders()
|
|
114
|
+
};
|
|
115
|
+
return await super.post(url, data, config);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
async postViaNodeHttps(https, url, data) {
|
|
119
|
+
return new Promise((resolve, reject) => {
|
|
120
|
+
const reqUrl = new URL(url);
|
|
121
|
+
const headers = this.getOverpassHeaders();
|
|
122
|
+
const queryData = typeof data === 'string' ? data : JSON.stringify(data);
|
|
123
|
+
const options = {
|
|
124
|
+
method: 'POST',
|
|
125
|
+
headers: {
|
|
126
|
+
...headers,
|
|
127
|
+
'Content-Length': Buffer.byteLength(queryData)
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
const req = https.request(reqUrl, options, (res) => {
|
|
131
|
+
let body = '';
|
|
132
|
+
res.on('data', (chunk) => body += chunk);
|
|
133
|
+
res.on('end', () => {
|
|
134
|
+
resolve({
|
|
135
|
+
data: body,
|
|
136
|
+
status: res.statusCode,
|
|
137
|
+
statusText: res.statusMessage,
|
|
138
|
+
headers: res.headers
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
req.on('error', reject);
|
|
143
|
+
req.write(queryData);
|
|
144
|
+
req.end();
|
|
145
|
+
});
|
|
146
|
+
}
|
|
73
147
|
async query(queryOL, timeout) {
|
|
74
148
|
const ts = Date.now();
|
|
75
149
|
this.logger.logEvent({ message: 'query', queryOL, queryId: ts, timeout });
|
|
@@ -90,24 +164,102 @@ let OverpassApi = (() => {
|
|
|
90
164
|
getBaseUrl() {
|
|
91
165
|
return '';
|
|
92
166
|
}
|
|
167
|
+
extractErrorInfo(err, mirror) {
|
|
168
|
+
return {
|
|
169
|
+
mirror,
|
|
170
|
+
status: err?.response?.status,
|
|
171
|
+
statusText: err?.response?.statusText,
|
|
172
|
+
error: err?.message ?? 'overpass query failed'
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
logUnexpectedErrors(fn, errors) {
|
|
176
|
+
const unexpectedErrors = errors.filter(e => {
|
|
177
|
+
const status = e.status;
|
|
178
|
+
if (!status || status === 408 || status === 504)
|
|
179
|
+
return false;
|
|
180
|
+
return status >= 406 && status < 500;
|
|
181
|
+
});
|
|
182
|
+
if (unexpectedErrors.length > 0 && unexpectedErrors.length === errors.length) {
|
|
183
|
+
unexpectedErrors.forEach(err => {
|
|
184
|
+
this.logger.logEvent({
|
|
185
|
+
message: 'error',
|
|
186
|
+
fn,
|
|
187
|
+
mirror: err.mirror,
|
|
188
|
+
status: err.status,
|
|
189
|
+
statusText: err.statusText,
|
|
190
|
+
error: err.error ?? 'all mirrors failed with 4xx error'
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
}
|
|
93
195
|
async bulkQuery(query, timeout) {
|
|
196
|
+
const errors = [];
|
|
94
197
|
const promises = [];
|
|
95
198
|
this.mirrors.forEach(mirror => {
|
|
96
|
-
promises.push(this.post(mirror, query)
|
|
199
|
+
promises.push(this.post(mirror, query)
|
|
200
|
+
.then((res) => res?.data)
|
|
201
|
+
.catch(err => {
|
|
202
|
+
errors.push(this.extractErrorInfo(err, mirror));
|
|
203
|
+
throw err;
|
|
204
|
+
}));
|
|
97
205
|
});
|
|
98
206
|
if (timeout !== undefined && timeout !== null) {
|
|
99
207
|
promises.push(sleep(timeout).then(() => 'timeout'));
|
|
100
208
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
209
|
+
try {
|
|
210
|
+
const res = await any(promises);
|
|
211
|
+
if (res === 'timeout') {
|
|
212
|
+
return undefined;
|
|
213
|
+
}
|
|
214
|
+
return res;
|
|
215
|
+
}
|
|
216
|
+
catch (err) {
|
|
217
|
+
this.logUnexpectedErrors('bulkQuery', errors);
|
|
218
|
+
throw err;
|
|
104
219
|
}
|
|
105
|
-
|
|
220
|
+
}
|
|
221
|
+
async sequentialQuery(query, timeout) {
|
|
222
|
+
const startTime = Date.now();
|
|
223
|
+
const errors = [];
|
|
224
|
+
let lastError;
|
|
225
|
+
for (const mirror of this.mirrors) {
|
|
226
|
+
if (timeout !== undefined && timeout !== null) {
|
|
227
|
+
const elapsed = Date.now() - startTime;
|
|
228
|
+
if (elapsed >= timeout) {
|
|
229
|
+
return undefined;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
try {
|
|
233
|
+
const res = await this.post(mirror, query);
|
|
234
|
+
return res?.data;
|
|
235
|
+
}
|
|
236
|
+
catch (err) {
|
|
237
|
+
lastError = err;
|
|
238
|
+
errors.push(this.extractErrorInfo(err, mirror));
|
|
239
|
+
if (mirror !== this.mirrors[this.mirrors.length - 1]) {
|
|
240
|
+
await sleep(100);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
this.logUnexpectedErrors('sequentialQuery', errors);
|
|
245
|
+
throw lastError;
|
|
106
246
|
}
|
|
107
247
|
reset() {
|
|
108
248
|
this.mirrors = [OVERPASS_URL_ALT1, OVERPASS_URL_ALT2, OVERPASS_URL_ALT3];
|
|
109
249
|
this.url = this.mirrors[0];
|
|
110
250
|
}
|
|
251
|
+
getAppVersion() {
|
|
252
|
+
return this.getBindings()?.appInfo?.getAppVersion() ?? '';
|
|
253
|
+
}
|
|
254
|
+
getUserId() {
|
|
255
|
+
return this.getUserSettings().getValue('uuid', '');
|
|
256
|
+
}
|
|
257
|
+
getUserSettings() {
|
|
258
|
+
return useUserSettings();
|
|
259
|
+
}
|
|
260
|
+
getBindings() {
|
|
261
|
+
return getBindings();
|
|
262
|
+
}
|
|
111
263
|
};
|
|
112
264
|
return OverpassApi = _classThis;
|
|
113
265
|
})();
|
|
@@ -389,9 +389,9 @@ let ActiveRidesService = (() => {
|
|
|
389
389
|
return 'Anonymous';
|
|
390
390
|
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'];
|
|
391
391
|
const fnKey = id.charAt(0).toLowerCase();
|
|
392
|
-
const idx = !isNaN(parseInt(fnKey)) ? parseInt(fnKey) : fnKey.
|
|
392
|
+
const idx = !Number.isNaN(Number.parseInt(fnKey)) ? Number.parseInt(fnKey) : (fnKey.codePointAt(0) ?? 0) - 96;
|
|
393
393
|
const lnKey = id.charAt(0).toUpperCase();
|
|
394
|
-
const ln = !isNaN(parseInt(lnKey)) ? '' : lnKey;
|
|
394
|
+
const ln = !Number.isNaN(Number.parseInt(lnKey)) ? '' : lnKey;
|
|
395
395
|
return `${names[idx]}${ln}`;
|
|
396
396
|
}
|
|
397
397
|
addCurrentActivity() {
|
|
@@ -564,7 +564,7 @@ let ActiveRidesService = (() => {
|
|
|
564
564
|
const logs = this.activity?.logs ?? [];
|
|
565
565
|
if (!logs.length)
|
|
566
566
|
return;
|
|
567
|
-
const point = logs
|
|
567
|
+
const point = logs.at(-1);
|
|
568
568
|
const { lat, lng, elevation, slope } = point;
|
|
569
569
|
return { lat, lng, elevation, slope };
|
|
570
570
|
}
|
|
@@ -804,7 +804,7 @@ let ActiveRidesService = (() => {
|
|
|
804
804
|
}
|
|
805
805
|
this.coaches = coaches.map(c => {
|
|
806
806
|
const props = c.getRidersListDisplayProperties();
|
|
807
|
-
|
|
807
|
+
const routeDistance = props.currentRideDistance;
|
|
808
808
|
const entry = { ...props,
|
|
809
809
|
ride: this.current?.ride,
|
|
810
810
|
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { ActivityConverterFactory } from "./factory";
|
|
2
|
-
import {
|
|
2
|
+
import { LocalFitConverter } from "./fit";
|
|
3
3
|
import { TcxConverter } from "./tcx";
|
|
4
4
|
export class ActivityConverter {
|
|
5
5
|
static factory;
|
|
6
6
|
static async convert(activity, format) {
|
|
7
7
|
if (!ActivityConverter.factory) {
|
|
8
8
|
ActivityConverter.factory = new ActivityConverterFactory();
|
|
9
|
-
ActivityConverter.factory.add('fit', new
|
|
9
|
+
ActivityConverter.factory.add('fit', new LocalFitConverter());
|
|
10
10
|
ActivityConverter.factory.add('tcx', new TcxConverter());
|
|
11
11
|
}
|
|
12
12
|
return await ActivityConverter.factory.convert(activity, format);
|