import 'dart:collection'; import 'dart:convert'; import 'package:flutter/foundation.dart'; import 'package:aitrainer_app/model/customer.dart'; import 'package:aitrainer_app/model/customer_activity.dart'; import 'package:aitrainer_app/model/customer_property.dart'; import 'package:aitrainer_app/model/customer_training_plan.dart'; import 'package:aitrainer_app/model/description.dart'; import 'package:aitrainer_app/model/evaluation.dart'; import 'package:aitrainer_app/model/exercise_plan.dart'; import 'package:aitrainer_app/model/exercise_plan_detail.dart'; import 'package:aitrainer_app/model/exercise_plan_template.dart'; import 'package:aitrainer_app/model/exercise_tree.dart'; import 'package:aitrainer_app/model/exercise.dart'; import 'package:aitrainer_app/model/faq.dart'; import 'package:aitrainer_app/model/model_change.dart'; import 'package:aitrainer_app/model/product.dart' as wt_product; import 'package:aitrainer_app/model/product.dart'; import 'package:aitrainer_app/model/property.dart'; import 'package:aitrainer_app/model/purchase.dart'; import 'package:aitrainer_app/model/split_test.dart'; import 'package:aitrainer_app/model/sport.dart'; import 'package:aitrainer_app/model/training_plan.dart'; import 'package:aitrainer_app/model/training_plan_day.dart'; import 'package:aitrainer_app/model/tutorial.dart'; import 'package:aitrainer_app/model/workout_menu_tree.dart'; import 'package:aitrainer_app/repository/customer_repository.dart'; import 'package:aitrainer_app/service/firebase_api.dart'; import 'package:aitrainer_app/service/logging.dart'; import 'package:aitrainer_app/service/package_service.dart'; import 'package:aitrainer_app/util/enums.dart'; import 'package:aitrainer_app/util/env.dart'; import 'package:aitrainer_app/util/track.dart'; import 'package:firebase_remote_config/firebase_remote_config.dart'; import 'package:flutter_facebook_auth/flutter_facebook_auth.dart'; import 'package:matomo_tracker/matomo_tracker.dart'; import 'package:package_info/package_info.dart'; import 'package:posthog_session/posthog_session.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:aitrainer_app/model/exercise_type.dart'; import 'package:intl/intl.dart'; import 'customer_exercise_device.dart'; import 'exercise_device.dart'; enum SharePrefsChange { login, registration, logout, } /* Auth flow of the app 1. During the login screen the authentication will be executed - if not successful: message: Network error, try again later - if successful - get the stored shared preferences and customer id - if customer_id not present -> registration page - if present, check if the expiration_date > 10 days -> login page - else get the API customer by the stored customer_id - After registration / login store the preferences: - AuthToken - customer_id - last_store_date - is_registered - is_logged_in */ enum ActivityDone { tutorialExecuteFirstTest, tutorialBasic, tutorialBasicChestPress, tutorialBasicLegPress, tutorialDevelopment, isExerciseLogSeen, isMuscleDevelopmentSeen, isBodyTypeSeen, exerciseSaveTestTip, exerciseSaveTrainingTip, exerciseSaveTestsetTip } extension ActivityDoneExt on ActivityDone { String toStr() => this.toString().split(".").last; bool equalsTo(ActivityDone value) => this.toString() == value.toString(); bool equalsStringTo(String value) => this.toStr() == value; ActivityDone? searchByString(String activityString) { ActivityDone? activity; ActivityDone.values.forEach((element) { if (element.equalsStringTo(activityString)) { activity = element; } }); return activity; } } class Cache with Logging { static final Cache _singleton = Cache._internal(); // Keys to store and fetch data from SharedPreferences static final String authTokenKey = "auth_token"; static final String customerIdKey = "customer_id"; static final String firebaseUidKey = "firebase_uid"; static final String lastStoreDateKey = "last_date"; static final String isRegisteredKey = "is_registered"; static final String isLoggedInKey = "is_logged_in"; static final String langKey = "lang"; static final String serverKey = "live"; static final String hardwareKey = "hardware"; static final String loginTypeKey = "login_type"; static final String timerDisplayKey = "timer_display"; static final String activeExercisePlanKey = "active_exercise_plan"; static final String activeExercisePlanDateKey = "active_exercise_plan_date"; static final String activeExercisePlanDetailsKey = "active_exercise_details_plan"; static final String myTrainingPlanKey = "myTrainingPlan"; static String baseUrlLive = 'https://api.workouttest.org/api/'; static String baseUrlTest = 'https://apitest.workouttest.org/api/'; late String baseUrl; static final String mediaUrl = 'https://admin.workouttest.org/media/'; static final String username = 'bosi'; static final String password = 'andio2009'; String authToken = ""; AccessToken? accessTokenFacebook; Customer? userLoggedIn; String? firebaseUid; String? firebaseMessageToken; LoginType? loginType; PackageInfo? packageInfo; bool hasPurchased = false; bool firstLoad = true; List? _exerciseTypes; List? _exerciseTree; List? _evaluations; List? _exercises; ExercisePlan? _myExercisePlan; List? _properties; List? _sports; List? _products; List _purchases = []; List _splitTests = []; List _trainingPlanDays = []; List _exercisePlanTemplates = []; ExercisePlan? activeExercisePlan; CustomerTrainingPlan? myTrainingPlan; List? activeExercisePlanDetails; List? _devices; List? _customerDevices; List? _customerActivities; List? _customerTrainingPlans; List? _customerPropertyAll; List? _tutorials; List? _descriptions; List? _faqs; List? _trainingPlans; LinkedHashMap _myExercisesPlanDetails = LinkedHashMap(); LinkedHashMap _tree = LinkedHashMap(); double _percentExercises = -1; Customer? _trainee; List? _exercisesTrainee; ExercisePlan? _traineeExercisePlan; FirebaseRemoteConfig? remoteConfig; LinkedHashMap _badges = LinkedHashMap(); List? deviceLanguages; String startPage = "home"; late String testEnvironment; bool liveServer = true; bool? hasHardware = false; HashMap activitiesDone = HashMap(); factory Cache() { return _singleton; } Cache._internal() { String testEnv = EnvironmentConfig.test_env; this.testEnvironment = testEnv; print("testEnv $testEnv"); if (testEnv == "1") { baseUrl = baseUrlTest; liveServer = false; } ActivityDone.values.forEach((element) { activitiesDone[element.toStr()] = false; }); } void setTestBaseUrl() { baseUrl = baseUrlTest; } String getAuthToken() { return this.authToken; } Future deleteCustomerId(int customerId) async { Future prefs = SharedPreferences.getInstance(); SharedPreferences sharedPreferences = await prefs; sharedPreferences.remove(Cache.customerIdKey); } Future saveActiveExercisePlan(ExercisePlan exercisePlan, List exercisePlanDetails) async { this.activeExercisePlan = exercisePlan; this.activeExercisePlanDetails = exercisePlanDetails; String exercisePlanJson = JsonEncoder().convert(exercisePlan.toJson()); String detailsJson = jsonEncode(exercisePlanDetails.map((i) => i.toJsonWithExerciseList()).toList()).toString(); Future prefs = SharedPreferences.getInstance(); SharedPreferences sharedPreferences; sharedPreferences = await prefs; final DateTime now = DateTime.now(); sharedPreferences.setString(Cache.activeExercisePlanKey, exercisePlanJson); sharedPreferences.setString(Cache.activeExercisePlanDetailsKey, detailsJson); String savingDay = DateFormat("yyyy-MM-dd HH:mm:ss").format(now); sharedPreferences.setString(Cache.activeExercisePlanDateKey, savingDay); } Future saveMyTrainingPlan() async { if (myTrainingPlan == null) { return; } String myTrainingPlanJson = JsonEncoder().convert(myTrainingPlan!.toJsonWithDetails()); Future prefs = SharedPreferences.getInstance(); SharedPreferences sharedPreferences; sharedPreferences = await prefs; sharedPreferences.setString(Cache.myTrainingPlanKey, myTrainingPlanJson); } Future deleteMyTrainingPlan() async { if (myTrainingPlan == null) { return; } Future prefs = SharedPreferences.getInstance(); SharedPreferences sharedPreferences; sharedPreferences = await prefs; sharedPreferences.remove(Cache.myTrainingPlanKey); } Future getMyTrainingPlan() async { Future prefs = SharedPreferences.getInstance(); SharedPreferences sharedPreferences; sharedPreferences = await prefs; final String? savedTrainingPlanJson = sharedPreferences.getString(Cache.myTrainingPlanKey); if (savedTrainingPlanJson == null) { return; } //String jsonPlan = savedTrainingPlanJson.replaceAllMapped(RegExp(r'[a-zA-Z]+\:'), (Match m) => "\"${m[0]}\""); Map map; try { map = JsonDecoder().convert(savedTrainingPlanJson); //print("Training plan: $savedTrainingPlanJson"); this.myTrainingPlan = CustomerTrainingPlan.fromJsonWithDetails(map); } on Exception catch (e) { print(e.toString()); } } Future deleteActiveExercisePlan() async { Future prefs = SharedPreferences.getInstance(); SharedPreferences sharedPreferences; sharedPreferences = await prefs; sharedPreferences.remove(Cache.activeExercisePlanDateKey); this.activeExercisePlan = null; this.activeExercisePlanDetails = null; } Future getActiveExercisePlan() async { Future prefs = SharedPreferences.getInstance(); SharedPreferences sharedPreferences; sharedPreferences = await prefs; final savedPlanDateString = sharedPreferences.getString(Cache.activeExercisePlanDateKey); if (savedPlanDateString == null) { return; } DateFormat format = DateFormat("yyyy-MM-dd HH:mm:ss"); DateTime savedPlanDate; savedPlanDate = format.parse(savedPlanDateString); print("Saved plan: $savedPlanDate"); final DateTime now = DateTime.now(); final DateTime added = savedPlanDate.add(Duration(days: 1)); if (added.isBefore(now)) { return; } String? exercisePlanJson = sharedPreferences.getString(Cache.activeExercisePlanKey); if (exercisePlanJson != null) { final Map map = JsonDecoder().convert(exercisePlanJson); this.activeExercisePlan = ExercisePlan.fromJson(map); } String? detailsJson = sharedPreferences.getString(Cache.activeExercisePlanDetailsKey); if (detailsJson != null) { Iterable json = jsonDecode(detailsJson); this.activeExercisePlanDetails = json.map((details) => ExercisePlanDetail.fromJsonWithExerciseList(details)).toList(); } } Future setServer(bool live) async { if (this.testEnvironment == "1") { liveServer = false; live = false; } Future prefs = SharedPreferences.getInstance(); SharedPreferences sharedPreferences; sharedPreferences = await prefs; liveServer = live; sharedPreferences.setBool(Cache.serverKey, live); } void getHardware(SharedPreferences prefs) { final bool? hasHardware = prefs.getBool(Cache.hardwareKey); this.hasHardware = hasHardware; if (hasHardware == null) { this.hasHardware = false; } } Future selectedHardwareBefore() async { Future prefs = SharedPreferences.getInstance(); SharedPreferences sharedPreferences = await prefs; final bool? selectedHardware = sharedPreferences.getBool(Cache.hardwareKey); return selectedHardware == null; } Future setHardware(bool hasHardware) async { Future prefs = SharedPreferences.getInstance(); SharedPreferences sharedPreferences; sharedPreferences = await prefs; sharedPreferences.setBool(Cache.hardwareKey, hasHardware); this.hasHardware = hasHardware; } void setServerAddress(SharedPreferences prefs) { if (this.testEnvironment == "1") { baseUrl = baseUrlTest; print("TestEnv $baseUrl"); return; } final bool? live = prefs.getBool(Cache.serverKey); if (live == null) { baseUrl = baseUrlLive; print("Live Env $baseUrl"); liveServer = true; return; } liveServer = live; if (live) { baseUrl = baseUrlLive; } else { baseUrl = baseUrlTest; } print("Env $baseUrl"); } Future setLoginTypeFromPrefs() async { Future prefs = SharedPreferences.getInstance(); SharedPreferences sharedPreferences = await prefs; final String? loginType = sharedPreferences.getString(Cache.loginTypeKey); LoginType type = LoginType.email; if (loginType == LoginType.apple.toString()) { type = LoginType.apple; } else if (loginType == LoginType.google.toString()) { type = LoginType.google; } else if (loginType == LoginType.fb.toString()) { type = LoginType.fb; } else if (loginType == LoginType.email.toString()) { type = LoginType.email; } //print("LoginType: " + loginType == null ? "NULL" : loginType); Cache().setLoginType(type); } static String? getToken(SharedPreferences prefs) { return prefs.getString(authTokenKey); } String getBaseUrl() { return baseUrl; } static String getMediaUrl() { return mediaUrl; } afterRegistration(Customer customer) async { Future prefs = SharedPreferences.getInstance(); userLoggedIn = customer; final String uid = Cache().firebaseUid!; SharedPreferences sharedPreferences = await prefs; sharedPreferences.setString(Cache.loginTypeKey, Cache().getLoginType().toString()); await setPreferences(prefs, SharePrefsChange.registration, customer.customerId!, uid); } afterLogin(Customer customer) async { Future prefs = SharedPreferences.getInstance(); userLoggedIn = customer; SharedPreferences sharedPreferences = await prefs; sharedPreferences.setString(Cache.loginTypeKey, Cache().getLoginType().toString()); await setPreferences(prefs, SharePrefsChange.login, customer.customerId!, Cache().firebaseUid!); } afterFirebaseLogin() async { Future prefs = SharedPreferences.getInstance(); SharedPreferences sharedPreferences = await prefs; sharedPreferences.setString(Cache.loginTypeKey, Cache().getLoginType().toString()); await setPreferences(prefs, SharePrefsChange.login, userLoggedIn!.customerId!, Cache().firebaseUid!); } afterFacebookLogin() async { Future prefs = SharedPreferences.getInstance(); SharedPreferences sharedPreferences = await prefs; sharedPreferences.setString(Cache.loginTypeKey, Cache().getLoginType().toString()); await setPreferences(prefs, SharePrefsChange.login, userLoggedIn!.customerId!, Cache().firebaseUid!); } logout() async { if (this.accessTokenFacebook != null) { await FirebaseApi().logOutFacebook(); } userLoggedIn = null; firebaseUid = null; authToken = ""; _trainee = null; _percentExercises = -1; _exercisesTrainee = null; _traineeExercisePlan = null; _exercises = []; _myExercisesPlanDetails = LinkedHashMap(); log("Trainees is null? " + (_trainee == null).toString()); Future prefs = SharedPreferences.getInstance(); await setPreferences(prefs, SharePrefsChange.logout, 0, ""); } Future setPreferences(Future prefs, SharePrefsChange type, int customerId, String firebaseUid) async { SharedPreferences sharedPreferences; sharedPreferences = await prefs; DateTime now = DateTime.now(); sharedPreferences.setString(Cache.lastStoreDateKey, now.toString()); if (type == SharePrefsChange.registration) { sharedPreferences.setInt(Cache.customerIdKey, customerId); sharedPreferences.setBool(Cache.isRegisteredKey, true); sharedPreferences.setBool(Cache.isLoggedInKey, true); sharedPreferences.setString(Cache.firebaseUidKey, firebaseUid); await initCustomer(customerId); } else if (type == SharePrefsChange.login) { sharedPreferences.setInt(Cache.customerIdKey, customerId); sharedPreferences.setString(Cache.firebaseUidKey, firebaseUid); sharedPreferences.setBool(Cache.isLoggedInKey, true); await initCustomer(customerId); } else if (type == SharePrefsChange.logout) { sharedPreferences.setBool(Cache.isLoggedInKey, false); sharedPreferences.setInt(Cache.customerIdKey, 0); sharedPreferences.setString(Cache.firebaseUidKey, ""); sharedPreferences.setString(authTokenKey, ""); } initBadges(); } void setExerciseTypes(List exerciseTypes) { this._exerciseTypes = exerciseTypes; } void setExerciseTree(List exerciseTree) { this._exerciseTree = exerciseTree; } void setExercises(List exercises) => this._exercises = exercises; void setExercisesTrainee(List exercises) { this._exercisesTrainee = exercises; } void setWorkoutMenuTree(LinkedHashMap tree) { this._tree = tree; } List? getExerciseTypes() => this._exerciseTypes; ExerciseType? getExerciseTypeById(int exerciseTypeId) { ExerciseType? exerciseType; if (_exerciseTypes != null) { this._exerciseTypes!.forEach((element) { if (element.exerciseTypeId == exerciseTypeId) { exerciseType = element; } }); } return exerciseType; } List? getExerciseTree() => this._exerciseTree; List? getExercises() => this._exercises; List? getExercisesTrainee() => this._exercisesTrainee; LinkedHashMap getWorkoutMenuTree() => this._tree; void setPercentExercises(double percent) => this._percentExercises = percent; double getPercentExercises() => this._percentExercises; void addExercise(Exercise exercise) => _exercises!.add(exercise); void addExerciseTrainee(Exercise exercise) => _exercisesTrainee!.add(exercise); Customer? getTrainee() => this._trainee; void setTrainee(Customer trainee) => _trainee = trainee; void setTraineeExercisePlan(ExercisePlan exercisePlan) => this._traineeExercisePlan = exercisePlan; ExercisePlan? getTraineesExercisePlan() => this._traineeExercisePlan; void setMyExercisePlan(ExercisePlan exercisePlan) => _myExercisePlan = exercisePlan; ExercisePlan? getMyExercisePlan() => _myExercisePlan; void setMyExercisePlanDetails(LinkedHashMap listExercisePlanDetail) => _myExercisesPlanDetails = listExercisePlanDetail; void addToMyExercisePlanDetails(ExercisePlanDetail detail) => _myExercisesPlanDetails[detail.exerciseTypeId] = detail; LinkedHashMap getMyExercisePlanDetails() => _myExercisesPlanDetails; void resetMyExercisePlanDetails() => _myExercisesPlanDetails = LinkedHashMap(); void updateMyExercisePlanDetail(ExercisePlanDetail detail) { this.addToMyExercisePlanDetails(detail); } void deleteMyExercisePlanDetail(ExercisePlanDetail detail) => this.deleteMyExercisePlanDetailByExerciseTypeId(detail.exerciseTypeId); void deletedMyExercisePlanDetail(ExercisePlanDetail detail) => this._myExercisesPlanDetails[detail.exerciseTypeId]!.change = ModelChange.deleted; void deleteMyExercisePlanDetailByExerciseTypeId(int exerciseTypeId) { this._myExercisesPlanDetails[exerciseTypeId]!.change = ModelChange.delete; } void setProperties(List properties) => this._properties = properties; List? getProperties() => _properties; List? getSports() => _sports; void setSports(List sports) => this._sports = sports; void setDevices(List devices) => this._devices = devices; List? getDevices() => this._devices; void setCustomerDevices(List devices) => this._customerDevices = devices; List? getCustomerDevices() => this._customerDevices; LinkedHashMap getBadges() => _badges; void setBadge(String key, bool inc) { if (inc) { if (_badges[key] != null) { _badges[key] = _badges[key]! + 1; } else { _badges[key] = 1; } } else { if (_badges[key] != null) { if (_badges[key] == 1) { _badges.remove(key); } else { _badges[key] = _badges[key]! - 1; } } } } void setBadgeNr(String key, int counter) { if (_badges[key] != null) { _badges[key] = _badges[key]! + counter; } else { _badges[key] = counter; } } void initBadges() { CustomerRepository customerRepository = CustomerRepository(); _badges = LinkedHashMap(); if (userLoggedIn == null) { return; } customerRepository.setCustomer(userLoggedIn!); int _ecto = customerRepository.getCustomerPropertyValue(PropertyEnum.Ectomorph.toStr()).toInt(); int _mezo = customerRepository.getCustomerPropertyValue(PropertyEnum.Mesomorph.toStr()).toInt(); int _endo = customerRepository.getCustomerPropertyValue(PropertyEnum.Endomorph.toStr()).toInt(); //print("endo " + _endo.toString() + " mezo " + _mezo.toString()); if (this.userLoggedIn != null) { if (this.userLoggedIn!.birthYear == null || this.userLoggedIn!.birthYear == 0) { setBadge("personalData", true); setBadge("account", true); } if (this._customerDevices == null || this._customerDevices!.isEmpty) { setBadge("customerDevice", true); setBadge("account", true); } if (userLoggedIn!.properties.isEmpty) { setBadge("personalData", true); setBadge("bodyType", true); setBadge("Sizes", true); setBadge("BMI", true); setBadge("BMR", true); setBadgeNr("My Body", 3); setBadgeNr("home", 3); } else if (customerRepository.getWeight() == 0) { setBadge("BMI", true); setBadge("BMR", true); setBadge("My Body", true); setBadgeNr("home", 1); } if (_ecto == 0 && _mezo == 0 && _endo == 0) { setBadge("account", true); setBadge("bodyType", true); } if (this._exercises == null || this._exercises!.isEmpty) { setBadge("home", true); setBadge("Custom Tests", true); setBadge("Start Training", true); } if (customerRepository.getHeight() == 0) { setBadge("BMI", true); setBadge("BMR", true); setBadge("My Body", true); setBadgeNr("home", 1); } if (userLoggedIn!.goal == null) { setBadge("Goal", true); setBadge("account", true); } if (userLoggedIn!.fitnessLevel == null) { setBadge("FitnessLevel", true); setBadge("account", true); } if (this._exercises != null && this._exercises!.isNotEmpty) { if (!activitiesDone[ActivityDone.isExerciseLogSeen.toStr()]!) { setBadge("exerciseLog", true); setBadge("development", true); } if (!activitiesDone[ActivityDone.isMuscleDevelopmentSeen.toStr()]!) { setBadge("muscleDevelopment", true); setBadge("development", true); } } } log("Badges: " + _badges.toString()); } List? get products => _products; void setProducts(List value) => _products = value; List get purchases => _purchases; setPurchases(List value) => _purchases = value; Future initCustomer(int customerId) async { log(" *** initCustomer"); try { await PackageApi().getCustomerPackage(customerId); } on Exception catch (_) { return; } if (kReleaseMode) { //FlurryData.setUserId(customerId.toString()); //FlutterUxcam.setUserProperty("username", customerId.toString()); //FlutterUxcam.setUserIdentity(customerId.toString()); //Smartlook.setUserIdentifier(customerId.toString()); //Smartlook.instance. Track().track(TrackingEvent.enter); MatomoTracker.instance.setVisitorUserId(customerId.toString()); MatomoTracker.instance.trackEvent(eventCategory: "wt", action: TrackingEvent.enter.enumToString()); Posthog().identify(userId: customerId.toString()); Posthog().capture(eventName: TrackingEvent.enter.enumToString()); } await Future.forEach(ActivityDone.values, (element) async { ActivityDone activity = element as ActivityDone; await isActivityDonePrefs(activity); }); print("Firebase token save: $firebaseMessageToken"); if (firebaseMessageToken != null) { userLoggedIn!.firebaseRegToken = firebaseMessageToken; CustomerRepository customerRepository = CustomerRepository(); customerRepository.customer = userLoggedIn; customerRepository.saveCustomer(); } await getMyTrainingPlan(); Cache().startPage = "home"; } AccessToken? get getAccessTokenFacebook => accessTokenFacebook; set setAccessTokenFacebook(AccessToken accessTokenFacebook) => this.accessTokenFacebook = accessTokenFacebook; LoginType? getLoginType() => loginType; void setLoginType(LoginType type) => this.loginType = type; List get exercisePlanTemplates => this._exercisePlanTemplates; setExercisePlanTemplates(value) => this._exercisePlanTemplates = value; isActivityDonePrefs(ActivityDone activity) async { Future prefs = SharedPreferences.getInstance(); SharedPreferences sharedPreferences = await prefs; if (sharedPreferences.getBool(activity.toStr()) != null) { activitiesDone[activity.toStr()] = sharedPreferences.getBool(activity.toStr())!; } return activitiesDone[activity.toStr()]!; } setActivityDonePrefs(ActivityDone activity) async { Future prefs = SharedPreferences.getInstance(); SharedPreferences sharedPreferences = await prefs; activitiesDone[activity.toStr()] = true; sharedPreferences.setBool(activity.toStr(), true); } bool isActivityDone(ActivityDone activity) => activitiesDone[activity.toStr()] == true; List? get evaluations => this._evaluations; set evaluations(List? value) => this._evaluations = value; List? get customerActivities => this._customerActivities; setCustomerActivities(List? value) => this._customerActivities = value; List? get tutorials => this._tutorials; setTutorials(List? value) => this._tutorials = value; FirebaseRemoteConfig? getRemoteConfig() => this.remoteConfig; setRemoteConfig(FirebaseRemoteConfig? remoteConfig) => this.remoteConfig = remoteConfig; List? getDescriptions() => this._descriptions; setDescriptions(List? value) => this._descriptions = value; List? getFaqs() => this._faqs; setFaqs(List? value) => this._faqs = value; List? getTrainingPlans() => this._trainingPlans; setTrainingPlans(List? value) => this._trainingPlans = value; List? getCustomerTrainingPlans() => this._customerTrainingPlans; setCustomerTrainingPlans(value) => this._customerTrainingPlans = value; List getSplitTests() => this._splitTests; setSplitTests(value) => this._splitTests = value; List getTrainingPlanDays() => this._trainingPlanDays; setTrainingPlanDays(value) => this._trainingPlanDays = value; List? getCustomerPropertyAll() => this._customerPropertyAll; setCustomerPropertyAll(value) => this._customerPropertyAll = value; addCustomerProperty(CustomerProperty property) { if (this._customerPropertyAll == null) { this._customerPropertyAll = []; } this._customerPropertyAll!.add(property); } }