diff --git a/lib/models/exercises/exercise.dart b/lib/models/exercises/exercise.dart
index e642dd15..74e269f2 100644
--- a/lib/models/exercises/exercise.dart
+++ b/lib/models/exercises/exercise.dart
@@ -147,21 +147,21 @@ class Exercise extends Equatable {
   Exercise.fromApiDataJson(Map<String, dynamic> baseData, List<Language> languages)
       : this.fromApiData(ExerciseApiData.fromJson(baseData), languages);
 
-  Exercise.fromApiData(ExerciseApiData baseData, List<Language> languages) {
-    id = baseData.id;
-    uuid = baseData.uuid;
-    categoryId = baseData.category.id;
-    category = baseData.category;
-
-    created = baseData.created;
-    lastUpdate = baseData.lastUpdate;
-    lastUpdateGlobal = baseData.lastUpdateGlobal;
-
-    musclesSecondary = baseData.muscles;
-    muscles = baseData.muscles;
-    equipment = baseData.equipment;
-    category = baseData.category;
-    translations = baseData.translations.map((e) {
+  Exercise.fromApiData(ExerciseApiData exerciseData, List<Language> languages) {
+    id = exerciseData.id;
+    uuid = exerciseData.uuid;
+    categoryId = exerciseData.category.id;
+    category = exerciseData.category;
+
+    created = exerciseData.created;
+    lastUpdate = exerciseData.lastUpdate;
+    lastUpdateGlobal = exerciseData.lastUpdateGlobal;
+
+    musclesSecondary = exerciseData.muscles;
+    muscles = exerciseData.muscles;
+    equipment = exerciseData.equipment;
+    category = exerciseData.category;
+    translations = exerciseData.translations.map((e) {
       e.language = languages.firstWhere(
         (l) => l.id == e.languageId,
 
@@ -173,13 +173,13 @@ class Exercise extends Equatable {
       );
       return e;
     }).toList();
-    videos = baseData.videos;
-    images = baseData.images;
+    videos = exerciseData.videos;
+    images = exerciseData.images;
 
-    authors = baseData.authors;
-    authorsGlobal = baseData.authorsGlobal;
+    authors = exerciseData.authors;
+    authorsGlobal = exerciseData.authorsGlobal;
 
-    variationId = baseData.variationId;
+    variationId = exerciseData.variationId;
   }
 
   /// Returns translation for the given language
diff --git a/lib/models/workouts/log.dart b/lib/models/workouts/log.dart
index 81c82767..615549a9 100644
--- a/lib/models/workouts/log.dart
+++ b/lib/models/workouts/log.dart
@@ -17,6 +17,7 @@
  */
 
 import 'package:json_annotation/json_annotation.dart';
+import 'package:wger/helpers/consts.dart';
 import 'package:wger/helpers/json.dart';
 import 'package:wger/helpers/misc.dart';
 import 'package:wger/models/exercises/exercise.dart';
@@ -86,12 +87,12 @@ class Log {
     required this.routineId,
     this.repetitions,
     this.repetitionsTarget,
-    required this.repetitionsUnitId,
+    this.repetitionsUnitId = REP_UNIT_REPETITIONS_ID,
     required this.rir,
     this.rirTarget,
     this.weight,
     this.weightTarget,
-    required this.weightUnitId,
+    this.weightUnitId = WEIGHT_UNIT_KG,
     required this.date,
   });
 
diff --git a/lib/models/workouts/log.g.dart b/lib/models/workouts/log.g.dart
index e2656f18..410af19d 100644
--- a/lib/models/workouts/log.g.dart
+++ b/lib/models/workouts/log.g.dart
@@ -32,12 +32,12 @@ Log _$LogFromJson(Map<String, dynamic> json) {
     routineId: (json['routine'] as num).toInt(),
     repetitions: stringToNum(json['repetitions'] as String?),
     repetitionsTarget: stringToNum(json['repetitions_target'] as String?),
-    repetitionsUnitId: (json['repetitions_unit'] as num).toInt(),
+    repetitionsUnitId: (json['repetitions_unit'] as num?)?.toInt() ?? REP_UNIT_REPETITIONS_ID,
     rir: json['rir'] as String?,
     rirTarget: json['rir_target'] as String?,
     weight: stringToNum(json['weight'] as String?),
     weightTarget: stringToNum(json['weight_target'] as String?),
-    weightUnitId: (json['weight_unit'] as num).toInt(),
+    weightUnitId: (json['weight_unit'] as num?)?.toInt() ?? WEIGHT_UNIT_KG,
     date: DateTime.parse(json['date'] as String),
   );
 }
diff --git a/lib/models/workouts/routine.dart b/lib/models/workouts/routine.dart
index 9af1492d..bf4b738a 100644
--- a/lib/models/workouts/routine.dart
+++ b/lib/models/workouts/routine.dart
@@ -118,8 +118,8 @@ class Routine {
   /// means here that the values are the same, i.e. logs with the same weight,
   /// reps, etc. are considered equal. Workout ID, Log ID and date are not
   /// considered.
-  List<Log> filterLogsByExercise(Exercise exercise, {bool unique = false}) {
-    var out = logs.where((element) => element.exerciseId == exercise.id).toList();
+  List<Log> filterLogsByExercise(int exerciseId, {bool unique = false}) {
+    var out = logs.where((log) => log.exerciseId == exerciseId).toList();
 
     if (unique) {
       out = out.toSet().toList();
@@ -129,6 +129,26 @@ class Routine {
     return out;
   }
 
+  /// Groups logs by repetition
+  Map<num, List<Log>> groupLogsByRepetition({List<Log>? logs}) {
+    final workoutLogs = logs ?? this.logs;
+    final Map<num, List<Log>> groupedLogs = {};
+
+    for (final log in workoutLogs) {
+      if (log.repetitions == null) {
+        continue;
+      }
+
+      if (!groupedLogs.containsKey(log.repetitions)) {
+        groupedLogs[log.repetitions!] = [];
+      }
+
+      groupedLogs[log.repetitions]!.add(log);
+    }
+
+    return groupedLogs;
+  }
+
   /// Massages the log data to more easily present on the log overview
   ///
   Map<DateTime, Map<String, dynamic>> get logData {
diff --git a/lib/providers/routines.dart b/lib/providers/routines.dart
index 0cd67895..4723aa2f 100644
--- a/lib/providers/routines.dart
+++ b/lib/providers/routines.dart
@@ -23,7 +23,6 @@ import 'package:flutter/material.dart';
 import 'package:shared_preferences/shared_preferences.dart';
 import 'package:wger/exceptions/http_exception.dart';
 import 'package:wger/helpers/consts.dart';
-import 'package:wger/models/exercises/exercise.dart';
 import 'package:wger/models/workouts/base_config.dart';
 import 'package:wger/models/workouts/day.dart';
 import 'package:wger/models/workouts/day_data.dart';
@@ -62,7 +61,7 @@ class RoutinesProvider with ChangeNotifier {
   static const _routineConfigRestTime = 'rest-config';
   static const _routineConfigMaxRestTime = 'max-rest-config';
 
-  Routine? _currentPlan;
+  Routine? _currentRoutine;
   late ExercisesProvider _exercises;
   final WgerBaseProvider baseProvider;
   List<Routine> _routines = [];
@@ -92,7 +91,7 @@ class RoutinesProvider with ChangeNotifier {
 
   /// Clears all lists
   void clear() {
-    _currentPlan = null;
+    _currentRoutine = null;
     _routines = [];
     _weightUnits = [];
     _repetitionUnits = [];
@@ -131,17 +130,17 @@ class RoutinesProvider with ChangeNotifier {
 
   /// Set the currently "active" workout plan
   void setCurrentPlan(int id) {
-    _currentPlan = findById(id);
+    _currentRoutine = findById(id);
   }
 
   /// Returns the currently "active" workout plan
-  Routine? get currentPlan {
-    return _currentPlan;
+  Routine? get currentRoutine {
+    return _currentRoutine;
   }
 
   /// Reset the currently "active" workout plan to null
   void resetCurrentRoutine() {
-    _currentPlan = null;
+    _currentRoutine = null;
   }
 
   /// Returns the current active workout plan. At the moment this is just
@@ -378,21 +377,6 @@ class RoutinesProvider with ChangeNotifier {
     }
   }
 
-  Future<Map<String, dynamic>> fetchLogData(
-    Routine workout,
-    Exercise base,
-  ) async {
-    final data = await baseProvider.fetch(
-      baseProvider.makeUrl(
-        _routinesUrlPath,
-        id: workout.id,
-        objectMethod: 'logs',
-        query: {'id': base.id!.toString()},
-      ),
-    );
-    return data;
-  }
-
   /// Fetch and set weight units for workout (kg, lb, plate, etc.)
   Future<void> fetchAndSetRepetitionUnits() async {
     final response =
diff --git a/lib/widgets/routines/charts.dart b/lib/widgets/routines/charts.dart
index e41e249a..41c20a3e 100644
--- a/lib/widgets/routines/charts.dart
+++ b/lib/widgets/routines/charts.dart
@@ -22,9 +22,10 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
 import 'package:intl/intl.dart';
 import 'package:wger/helpers/charts.dart';
 import 'package:wger/helpers/colors.dart';
+import 'package:wger/models/workouts/log.dart';
 
 class LogChartWidgetFl extends StatefulWidget {
-  final Map _data;
+  final Map<num, List<Log>> _data;
   final DateTime _currentDate;
 
   const LogChartWidgetFl(this._data, this._currentDate);
@@ -50,7 +51,7 @@ class _LogChartWidgetFlState extends State<LogChartWidgetFl> {
       touchTooltipData: LineTouchTooltipData(
         getTooltipItems: (touchedSpots) {
           return touchedSpots.map((touchedSpot) {
-            final reps = widget._data['chart_data'][touchedSpot.barIndex].first['reps'];
+            final reps = widget._data[touchedSpot.barIndex]?.first.repetitions;
 
             return LineTooltipItem(
               '$reps × ${touchedSpot.y} kg',
@@ -63,7 +64,7 @@ class _LogChartWidgetFlState extends State<LogChartWidgetFl> {
   }
 
   LineChartData mainData() {
-    final colors = generateChartColors(widget._data['chart_data'].length).iterator;
+    final colors = generateChartColors(widget._data.keys.length).iterator;
 
     return LineChartData(
       lineTouchData: tooltipData(),
@@ -101,8 +102,9 @@ class _LogChartWidgetFlState extends State<LogChartWidgetFl> {
               );
             },
             interval: chartGetInterval(
-              DateTime.parse(widget._data['logs'].keys.first),
-              DateTime.parse(widget._data['logs'].keys.last),
+              // TODO: make sure this works when the data is empty etc
+              widget._data[widget._data.keys.first]!.first.date,
+              widget._data[widget._data.keys.last]!.first.date,
             ),
           ),
         ),
@@ -121,14 +123,14 @@ class _LogChartWidgetFlState extends State<LogChartWidgetFl> {
         border: Border.all(color: const Color(0xff37434d)),
       ),
       lineBarsData: [
-        ...widget._data['chart_data'].map((e) {
+        ...widget._data.keys.map((reps) {
           colors.moveNext();
           return LineChartBarData(
             spots: [
-              ...e.map(
+              ...widget._data[reps]!.map(
                 (entry) => FlSpot(
-                  DateTime.parse(entry['date']).millisecondsSinceEpoch.toDouble(),
-                  double.parse(entry['weight']),
+                  entry.date.millisecondsSinceEpoch.toDouble(),
+                  entry.weight!.toDouble(),
                 ),
               ),
             ],
diff --git a/lib/widgets/routines/gym_mode.dart b/lib/widgets/routines/gym_mode.dart
index ecdbc8eb..0e8db6e8 100644
--- a/lib/widgets/routines/gym_mode.dart
+++ b/lib/widgets/routines/gym_mode.dart
@@ -533,7 +533,7 @@ class _LogPageState extends State<LogPage> {
           style: Theme.of(context).textTheme.titleLarge,
           textAlign: TextAlign.center,
         ),
-        ...widget._workoutPlan.filterLogsByExercise(widget._exercise, unique: true).map((log) {
+        ...widget._workoutPlan.filterLogsByExercise(widget._exercise.id!, unique: true).map((log) {
           return ListTile(
             title: Text(log.singleLogRepTextNoNl),
             subtitle: Text(
@@ -646,7 +646,7 @@ class _LogPageState extends State<LogPage> {
           Text(widget._slotData.comment, textAlign: TextAlign.center),
         const SizedBox(height: 10),
         Expanded(
-          child: (widget._workoutPlan.filterLogsByExercise(widget._exercise).isNotEmpty)
+          child: (widget._workoutPlan.filterLogsByExercise(widget._exercise.id!).isNotEmpty)
               ? getPastLogs()
               : Container(),
         ),
diff --git a/lib/widgets/routines/log.dart b/lib/widgets/routines/log.dart
index 8ddb3879..068ae9db 100644
--- a/lib/widgets/routines/log.dart
+++ b/lib/widgets/routines/log.dart
@@ -18,89 +18,60 @@
 
 import 'package:flutter/material.dart';
 import 'package:intl/intl.dart';
-import 'package:provider/provider.dart';
 import 'package:wger/helpers/colors.dart';
 import 'package:wger/helpers/ui.dart';
 import 'package:wger/models/exercises/exercise.dart';
 import 'package:wger/models/workouts/log.dart';
+import 'package:wger/models/workouts/routine.dart';
 import 'package:wger/models/workouts/session.dart';
-import 'package:wger/providers/routines.dart';
 import 'package:wger/widgets/measurements/charts.dart';
 import 'package:wger/widgets/routines/charts.dart';
 
 class ExerciseLogChart extends StatelessWidget {
-  final Exercise _base;
-  final DateTime _currentDate;
+  final Map<num, List<Log>> _logs;
+  final DateTime _selectedDate;
 
-  const ExerciseLogChart(this._base, this._currentDate);
+  const ExerciseLogChart(this._logs, this._selectedDate);
 
   @override
   Widget build(BuildContext context) {
-    final workoutPlansData = Provider.of<RoutinesProvider>(context, listen: false);
-    final workout = workoutPlansData.currentPlan;
-    var colors = generateChartColors(1).iterator;
+    final colors = generateChartColors(_logs.keys.length).iterator;
 
-    Future<Map<String, dynamic>> getChartEntries(BuildContext context) async {
-      return workoutPlansData.fetchLogData(workout!, _base);
-    }
+    return Column(
+      mainAxisSize: MainAxisSize.max,
+      children: [
+        LogChartWidgetFl(_logs, _selectedDate),
+        Row(
+          mainAxisAlignment: MainAxisAlignment.center,
+          children: [
+            ..._logs.keys.map((reps) {
+              // e is the list of logs with the same reps, so we can just take the
+              // first entry and read the reps from it. Yes, this is an amazingly ugly hack
+              // final reps = log.repetitions;
 
-    return FutureBuilder(
-      future: getChartEntries(context),
-      builder: (context, AsyncSnapshot<Map<String, dynamic>> snapshot) {
-        if (snapshot.connectionState == ConnectionState.done) {
-          colors = generateChartColors(snapshot.data!['chart_data'].length).iterator;
-        }
-
-        return SizedBox(
-          height: 260,
-          child: snapshot.connectionState == ConnectionState.waiting
-              ? const Center(child: CircularProgressIndicator())
-              : Column(
-                  mainAxisSize: MainAxisSize.max,
-                  children: [
-                    LogChartWidgetFl(snapshot.data!, _currentDate),
-                    Row(
-                      mainAxisAlignment: MainAxisAlignment.center,
-                      children: [
-                        ...snapshot.data!['chart_data'].map((e) {
-                          // e is the list of logs with the same reps, so we can just take the
-                          // first entry and read the reps from it. Yes, this is an amazingly ugly hack
-                          final reps = e.first['reps'];
-
-                          colors.moveNext();
-                          return Indicator(
-                            color: colors.current,
-                            text: reps.toString(),
-                            isSquare: false,
-                          );
-                        }).toList(),
-                      ],
-                    ),
-                    const SizedBox(height: 15),
-                  ],
-                ),
-        );
-      },
+              colors.moveNext();
+              return Indicator(
+                color: colors.current,
+                text: reps.toString(),
+                isSquare: false,
+              );
+            }).toList(),
+          ],
+        ),
+        const SizedBox(height: 15),
+      ],
     );
   }
 }
 
-class DayLogWidget extends StatefulWidget {
+class DayLogWidget extends StatelessWidget {
   final DateTime _date;
+  final Routine _routine;
+
   final WorkoutSession? _session;
   final Map<Exercise, List<Log>> _exerciseData;
 
-  const DayLogWidget(this._date, this._exerciseData, this._session);
-
-  @override
-  _DayLogWidgetState createState() => _DayLogWidgetState();
-}
-
-class _DayLogWidgetState extends State<DayLogWidget> {
-  @override
-  void initState() {
-    super.initState();
-  }
+  const DayLogWidget(this._date, this._exerciseData, this._session, this._routine);
 
   @override
   Widget build(BuildContext context) {
@@ -108,35 +79,36 @@ class _DayLogWidgetState extends State<DayLogWidget> {
       child: Column(
         children: [
           Text(
-            DateFormat.yMd(Localizations.localeOf(context).languageCode).format(widget._date),
+            DateFormat.yMd(Localizations.localeOf(context).languageCode).format(_date),
             style: Theme.of(context).textTheme.headlineSmall,
           ),
-          if (widget._session != null) const Text('Session data here'),
-          ...widget._exerciseData.keys.map((base) {
-            final exercise = base.getTranslation(Localizations.localeOf(context).languageCode);
+          if (_session != null) const Text('Session data here'),
+          ..._exerciseData.keys.map((exercise) {
+            final translation =
+                exercise.getTranslation(Localizations.localeOf(context).languageCode);
             return Column(
               children: [
-                if (widget._exerciseData[base]!.isNotEmpty)
+                if (_exerciseData[exercise]!.isNotEmpty)
                   Text(
-                    exercise.name,
+                    translation.name,
                     style: Theme.of(context).textTheme.headlineSmall,
                   )
                 else
                   Container(),
-                ...widget._exerciseData[base]!.map(
+                ..._exerciseData[exercise]!.map(
                   (log) => Row(
                     mainAxisAlignment: MainAxisAlignment.spaceBetween,
                     children: [
                       Text(log.singleLogRepTextNoNl),
                       IconButton(
                         icon: const Icon(Icons.delete),
-                        onPressed: () async {
+                        onPressed: () {
                           showDeleteDialog(
                             context,
-                            exercise.name,
+                            translation.name,
                             log,
-                            exercise,
-                            widget._exerciseData,
+                            translation,
+                            _exerciseData,
                           );
                         },
                       ),
@@ -145,7 +117,12 @@ class _DayLogWidgetState extends State<DayLogWidget> {
                 ),
                 Padding(
                   padding: const EdgeInsets.symmetric(horizontal: 15),
-                  child: ExerciseLogChart(base, widget._date),
+                  child: ExerciseLogChart(
+                    _routine.groupLogsByRepetition(
+                      logs: _routine.filterLogsByExercise(exercise.id!),
+                    ),
+                    _date,
+                  ),
                 ),
               ],
             );
diff --git a/lib/widgets/routines/workout_logs.dart b/lib/widgets/routines/workout_logs.dart
index 4479ecce..3be4e395 100644
--- a/lib/widgets/routines/workout_logs.dart
+++ b/lib/widgets/routines/workout_logs.dart
@@ -28,9 +28,9 @@ import 'package:wger/theme/theme.dart';
 import 'package:wger/widgets/routines/log.dart';
 
 class WorkoutLogs extends StatefulWidget {
-  final Routine _workoutPlan;
+  final Routine _routine;
 
-  const WorkoutLogs(this._workoutPlan);
+  const WorkoutLogs(this._routine);
 
   @override
   _WorkoutLogsState createState() => _WorkoutLogsState();
@@ -72,7 +72,7 @@ class _WorkoutLogsState extends State<WorkoutLogs> {
         ),
         SizedBox(
           width: double.infinity,
-          child: WorkoutLogCalendar(widget._workoutPlan),
+          child: WorkoutLogCalendar(widget._routine),
         ),
       ],
     );
@@ -89,9 +89,9 @@ class WorkoutLogEvent {
 }
 
 class WorkoutLogCalendar extends StatefulWidget {
-  final Routine _workoutPlan;
+  final Routine _routine;
 
-  const WorkoutLogCalendar(this._workoutPlan);
+  const WorkoutLogCalendar(this._routine);
 
   @override
   _WorkoutLogCalendarState createState() => _WorkoutLogCalendarState();
@@ -120,8 +120,8 @@ class _WorkoutLogCalendarState extends State<WorkoutLogCalendar> {
   }
 
   void loadEvents() {
-    for (final date in widget._workoutPlan.logData.keys) {
-      final entry = widget._workoutPlan.logData[date]!;
+    for (final date in widget._routine.logData.keys) {
+      final entry = widget._routine.logData[date]!;
       _events[DateFormatLists.format(date)] = [
         WorkoutLogEvent(date, entry['session'], entry['exercises']),
       ];
@@ -179,6 +179,7 @@ class _WorkoutLogCalendarState extends State<WorkoutLogCalendar> {
                       logEvents.first.dateTime,
                       logEvents.first.exercises,
                       logEvents.first.session,
+                      widget._routine,
                     )
                   : Container();
             },
diff --git a/test/core/settings_test.mocks.dart b/test/core/settings_test.mocks.dart
index 07d9fc3a..7a90604f 100644
--- a/test/core/settings_test.mocks.dart
+++ b/test/core/settings_test.mocks.dart
@@ -392,6 +392,13 @@ class MockExercisesProvider extends _i1.Mock implements _i17.ExercisesProvider {
         returnValueForMissingStub: _i18.Future<void>.value(),
       ) as _i18.Future<void>);
 
+  @override
+  _i18.Future<void> updateExerciseCache(_i3.ExerciseDatabase? database) => (super.noSuchMethod(
+        Invocation.method(#updateExerciseCache, [database]),
+        returnValue: _i18.Future<void>.value(),
+        returnValueForMissingStub: _i18.Future<void>.value(),
+      ) as _i18.Future<void>);
+
   @override
   _i18.Future<void> fetchAndSetMuscles(_i3.ExerciseDatabase? database) => (super.noSuchMethod(
         Invocation.method(#fetchAndSetMuscles, [database]),
diff --git a/test/workout/day_form_test.mocks.dart b/test/workout/day_form_test.mocks.dart
index 8b2078ba..9568e477 100644
--- a/test/workout/day_form_test.mocks.dart
+++ b/test/workout/day_form_test.mocks.dart
@@ -4,11 +4,10 @@
 
 // ignore_for_file: no_leading_underscores_for_library_prefixes
 import 'dart:async' as _i13;
-import 'dart:ui' as _i17;
+import 'dart:ui' as _i16;
 
 import 'package:mockito/mockito.dart' as _i1;
-import 'package:mockito/src/dummies.dart' as _i16;
-import 'package:wger/models/exercises/exercise.dart' as _i15;
+import 'package:mockito/src/dummies.dart' as _i15;
 import 'package:wger/models/workouts/base_config.dart' as _i9;
 import 'package:wger/models/workouts/day.dart' as _i6;
 import 'package:wger/models/workouts/day_data.dart' as _i14;
@@ -257,18 +256,6 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider {
         returnValueForMissingStub: _i13.Future<void>.value(),
       ) as _i13.Future<void>);
 
-  @override
-  _i13.Future<Map<String, dynamic>> fetchLogData(
-    _i5.Routine? workout,
-    _i15.Exercise? base,
-  ) =>
-      (super.noSuchMethod(
-        Invocation.method(#fetchLogData, [workout, base]),
-        returnValue: _i13.Future<Map<String, dynamic>>.value(
-          <String, dynamic>{},
-        ),
-      ) as _i13.Future<Map<String, dynamic>>);
-
   @override
   _i13.Future<void> fetchAndSetRepetitionUnits() => (super.noSuchMethod(
         Invocation.method(#fetchAndSetRepetitionUnits, []),
@@ -376,7 +363,7 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider {
   @override
   String getConfigUrl(_i8.ConfigType? type) => (super.noSuchMethod(
         Invocation.method(#getConfigUrl, [type]),
-        returnValue: _i16.dummyValue<String>(
+        returnValue: _i15.dummyValue<String>(
           this,
           Invocation.method(#getConfigUrl, [type]),
         ),
@@ -464,13 +451,13 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider {
       ) as _i13.Future<void>);
 
   @override
-  void addListener(_i17.VoidCallback? listener) => super.noSuchMethod(
+  void addListener(_i16.VoidCallback? listener) => super.noSuchMethod(
         Invocation.method(#addListener, [listener]),
         returnValueForMissingStub: null,
       );
 
   @override
-  void removeListener(_i17.VoidCallback? listener) => super.noSuchMethod(
+  void removeListener(_i16.VoidCallback? listener) => super.noSuchMethod(
         Invocation.method(#removeListener, [listener]),
         returnValueForMissingStub: null,
       );
diff --git a/test/workout/gym_mode_screen_test.mocks.dart b/test/workout/gym_mode_screen_test.mocks.dart
index a17dabbf..f19ff3b5 100644
--- a/test/workout/gym_mode_screen_test.mocks.dart
+++ b/test/workout/gym_mode_screen_test.mocks.dart
@@ -464,6 +464,13 @@ class MockExercisesProvider extends _i1.Mock implements _i12.ExercisesProvider {
         returnValueForMissingStub: _i11.Future<void>.value(),
       ) as _i11.Future<void>);
 
+  @override
+  _i11.Future<void> updateExerciseCache(_i5.ExerciseDatabase? database) => (super.noSuchMethod(
+        Invocation.method(#updateExerciseCache, [database]),
+        returnValue: _i11.Future<void>.value(),
+        returnValueForMissingStub: _i11.Future<void>.value(),
+      ) as _i11.Future<void>);
+
   @override
   _i11.Future<void> fetchAndSetMuscles(_i5.ExerciseDatabase? database) => (super.noSuchMethod(
         Invocation.method(#fetchAndSetMuscles, [database]),
diff --git a/test/workout/repetition_unit_form_widget_test.mocks.dart b/test/workout/repetition_unit_form_widget_test.mocks.dart
index 95b4a18c..cea8ae43 100644
--- a/test/workout/repetition_unit_form_widget_test.mocks.dart
+++ b/test/workout/repetition_unit_form_widget_test.mocks.dart
@@ -4,11 +4,10 @@
 
 // ignore_for_file: no_leading_underscores_for_library_prefixes
 import 'dart:async' as _i13;
-import 'dart:ui' as _i17;
+import 'dart:ui' as _i16;
 
 import 'package:mockito/mockito.dart' as _i1;
-import 'package:mockito/src/dummies.dart' as _i16;
-import 'package:wger/models/exercises/exercise.dart' as _i15;
+import 'package:mockito/src/dummies.dart' as _i15;
 import 'package:wger/models/workouts/base_config.dart' as _i9;
 import 'package:wger/models/workouts/day.dart' as _i6;
 import 'package:wger/models/workouts/day_data.dart' as _i14;
@@ -257,18 +256,6 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider {
         returnValueForMissingStub: _i13.Future<void>.value(),
       ) as _i13.Future<void>);
 
-  @override
-  _i13.Future<Map<String, dynamic>> fetchLogData(
-    _i5.Routine? workout,
-    _i15.Exercise? base,
-  ) =>
-      (super.noSuchMethod(
-        Invocation.method(#fetchLogData, [workout, base]),
-        returnValue: _i13.Future<Map<String, dynamic>>.value(
-          <String, dynamic>{},
-        ),
-      ) as _i13.Future<Map<String, dynamic>>);
-
   @override
   _i13.Future<void> fetchAndSetRepetitionUnits() => (super.noSuchMethod(
         Invocation.method(#fetchAndSetRepetitionUnits, []),
@@ -376,7 +363,7 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider {
   @override
   String getConfigUrl(_i8.ConfigType? type) => (super.noSuchMethod(
         Invocation.method(#getConfigUrl, [type]),
-        returnValue: _i16.dummyValue<String>(
+        returnValue: _i15.dummyValue<String>(
           this,
           Invocation.method(#getConfigUrl, [type]),
         ),
@@ -464,13 +451,13 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider {
       ) as _i13.Future<void>);
 
   @override
-  void addListener(_i17.VoidCallback? listener) => super.noSuchMethod(
+  void addListener(_i16.VoidCallback? listener) => super.noSuchMethod(
         Invocation.method(#addListener, [listener]),
         returnValueForMissingStub: null,
       );
 
   @override
-  void removeListener(_i17.VoidCallback? listener) => super.noSuchMethod(
+  void removeListener(_i16.VoidCallback? listener) => super.noSuchMethod(
         Invocation.method(#removeListener, [listener]),
         returnValueForMissingStub: null,
       );
diff --git a/test/workout/routine_edit_screen_test.mocks.dart b/test/workout/routine_edit_screen_test.mocks.dart
index bcccb3aa..e80671ea 100644
--- a/test/workout/routine_edit_screen_test.mocks.dart
+++ b/test/workout/routine_edit_screen_test.mocks.dart
@@ -4,11 +4,10 @@
 
 // ignore_for_file: no_leading_underscores_for_library_prefixes
 import 'dart:async' as _i13;
-import 'dart:ui' as _i17;
+import 'dart:ui' as _i16;
 
 import 'package:mockito/mockito.dart' as _i1;
-import 'package:mockito/src/dummies.dart' as _i16;
-import 'package:wger/models/exercises/exercise.dart' as _i15;
+import 'package:mockito/src/dummies.dart' as _i15;
 import 'package:wger/models/workouts/base_config.dart' as _i9;
 import 'package:wger/models/workouts/day.dart' as _i6;
 import 'package:wger/models/workouts/day_data.dart' as _i14;
@@ -257,18 +256,6 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider {
         returnValueForMissingStub: _i13.Future<void>.value(),
       ) as _i13.Future<void>);
 
-  @override
-  _i13.Future<Map<String, dynamic>> fetchLogData(
-    _i5.Routine? workout,
-    _i15.Exercise? base,
-  ) =>
-      (super.noSuchMethod(
-        Invocation.method(#fetchLogData, [workout, base]),
-        returnValue: _i13.Future<Map<String, dynamic>>.value(
-          <String, dynamic>{},
-        ),
-      ) as _i13.Future<Map<String, dynamic>>);
-
   @override
   _i13.Future<void> fetchAndSetRepetitionUnits() => (super.noSuchMethod(
         Invocation.method(#fetchAndSetRepetitionUnits, []),
@@ -376,7 +363,7 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider {
   @override
   String getConfigUrl(_i8.ConfigType? type) => (super.noSuchMethod(
         Invocation.method(#getConfigUrl, [type]),
-        returnValue: _i16.dummyValue<String>(
+        returnValue: _i15.dummyValue<String>(
           this,
           Invocation.method(#getConfigUrl, [type]),
         ),
@@ -464,13 +451,13 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider {
       ) as _i13.Future<void>);
 
   @override
-  void addListener(_i17.VoidCallback? listener) => super.noSuchMethod(
+  void addListener(_i16.VoidCallback? listener) => super.noSuchMethod(
         Invocation.method(#addListener, [listener]),
         returnValueForMissingStub: null,
       );
 
   @override
-  void removeListener(_i17.VoidCallback? listener) => super.noSuchMethod(
+  void removeListener(_i16.VoidCallback? listener) => super.noSuchMethod(
         Invocation.method(#removeListener, [listener]),
         returnValueForMissingStub: null,
       );
diff --git a/test/workout/routine_edit_test.mocks.dart b/test/workout/routine_edit_test.mocks.dart
index 53590528..e23a10c7 100644
--- a/test/workout/routine_edit_test.mocks.dart
+++ b/test/workout/routine_edit_test.mocks.dart
@@ -4,11 +4,10 @@
 
 // ignore_for_file: no_leading_underscores_for_library_prefixes
 import 'dart:async' as _i13;
-import 'dart:ui' as _i17;
+import 'dart:ui' as _i16;
 
 import 'package:mockito/mockito.dart' as _i1;
-import 'package:mockito/src/dummies.dart' as _i16;
-import 'package:wger/models/exercises/exercise.dart' as _i15;
+import 'package:mockito/src/dummies.dart' as _i15;
 import 'package:wger/models/workouts/base_config.dart' as _i9;
 import 'package:wger/models/workouts/day.dart' as _i6;
 import 'package:wger/models/workouts/day_data.dart' as _i14;
@@ -257,18 +256,6 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider {
         returnValueForMissingStub: _i13.Future<void>.value(),
       ) as _i13.Future<void>);
 
-  @override
-  _i13.Future<Map<String, dynamic>> fetchLogData(
-    _i5.Routine? workout,
-    _i15.Exercise? base,
-  ) =>
-      (super.noSuchMethod(
-        Invocation.method(#fetchLogData, [workout, base]),
-        returnValue: _i13.Future<Map<String, dynamic>>.value(
-          <String, dynamic>{},
-        ),
-      ) as _i13.Future<Map<String, dynamic>>);
-
   @override
   _i13.Future<void> fetchAndSetRepetitionUnits() => (super.noSuchMethod(
         Invocation.method(#fetchAndSetRepetitionUnits, []),
@@ -376,7 +363,7 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider {
   @override
   String getConfigUrl(_i8.ConfigType? type) => (super.noSuchMethod(
         Invocation.method(#getConfigUrl, [type]),
-        returnValue: _i16.dummyValue<String>(
+        returnValue: _i15.dummyValue<String>(
           this,
           Invocation.method(#getConfigUrl, [type]),
         ),
@@ -464,13 +451,13 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider {
       ) as _i13.Future<void>);
 
   @override
-  void addListener(_i17.VoidCallback? listener) => super.noSuchMethod(
+  void addListener(_i16.VoidCallback? listener) => super.noSuchMethod(
         Invocation.method(#addListener, [listener]),
         returnValueForMissingStub: null,
       );
 
   @override
-  void removeListener(_i17.VoidCallback? listener) => super.noSuchMethod(
+  void removeListener(_i16.VoidCallback? listener) => super.noSuchMethod(
         Invocation.method(#removeListener, [listener]),
         returnValueForMissingStub: null,
       );
diff --git a/test/workout/routine_form_test.mocks.dart b/test/workout/routine_form_test.mocks.dart
index 225f0fe7..db77f4a4 100644
--- a/test/workout/routine_form_test.mocks.dart
+++ b/test/workout/routine_form_test.mocks.dart
@@ -4,11 +4,10 @@
 
 // ignore_for_file: no_leading_underscores_for_library_prefixes
 import 'dart:async' as _i13;
-import 'dart:ui' as _i17;
+import 'dart:ui' as _i16;
 
 import 'package:mockito/mockito.dart' as _i1;
-import 'package:mockito/src/dummies.dart' as _i16;
-import 'package:wger/models/exercises/exercise.dart' as _i15;
+import 'package:mockito/src/dummies.dart' as _i15;
 import 'package:wger/models/workouts/base_config.dart' as _i9;
 import 'package:wger/models/workouts/day.dart' as _i6;
 import 'package:wger/models/workouts/day_data.dart' as _i14;
@@ -257,18 +256,6 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider {
         returnValueForMissingStub: _i13.Future<void>.value(),
       ) as _i13.Future<void>);
 
-  @override
-  _i13.Future<Map<String, dynamic>> fetchLogData(
-    _i5.Routine? workout,
-    _i15.Exercise? base,
-  ) =>
-      (super.noSuchMethod(
-        Invocation.method(#fetchLogData, [workout, base]),
-        returnValue: _i13.Future<Map<String, dynamic>>.value(
-          <String, dynamic>{},
-        ),
-      ) as _i13.Future<Map<String, dynamic>>);
-
   @override
   _i13.Future<void> fetchAndSetRepetitionUnits() => (super.noSuchMethod(
         Invocation.method(#fetchAndSetRepetitionUnits, []),
@@ -376,7 +363,7 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider {
   @override
   String getConfigUrl(_i8.ConfigType? type) => (super.noSuchMethod(
         Invocation.method(#getConfigUrl, [type]),
-        returnValue: _i16.dummyValue<String>(
+        returnValue: _i15.dummyValue<String>(
           this,
           Invocation.method(#getConfigUrl, [type]),
         ),
@@ -464,13 +451,13 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider {
       ) as _i13.Future<void>);
 
   @override
-  void addListener(_i17.VoidCallback? listener) => super.noSuchMethod(
+  void addListener(_i16.VoidCallback? listener) => super.noSuchMethod(
         Invocation.method(#addListener, [listener]),
         returnValueForMissingStub: null,
       );
 
   @override
-  void removeListener(_i17.VoidCallback? listener) => super.noSuchMethod(
+  void removeListener(_i16.VoidCallback? listener) => super.noSuchMethod(
         Invocation.method(#removeListener, [listener]),
         returnValueForMissingStub: null,
       );
diff --git a/test/workout/routine_logs_screen_test.dart b/test/workout/routine_logs_screen_test.dart
index ad8cda1d..d7fc5640 100644
--- a/test/workout/routine_logs_screen_test.dart
+++ b/test/workout/routine_logs_screen_test.dart
@@ -16,6 +16,8 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+import 'dart:io';
+
 import 'package:flutter/material.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
 import 'package:flutter_test/flutter_test.dart';
@@ -71,7 +73,7 @@ void main() {
     await tester.tap(find.byType(TextButton));
     await tester.pumpAndSettle();
 
-    await screenMatchesGolden(tester, 'routine_logs_screen_detail');
+    await screenMatchesGolden(tester, 'routine_logs_screen_detail', skip: !Platform.isLinux);
 
     // expect(find.text('3 day workout'), findsOneWidget);
 
diff --git a/test/workout/routine_logs_screen_test.mocks.dart b/test/workout/routine_logs_screen_test.mocks.dart
index 943b73df..721d7844 100644
--- a/test/workout/routine_logs_screen_test.mocks.dart
+++ b/test/workout/routine_logs_screen_test.mocks.dart
@@ -4,11 +4,10 @@
 
 // ignore_for_file: no_leading_underscores_for_library_prefixes
 import 'dart:async' as _i13;
-import 'dart:ui' as _i17;
+import 'dart:ui' as _i16;
 
 import 'package:mockito/mockito.dart' as _i1;
-import 'package:mockito/src/dummies.dart' as _i16;
-import 'package:wger/models/exercises/exercise.dart' as _i15;
+import 'package:mockito/src/dummies.dart' as _i15;
 import 'package:wger/models/workouts/base_config.dart' as _i9;
 import 'package:wger/models/workouts/day.dart' as _i6;
 import 'package:wger/models/workouts/day_data.dart' as _i14;
@@ -257,18 +256,6 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider {
         returnValueForMissingStub: _i13.Future<void>.value(),
       ) as _i13.Future<void>);
 
-  @override
-  _i13.Future<Map<String, dynamic>> fetchLogData(
-    _i5.Routine? workout,
-    _i15.Exercise? base,
-  ) =>
-      (super.noSuchMethod(
-        Invocation.method(#fetchLogData, [workout, base]),
-        returnValue: _i13.Future<Map<String, dynamic>>.value(
-          <String, dynamic>{},
-        ),
-      ) as _i13.Future<Map<String, dynamic>>);
-
   @override
   _i13.Future<void> fetchAndSetRepetitionUnits() => (super.noSuchMethod(
         Invocation.method(#fetchAndSetRepetitionUnits, []),
@@ -376,7 +363,7 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider {
   @override
   String getConfigUrl(_i8.ConfigType? type) => (super.noSuchMethod(
         Invocation.method(#getConfigUrl, [type]),
-        returnValue: _i16.dummyValue<String>(
+        returnValue: _i15.dummyValue<String>(
           this,
           Invocation.method(#getConfigUrl, [type]),
         ),
@@ -464,13 +451,13 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider {
       ) as _i13.Future<void>);
 
   @override
-  void addListener(_i17.VoidCallback? listener) => super.noSuchMethod(
+  void addListener(_i16.VoidCallback? listener) => super.noSuchMethod(
         Invocation.method(#addListener, [listener]),
         returnValueForMissingStub: null,
       );
 
   @override
-  void removeListener(_i17.VoidCallback? listener) => super.noSuchMethod(
+  void removeListener(_i16.VoidCallback? listener) => super.noSuchMethod(
         Invocation.method(#removeListener, [listener]),
         returnValueForMissingStub: null,
       );
diff --git a/test/workout/routine_model_test.dart b/test/workout/routine_model_test.dart
index b6b5e64e..2ec646a0 100644
--- a/test/workout/routine_model_test.dart
+++ b/test/workout/routine_model_test.dart
@@ -18,7 +18,6 @@
 
 import 'package:flutter_test/flutter_test.dart';
 
-import '../../test_data/exercises.dart';
 import '../../test_data/routines.dart';
 
 void main() {
@@ -27,16 +26,27 @@ void main() {
       final routine = getTestRoutine();
 
       expect(routine.logs.length, 3);
-      final logExercise1 = routine.filterLogsByExercise(getTestExercises()[0]);
+      final logExercise1 = routine.filterLogsByExercise(1);
       expect(logExercise1.length, 2);
       expect(logExercise1[0].id, 1);
       expect(logExercise1[1].id, 2);
 
-      final logExercise2 = routine.filterLogsByExercise(getTestExercises()[1]);
+      final logExercise2 = routine.filterLogsByExercise(2);
       expect(logExercise2.length, 1);
       expect(logExercise2[0].id, 3);
 
-      expect(routine.filterLogsByExercise(getTestExercises()[2]).length, 0);
+      expect(routine.filterLogsByExercise(3).length, 0);
+    });
+
+    test('Test the groupLogsByRepetition method', () {
+      final routine = getTestRoutine();
+
+      expect(routine.logs.length, 3);
+      final result = routine.groupLogsByRepetition();
+      expect(result.keys, [10, 12, 8]);
+      expect(result[8], [routine.logs[2]]);
+      expect(result[10], [routine.logs[0]]);
+      expect(result[12], [routine.logs[1]]);
     });
   });
 }
diff --git a/test/workout/slot_entry_form_test.mocks.dart b/test/workout/slot_entry_form_test.mocks.dart
index 78ac108c..d882bee3 100644
--- a/test/workout/slot_entry_form_test.mocks.dart
+++ b/test/workout/slot_entry_form_test.mocks.dart
@@ -4,11 +4,10 @@
 
 // ignore_for_file: no_leading_underscores_for_library_prefixes
 import 'dart:async' as _i13;
-import 'dart:ui' as _i17;
+import 'dart:ui' as _i16;
 
 import 'package:mockito/mockito.dart' as _i1;
-import 'package:mockito/src/dummies.dart' as _i16;
-import 'package:wger/models/exercises/exercise.dart' as _i15;
+import 'package:mockito/src/dummies.dart' as _i15;
 import 'package:wger/models/workouts/base_config.dart' as _i9;
 import 'package:wger/models/workouts/day.dart' as _i6;
 import 'package:wger/models/workouts/day_data.dart' as _i14;
@@ -257,18 +256,6 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider {
         returnValueForMissingStub: _i13.Future<void>.value(),
       ) as _i13.Future<void>);
 
-  @override
-  _i13.Future<Map<String, dynamic>> fetchLogData(
-    _i5.Routine? workout,
-    _i15.Exercise? base,
-  ) =>
-      (super.noSuchMethod(
-        Invocation.method(#fetchLogData, [workout, base]),
-        returnValue: _i13.Future<Map<String, dynamic>>.value(
-          <String, dynamic>{},
-        ),
-      ) as _i13.Future<Map<String, dynamic>>);
-
   @override
   _i13.Future<void> fetchAndSetRepetitionUnits() => (super.noSuchMethod(
         Invocation.method(#fetchAndSetRepetitionUnits, []),
@@ -376,7 +363,7 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider {
   @override
   String getConfigUrl(_i8.ConfigType? type) => (super.noSuchMethod(
         Invocation.method(#getConfigUrl, [type]),
-        returnValue: _i16.dummyValue<String>(
+        returnValue: _i15.dummyValue<String>(
           this,
           Invocation.method(#getConfigUrl, [type]),
         ),
@@ -464,13 +451,13 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider {
       ) as _i13.Future<void>);
 
   @override
-  void addListener(_i17.VoidCallback? listener) => super.noSuchMethod(
+  void addListener(_i16.VoidCallback? listener) => super.noSuchMethod(
         Invocation.method(#addListener, [listener]),
         returnValueForMissingStub: null,
       );
 
   @override
-  void removeListener(_i17.VoidCallback? listener) => super.noSuchMethod(
+  void removeListener(_i16.VoidCallback? listener) => super.noSuchMethod(
         Invocation.method(#removeListener, [listener]),
         returnValueForMissingStub: null,
       );
diff --git a/test/workout/weight_unit_form_widget_test.mocks.dart b/test/workout/weight_unit_form_widget_test.mocks.dart
index 16877e0d..d08b8278 100644
--- a/test/workout/weight_unit_form_widget_test.mocks.dart
+++ b/test/workout/weight_unit_form_widget_test.mocks.dart
@@ -4,11 +4,10 @@
 
 // ignore_for_file: no_leading_underscores_for_library_prefixes
 import 'dart:async' as _i13;
-import 'dart:ui' as _i17;
+import 'dart:ui' as _i16;
 
 import 'package:mockito/mockito.dart' as _i1;
-import 'package:mockito/src/dummies.dart' as _i16;
-import 'package:wger/models/exercises/exercise.dart' as _i15;
+import 'package:mockito/src/dummies.dart' as _i15;
 import 'package:wger/models/workouts/base_config.dart' as _i9;
 import 'package:wger/models/workouts/day.dart' as _i6;
 import 'package:wger/models/workouts/day_data.dart' as _i14;
@@ -257,18 +256,6 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider {
         returnValueForMissingStub: _i13.Future<void>.value(),
       ) as _i13.Future<void>);
 
-  @override
-  _i13.Future<Map<String, dynamic>> fetchLogData(
-    _i5.Routine? workout,
-    _i15.Exercise? base,
-  ) =>
-      (super.noSuchMethod(
-        Invocation.method(#fetchLogData, [workout, base]),
-        returnValue: _i13.Future<Map<String, dynamic>>.value(
-          <String, dynamic>{},
-        ),
-      ) as _i13.Future<Map<String, dynamic>>);
-
   @override
   _i13.Future<void> fetchAndSetRepetitionUnits() => (super.noSuchMethod(
         Invocation.method(#fetchAndSetRepetitionUnits, []),
@@ -376,7 +363,7 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider {
   @override
   String getConfigUrl(_i8.ConfigType? type) => (super.noSuchMethod(
         Invocation.method(#getConfigUrl, [type]),
-        returnValue: _i16.dummyValue<String>(
+        returnValue: _i15.dummyValue<String>(
           this,
           Invocation.method(#getConfigUrl, [type]),
         ),
@@ -464,13 +451,13 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider {
       ) as _i13.Future<void>);
 
   @override
-  void addListener(_i17.VoidCallback? listener) => super.noSuchMethod(
+  void addListener(_i16.VoidCallback? listener) => super.noSuchMethod(
         Invocation.method(#addListener, [listener]),
         returnValueForMissingStub: null,
       );
 
   @override
-  void removeListener(_i17.VoidCallback? listener) => super.noSuchMethod(
+  void removeListener(_i16.VoidCallback? listener) => super.noSuchMethod(
         Invocation.method(#removeListener, [listener]),
         returnValueForMissingStub: null,
       );