@abyss-project/training 1.0.0 → 1.0.2

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 (79) hide show
  1. package/dist/api/analytics.public.api.d.ts +2 -0
  2. package/dist/api/analytics.public.api.js +8 -0
  3. package/dist/api/exercise.api.d.ts +10 -0
  4. package/dist/api/exercise.api.js +52 -0
  5. package/dist/api/exercise.public.api.d.ts +3 -0
  6. package/dist/api/exercise.public.api.js +14 -0
  7. package/dist/api/index.d.ts +4 -0
  8. package/dist/api/index.js +4 -0
  9. package/dist/api/training-program.api.d.ts +13 -0
  10. package/dist/api/training-program.api.js +53 -0
  11. package/dist/api/user.api.d.ts +3 -1
  12. package/dist/api/user.api.js +11 -1
  13. package/dist/api/workout-session.api.d.ts +2 -5
  14. package/dist/api/workout-session.api.js +4 -16
  15. package/dist/api/workout-template.api.d.ts +1 -2
  16. package/dist/api/workout-template.api.js +1 -5
  17. package/dist/index.js +2 -1
  18. package/dist/types/enum/day-of-week.enum.d.ts +9 -0
  19. package/dist/types/enum/day-of-week.enum.js +13 -0
  20. package/dist/types/enum/exercise-measurement-type.enum.d.ts +7 -0
  21. package/dist/types/enum/exercise-measurement-type.enum.js +11 -0
  22. package/dist/types/enum/index.d.ts +7 -2
  23. package/dist/types/enum/index.js +7 -2
  24. package/dist/types/enum/personal-record-type.enum.d.ts +9 -0
  25. package/dist/types/enum/personal-record-type.enum.js +13 -0
  26. package/dist/types/enum/schedule-type.enum.d.ts +5 -0
  27. package/dist/types/enum/schedule-type.enum.js +9 -0
  28. package/dist/types/enum/skip-reason.enum.d.ts +9 -0
  29. package/dist/types/enum/skip-reason.enum.js +13 -0
  30. package/dist/types/enum/training-program-status.enum.d.ts +6 -0
  31. package/dist/types/enum/training-program-status.enum.js +10 -0
  32. package/dist/types/enum/workout-group-type.enum.d.ts +5 -0
  33. package/dist/types/enum/workout-group-type.enum.js +9 -0
  34. package/dist/types/interface/api/index.d.ts +24 -0
  35. package/dist/types/interface/api/index.js +7 -0
  36. package/dist/types/interface/api/requests/exercise.public.request.d.ts +20 -0
  37. package/dist/types/interface/api/requests/exercise.public.request.js +2 -0
  38. package/dist/types/interface/api/requests/exercise.request.d.ts +61 -0
  39. package/dist/types/interface/api/requests/exercise.request.js +2 -0
  40. package/dist/types/interface/api/requests/training-program.request.d.ts +67 -0
  41. package/dist/types/interface/api/requests/training-program.request.js +2 -0
  42. package/dist/types/interface/api/requests/user.request.d.ts +4 -0
  43. package/dist/types/interface/api/requests/workout-session.request.d.ts +10 -58
  44. package/dist/types/interface/api/requests/workout-template.public.request.d.ts +5 -2
  45. package/dist/types/interface/api/requests/workout-template.request.d.ts +20 -23
  46. package/dist/types/interface/api/responses/analytics.public.response.d.ts +24 -0
  47. package/dist/types/interface/api/responses/analytics.public.response.js +2 -0
  48. package/dist/types/interface/api/responses/exercise.public.response.d.ts +7 -0
  49. package/dist/types/interface/api/responses/exercise.public.response.js +2 -0
  50. package/dist/types/interface/api/responses/exercise.response.d.ts +110 -0
  51. package/dist/types/interface/api/responses/exercise.response.js +2 -0
  52. package/dist/types/interface/api/responses/training-program.response.d.ts +46 -0
  53. package/dist/types/interface/api/responses/training-program.response.js +2 -0
  54. package/dist/types/interface/api/responses/user.response.d.ts +41 -1
  55. package/dist/types/interface/api/responses/workout-session.response.d.ts +4 -0
  56. package/dist/types/interface/api/responses/workout-template.response.d.ts +3 -3
  57. package/dist/types/interface/index.d.ts +6 -1
  58. package/dist/types/interface/index.js +6 -1
  59. package/dist/types/interface/models/exercise.model.d.ts +2 -1
  60. package/dist/types/interface/models/training-program-schedule.model.d.ts +18 -0
  61. package/dist/types/interface/models/training-program-schedule.model.js +2 -0
  62. package/dist/types/interface/models/training-program.model.d.ts +17 -0
  63. package/dist/types/interface/models/training-program.model.js +2 -0
  64. package/dist/types/interface/models/workout-exercise.model.d.ts +6 -9
  65. package/dist/types/interface/models/workout-group.model.d.ts +18 -0
  66. package/dist/types/interface/models/workout-group.model.js +2 -0
  67. package/dist/types/interface/models/workout-section.model.d.ts +13 -0
  68. package/dist/types/interface/models/workout-section.model.js +2 -0
  69. package/dist/types/interface/models/workout-session.model.d.ts +3 -6
  70. package/dist/types/interface/models/workout-template.model.d.ts +2 -2
  71. package/dist/types/interface/personal-record.interface.d.ts +29 -0
  72. package/dist/types/interface/personal-record.interface.js +2 -0
  73. package/dist/types/interface/template-snapshot.interface.d.ts +36 -0
  74. package/dist/types/interface/template-snapshot.interface.js +2 -0
  75. package/dist/utils/index.d.ts +1 -0
  76. package/dist/utils/index.js +1 -0
  77. package/dist/utils/workout-template.utils.d.ts +51 -0
  78. package/dist/utils/workout-template.utils.js +318 -0
  79. package/package.json +47 -51
@@ -0,0 +1,18 @@
1
+ import { DayOfWeek, ScheduleType } from '../../enum';
2
+ import { ITrainingProgram } from './training-program.model';
3
+ import { IWorkoutTemplate } from './workout-template.model';
4
+ export interface ITrainingProgramSchedule {
5
+ id?: string;
6
+ trainingProgramId: string;
7
+ workoutTemplateId: string;
8
+ scheduleType: ScheduleType;
9
+ dayOfWeek: DayOfWeek | null;
10
+ cycleDay: number | null;
11
+ monthDay: number | null;
12
+ weekNumber: number | null;
13
+ order: number;
14
+ createdAt?: Date;
15
+ updatedAt?: Date;
16
+ trainingProgram?: ITrainingProgram;
17
+ workoutTemplate?: IWorkoutTemplate;
18
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,17 @@
1
+ import { TrainingProgramStatus } from '../../enum';
2
+ import { IUser } from './user.model';
3
+ import { ITrainingProgramSchedule } from './training-program-schedule.model';
4
+ export interface ITrainingProgram {
5
+ id?: string;
6
+ name: string;
7
+ description: string | null;
8
+ userId: string | null;
9
+ status: TrainingProgramStatus;
10
+ durationWeeks: number;
11
+ startDate: Date | null;
12
+ endDate: Date | null;
13
+ createdAt?: Date;
14
+ updatedAt?: Date;
15
+ user?: IUser;
16
+ trainingProgramSchedules?: ITrainingProgramSchedule[];
17
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,21 +1,18 @@
1
- import { IWorkoutTemplate } from './workout-template.model';
2
1
  import { IExercise } from './exercise.model';
3
- import { ExerciseGroupType } from '../../enum/exercise-group-type.enum';
2
+ import { IWorkoutGroup } from './workout-group.model';
4
3
  export interface IWorkoutExercise {
5
4
  id?: string;
6
- workoutTemplateId: string;
5
+ workoutGroupId: string;
7
6
  exerciseId: string;
8
7
  order: number;
9
- groupType: ExerciseGroupType;
10
- groupId: string | null;
11
- groupOrder: number | null;
12
- plannedSets: number | null;
13
8
  plannedReps: number | null;
14
9
  plannedWeight: number | null;
15
- plannedRestTime: number | null;
10
+ plannedDuration: number | null;
11
+ plannedDistance: number | null;
12
+ plannedCalories: number | null;
16
13
  notes: string | null;
17
14
  createdAt?: Date;
18
15
  updatedAt?: Date;
19
- workoutTemplate?: IWorkoutTemplate;
16
+ workoutGroup?: IWorkoutGroup;
20
17
  exercise?: IExercise;
21
18
  }
@@ -0,0 +1,18 @@
1
+ import { IWorkoutSection } from './workout-section.model';
2
+ import { IWorkoutExercise } from './workout-exercise.model';
3
+ import { WorkoutGroupType } from '../../enum';
4
+ export interface IWorkoutGroup {
5
+ id?: string;
6
+ workoutSectionId: string;
7
+ name: string | null;
8
+ order: number;
9
+ plannedSets: number;
10
+ plannedRestTime: number | null;
11
+ type: WorkoutGroupType;
12
+ timeCap: number | null;
13
+ intervalSeconds: number | null;
14
+ createdAt?: Date;
15
+ updatedAt?: Date;
16
+ workoutSection?: IWorkoutSection;
17
+ workoutExercises?: IWorkoutExercise[];
18
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,13 @@
1
+ import { IWorkoutTemplate } from './workout-template.model';
2
+ import { IWorkoutGroup } from './workout-group.model';
3
+ export interface IWorkoutSection {
4
+ id?: string;
5
+ workoutTemplateId: string;
6
+ name: string;
7
+ description: string | null;
8
+ order: number;
9
+ createdAt?: Date;
10
+ updatedAt?: Date;
11
+ workoutTemplate?: IWorkoutTemplate;
12
+ workoutGroups?: IWorkoutGroup[];
13
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,14 +1,12 @@
1
- import { WorkoutSessionStatus } from '../../enum/workout-session-status.enum';
2
- import { IExerciseSet } from './exercise-set.model';
3
1
  import { IUser } from './user.model';
4
2
  import { IWorkoutTemplate } from './workout-template.model';
3
+ import { ITemplateSnapshot, IWorkoutSessionSet } from '../template-snapshot.interface';
5
4
  export interface IWorkoutSession {
6
5
  id?: string;
7
6
  userId: string;
8
7
  workoutTemplateId: string | null;
9
- name: string;
10
- status: WorkoutSessionStatus;
11
- scheduledAt: Date | null;
8
+ templateSnapshot: ITemplateSnapshot;
9
+ sets: IWorkoutSessionSet[];
12
10
  startedAt: Date | null;
13
11
  completedAt: Date | null;
14
12
  duration: number | null;
@@ -17,5 +15,4 @@ export interface IWorkoutSession {
17
15
  updatedAt?: Date;
18
16
  user?: IUser;
19
17
  workoutTemplate?: IWorkoutTemplate;
20
- exerciseSet?: IExerciseSet[];
21
18
  }
@@ -1,6 +1,6 @@
1
1
  import { IUser } from './user.model';
2
- import { IWorkoutExercise } from './workout-exercise.model';
3
2
  import { IWorkoutSession } from './workout-session.model';
3
+ import { IWorkoutSection } from './workout-section.model';
4
4
  export interface IWorkoutTemplate {
5
5
  id?: string;
6
6
  name: string;
@@ -11,6 +11,6 @@ export interface IWorkoutTemplate {
11
11
  createdAt?: Date;
12
12
  updatedAt?: Date;
13
13
  user?: IUser;
14
- workoutExercise?: IWorkoutExercise[];
14
+ workoutSections?: IWorkoutSection[];
15
15
  workoutSession?: IWorkoutSession[];
16
16
  }
@@ -0,0 +1,29 @@
1
+ import { PersonalRecordType } from '../enum';
2
+ export interface PersonalRecord {
3
+ id: string;
4
+ recordType: PersonalRecordType;
5
+ value: number;
6
+ unit: string;
7
+ achievedAt: string;
8
+ sessionId: string;
9
+ previousValue: number | null;
10
+ previousAchievedAt: string | null;
11
+ improvementPercent: number | null;
12
+ }
13
+ export interface ExercisePersonalRecords {
14
+ exerciseId: string;
15
+ exerciseName: string;
16
+ exerciseUserId: string | null;
17
+ exerciseImageUrl: string | null;
18
+ primaryMuscleGroups: string[];
19
+ totalSessions: number;
20
+ firstPerformed: string | null;
21
+ lastPerformed: string | null;
22
+ records: PersonalRecord[];
23
+ }
24
+ export interface UserPersonalRecords {
25
+ totalRecords: number;
26
+ exercisesWithRecords: number;
27
+ latestRecordDate: string | null;
28
+ exercises: ExercisePersonalRecords[];
29
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,36 @@
1
+ import { IWorkoutTemplate } from './models/workout-template.model';
2
+ import { IWorkoutSection } from './models/workout-section.model';
3
+ import { IWorkoutGroup } from './models/workout-group.model';
4
+ import { IWorkoutExercise } from './models/workout-exercise.model';
5
+ import { IExercise } from './models/exercise.model';
6
+ import { SkipReason } from '../enum';
7
+ export interface ITemplateSnapshot extends IWorkoutTemplate {
8
+ sections: ITemplateSnapshotSection[];
9
+ }
10
+ export interface ITemplateSnapshotSection extends IWorkoutSection {
11
+ groups: ITemplateSnapshotGroup[];
12
+ }
13
+ export interface ITemplateSnapshotGroup extends IWorkoutGroup {
14
+ exercises: ITemplateSnapshotExercise[];
15
+ }
16
+ export interface ITemplateSnapshotExercise extends IWorkoutExercise {
17
+ exercise: IExercise;
18
+ }
19
+ export interface IWorkoutSessionSet {
20
+ workoutSectionId: string;
21
+ workoutGroupId: string;
22
+ workoutExerciseId: string;
23
+ exerciseId: string;
24
+ setNumber: number;
25
+ reps?: number | null;
26
+ weight?: number | null;
27
+ duration?: number | null;
28
+ distance?: number | null;
29
+ calories?: number | null;
30
+ isSkipped?: boolean;
31
+ skipReason?: SkipReason | null;
32
+ skipDetails?: string | null;
33
+ startedAt?: Date | null;
34
+ completedAt?: Date | null;
35
+ notes?: string | null;
36
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1 +1,2 @@
1
1
  export * from './error.utils';
2
+ export * from './workout-template.utils';
@@ -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("./error.utils"), exports);
18
+ __exportStar(require("./workout-template.utils"), exports);
@@ -0,0 +1,51 @@
1
+ import { IWorkoutTemplate, EquipmentType, IWorkoutExercise, ExerciseMeasurementType, WorkoutGroupType } from '../types';
2
+ export interface WorkoutTemplateDurationOptions {
3
+ averageSetDurationSeconds?: number;
4
+ averageDistancePaceSecondsPerKm?: number;
5
+ defaultRestTimeSeconds?: number;
6
+ defaultSetsPerExercise?: number;
7
+ transitionTimeMinutes?: number;
8
+ }
9
+ export interface WorkoutExerciseConfig {
10
+ id?: string;
11
+ exerciseId: string;
12
+ plannedReps?: number | null;
13
+ plannedWeight?: number | null;
14
+ plannedDuration?: number | null;
15
+ plannedDistance?: number | null;
16
+ plannedCalories?: number | null;
17
+ measurementTypes?: ExerciseMeasurementType[];
18
+ notes?: string | null;
19
+ exercise?: {
20
+ measurementTypes?: ExerciseMeasurementType[];
21
+ };
22
+ }
23
+ export interface WorkoutGroupConfig {
24
+ id?: string;
25
+ name?: string | null;
26
+ plannedSets: number;
27
+ plannedRestTime?: number | null;
28
+ type?: WorkoutGroupType;
29
+ timeCap?: number | null;
30
+ intervalSeconds?: number | null;
31
+ exercises: WorkoutExerciseConfig[];
32
+ }
33
+ export interface WorkoutSectionConfig {
34
+ id?: string;
35
+ name: string;
36
+ description?: string | null;
37
+ groups?: WorkoutGroupConfig[];
38
+ }
39
+ export declare function calculateExerciseDuration(exercise: WorkoutExerciseConfig | IWorkoutExercise, options?: WorkoutTemplateDurationOptions, sets?: number | null): number;
40
+ export declare function calculateGroupDuration(group: WorkoutGroupConfig, options?: WorkoutTemplateDurationOptions): number;
41
+ export declare function calculateSectionDuration(section: WorkoutSectionConfig, options?: WorkoutTemplateDurationOptions): number;
42
+ export declare function calculateWorkoutTemplateDuration(workoutTemplate: IWorkoutTemplate | null | undefined, options?: WorkoutTemplateDurationOptions): number;
43
+ export declare function formatDuration(totalSeconds: number, options?: {
44
+ showSeconds?: boolean;
45
+ roundToMinutes?: boolean;
46
+ }): string;
47
+ export declare function calculateWorkoutTemplateIntensity(workoutTemplate: IWorkoutTemplate | null | undefined): 'light' | 'moderate' | 'high';
48
+ export declare function extractWorkoutTemplateEquipment(workoutTemplate: IWorkoutTemplate | null | undefined): (EquipmentType | null)[];
49
+ export declare function filterEmptyGroups(sections?: WorkoutSectionConfig[]): WorkoutSectionConfig[];
50
+ export declare function getAllWorkoutExercises(workoutTemplate: IWorkoutTemplate | null | undefined): IWorkoutExercise[];
51
+ export declare function getWorkoutExerciseCount(workoutTemplate: IWorkoutTemplate | null | undefined): number;
@@ -0,0 +1,318 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getWorkoutExerciseCount = exports.getAllWorkoutExercises = exports.filterEmptyGroups = exports.extractWorkoutTemplateEquipment = exports.calculateWorkoutTemplateIntensity = exports.formatDuration = exports.calculateWorkoutTemplateDuration = exports.calculateSectionDuration = exports.calculateGroupDuration = exports.calculateExerciseDuration = void 0;
4
+ const types_1 = require("../types");
5
+ const DEFAULT_OPTIONS = {
6
+ averageSetDurationSeconds: 60,
7
+ averageDistancePaceSecondsPerKm: 300,
8
+ defaultRestTimeSeconds: 60,
9
+ defaultSetsPerExercise: 3,
10
+ transitionTimeMinutes: 5,
11
+ };
12
+ function roundUpToMultipleOf5(value) {
13
+ return Math.ceil(value / 5) * 5;
14
+ }
15
+ function calculateExerciseDuration(exercise, options = {}, sets) {
16
+ var _a;
17
+ const opts = { ...DEFAULT_OPTIONS, ...options };
18
+ const effectiveSets = sets || opts.defaultSetsPerExercise;
19
+ const measurementTypes = 'measurementTypes' in exercise && exercise.measurementTypes
20
+ ? exercise.measurementTypes
21
+ : 'exercise' in exercise && ((_a = exercise.exercise) === null || _a === void 0 ? void 0 : _a.measurementTypes)
22
+ ? exercise.exercise.measurementTypes
23
+ : [types_1.ExerciseMeasurementType.REPS];
24
+ let primaryType = types_1.ExerciseMeasurementType.REPS;
25
+ if (measurementTypes.includes(types_1.ExerciseMeasurementType.TIME)) {
26
+ primaryType = types_1.ExerciseMeasurementType.TIME;
27
+ }
28
+ else if (measurementTypes.includes(types_1.ExerciseMeasurementType.DISTANCE)) {
29
+ primaryType = types_1.ExerciseMeasurementType.DISTANCE;
30
+ }
31
+ else if (measurementTypes.includes(types_1.ExerciseMeasurementType.CALORIES)) {
32
+ primaryType = types_1.ExerciseMeasurementType.CALORIES;
33
+ }
34
+ let setDuration;
35
+ switch (primaryType) {
36
+ case types_1.ExerciseMeasurementType.TIME:
37
+ const duration = 'plannedDuration' in exercise ? exercise.plannedDuration : null;
38
+ setDuration = duration && duration > 0 ? duration : opts.averageSetDurationSeconds;
39
+ break;
40
+ case types_1.ExerciseMeasurementType.DISTANCE:
41
+ const distance = 'plannedDistance' in exercise ? exercise.plannedDistance : null;
42
+ setDuration =
43
+ distance && distance > 0
44
+ ? distance * opts.averageDistancePaceSecondsPerKm
45
+ : opts.averageDistancePaceSecondsPerKm;
46
+ break;
47
+ case types_1.ExerciseMeasurementType.CALORIES:
48
+ const calories = 'plannedCalories' in exercise ? exercise.plannedCalories : null;
49
+ setDuration = calories && calories > 0 ? calories * 6 : opts.averageSetDurationSeconds;
50
+ break;
51
+ case types_1.ExerciseMeasurementType.REPS:
52
+ default:
53
+ setDuration = opts.averageSetDurationSeconds;
54
+ break;
55
+ }
56
+ const totalSetTime = effectiveSets * setDuration;
57
+ const restBetweenSets = effectiveSets > 1 ? (effectiveSets - 1) * opts.defaultRestTimeSeconds : 0;
58
+ return totalSetTime + restBetweenSets;
59
+ }
60
+ exports.calculateExerciseDuration = calculateExerciseDuration;
61
+ function calculateGroupDuration(group, options = {}) {
62
+ if (!group.exercises || group.exercises.length === 0) {
63
+ return 0;
64
+ }
65
+ const opts = { ...DEFAULT_OPTIONS, ...options };
66
+ const groupType = group.type || types_1.WorkoutGroupType.SUPERSET;
67
+ if (groupType === types_1.WorkoutGroupType.AMRAP) {
68
+ if (group.timeCap && group.timeCap > 0) {
69
+ return group.timeCap;
70
+ }
71
+ }
72
+ if (groupType === types_1.WorkoutGroupType.EMOM) {
73
+ if (group.timeCap && group.timeCap > 0) {
74
+ return group.timeCap;
75
+ }
76
+ const interval = group.intervalSeconds || 60;
77
+ const rounds = group.plannedSets || opts.defaultSetsPerExercise;
78
+ return rounds * interval;
79
+ }
80
+ const groupSets = group.plannedSets || opts.defaultSetsPerExercise;
81
+ if (group.exercises.length === 1) {
82
+ const exercise = group.exercises[0];
83
+ const exerciseDuration = calculateExerciseDuration(exercise, options, groupSets);
84
+ if (group.plannedRestTime) {
85
+ const defaultRestAdded = groupSets > 1 ? (groupSets - 1) * opts.defaultRestTimeSeconds : 0;
86
+ const groupRest = groupSets > 1 ? (groupSets - 1) * group.plannedRestTime : 0;
87
+ return exerciseDuration - defaultRestAdded + groupRest;
88
+ }
89
+ return exerciseDuration;
90
+ }
91
+ const maxSets = groupSets;
92
+ const oneRoundTime = group.exercises.reduce((total, exercise) => {
93
+ var _a;
94
+ const measurementTypes = 'measurementTypes' in exercise && exercise.measurementTypes
95
+ ? exercise.measurementTypes
96
+ : 'exercise' in exercise && ((_a = exercise.exercise) === null || _a === void 0 ? void 0 : _a.measurementTypes)
97
+ ? exercise.exercise.measurementTypes
98
+ : [types_1.ExerciseMeasurementType.REPS];
99
+ let primaryType = types_1.ExerciseMeasurementType.REPS;
100
+ if (measurementTypes.includes(types_1.ExerciseMeasurementType.TIME)) {
101
+ primaryType = types_1.ExerciseMeasurementType.TIME;
102
+ }
103
+ else if (measurementTypes.includes(types_1.ExerciseMeasurementType.DISTANCE)) {
104
+ primaryType = types_1.ExerciseMeasurementType.DISTANCE;
105
+ }
106
+ else if (measurementTypes.includes(types_1.ExerciseMeasurementType.CALORIES)) {
107
+ primaryType = types_1.ExerciseMeasurementType.CALORIES;
108
+ }
109
+ let setDuration;
110
+ switch (primaryType) {
111
+ case types_1.ExerciseMeasurementType.TIME:
112
+ const duration = 'plannedDuration' in exercise ? exercise.plannedDuration : null;
113
+ setDuration = duration && duration > 0 ? duration : opts.averageSetDurationSeconds;
114
+ break;
115
+ case types_1.ExerciseMeasurementType.DISTANCE:
116
+ const distance = 'plannedDistance' in exercise ? exercise.plannedDistance : null;
117
+ setDuration =
118
+ distance && distance > 0
119
+ ? distance * opts.averageDistancePaceSecondsPerKm
120
+ : opts.averageDistancePaceSecondsPerKm;
121
+ break;
122
+ case types_1.ExerciseMeasurementType.CALORIES:
123
+ const calories = 'plannedCalories' in exercise ? exercise.plannedCalories : null;
124
+ setDuration = calories && calories > 0 ? calories * 6 : opts.averageSetDurationSeconds;
125
+ break;
126
+ default:
127
+ setDuration = opts.averageSetDurationSeconds;
128
+ }
129
+ return total + setDuration;
130
+ }, 0);
131
+ const restTime = group.plannedRestTime || opts.defaultRestTimeSeconds;
132
+ const totalRoundsTime = maxSets * oneRoundTime;
133
+ const totalRestTime = maxSets > 1 ? (maxSets - 1) * restTime : 0;
134
+ return totalRoundsTime + totalRestTime;
135
+ }
136
+ exports.calculateGroupDuration = calculateGroupDuration;
137
+ function calculateSectionDuration(section, options = {}) {
138
+ if (!section.groups || section.groups.length === 0) {
139
+ return 0;
140
+ }
141
+ return section.groups.reduce((totalSeconds, group) => {
142
+ if (group.exercises && group.exercises.length > 0) {
143
+ return totalSeconds + calculateGroupDuration(group, options);
144
+ }
145
+ return totalSeconds;
146
+ }, 0);
147
+ }
148
+ exports.calculateSectionDuration = calculateSectionDuration;
149
+ function calculateWorkoutTemplateDuration(workoutTemplate, options = {}) {
150
+ if (!workoutTemplate) {
151
+ return 0;
152
+ }
153
+ const opts = { ...DEFAULT_OPTIONS, ...options };
154
+ if (!workoutTemplate.workoutSections || workoutTemplate.workoutSections.length === 0) {
155
+ return 0;
156
+ }
157
+ let totalSeconds = opts.transitionTimeMinutes * 60;
158
+ workoutTemplate.workoutSections.forEach((section) => {
159
+ if (section.workoutGroups && section.workoutGroups.length > 0) {
160
+ section.workoutGroups.forEach((group) => {
161
+ if (group.workoutExercises && group.workoutExercises.length > 0) {
162
+ const groupConfig = {
163
+ plannedSets: group.plannedSets,
164
+ plannedRestTime: group.plannedRestTime,
165
+ type: group.type,
166
+ timeCap: group.timeCap,
167
+ intervalSeconds: group.intervalSeconds,
168
+ exercises: group.workoutExercises.map((we) => ({
169
+ exerciseId: we.exerciseId,
170
+ plannedReps: we.plannedReps,
171
+ plannedWeight: we.plannedWeight,
172
+ plannedDuration: we.plannedDuration,
173
+ plannedDistance: we.plannedDistance,
174
+ plannedCalories: we.plannedCalories,
175
+ notes: we.notes,
176
+ exercise: we.exercise,
177
+ })),
178
+ };
179
+ totalSeconds += calculateGroupDuration(groupConfig, options);
180
+ }
181
+ });
182
+ }
183
+ });
184
+ return roundUpToMultipleOf5(Math.ceil(totalSeconds / 60));
185
+ }
186
+ exports.calculateWorkoutTemplateDuration = calculateWorkoutTemplateDuration;
187
+ function formatDuration(totalSeconds, options) {
188
+ var _a, _b;
189
+ const showSeconds = (_a = options === null || options === void 0 ? void 0 : options.showSeconds) !== null && _a !== void 0 ? _a : true;
190
+ const roundToMinutes = (_b = options === null || options === void 0 ? void 0 : options.roundToMinutes) !== null && _b !== void 0 ? _b : false;
191
+ if (roundToMinutes) {
192
+ const minutes = Math.round(totalSeconds / 60);
193
+ if (minutes < 60) {
194
+ return `${minutes}min`;
195
+ }
196
+ const hours = Math.floor(minutes / 60);
197
+ const mins = minutes % 60;
198
+ return mins > 0 ? `${hours}h ${mins}min` : `${hours}h`;
199
+ }
200
+ const hours = Math.floor(totalSeconds / 3600);
201
+ const minutes = Math.floor((totalSeconds % 3600) / 60);
202
+ const seconds = totalSeconds % 60;
203
+ if (!showSeconds) {
204
+ const totalMinutes = Math.round(totalSeconds / 60);
205
+ if (totalMinutes < 60) {
206
+ return `${totalMinutes}min`;
207
+ }
208
+ const h = Math.floor(totalMinutes / 60);
209
+ const m = totalMinutes % 60;
210
+ return m > 0 ? `${h}h ${m}min` : `${h}h`;
211
+ }
212
+ if (hours > 0) {
213
+ if (minutes > 0 && seconds > 0) {
214
+ return `${hours}h ${minutes}min ${seconds}s`;
215
+ }
216
+ if (minutes > 0) {
217
+ return `${hours}h ${minutes}min`;
218
+ }
219
+ if (seconds > 0) {
220
+ return `${hours}h ${seconds}s`;
221
+ }
222
+ return `${hours}h`;
223
+ }
224
+ if (minutes > 0) {
225
+ return seconds > 0 ? `${minutes}min ${seconds}s` : `${minutes}min`;
226
+ }
227
+ return `${seconds}s`;
228
+ }
229
+ exports.formatDuration = formatDuration;
230
+ function calculateWorkoutTemplateIntensity(workoutTemplate) {
231
+ if (!workoutTemplate) {
232
+ return 'moderate';
233
+ }
234
+ let totalSets = 0;
235
+ if (!workoutTemplate.workoutSections || workoutTemplate.workoutSections.length === 0) {
236
+ return 'light';
237
+ }
238
+ workoutTemplate.workoutSections.forEach((section) => {
239
+ if (section.workoutGroups && section.workoutGroups.length > 0) {
240
+ section.workoutGroups.forEach((group) => {
241
+ totalSets += group.plannedSets;
242
+ });
243
+ }
244
+ });
245
+ if (totalSets > 25) {
246
+ return 'high';
247
+ }
248
+ if (totalSets > 15) {
249
+ return 'moderate';
250
+ }
251
+ return 'light';
252
+ }
253
+ exports.calculateWorkoutTemplateIntensity = calculateWorkoutTemplateIntensity;
254
+ function extractWorkoutTemplateEquipment(workoutTemplate) {
255
+ if (!workoutTemplate) {
256
+ return [];
257
+ }
258
+ const equipment = [];
259
+ if (!workoutTemplate.workoutSections || workoutTemplate.workoutSections.length === 0) {
260
+ return [];
261
+ }
262
+ workoutTemplate.workoutSections.forEach((section) => {
263
+ if (section.workoutGroups && section.workoutGroups.length > 0) {
264
+ section.workoutGroups.forEach((group) => {
265
+ if (group.workoutExercises && group.workoutExercises.length > 0) {
266
+ group.workoutExercises.forEach((workoutExercise) => {
267
+ var _a;
268
+ const eq = ((_a = workoutExercise.exercise) === null || _a === void 0 ? void 0 : _a.requiredEquipment) || null;
269
+ if (eq !== null) {
270
+ equipment.push(eq);
271
+ }
272
+ });
273
+ }
274
+ });
275
+ }
276
+ });
277
+ return Array.from(new Set(equipment));
278
+ }
279
+ exports.extractWorkoutTemplateEquipment = extractWorkoutTemplateEquipment;
280
+ function filterEmptyGroups(sections) {
281
+ if (!sections || sections.length === 0) {
282
+ return [];
283
+ }
284
+ return sections
285
+ .map((section) => {
286
+ var _a;
287
+ return ({
288
+ ...section,
289
+ groups: (_a = section.groups) === null || _a === void 0 ? void 0 : _a.filter((group) => group.exercises && group.exercises.length > 0),
290
+ });
291
+ })
292
+ .filter((section) => section.groups && section.groups.length > 0);
293
+ }
294
+ exports.filterEmptyGroups = filterEmptyGroups;
295
+ function getAllWorkoutExercises(workoutTemplate) {
296
+ if (!workoutTemplate) {
297
+ return [];
298
+ }
299
+ if (workoutTemplate.workoutSections && workoutTemplate.workoutSections.length > 0) {
300
+ const exercises = [];
301
+ workoutTemplate.workoutSections.forEach((section) => {
302
+ if (section.workoutGroups && section.workoutGroups.length > 0) {
303
+ section.workoutGroups.forEach((group) => {
304
+ if (group.workoutExercises && group.workoutExercises.length > 0) {
305
+ exercises.push(...group.workoutExercises);
306
+ }
307
+ });
308
+ }
309
+ });
310
+ return exercises;
311
+ }
312
+ return [];
313
+ }
314
+ exports.getAllWorkoutExercises = getAllWorkoutExercises;
315
+ function getWorkoutExerciseCount(workoutTemplate) {
316
+ return getAllWorkoutExercises(workoutTemplate).length;
317
+ }
318
+ exports.getWorkoutExerciseCount = getWorkoutExerciseCount;