hevy-shared 1.0.714 → 1.0.716
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/built/hevyTrainer.d.ts +47 -9
- package/built/hevyTrainer.js +149 -83
- package/built/index.d.ts +14 -2
- package/package.json +1 -1
package/built/hevyTrainer.d.ts
CHANGED
|
@@ -5,6 +5,34 @@ export type HevyTrainerProgramEquipment = Extract<Equipment, 'barbell' | 'dumbbe
|
|
|
5
5
|
export declare const hevyTrainerExerciseCategories: readonly ["compound", "isolation"];
|
|
6
6
|
export declare const routineNames: readonly ["full_body_1", "full_body_2_a", "full_body_2_b", "full_body_3_a", "full_body_3_b", "full_body_3_c", "upper_1_a", "lower_1_a", "upper_1_b", "lower_1_b", "push_1", "pull_1", "legs_1", "upper_2", "lower_2", "push_2_a", "pull_2_a", "legs_2_a", "push_2_b", "pull_2_b", "legs_2_b"];
|
|
7
7
|
export type exerciseId = string;
|
|
8
|
+
export interface ExerciseSelectionCriteria {
|
|
9
|
+
exerciseCategory: HevyTrainerExerciseCategory;
|
|
10
|
+
equipments: HevyTrainerProgramEquipment[];
|
|
11
|
+
routineBarbellExerciseCount: number;
|
|
12
|
+
level: TrainingLevel;
|
|
13
|
+
goal: TrainingGoal;
|
|
14
|
+
muscleGroup: MuscleGroup;
|
|
15
|
+
}
|
|
16
|
+
export interface ExerciseSelectionContext {
|
|
17
|
+
programUsedExerciseIds?: Set<string>;
|
|
18
|
+
routineUsedExerciseIds?: Set<string>;
|
|
19
|
+
excludedExerciseIds?: Set<string>;
|
|
20
|
+
}
|
|
21
|
+
export interface ExerciseSelectionParams {
|
|
22
|
+
sortedExercises: Record<MuscleGroup, HevyTrainerLibraryExercise[]>;
|
|
23
|
+
criteria: ExerciseSelectionCriteria;
|
|
24
|
+
context: ExerciseSelectionContext;
|
|
25
|
+
}
|
|
26
|
+
export interface ProgramGenerationParams<T extends HevyTrainerLibraryExercise> {
|
|
27
|
+
trainerPreset: TrainerPreset;
|
|
28
|
+
selectedDays: WeeklyTrainingFrequency;
|
|
29
|
+
selectedGoal: TrainingGoal;
|
|
30
|
+
selectedLevel: TrainingLevel;
|
|
31
|
+
selectedEquipments: HevyTrainerProgramEquipment[];
|
|
32
|
+
exerciseStore: T[];
|
|
33
|
+
focusMuscle?: SimplifiedMuscleGroup;
|
|
34
|
+
excludedExerciseIds?: Set<string>;
|
|
35
|
+
}
|
|
8
36
|
export declare const frequencyMap: Record<WeeklyTrainingFrequency, string>;
|
|
9
37
|
export declare const programSplits: Record<WeeklyTrainingFrequency, HevyTrainerRoutineName[]>;
|
|
10
38
|
export type SetsPerGoal = {
|
|
@@ -84,6 +112,21 @@ export interface TrainerProgram {
|
|
|
84
112
|
name: WeeklyTrainingFrequency;
|
|
85
113
|
routines: TrainerProgramRoutine[];
|
|
86
114
|
}
|
|
115
|
+
/**
|
|
116
|
+
* Sorts exercises by priority for each muscle group based on the provided priorities
|
|
117
|
+
* and adds any remaining exercises from the store that weren't in the priorities.
|
|
118
|
+
*
|
|
119
|
+
* @param exercisePriorities - Object mapping muscle groups to arrays of exercise IDs in priority order
|
|
120
|
+
* @param exerciseStore - Array of all available exercises
|
|
121
|
+
* @returns Object mapping muscle groups to arrays of exercises sorted by priority
|
|
122
|
+
*/
|
|
123
|
+
export declare const getPrioritySortedExercises: <T extends HevyTrainerLibraryExercise>(exercisePriorities: ExercisePriorities, exerciseStore: T[]) => Record<MuscleGroup, T[]>;
|
|
124
|
+
/**
|
|
125
|
+
* Selects the best exercise for a given prescription using a multi-pass strategy
|
|
126
|
+
*/
|
|
127
|
+
export declare const pickExerciseForPrescription: <T extends HevyTrainerLibraryExercise>(params: ExerciseSelectionParams & {
|
|
128
|
+
sortedExercises: Record<MuscleGroup, T[]>;
|
|
129
|
+
}) => T | undefined;
|
|
87
130
|
export type HevyTrainerLibraryExercise = Pick<LibraryExercise, 'id' | 'title' | 'priority' | 'muscle_group' | 'other_muscles' | 'exercise_type' | 'equipment_category' | 'category' | 'level' | 'goal'>;
|
|
88
131
|
export interface ExercisePrescriptionError {
|
|
89
132
|
type: 'exercise_not_found';
|
|
@@ -115,12 +158,7 @@ export interface TrainerProgramError {
|
|
|
115
158
|
partialProgram?: TrainerProgram;
|
|
116
159
|
}
|
|
117
160
|
export type TrainerProgramAttempt = TrainerProgramResult | TrainerProgramError;
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
selectedLevel: TrainingLevel;
|
|
123
|
-
selectedEquipments: HevyTrainerProgramEquipment[];
|
|
124
|
-
exerciseStore: HevyTrainerLibraryExercise[];
|
|
125
|
-
focusMuscle?: SimplifiedMuscleGroup;
|
|
126
|
-
}) => TrainerProgramAttempt;
|
|
161
|
+
/**
|
|
162
|
+
* Generates a complete training program based on the provided parameters
|
|
163
|
+
*/
|
|
164
|
+
export declare const generateProgram: <T extends HevyTrainerLibraryExercise>(params: ProgramGenerationParams<T>) => TrainerProgramAttempt;
|
package/built/hevyTrainer.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.generateProgram = exports.programSplits = exports.frequencyMap = exports.routineNames = exports.hevyTrainerExerciseCategories = void 0;
|
|
3
|
+
exports.generateProgram = exports.pickExerciseForPrescription = exports.getPrioritySortedExercises = exports.programSplits = exports.frequencyMap = exports.routineNames = exports.hevyTrainerExerciseCategories = void 0;
|
|
4
4
|
const _1 = require(".");
|
|
5
|
+
const MAX_BARBELL_EXERCISES_PER_ROUTINE = 2;
|
|
5
6
|
exports.hevyTrainerExerciseCategories = ['compound', 'isolation'];
|
|
6
7
|
exports.routineNames = [
|
|
7
8
|
// Full body 1x
|
|
@@ -48,6 +49,24 @@ exports.programSplits = {
|
|
|
48
49
|
5: ['push_1', 'pull_1', 'legs_1', 'upper_2', 'lower_2'],
|
|
49
50
|
6: ['push_2_a', 'pull_2_a', 'legs_2_a', 'push_2_b', 'pull_2_b', 'legs_2_b'],
|
|
50
51
|
};
|
|
52
|
+
// Utility functions for better code organization
|
|
53
|
+
const isEquipmentCompatible = (exercise, allowedEquipments) => {
|
|
54
|
+
return (allowedEquipments.includes(exercise.equipment_category) ||
|
|
55
|
+
exercise.equipment_category === 'none' ||
|
|
56
|
+
exercise.equipment_category === 'other');
|
|
57
|
+
};
|
|
58
|
+
const isBarbellLimitExceeded = (exercise, routineBarbellExerciseCount, allowedEquipments) => {
|
|
59
|
+
return (exercise.equipment_category === 'barbell' &&
|
|
60
|
+
routineBarbellExerciseCount >= MAX_BARBELL_EXERCISES_PER_ROUTINE &&
|
|
61
|
+
allowedEquipments.length > 1);
|
|
62
|
+
};
|
|
63
|
+
const isExerciseUsed = (exercise, context) => {
|
|
64
|
+
var _a, _b, _c;
|
|
65
|
+
return (((_a = context.programUsedExerciseIds) === null || _a === void 0 ? void 0 : _a.has(exercise.id)) ||
|
|
66
|
+
((_b = context.routineUsedExerciseIds) === null || _b === void 0 ? void 0 : _b.has(exercise.id)) ||
|
|
67
|
+
((_c = context.excludedExerciseIds) === null || _c === void 0 ? void 0 : _c.has(exercise.id)) ||
|
|
68
|
+
false);
|
|
69
|
+
};
|
|
51
70
|
const isolationExerciseAlternatives = {
|
|
52
71
|
chest: ['B74A95BB', '392887AA', '39C99849'],
|
|
53
72
|
triceps: ['6575F52D', 'CD6DC8E5'],
|
|
@@ -70,68 +89,145 @@ const isolationExerciseAlternatives = {
|
|
|
70
89
|
neck: [],
|
|
71
90
|
full_body: [],
|
|
72
91
|
};
|
|
92
|
+
/**
|
|
93
|
+
* Sorts exercises by priority for each muscle group based on the provided priorities
|
|
94
|
+
* and adds any remaining exercises from the store that weren't in the priorities.
|
|
95
|
+
*
|
|
96
|
+
* @param exercisePriorities - Object mapping muscle groups to arrays of exercise IDs in priority order
|
|
97
|
+
* @param exerciseStore - Array of all available exercises
|
|
98
|
+
* @returns Object mapping muscle groups to arrays of exercises sorted by priority
|
|
99
|
+
*/
|
|
100
|
+
const getPrioritySortedExercises = (exercisePriorities, exerciseStore) => {
|
|
101
|
+
// Have a map of muscle group to exercises sorted by exercise priority
|
|
102
|
+
const sortedExercises = Object.entries(exercisePriorities).reduce((acc, [muscleGroup, exercises]) => {
|
|
103
|
+
const foundExercises = exercises
|
|
104
|
+
.map((exercise) => exerciseStore.find((e) => e.id === exercise))
|
|
105
|
+
.filter((exercise) => exercise !== undefined);
|
|
106
|
+
// Debug: Log missing exercise IDs
|
|
107
|
+
const missingIds = exercises.filter((id) => !exerciseStore.some((e) => e.id === id));
|
|
108
|
+
if (missingIds.length > 0) {
|
|
109
|
+
console.log(`Missing the following exercises with IDs in the store for muscle group ${muscleGroup}:`, missingIds);
|
|
110
|
+
}
|
|
111
|
+
acc[muscleGroup] = foundExercises;
|
|
112
|
+
return acc;
|
|
113
|
+
}, {});
|
|
114
|
+
// Then add remaining exercises to the map
|
|
115
|
+
Object.keys(sortedExercises).forEach((muscleGroup) => {
|
|
116
|
+
const remainingExercises = exerciseStore
|
|
117
|
+
.filter((e) => e.muscle_group === muscleGroup &&
|
|
118
|
+
!sortedExercises[muscleGroup].includes(e))
|
|
119
|
+
.sort((a, b) => b.priority - a.priority);
|
|
120
|
+
sortedExercises[muscleGroup].push(...remainingExercises);
|
|
121
|
+
});
|
|
122
|
+
return sortedExercises;
|
|
123
|
+
};
|
|
124
|
+
exports.getPrioritySortedExercises = getPrioritySortedExercises;
|
|
73
125
|
const getMuscleGroup = ({ muscleGroupPrescription, programFocusMuscleExerciseCount, focusMuscle, }) => {
|
|
74
126
|
if (muscleGroupPrescription === 'focus_muscle') {
|
|
75
127
|
if (!!focusMuscle) {
|
|
76
128
|
const n = _1.simplifiedMuscleGroupToMuscleGroups[focusMuscle].length;
|
|
77
129
|
return _1.simplifiedMuscleGroupToMuscleGroups[focusMuscle][programFocusMuscleExerciseCount % n];
|
|
78
130
|
}
|
|
79
|
-
// User has not selected a focus muscle, so we skip this extra exercise for the focus muscle
|
|
131
|
+
// User has not selected a focus muscle, so we skip this extra exercise for the focus muscle in the program
|
|
80
132
|
return undefined;
|
|
81
133
|
}
|
|
82
134
|
return muscleGroupPrescription;
|
|
83
135
|
};
|
|
84
|
-
|
|
136
|
+
/**
|
|
137
|
+
* Checks if an exercise matches the given criteria for selection
|
|
138
|
+
*/
|
|
139
|
+
const isExerciseMatch = (exercise, criteria) => {
|
|
140
|
+
var _a, _b, _c, _d;
|
|
141
|
+
const categoryMatch = exercise.category === criteria.exerciseCategory ||
|
|
142
|
+
(exercise.category === 'assistance-compound' &&
|
|
143
|
+
criteria.exerciseCategory === 'compound');
|
|
144
|
+
const levelMatch = (_b = (_a = exercise.level) === null || _a === void 0 ? void 0 : _a.includes(criteria.level)) !== null && _b !== void 0 ? _b : false;
|
|
145
|
+
const goalMatch = (_d = (_c = exercise.goal) === null || _c === void 0 ? void 0 : _c.includes(criteria.goal)) !== null && _d !== void 0 ? _d : false;
|
|
146
|
+
const equipmentMatch = isEquipmentCompatible(exercise, criteria.equipments);
|
|
147
|
+
const barbellLimitOk = !isBarbellLimitExceeded(exercise, criteria.routineBarbellExerciseCount, criteria.equipments);
|
|
148
|
+
return (categoryMatch && levelMatch && goalMatch && equipmentMatch && barbellLimitOk);
|
|
149
|
+
};
|
|
150
|
+
/**
|
|
151
|
+
* Checks if an exercise is a valid alternative isolation exercise
|
|
152
|
+
*/
|
|
153
|
+
const isAlternativeIsolationExerciseMatch = (exercise, criteria) => {
|
|
85
154
|
var _a, _b;
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
(equipments.includes(exercise.equipment_category) ||
|
|
92
|
-
exercise.equipment_category === 'none' ||
|
|
93
|
-
exercise.equipment_category === 'other') &&
|
|
94
|
-
// Up to 2 barbell exercises per routine, unless there is only one equipment category selected
|
|
95
|
-
(exercise.equipment_category !== 'barbell' ||
|
|
96
|
-
routineBarbellExerciseCount < 2 ||
|
|
97
|
-
equipments.length === 1));
|
|
155
|
+
const isIsolationCategory = criteria.exerciseCategory === 'isolation';
|
|
156
|
+
const isAlternativeExercise = isolationExerciseAlternatives[criteria.muscleGroup].includes(exercise.id);
|
|
157
|
+
const equipmentMatch = isEquipmentCompatible(exercise, criteria.equipments);
|
|
158
|
+
const levelMatch = (_b = (_a = exercise.level) === null || _a === void 0 ? void 0 : _a.includes(criteria.level)) !== null && _b !== void 0 ? _b : false;
|
|
159
|
+
return (isIsolationCategory && isAlternativeExercise && equipmentMatch && levelMatch);
|
|
98
160
|
};
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
161
|
+
/**
|
|
162
|
+
* Finds an exercise that matches the criteria and is not already used
|
|
163
|
+
*/
|
|
164
|
+
const findMatchingExercise = (exercises, criteria, context) => {
|
|
165
|
+
return exercises.find((exercise) => {
|
|
166
|
+
const matchesCriteria = isExerciseMatch(exercise, criteria);
|
|
167
|
+
const isNotUsed = !isExerciseUsed(exercise, context);
|
|
168
|
+
return matchesCriteria && isNotUsed;
|
|
169
|
+
});
|
|
170
|
+
};
|
|
171
|
+
/**
|
|
172
|
+
* Finds an alternative isolation exercise that matches the criteria
|
|
173
|
+
*/
|
|
174
|
+
const findAlternativeIsolationExercise = (exercises, criteria, context) => {
|
|
175
|
+
return exercises.find((exercise) => {
|
|
176
|
+
const matchesCriteria = isAlternativeIsolationExerciseMatch(exercise, criteria);
|
|
177
|
+
const isNotUsed = !isExerciseUsed(exercise, context);
|
|
178
|
+
return matchesCriteria && isNotUsed;
|
|
179
|
+
});
|
|
180
|
+
};
|
|
181
|
+
/**
|
|
182
|
+
* Selects the best exercise for a given prescription using a multi-pass strategy
|
|
183
|
+
*/
|
|
184
|
+
const pickExerciseForPrescription = (params) => {
|
|
185
|
+
const { sortedExercises, criteria, context } = params;
|
|
186
|
+
const exercises = sortedExercises[criteria.muscleGroup];
|
|
187
|
+
// Pass 1: Find exact match not used in program
|
|
188
|
+
const programContext = {
|
|
189
|
+
programUsedExerciseIds: context.programUsedExerciseIds,
|
|
190
|
+
excludedExerciseIds: context.excludedExerciseIds,
|
|
191
|
+
};
|
|
192
|
+
let exercise = findMatchingExercise(exercises, criteria, programContext);
|
|
193
|
+
if (exercise)
|
|
194
|
+
return exercise;
|
|
195
|
+
// Pass 2: Find exact match not used in routine (allow reuse in program)
|
|
196
|
+
const routineContext = {
|
|
197
|
+
routineUsedExerciseIds: context.routineUsedExerciseIds,
|
|
198
|
+
excludedExerciseIds: context.excludedExerciseIds,
|
|
199
|
+
};
|
|
200
|
+
exercise = findMatchingExercise(exercises, criteria, routineContext);
|
|
201
|
+
if (exercise)
|
|
202
|
+
return exercise;
|
|
203
|
+
// Pass 3: Find alternative isolation exercise not used in program
|
|
204
|
+
exercise = findAlternativeIsolationExercise(exercises, criteria, programContext);
|
|
205
|
+
if (exercise)
|
|
206
|
+
return exercise;
|
|
207
|
+
// Pass 4: Find alternative isolation exercise not used in routine
|
|
208
|
+
exercise = findAlternativeIsolationExercise(exercises, criteria, routineContext);
|
|
209
|
+
return exercise;
|
|
107
210
|
};
|
|
108
|
-
|
|
211
|
+
exports.pickExerciseForPrescription = pickExerciseForPrescription;
|
|
212
|
+
/**
|
|
213
|
+
* Generates a complete training program based on the provided parameters
|
|
214
|
+
*/
|
|
215
|
+
const generateProgram = (params) => {
|
|
109
216
|
var _a;
|
|
217
|
+
const { trainerPreset, selectedDays, selectedGoal, selectedLevel, selectedEquipments, exerciseStore, focusMuscle, excludedExerciseIds, } = params;
|
|
110
218
|
const routines = exports.programSplits[selectedDays];
|
|
111
219
|
const program = {
|
|
112
220
|
name: selectedDays,
|
|
113
221
|
routines: [],
|
|
114
222
|
};
|
|
115
|
-
|
|
116
|
-
const
|
|
117
|
-
acc[muscleGroup] = exercises.map((exercise) => exerciseStore.find((e) => e.id === exercise));
|
|
118
|
-
return acc;
|
|
119
|
-
}, {});
|
|
120
|
-
// Then add remaining exercises to the map
|
|
121
|
-
Object.keys(sortedExercises).forEach((muscleGroup) => {
|
|
122
|
-
const remainingExercises = exerciseStore
|
|
123
|
-
.filter((e) => e.muscle_group === muscleGroup &&
|
|
124
|
-
!sortedExercises[muscleGroup].includes(e))
|
|
125
|
-
.sort((a, b) => b.priority - a.priority);
|
|
126
|
-
sortedExercises[muscleGroup].push(...remainingExercises);
|
|
127
|
-
});
|
|
128
|
-
const programUsedExercises = new Set();
|
|
223
|
+
const sortedExercises = (0, exports.getPrioritySortedExercises)(trainerPreset.settings.exercise_priorities, exerciseStore);
|
|
224
|
+
const programUsedExerciseIds = new Set();
|
|
129
225
|
let programFocusMuscleExerciseCount = 0;
|
|
130
226
|
const allErrors = [];
|
|
131
227
|
for (const routine of routines) {
|
|
132
228
|
const routineTemplate = trainerPreset.settings.templates[routine];
|
|
133
229
|
let routineBarbellExerciseCount = 0;
|
|
134
|
-
const
|
|
230
|
+
const routineUsedExerciseIds = new Set();
|
|
135
231
|
const routineExercises = [];
|
|
136
232
|
for (const exercisePrescription of routineTemplate.exercises) {
|
|
137
233
|
const muscleGroup = getMuscleGroup({
|
|
@@ -143,55 +239,25 @@ const generateProgram = ({ trainerPreset, selectedDays, selectedGoal, selectedLe
|
|
|
143
239
|
if (!muscleGroup) {
|
|
144
240
|
continue;
|
|
145
241
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
equipments: selectedEquipments,
|
|
151
|
-
routineBarbellExerciseCount,
|
|
152
|
-
level: selectedLevel,
|
|
153
|
-
goal: selectedGoal,
|
|
154
|
-
}) && !programUsedExercises.has(e.title));
|
|
155
|
-
if (exercise === undefined) {
|
|
156
|
-
// Second pass
|
|
157
|
-
// By allowing the same exercise to be assigned in the same program more than once
|
|
158
|
-
const extendedMatchingExercise = sortedExercises[muscleGroup].find((e) => isExerciseMatch({
|
|
159
|
-
exercisePrescription,
|
|
160
|
-
exercise: e,
|
|
242
|
+
const exercise = (0, exports.pickExerciseForPrescription)({
|
|
243
|
+
sortedExercises,
|
|
244
|
+
criteria: {
|
|
245
|
+
exerciseCategory: exercisePrescription.category,
|
|
161
246
|
equipments: selectedEquipments,
|
|
247
|
+
muscleGroup,
|
|
162
248
|
routineBarbellExerciseCount,
|
|
163
249
|
level: selectedLevel,
|
|
164
250
|
goal: selectedGoal,
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
exercise: e,
|
|
173
|
-
exercisePrescription,
|
|
174
|
-
equipments: selectedEquipments,
|
|
175
|
-
level: selectedLevel,
|
|
176
|
-
muscleGroup,
|
|
177
|
-
}) && !programUsedExercises.has(e.title));
|
|
178
|
-
exercise = alternativeIsolationExercise;
|
|
179
|
-
}
|
|
180
|
-
if (exercise === undefined) {
|
|
181
|
-
// Fourth pass
|
|
182
|
-
// Check if isolation exercise alternatives are available and not used in the workout
|
|
183
|
-
const extendedIsolationExercise = sortedExercises[muscleGroup].find((e) => isAlternativeIsolationExerciseMatch({
|
|
184
|
-
exercise: e,
|
|
185
|
-
exercisePrescription,
|
|
186
|
-
equipments: selectedEquipments,
|
|
187
|
-
level: selectedLevel,
|
|
188
|
-
muscleGroup,
|
|
189
|
-
}) && !routineUsedExercises.has(e.title));
|
|
190
|
-
exercise = extendedIsolationExercise;
|
|
191
|
-
}
|
|
251
|
+
},
|
|
252
|
+
context: {
|
|
253
|
+
programUsedExerciseIds,
|
|
254
|
+
routineUsedExerciseIds,
|
|
255
|
+
excludedExerciseIds,
|
|
256
|
+
},
|
|
257
|
+
});
|
|
192
258
|
if (!!exercise) {
|
|
193
|
-
|
|
194
|
-
|
|
259
|
+
programUsedExerciseIds.add(exercise.id);
|
|
260
|
+
routineUsedExerciseIds.add(exercise.id);
|
|
195
261
|
if (exercise.equipment_category === 'barbell')
|
|
196
262
|
routineBarbellExerciseCount++;
|
|
197
263
|
if (exercisePrescription.muscle_group === 'focus_muscle')
|
package/built/index.d.ts
CHANGED
|
@@ -1730,12 +1730,24 @@ export interface GoogleCoachWebSignInRequest {
|
|
|
1730
1730
|
invite_short_id?: string;
|
|
1731
1731
|
}
|
|
1732
1732
|
export interface UserPushNotificationSettings {
|
|
1733
|
-
|
|
1733
|
+
comment_discussion: boolean;
|
|
1734
1734
|
comment_likes: boolean;
|
|
1735
|
+
comment_mention: boolean;
|
|
1736
|
+
comment_on_workout: boolean;
|
|
1737
|
+
comment_replies: boolean;
|
|
1738
|
+
follows: boolean;
|
|
1739
|
+
likes: boolean;
|
|
1740
|
+
monthly_report: boolean;
|
|
1735
1741
|
}
|
|
1736
1742
|
export interface UserPushNotificationSettingsUpdate {
|
|
1737
|
-
|
|
1743
|
+
comment_discussion?: boolean;
|
|
1738
1744
|
comment_likes?: boolean;
|
|
1745
|
+
comment_mention?: boolean;
|
|
1746
|
+
comment_on_workout?: boolean;
|
|
1747
|
+
comment_replies?: boolean;
|
|
1748
|
+
follows?: boolean;
|
|
1749
|
+
likes?: boolean;
|
|
1750
|
+
monthly_report?: boolean;
|
|
1739
1751
|
}
|
|
1740
1752
|
export interface ProgressiveOverloadSettings {
|
|
1741
1753
|
plate: {
|