diff --git a/.gitignore b/.gitignore index 7899ba06..5375ea06 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,8 @@ expo-env.d.ts # @end expo-cli coverage/ +docs/ .claude/ *copilot-instructions.md *EXPO_SDK_52_UPGRADE_PLAN.md +.firebaserc diff --git a/app.config.js b/app.config.js index a4a4e8f2..a2f259aa 100644 --- a/app.config.js +++ b/app.config.js @@ -4,7 +4,7 @@ export default { expo: { name: IS_DEV ? "Muscle Quest (Dev)" : "Muscle Quest", slug: "musclequest", - version: "1.0.0", // MM.mm.pp + version: "1.3.0", // M.mm.pp orientation: "portrait", icon: "./assets/images/icon.png", scheme: "musclequest", @@ -14,7 +14,7 @@ export default { bundleIdentifier: "com.isotronic.musclequest", }, android: { - versionCode: 10000, // MMmmpp + versionCode: 10300, // Mmmpp googleServicesFile: "./google-services.json", adaptiveIcon: { foregroundImage: "./assets/images/ic_launcher_foreground.png", diff --git a/app/(app)/(tabs)/(plans)/index.tsx b/app/(app)/(tabs)/(plans)/index.tsx index 9042e7b7..6acfd27b 100644 --- a/app/(app)/(tabs)/(plans)/index.tsx +++ b/app/(app)/(tabs)/(plans)/index.tsx @@ -18,6 +18,8 @@ import { Trans } from "@lingui/react/macro"; import { t } from "@lingui/core/macro"; import { useAppTheme } from "@/theme"; import type { AppThemeColors } from "@/theme/types"; +import { usePublishedPlanIdsQuery } from "@/hooks/usePublishedPlanIdsQuery"; +import { useSocialStore } from "@/store/socialStore"; export default function PlansScreen() { const { colors } = useAppTheme(); @@ -35,6 +37,8 @@ export default function PlansScreen() { isError: standaloneIsError, error: standaloneError, } = useStandaloneWorkoutsQuery(); + const { data: publishedPlanIds } = usePublishedPlanIdsQuery(); + const { privacySettings } = useSocialStore(); useEffect(() => { if (standaloneIsError && standaloneError) { @@ -129,6 +133,8 @@ export default function PlansScreen() { viewMode={viewMode} showViewToggle onViewModeChange={handleViewModeChange} + publishedPlanIds={publishedPlanIds} + sharePlansEnabled={!!privacySettings?.sharePlans} /> { deloadMutation.mutate(isCurrentWeekDeload ? null : getCurrentISOWeek()); }, [isCurrentWeekDeload, deloadMutation]); @@ -270,6 +281,40 @@ export default function PlanOverviewScreen() { )} + + {showShareToggle && ( + publishMutation.mutate(!isPublished)} + style={[styles.deloadRow]} + activeOpacity={0.7} + disabled={publishMutation.isPending || isPublishLoading} + > + + + + Share Plan + + + {publishMutation.isPending || isPublishLoading ? ( + + ) : ( + + + + )} + + )} diff --git a/app/(app)/(tabs)/(plans)/standalone-workout.tsx b/app/(app)/(tabs)/(plans)/standalone-workout.tsx index 5f53abb6..15c68f7d 100644 --- a/app/(app)/(tabs)/(plans)/standalone-workout.tsx +++ b/app/(app)/(tabs)/(plans)/standalone-workout.tsx @@ -1,4 +1,4 @@ -import { useMemo, useState } from "react"; +import { useContext, useMemo, useState } from "react"; import { View, StyleSheet, @@ -10,13 +10,14 @@ import { ThemedText } from "@/components/ThemedText"; import { ThemedView } from "@/components/ThemedView"; import { router, Stack, useLocalSearchParams } from "expo-router"; import { UserExercise } from "@/store/workoutStore"; -import { AppImage } from "@/components/ui"; +import { AppIcon, AppImage } from "@/components/ui"; import { ActivityIndicator, Button, IconButton, Portal, Modal, + Switch, } from "react-native-paper"; import { Notes } from "@/components/Notes"; import { byteArrayToBase64, formatFromTotalSeconds } from "@/utils/utility"; @@ -30,6 +31,10 @@ import { Trans } from "@lingui/react/macro"; import { t } from "@lingui/core/macro"; import { useAppTheme, radii } from "@/theme"; import type { AppThemeColors } from "@/theme/types"; +import { AuthContext } from "@/context/AuthProvider"; +import { useSocialStore } from "@/store/socialStore"; +import { useWorkoutPublishQuery } from "@/hooks/useWorkoutPublishQuery"; +import { useWorkoutPublishMutation } from "@/hooks/useWorkoutPublishMutation"; const fallbackImage = require("@/assets/images/placeholder.webp"); @@ -47,6 +52,13 @@ export default function StandaloneWorkoutScreen() { const { data: settings } = useSettingsQuery(); const distanceUnit = settings?.distanceUnit || "m"; + const user = useContext(AuthContext); + const { privacySettings } = useSocialStore(); + const showShareToggle = !!user && !!privacySettings?.shareStandaloneWorkouts; + const { data: isPublished = false, isLoading: isPublishLoading } = + useWorkoutPublishQuery(showShareToggle ? workoutId : null); + const publishMutation = useWorkoutPublishMutation(workoutId); + if (!Number.isInteger(workoutId) || workoutId <= 0) { return ( @@ -254,6 +266,46 @@ export default function StandaloneWorkoutScreen() { ) : ( workout.exercises.map((exercise) => renderExercise(exercise)) )} + {showShareToggle && ( + <> + publishMutation.mutate(!isPublished)} + style={styles.shareRow} + activeOpacity={0.7} + disabled={publishMutation.isPending || isPublishLoading} + > + + + + Share Workout + + + {publishMutation.isPending || isPublishLoading ? ( + + ) : ( + + + + )} + + {publishMutation.isError && ( + + Failed to update sharing. Please try again. + + )} + + )} + + ); + } + + const tabs: { key: Tab; label: string; badge?: number }[] = [ + { key: "friends", label: t`Friends` }, + { key: "search", label: t`Search` }, + { + key: "requests", + label: t`Requests`, + badge: pendingRequests.length || undefined, + }, + ]; + + return ( + + + + {/* Internal tab bar */} + + {tabs.map(({ key, label, badge }) => { + const isActive = activeTab === key; + return ( + + ); + })} + + + {activeTab === "friends" && ( + { + router.push({ + pathname: "/(app)/friend-profile", + params: { friendUid: uid }, + } as unknown as Parameters[0]); + }} + colors={colors} + /> + )} + {activeTab === "search" && ( + + )} + {activeTab === "requests" && ( + + )} + + ); +} + +interface FriendsTabProps { + friends: FriendInfo[]; + onFriendPress: (uid: string) => void; + colors: AppThemeColors; +} + +function FriendsTab({ friends, onFriendPress, colors }: FriendsTabProps) { + if (friends.length === 0) { + return ( + + + + No friends yet. Search by email to add someone. + + + ); + } + + return ( + item.uid} + renderItem={({ item }: { item: FriendInfo }) => ( + + )} + /> + ); +} + +interface SearchTabProps { + currentUid: string; + colors: AppThemeColors; + borders: AppThemeBorders; +} + +function SearchTab({ currentUid, colors, borders }: SearchTabProps) { + const [email, setEmail] = useState(""); + const [loading, setLoading] = useState(false); + // undefined = no search yet, null = not found, UserSearchResult = found + const [result, setResult] = useState( + undefined, + ); + const [requestSent, setRequestSent] = useState(false); + const [searchError, setSearchError] = useState(false); + const sendMutation = useSendFriendRequestMutation(); + const { friends, sentRequests, pendingRequests } = useSocialStore(); + + const isFriend = result ? friends.some((f) => f.uid === result.uid) : false; + const hasPendingSent = result + ? sentRequests.some((r) => r.toUid === result.uid) + : false; + const hasIncoming = result + ? pendingRequests.some((r) => r.fromUid === result.uid) + : false; + + const handleSearch = async () => { + if (!email.trim()) return; + setLoading(true); + setResult(undefined); + setRequestSent(false); + setSearchError(false); + try { + const found = await searchUserByEmail(email, currentUid); + setResult(found); + } catch (error) { + Bugsnag.notify(error as Error); + setSearchError(true); + } finally { + setLoading(false); + } + }; + + return ( + + + + + + + {result === null && ( + + No user found with that email address. + + )} + + {searchError && ( + + Something went wrong. Please try again. + + )} + + {result != null && ( + + {result.photoURL ? ( + + ) : ( + + )} + + + {result.displayName} + + + {result.email} + + + {isFriend ? ( + + Friends + + ) : requestSent || hasPendingSent ? ( + + Sent + + ) : hasIncoming ? ( + + Incoming + + ) : ( + + )} + + )} + + ); +} + +interface RequestsTabProps { + pendingRequests: PendingRequest[]; + sentRequests: SentRequest[]; + colors: AppThemeColors; + borders: AppThemeBorders; +} + +function RequestsTab({ + pendingRequests, + sentRequests, + colors, + borders, +}: RequestsTabProps) { + if (pendingRequests.length === 0 && sentRequests.length === 0) { + return ( + + + No pending friend requests. + + + ); + } + + return ( + + {pendingRequests.length > 0 && ( + <> + + Incoming + + {pendingRequests.map((req) => ( + + ))} + + )} + {sentRequests.length > 0 && ( + <> + + Sent + + {sentRequests.map((req) => ( + + {req.photoURL ? ( + + ) : ( + + )} + + + {req.displayName} + + + {req.email} + + + + Pending + + + ))} + + )} + + ); +} + +const styles = StyleSheet.create({ + container: { flex: 1 }, + centered: { + flex: 1, + justifyContent: "center", + alignItems: "center", + padding: 32, + gap: 8, + }, + tabBar: { + flexDirection: "row", + borderBottomWidth: StyleSheet.hairlineWidth, + paddingHorizontal: 8, + paddingVertical: 4, + }, + tabButton: { flex: 1 }, + searchContainer: { padding: 16 }, + searchRow: { flexDirection: "row", gap: 8, alignItems: "center" }, + input: { + flex: 1, + height: 44, + borderWidth: StyleSheet.hairlineWidth, + borderRadius: 8, + paddingHorizontal: 12, + fontSize: 15, + }, + resultCard: { + flexDirection: "row", + alignItems: "center", + gap: 12, + marginTop: 16, + padding: 12, + borderWidth: StyleSheet.hairlineWidth, + borderRadius: 8, + }, + sectionHeader: { + paddingHorizontal: 16, + paddingTop: 16, + paddingBottom: 6, + textTransform: "uppercase", + letterSpacing: 0.5, + }, + sentRow: { + flexDirection: "row", + alignItems: "center", + paddingHorizontal: 16, + paddingVertical: 12, + gap: 12, + borderBottomWidth: StyleSheet.hairlineWidth, + }, +}); diff --git a/app/(app)/settings.tsx b/app/(app)/settings.tsx index e33518b8..5cb29e86 100644 --- a/app/(app)/settings.tsx +++ b/app/(app)/settings.tsx @@ -24,6 +24,9 @@ import { useAppTheme } from "@/theme"; import type { AppThemeColors } from "@/theme/types"; import { useSettingsQuery } from "@/hooks/useSettingsQuery"; import { useUpdateSettingsMutation } from "@/hooks/useUpdateSettingsMutation"; +import { useSocialStore } from "@/store/socialStore"; +import { usePrivacySettingsMutation } from "@/hooks/usePrivacySettingsMutation"; +import { deleteAllSharedData } from "@/utils/sharing"; import { SettingsModal } from "@/components/SettingsModal"; // import { clearDatabaseAndReinitialize } from "@/utils/clearUserData"; import { useImageManagement } from "@/hooks/useImageManagement"; @@ -73,6 +76,39 @@ export default function SettingsScreen() { toggleDownloadImages, } = useImageManagement(updateSetting, settings?.downloadImages); + const { privacySettings } = useSocialStore(); + const { mutate: updatePrivacy, isPending: isPrivacyPending } = + usePrivacySettingsMutation(); + const [isDeletingSharedData, setIsDeletingSharedData] = useState(false); + + const handleDeleteAllSharedData = () => { + if (!user) return; + Alert.alert( + t`Delete all shared data?`, + t`This removes all content you have shared with friends. Your friends and friend list are not affected.`, + [ + { text: t`Cancel`, style: "cancel" }, + { + text: t`Delete`, + style: "destructive", + onPress: async () => { + setIsDeletingSharedData(true); + try { + await deleteAllSharedData(user.uid); + Alert.alert(t`Done`, t`All shared data has been removed.`); + } catch (error: unknown) { + Bugsnag.notify( + error instanceof Error ? error : new Error(String(error)), + ); + } finally { + setIsDeletingSharedData(false); + } + }, + }, + ], + ); + }; + const [isBackupLoading, setIsBackupLoading] = useState(false); const [isRestoreLoading, setIsRestoreLoading] = useState(false); const [backupProgress, setBackupProgress] = useState(1); @@ -1558,6 +1594,280 @@ export default function SettingsScreen() { */} + {user && ( + <> + + + Privacy + + + + Previously shared data always remains visible to your friends + until you delete it below. + + + + {/* Share Plans */} + + updatePrivacy({ sharePlans: !privacySettings?.sharePlans }) + } + disabled={isPrivacyPending} + > + + + Share plans with friends + + {privacySettings?.sharePlans ? ( + + Enables a per-plan publish toggle. + + ) : ( + + + Enable to add a publish toggle to each plan. + + + )} + + + updatePrivacy({ sharePlans: v }) + } + disabled={isPrivacyPending} + color={colors.accent} + style={styles.switch} + /> + + + {/* Share Standalone Workouts */} + + updatePrivacy({ + shareStandaloneWorkouts: + !privacySettings?.shareStandaloneWorkouts, + }) + } + disabled={isPrivacyPending} + > + + + Share standalone workouts with friends + + {privacySettings?.shareStandaloneWorkouts ? ( + + Enables a per-workout publish toggle. + + ) : ( + + + Enable to add a publish toggle to each standalone + workout. + + + )} + + + updatePrivacy({ shareStandaloneWorkouts: v }) + } + disabled={isPrivacyPending} + color={colors.accent} + style={styles.switch} + /> + + + {/* Share Custom Exercises */} + + updatePrivacy({ + shareCustomExercises: + !privacySettings?.shareCustomExercises, + }) + } + disabled={isPrivacyPending} + > + + + Share custom exercises with friends + + {privacySettings?.shareCustomExercises ? ( + + + Custom exercises you create or edit are shared + automatically. + + + ) : ( + + + Enable to automatically share custom exercises you + create or edit. + + + )} + + + updatePrivacy({ shareCustomExercises: v }) + } + disabled={isPrivacyPending} + color={colors.accent} + style={styles.switch} + /> + + + {/* Share Completed Workouts */} + + updatePrivacy({ + shareCompletedWorkouts: + !privacySettings?.shareCompletedWorkouts, + }) + } + disabled={isPrivacyPending} + > + + + Share completed workouts with friends + + {privacySettings?.shareCompletedWorkouts ? ( + + + Each workout you complete is shared automatically. + + + ) : ( + + + Enable to automatically share each workout you complete. + + + )} + + + updatePrivacy({ shareCompletedWorkouts: v }) + } + disabled={isPrivacyPending} + color={colors.accent} + style={styles.switch} + /> + + + {/* Share Body Measurements */} + + updatePrivacy({ + shareBodyMeasurements: + !privacySettings?.shareBodyMeasurements, + }) + } + disabled={isPrivacyPending} + > + + + Share body measurements with friends + + {privacySettings?.shareBodyMeasurements ? ( + + + Each measurement entry you record is shared + automatically. + + + ) : ( + + + Enable to automatically share each body measurement you + record. + + + )} + + + updatePrivacy({ shareBodyMeasurements: v }) + } + disabled={isPrivacyPending} + color={colors.accent} + style={styles.switch} + /> + + + {/* Share Strength PRs */} + + updatePrivacy({ + shareStrengthProgress: + !privacySettings?.shareStrengthProgress, + }) + } + disabled={isPrivacyPending} + > + + + Share strength PRs with friends + + {privacySettings?.shareStrengthProgress ? ( + + + Strength PRs are shared automatically after each + workout. + + + ) : ( + + + Enable to automatically share strength PRs after each + workout. + + + )} + + + updatePrivacy({ shareStrengthProgress: v }) + } + disabled={isPrivacyPending} + color={colors.accent} + style={styles.switch} + /> + + + {/* Delete all shared data */} + + {isDeletingSharedData ? ( + + ) : ( + + Delete all shared data + + )} + + + + + )} + About @@ -1758,5 +2068,26 @@ function createStyles(colors: AppThemeColors) { color: colors.danger, marginTop: 6, }, + progressContainer: { + marginTop: 8, + }, + progressText: { + fontSize: 14, + color: colors.contentSecondary, + marginBottom: 4, + }, + rowLeft: { + flex: 1, + marginRight: 8, + }, + rowTitle: { + fontSize: 16, + color: colors.contentPrimary, + }, + rowSubtitle: { + fontSize: 13, + color: colors.contentSecondary, + marginTop: 2, + }, }); } diff --git a/app/_layout.tsx b/app/_layout.tsx index fc16f509..83f96aab 100644 --- a/app/_layout.tsx +++ b/app/_layout.tsx @@ -16,8 +16,10 @@ import "@formatjs/intl-pluralrules/locale-data/es.js"; import "@formatjs/intl-pluralrules/locale-data/fr.js"; import Bugsnag from "@bugsnag/expo"; +import BugsnagPerformance from "@bugsnag/expo-performance"; +import BugsnagPluginReactNavigationNativePerformance from "@bugsnag/plugin-react-navigation-performance"; import React, { useEffect, useState } from "react"; -import { Slot } from "expo-router"; +import { Slot, useNavigationContainerRef } from "expo-router"; import { ActivityIndicator, Button } from "react-native-paper"; import { AppThemeProvider } from "@/theme"; import { useFonts } from "expo-font"; @@ -80,6 +82,10 @@ Bugsnag.start({ codeBundleId, }); +BugsnagPerformance.start({ + plugins: [new BugsnagPluginReactNavigationNativePerformance()], +}); + const ErrorBoundary = Bugsnag.getPlugin("react").createErrorBoundary(React); const ErrorView = ({ clearError }: { clearError: () => void }) => { @@ -125,6 +131,14 @@ function RootLayout() { Inter_900Black, }); + const navigationRef = useNavigationContainerRef(); + + useEffect(() => { + BugsnagPerformance.getPlugin( + BugsnagPluginReactNavigationNativePerformance, + )?.registerNavigationContainerRef(navigationRef); + }, [navigationRef]); + useEffect(() => { async function initializeDatabase() { const databaseRestored = await getAsyncStorageItem("databaseRestored"); @@ -219,7 +233,7 @@ function RootLayout() { ); } -export default function App() { +function App() { return ( @@ -228,3 +242,5 @@ export default function App() { ); } + +export default BugsnagPerformance.withInstrumentedAppStarts(App); diff --git a/components/AppMenu.tsx b/components/AppMenu.tsx index f32f9c42..a7fda2ec 100644 --- a/components/AppMenu.tsx +++ b/components/AppMenu.tsx @@ -20,6 +20,7 @@ import Animated, { import { scheduleOnRN } from "react-native-worklets"; import { t } from "@lingui/core/macro"; import { useMenuStore } from "@/store/menuStore"; +import { useSocialStore } from "@/store/socialStore"; import { AppIcon } from "@/components/ui"; import { useAppTheme } from "@/theme"; import type { AppThemeColors } from "@/theme/types"; @@ -37,9 +38,10 @@ type MenuItemProps = { label: string; onPress: () => void; hint?: string; + badge?: number; }; -function MenuItem({ icon, label, onPress, hint }: MenuItemProps) { +function MenuItem({ icon, label, onPress, hint, badge }: MenuItemProps) { const { colors } = useAppTheme(); const styles = useMemo(() => createMenuItemStyles(colors), [colors]); return ( @@ -49,13 +51,20 @@ function MenuItem({ icon, label, onPress, hint }: MenuItemProps) { accessibilityRole="button" accessibilityHint={hint} > - + + + {!!badge && badge > 0 && ( + + {badge > 9 ? "9+" : badge} + + )} + {label} createStyles(colors), [colors]); const { isMenuOpen, closeMenu } = useMenuStore(); + const { pendingRequests } = useSocialStore(); const { width: screenWidth } = useWindowDimensions(); const insets = useSafeAreaInsets(); @@ -179,6 +189,14 @@ export function AppMenu() { + navigate("/(app)/friends")} + badge={pendingRequests.length} + /> + + void; + publishedPlanIds?: string[]; + sharePlansEnabled?: boolean; } export const PlanList: React.FC = ({ @@ -33,6 +35,8 @@ export const PlanList: React.FC = ({ viewMode = "carousel", showViewToggle = false, onViewModeChange, + publishedPlanIds, + sharePlansEnabled, }) => { const { colors } = useAppTheme(); const styles = useMemo(() => createStyles(colors), [colors]); @@ -56,6 +60,10 @@ export const PlanList: React.FC = ({ key={item.id?.toString() ?? index.toString()} plan={item} onPress={() => onPressItem(item)} + isPublished={ + !!sharePlansEnabled && + !!publishedPlanIds?.includes(String(item.id)) + } /> ))} @@ -75,6 +83,10 @@ export const PlanList: React.FC = ({ imageUrl={item.image_url} onPress={() => onPressItem(item)} isActive={item.is_active === 1} + isPublished={ + !!sharePlansEnabled && + !!publishedPlanIds?.includes(String(item.id)) + } width={gridCardWidth} /> @@ -97,6 +109,10 @@ export const PlanList: React.FC = ({ imageUrl={item.image_url} onPress={() => onPressItem(item)} isActive={item.is_active === 1} + isPublished={ + !!sharePlansEnabled && + !!publishedPlanIds?.includes(String(item.id)) + } /> )} keyExtractor={(item: any, index: number) => index.toString()} diff --git a/components/TrainingPlanCard.tsx b/components/TrainingPlanCard.tsx index a6b89113..b1359a0f 100644 --- a/components/TrainingPlanCard.tsx +++ b/components/TrainingPlanCard.tsx @@ -7,6 +7,7 @@ import { } from "react-native"; import { Card, Text } from "react-native-paper"; import { ThemedView } from "./ThemedView"; +import { AppIcon } from "@/components/ui"; import { t } from "@lingui/core/macro"; import { Trans } from "@lingui/react/macro"; import { useAppTheme, radii } from "@/theme"; @@ -17,12 +18,14 @@ export default function TrainingPlanCard({ imageUrl, onPress, isActive, + isPublished, width = 300, }: { title?: string; imageUrl?: string; onPress: () => void; isActive: boolean; + isPublished?: boolean; width?: number; }) { const { colors } = useAppTheme(); @@ -81,6 +84,16 @@ export default function TrainingPlanCard({ )} + {isPublished && ( + + + + )} @@ -132,5 +145,13 @@ function createStyles(colors: AppThemeColors, width: number) { color: colors.contentPrimary, fontWeight: "bold", }, + publishedBadge: { + position: "absolute", + top: 10, + left: 10, + backgroundColor: "rgba(0,0,0,0.45)", + padding: 4, + borderRadius: radii.sm, + }, }); } diff --git a/components/TrainingPlanListItem.tsx b/components/TrainingPlanListItem.tsx index 0d71ae6c..2ba2bf80 100644 --- a/components/TrainingPlanListItem.tsx +++ b/components/TrainingPlanListItem.tsx @@ -12,11 +12,13 @@ import type { AppThemeColors } from "@/theme/types"; interface TrainingPlanListItemProps { plan: Plan; onPress: () => void; + isPublished?: boolean; } export default function TrainingPlanListItem({ plan, onPress, + isPublished, }: TrainingPlanListItemProps) { const { colors } = useAppTheme(); const styles = useMemo(() => createStyles(colors), [colors]); @@ -55,6 +57,15 @@ export default function TrainingPlanListItem({ )} + {isPublished && ( + + )} void; +} + +export const FriendListItem = ({ friend, onPress }: Props) => { + const { colors, borders } = useAppTheme(); + const removeMutation = useRemoveFriendMutation(); + + const handleLongPress = () => { + Alert.alert( + friend.displayName, + t`Remove this friend? They will no longer be able to see your shared content.`, + [ + { text: t`Cancel`, style: "cancel" }, + { + text: t`Remove`, + style: "destructive", + onPress: () => removeMutation.mutate(friend.uid), + }, + ], + ); + }; + + return ( + onPress(friend.uid)} + onLongPress={handleLongPress} + style={[styles.container, { borderBottomColor: borders.divider }]} + > + {friend.photoURL ? ( + + ) : ( + + )} + + + {friend.displayName} + + + {friend.email} + + + + + ); +}; + +const styles = StyleSheet.create({ + container: { + flexDirection: "row", + alignItems: "center", + paddingHorizontal: 16, + paddingVertical: 12, + gap: 12, + borderBottomWidth: StyleSheet.hairlineWidth, + }, + info: { flex: 1 }, +}); diff --git a/components/friends/FriendRequestItem.tsx b/components/friends/FriendRequestItem.tsx new file mode 100644 index 00000000..41e0a33b --- /dev/null +++ b/components/friends/FriendRequestItem.tsx @@ -0,0 +1,74 @@ +import React from "react"; +import { View, StyleSheet } from "react-native"; +import { Avatar, Button } from "react-native-paper"; +import { AppText } from "@/components/ui"; +import { useAppTheme } from "@/theme"; +import { PendingRequest } from "@/store/socialStore"; +import { useAcceptFriendRequestMutation } from "@/hooks/useAcceptFriendRequestMutation"; +import { useDeclineFriendRequestMutation } from "@/hooks/useDeclineFriendRequestMutation"; +import { t } from "@lingui/core/macro"; + +interface Props { + request: PendingRequest; +} + +export const FriendRequestItem = ({ request }: Props) => { + const { colors, borders } = useAppTheme(); + const acceptMutation = useAcceptFriendRequestMutation(); + const declineMutation = useDeclineFriendRequestMutation(); + const isBusy = acceptMutation.isPending || declineMutation.isPending; + + return ( + + {request.photoURL ? ( + + ) : ( + + )} + + + {request.displayName} + + + {request.email} + + + + + + + + ); +}; + +const styles = StyleSheet.create({ + container: { + flexDirection: "row", + alignItems: "center", + paddingHorizontal: 16, + paddingVertical: 12, + gap: 12, + borderBottomWidth: StyleSheet.hairlineWidth, + }, + info: { flex: 1 }, + actions: { flexDirection: "row", gap: 8 }, +}); diff --git a/constants/HelpData.ts b/constants/HelpData.ts index 8d652f4c..ea5e2425 100644 --- a/constants/HelpData.ts +++ b/constants/HelpData.ts @@ -160,6 +160,26 @@ export const HELP_DATA: GroupData[] = [ }, ], }, + { + group: msg`Friends & Social`, + sections: [ + { + icon: "people-outline", + title: msg`Adding Friends`, + body: msg`Open the Friends tab from the menu to manage your connections. Use the search bar to find other users by username and send them a friend request. Incoming requests appear in the Requests tab; tap Accept to confirm or Decline to ignore. A badge on the Friends menu item shows how many pending requests are waiting. Once a request is accepted, both users appear in each other's Friends list and can view each other's shared content.`, + }, + { + icon: "share-social-outline", + title: msg`Sharing Your Content`, + body: msg`You can share plans, standalone workouts, custom exercises, body measurements, and strength PRs with your friends. All five categories have a global toggle in Privacy Settings, found in the Account section of Settings. Enabling the global toggle for a category shares all items in that category and syncs new data automatically whenever it changes. Plans and standalone workouts also have an individual Share toggle on each item's overview screen, so you can publish specific plans or workouts without sharing everything. A cloud icon on the plan or workout card confirms it is currently published. To remove shared data, disable the toggle in Privacy Settings and tap Delete Shared Data for that category. You can also delete all shared data for every category from the same screen.`, + }, + { + icon: "download-outline", + title: msg`Importing from Friends`, + body: msg`Tap any accepted friend in your Friends list to open their profile. Their profile shows the plans, standalone workouts, and custom exercises they have chosen to share. Tap Import on any item to add it directly to your own library. Imported plans and workouts are saved as new copies that you can edit freely without affecting the original. Imported custom exercises are added to your exercise library and available immediately when building workouts.`, + }, + ], + }, { group: msg`Account`, sections: [ diff --git a/constants/WhatsNew.ts b/constants/WhatsNew.ts index 964e510b..9f153017 100644 --- a/constants/WhatsNew.ts +++ b/constants/WhatsNew.ts @@ -291,13 +291,25 @@ The Plans screen now has three display modes. Use the icons next to the "Your Tr { version: 2634, message: msg` -📈 New: Adaptive Progression! +📈 Beta: Adaptive Progression! MuscleQuest can now suggest when to increase your weight or reps based on how your sessions feel. After each exercise, answer two quick questions about effort and pain. Once you have reported the same signal for two sessions in a row, the app suggests a change. All suggestions appear in the Workout Summary screen, where you can accept or dismiss each one individually. Accepted suggestions are pre-filled into your next session automatically. A Recovery Check-in at the start of your next workout lets you factor in soreness before any suggestion is applied. You can also mark a full week as a Deload from the plan overview, which pauses feedback and progression tracking for that week. Enable it in Settings under Adaptive Progression, and configure your preferred load increment per equipment category. +`, + }, + { + version: 2635, + message: msg` +👥 New: Friends & Social Sharing! + +Add friends by searching for their username from the Friends tab in the menu. Send a request, and once accepted you can browse each other's shared content. A badge on the Friends menu item shows pending incoming requests. + +Share your plans, standalone workouts, custom exercises, body measurements, and strength PRs by toggling Share in the relevant screen or from Privacy Settings in the Account section of Settings. Shared content syncs automatically whenever it changes, and a cloud icon on plan and workout cards shows what is currently published. You can delete all shared data for any category from Privacy Settings at any time. + +Tap any accepted friend's name to open their profile and import their plans, standalone workouts, or custom exercises directly into your own library. `, }, ]; diff --git a/context/AuthProvider.tsx b/context/AuthProvider.tsx index 09f2ae40..c1bed64d 100644 --- a/context/AuthProvider.tsx +++ b/context/AuthProvider.tsx @@ -4,6 +4,7 @@ import { onAuthStateChanged, FirebaseAuthTypes, } from "@react-native-firebase/auth"; +import { upsertUserProfile } from "../utils/userProfile"; export const AuthContext = createContext(null); @@ -14,6 +15,9 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => { const auth = getAuth(); return onAuthStateChanged(auth, (userState) => { setUser(userState); + if (userState) { + upsertUserProfile(userState); + } }); }, []); diff --git a/firebase.json b/firebase.json new file mode 100644 index 00000000..d4d918a8 --- /dev/null +++ b/firebase.json @@ -0,0 +1,6 @@ +{ + "firestore": { + "rules": "firestore.rules", + "indexes": "firestore.indexes.json" + } +} diff --git a/firestore.indexes.json b/firestore.indexes.json new file mode 100644 index 00000000..415027e5 --- /dev/null +++ b/firestore.indexes.json @@ -0,0 +1,4 @@ +{ + "indexes": [], + "fieldOverrides": [] +} diff --git a/firestore.rules b/firestore.rules new file mode 100644 index 00000000..5a49c81f --- /dev/null +++ b/firestore.rules @@ -0,0 +1,107 @@ +rules_version = '2'; +service cloud.firestore { + match /databases/{database}/documents { + + function areFriends(uid1, uid2) { + return exists(/databases/$(database)/documents/users/$(uid1)/friends/$(uid2)); + } + + // Returns true only when a friendRequest document from→to exists with status "pending" + // and the stored from/to fields match the expected UIDs (defence-in-depth). + function hasPendingRequest(fromUid, toUid) { + let doc = get(/databases/$(database)/documents/friendRequests/$(fromUid + '_' + toUid)); + return doc != null && + doc.data.status == 'pending' && + doc.data.from == fromUid && + doc.data.to == toUid; + } + + // Public profiles: any authenticated user can read (email search). + // Owner can write. + match /users/{uid} { + allow read: if request.auth != null; + allow write: if request.auth != null && request.auth.uid == uid; + + // Private settings: owner only + match /private/{doc} { + allow read, write: if request.auth != null && request.auth.uid == uid; + } + + // Friends subcollection. + // Readable by owner or the named friend. + // Owner can write freely (create/update/delete their own records). + // The named friend (friendUid) may only create if the owner previously sent + // them a pending request — hasPendingRequest(uid, friendUid) checks + // friendRequests/{uid}_{friendUid}. + // The named friend may also delete, which is needed for mutual removal. + match /friends/{friendUid} { + allow read: if request.auth != null && + (request.auth.uid == uid || request.auth.uid == friendUid); + allow write: if request.auth != null && request.auth.uid == uid; + allow create: if request.auth != null && + request.auth.uid == friendUid && + hasPendingRequest(uid, friendUid); + allow delete: if request.auth != null && request.auth.uid == friendUid; + } + + // All shared-content subcollections: friends can read, owner can write. + match /sharedPlans/{docId} { + allow read: if request.auth != null && areFriends(uid, request.auth.uid); + allow write: if request.auth != null && request.auth.uid == uid; + } + match /sharedStandaloneWorkouts/{docId} { + allow read: if request.auth != null && areFriends(uid, request.auth.uid); + allow write: if request.auth != null && request.auth.uid == uid; + } + match /sharedCustomExercises/{docId} { + allow read: if request.auth != null && areFriends(uid, request.auth.uid); + allow write: if request.auth != null && request.auth.uid == uid; + } + match /sharedWorkouts/{docId} { + allow read: if request.auth != null && areFriends(uid, request.auth.uid); + allow write: if request.auth != null && request.auth.uid == uid; + } + match /sharedMeasurements/{docId} { + allow read: if request.auth != null && areFriends(uid, request.auth.uid); + allow write: if request.auth != null && request.auth.uid == uid; + } + match /sharedStrength/{docId} { + allow read: if request.auth != null && areFriends(uid, request.auth.uid); + allow write: if request.auth != null && request.auth.uid == uid; + } + } + + // Friend requests. + // Sender creates with a fixed id = from_to, status must be "pending". + // Re-sending after accept/decline uses .set() which triggers update, handled + // by the sender re-send branch below. + // Only receiver can flip status from "pending" → "accepted"/"declined". + match /friendRequests/{requestId} { + allow create: if request.auth != null && + request.auth.uid == request.resource.data.from && + requestId == request.resource.data.from + '_' + request.resource.data.to && + request.resource.data.to != request.auth.uid && + request.resource.data.status == 'pending'; + allow read: if request.auth != null && + (request.auth.uid == resource.data.from || + request.auth.uid == resource.data.to); + allow update: if request.auth != null && + ( + // receiver accepts or declines a pending request + (request.auth.uid == resource.data.to && + resource.data.status == 'pending' && + request.resource.data.diff(resource.data).affectedKeys().hasOnly(['status']) && + (request.resource.data.status == 'accepted' || + request.resource.data.status == 'declined')) + || + // sender re-sends after accept/decline (.set() on existing doc = update); + // from/to must be unchanged and new status must be "pending" + (request.auth.uid == resource.data.from && + resource.data.status != 'pending' && + request.resource.data.from == resource.data.from && + request.resource.data.to == resource.data.to && + request.resource.data.status == 'pending') + ); + } + } +} diff --git a/hooks/__tests__/useAnimatedImageQuery.test.ts b/hooks/__tests__/useAnimatedImageQuery.test.ts index 376bf253..4843fa72 100644 --- a/hooks/__tests__/useAnimatedImageQuery.test.ts +++ b/hooks/__tests__/useAnimatedImageQuery.test.ts @@ -101,8 +101,8 @@ describe("useAnimatedImageQuery Tests", () => { queryKey: ["animatedImage", animatedUrlPath], queryFn: expect.any(Function), enabled: !!animatedUrlPath, - staleTime: Infinity, - gcTime: 1000 * 60 * 60 * 24, + staleTime: 1000 * 60 * 60, + gcTime: 1000 * 60 * 60, }); }); }); diff --git a/hooks/__tests__/useBodyMeasurementMutations.test.ts b/hooks/__tests__/useBodyMeasurementMutations.test.ts index 8fbb9bf9..9729e2d3 100644 --- a/hooks/__tests__/useBodyMeasurementMutations.test.ts +++ b/hooks/__tests__/useBodyMeasurementMutations.test.ts @@ -8,6 +8,28 @@ import { } from "@/utils/database"; import { useMutation, useQueryClient } from "@tanstack/react-query"; +jest.mock("react", () => ({ + ...jest.requireActual("react"), + useContext: jest.fn().mockReturnValue(null), +})); +jest.mock("@/context/AuthProvider", () => { + const React = jest.requireActual("react"); + return { AuthContext: React.createContext(null) }; +}); +jest.mock("@react-native-firebase/firestore", () => { + const mockFirestore: any = jest.fn(() => ({ collection: jest.fn() })); + mockFirestore.FieldValue = { serverTimestamp: jest.fn() }; + mockFirestore.Timestamp = { + fromDate: jest.fn((d: Date) => ({ toDate: () => d })), + }; + return mockFirestore; +}); +jest.mock("@/store/socialStore", () => ({ + useSocialStore: jest.fn(() => ({ privacySettings: null })), +})); +jest.mock("@/utils/sharing", () => ({ + pushBodyMeasurement: jest.fn(() => Promise.resolve()), +})); jest.mock("@/utils/database", () => ({ insertBodyMeasurementSession: jest.fn(), updateBodyMeasurementSession: jest.fn(), diff --git a/hooks/__tests__/useCreateStandaloneWorkout.test.ts b/hooks/__tests__/useCreateStandaloneWorkout.test.ts index 6849779e..bba79576 100644 --- a/hooks/__tests__/useCreateStandaloneWorkout.test.ts +++ b/hooks/__tests__/useCreateStandaloneWorkout.test.ts @@ -11,6 +11,47 @@ import { import { useMutation, useQueryClient } from "@tanstack/react-query"; import Bugsnag from "@bugsnag/expo"; +jest.mock("react", () => ({ + ...jest.requireActual("react"), + useContext: jest.fn().mockReturnValue(null), +})); +jest.mock("@/context/AuthProvider", () => { + const React = jest.requireActual("react"); + return { AuthContext: React.createContext(null) }; +}); +jest.mock("@react-native-firebase/firestore", () => { + const mockFirestore: any = jest.fn(() => ({ + collection: jest.fn(() => ({ + doc: jest.fn(() => ({ + get: jest.fn(() => + Promise.resolve({ exists: false, data: jest.fn(() => null) }), + ), + set: jest.fn(() => Promise.resolve()), + update: jest.fn(() => Promise.resolve()), + delete: jest.fn(() => Promise.resolve()), + onSnapshot: jest.fn(() => jest.fn()), + collection: jest.fn(() => ({ doc: jest.fn() })), + })), + })), + batch: jest.fn(() => ({ + set: jest.fn(), + delete: jest.fn(), + commit: jest.fn(() => Promise.resolve()), + })), + })); + mockFirestore.FieldValue = { serverTimestamp: jest.fn() }; + mockFirestore.Timestamp = { + fromDate: jest.fn((d: Date) => ({ toDate: () => d })), + }; + return mockFirestore; +}); +jest.mock("@/store/socialStore", () => ({ + useSocialStore: jest.fn(() => ({ privacySettings: null })), +})); +jest.mock("@/utils/sharing", () => ({ + publishStandaloneWorkout: jest.fn(() => Promise.resolve()), + unpublishStandaloneWorkout: jest.fn(() => Promise.resolve()), +})); jest.mock("@/utils/database", () => ({ createStandaloneWorkout: jest.fn(), updateStandaloneWorkout: jest.fn(), @@ -124,7 +165,11 @@ describe("useUpdateStandaloneWorkout", () => { it("onSuccess invalidates ['standaloneWorkouts']", () => { useUpdateStandaloneWorkout(); - capturedArgs.onSuccess(); + capturedArgs.onSuccess(undefined, { + workoutId: 42, + name: "Updated", + exercises: [], + }); expect(mockInvalidateQueries).toHaveBeenCalledWith({ queryKey: ["standaloneWorkouts"], }); diff --git a/hooks/__tests__/useExerciseDetailQuery.test.ts b/hooks/__tests__/useExerciseDetailQuery.test.ts index 7f6e5b05..d3726052 100644 --- a/hooks/__tests__/useExerciseDetailQuery.test.ts +++ b/hooks/__tests__/useExerciseDetailQuery.test.ts @@ -92,6 +92,7 @@ describe("useExerciseDetailQuery — configuration", () => { true, true, false, + false, // excludeDeload default ]); }); diff --git a/hooks/__tests__/useSaveCompletedWorkoutMutation.test.ts b/hooks/__tests__/useSaveCompletedWorkoutMutation.test.ts index 504c9d5b..89ce8ae1 100644 --- a/hooks/__tests__/useSaveCompletedWorkoutMutation.test.ts +++ b/hooks/__tests__/useSaveCompletedWorkoutMutation.test.ts @@ -2,6 +2,33 @@ import { useSaveCompletedWorkoutMutation } from "../useSaveCompletedWorkoutMutat import { saveCompletedWorkout } from "@/utils/database"; import { useMutation, useQueryClient } from "@tanstack/react-query"; +jest.mock("react", () => ({ + ...jest.requireActual("react"), + useContext: jest.fn().mockReturnValue(null), +})); +jest.mock("@/context/AuthProvider", () => { + const React = jest.requireActual("react"); + return { AuthContext: React.createContext(null) }; +}); +jest.mock("@react-native-firebase/firestore", () => { + const mockFirestore: any = jest.fn(() => ({ collection: jest.fn() })); + mockFirestore.FieldValue = { serverTimestamp: jest.fn() }; + mockFirestore.Timestamp = { + fromDate: jest.fn((d: Date) => ({ toDate: () => d })), + }; + return mockFirestore; +}); +jest.mock("@/store/socialStore", () => ({ + useSocialStore: jest.fn(() => ({ privacySettings: null })), +})); +jest.mock("@/utils/sharing", () => ({ + pushCompletedWorkout: jest.fn(() => Promise.resolve()), + pushStrengthPRs: jest.fn(() => Promise.resolve()), +})); +jest.mock("@bugsnag/expo", () => ({ + __esModule: true, + default: { notify: jest.fn() }, +})); jest.mock("@/utils/database", () => ({ saveCompletedWorkout: jest.fn(), })); @@ -61,6 +88,7 @@ describe("useSaveCompletedWorkoutMutation", () => { 2, // workoutId 3600, // duration 3, // totalSetsCompleted + false, // isDeload expect.arrayContaining([ expect.objectContaining({ sets: expect.arrayContaining([ @@ -81,6 +109,7 @@ describe("useSaveCompletedWorkoutMutation", () => { expect.anything(), expect.anything(), expect.anything(), + expect.anything(), // isDeload expect.arrayContaining([ expect.objectContaining({ sets: expect.arrayContaining([ @@ -120,6 +149,7 @@ describe("useSaveCompletedWorkoutMutation", () => { expect.anything(), expect.anything(), expect.anything(), + expect.anything(), // isDeload expect.arrayContaining([ expect.objectContaining({ sets: expect.arrayContaining([ @@ -159,6 +189,7 @@ describe("useSaveCompletedWorkoutMutation", () => { expect.anything(), expect.anything(), expect.anything(), + expect.anything(), // isDeload expect.arrayContaining([ expect.objectContaining({ sets: expect.arrayContaining([ diff --git a/hooks/__tests__/useTrackedExercisesQuery.test.ts b/hooks/__tests__/useTrackedExercisesQuery.test.ts index f54334fd..7ff6db14 100644 --- a/hooks/__tests__/useTrackedExercisesQuery.test.ts +++ b/hooks/__tests__/useTrackedExercisesQuery.test.ts @@ -46,7 +46,7 @@ describe("useTrackedExercisesQuery", () => { expect(useQuery).toHaveBeenCalledWith( expect.objectContaining({ - queryKey: ["trackedExercises", "30", false, false, false], + queryKey: ["trackedExercises", "30", false, false, false, false], }), ); }); diff --git a/hooks/useAcceptFriendRequestMutation.ts b/hooks/useAcceptFriendRequestMutation.ts new file mode 100644 index 00000000..20e98aad --- /dev/null +++ b/hooks/useAcceptFriendRequestMutation.ts @@ -0,0 +1,14 @@ +import { useMutation } from "@tanstack/react-query"; +import { useContext } from "react"; +import { AuthContext } from "../context/AuthProvider"; +import { acceptFriendRequest } from "../utils/friends"; + +export const useAcceptFriendRequestMutation = () => { + const user = useContext(AuthContext); + return useMutation({ + mutationFn: (fromUid: string) => { + if (!user) throw new Error("Not authenticated"); + return acceptFriendRequest(fromUid, user.uid); + }, + }); +}; diff --git a/hooks/useBodyMeasurementMutations.ts b/hooks/useBodyMeasurementMutations.ts index 5e15dcb0..2a82f53b 100644 --- a/hooks/useBodyMeasurementMutations.ts +++ b/hooks/useBodyMeasurementMutations.ts @@ -1,10 +1,14 @@ import { useMutation, useQueryClient } from "@tanstack/react-query"; +import { useContext } from "react"; import Bugsnag from "@bugsnag/expo"; import { insertBodyMeasurementSession, updateBodyMeasurementSession, deleteBodyMeasurementSession, } from "@/utils/database"; +import { AuthContext } from "@/context/AuthProvider"; +import { useSocialStore } from "@/store/socialStore"; +import { pushBodyMeasurement } from "@/utils/sharing"; import { toCanonicalValue, type ValueKind, @@ -27,6 +31,8 @@ export const useInsertBodyMeasurementMutation = ( options: MeasurementDisplayOptions, ) => { const queryClient = useQueryClient(); + const user = useContext(AuthContext); + const { privacySettings } = useSocialStore(); return useMutation({ mutationFn: ({ recorded_at, @@ -43,9 +49,14 @@ export const useInsertBodyMeasurementMutation = ( })); return insertBodyMeasurementSession(recorded_at, canonicalValues); }, - onSuccess: () => { + onSuccess: (entryId) => { invalidateBodyMeasurements(queryClient); queryClient.invalidateQueries({ queryKey: ["settings"] }); + if (user && privacySettings?.shareBodyMeasurements && entryId) { + pushBodyMeasurement(user.uid, entryId).catch((err) => + Bugsnag.notify(err), + ); + } }, onError: (error) => { console.error("Failed to insert body measurement session:", error); diff --git a/hooks/useCreatePlan.ts b/hooks/useCreatePlan.ts index 8af22895..34368be0 100644 --- a/hooks/useCreatePlan.ts +++ b/hooks/useCreatePlan.ts @@ -6,14 +6,18 @@ import { updateSettings, updateWorkoutPlan, } from "@/utils/database"; -import { useEffect, useState } from "react"; +import { useEffect, useState, useContext } from "react"; import { Alert } from "react-native"; import { Plan } from "./useAllPlansQuery"; import { useQueryClient } from "@tanstack/react-query"; import Bugsnag from "@bugsnag/expo"; +import { AuthContext } from "@/context/AuthProvider"; +import firestore from "@react-native-firebase/firestore"; +import { publishPlan } from "@/utils/sharing"; export const useCreatePlan = (existingPlan?: Plan) => { const queryClient = useQueryClient(); + const user = useContext(AuthContext); const [planSaved, setPlanSaved] = useState(false); const [planName, setPlanName] = useState(""); const [isError, setIsError] = useState(false); @@ -57,6 +61,20 @@ export const useCreatePlan = (existingPlan?: Plan) => { } else { await updateWorkoutPlan(planId, planName, planImageUrl, workouts); savedPlanId = planId; + + // Auto re-publish if already shared + if (user) { + const docRef = firestore() + .collection("users") + .doc(user.uid) + .collection("sharedPlans") + .doc(String(planId)); + const snap = await docRef.get(); + if (snap.exists()) { + publishPlan(user.uid, planId).catch((err) => Bugsnag.notify(err)); + } + } + queryClient.invalidateQueries({ queryKey: ["plan", planId] }); } diff --git a/hooks/useCreateStandaloneWorkout.ts b/hooks/useCreateStandaloneWorkout.ts index 4db2d101..225515f4 100644 --- a/hooks/useCreateStandaloneWorkout.ts +++ b/hooks/useCreateStandaloneWorkout.ts @@ -1,3 +1,4 @@ +import { useContext } from "react"; import { useMutation, useQueryClient } from "@tanstack/react-query"; import { createStandaloneWorkout, @@ -6,6 +7,9 @@ import { } from "@/utils/database"; import { UserExercise } from "@/store/workoutStore"; import Bugsnag from "@bugsnag/expo"; +import { AuthContext } from "@/context/AuthProvider"; +import firestore from "@react-native-firebase/firestore"; +import { publishStandaloneWorkout } from "@/utils/sharing"; export const useCreateStandaloneWorkout = () => { const queryClient = useQueryClient(); @@ -27,6 +31,7 @@ export const useCreateStandaloneWorkout = () => { }; export const useUpdateStandaloneWorkout = () => { + const user = useContext(AuthContext); const queryClient = useQueryClient(); return useMutation({ mutationFn: ({ @@ -38,8 +43,25 @@ export const useUpdateStandaloneWorkout = () => { name: string; exercises: UserExercise[]; }) => updateStandaloneWorkout(workoutId, name, exercises), - onSuccess: () => { + onSuccess: (_, { workoutId }) => { queryClient.invalidateQueries({ queryKey: ["standaloneWorkouts"] }); + if (user) { + const ref = firestore() + .collection("users") + .doc(user.uid) + .collection("sharedStandaloneWorkouts") + .doc(String(workoutId)); + ref + .get() + .then((snap) => { + if ((snap as any).exists) { + publishStandaloneWorkout(user.uid, workoutId).catch((err) => + Bugsnag.notify(err), + ); + } + }) + .catch((err) => Bugsnag.notify(err)); + } }, onError: (error: Error) => { Bugsnag.notify(error); diff --git a/hooks/useDeclineFriendRequestMutation.ts b/hooks/useDeclineFriendRequestMutation.ts new file mode 100644 index 00000000..1c2c8d5b --- /dev/null +++ b/hooks/useDeclineFriendRequestMutation.ts @@ -0,0 +1,14 @@ +import { useMutation } from "@tanstack/react-query"; +import { useContext } from "react"; +import { AuthContext } from "../context/AuthProvider"; +import { declineFriendRequest } from "../utils/friends"; + +export const useDeclineFriendRequestMutation = () => { + const user = useContext(AuthContext); + return useMutation({ + mutationFn: (fromUid: string) => { + if (!user) throw new Error("Not authenticated"); + return declineFriendRequest(fromUid, user.uid); + }, + }); +}; diff --git a/hooks/useFriendSharedCompletedWorkoutsQuery.ts b/hooks/useFriendSharedCompletedWorkoutsQuery.ts new file mode 100644 index 00000000..91cc5263 --- /dev/null +++ b/hooks/useFriendSharedCompletedWorkoutsQuery.ts @@ -0,0 +1,25 @@ +import { useContext } from "react"; +import { useQuery } from "@tanstack/react-query"; +import firestore from "@react-native-firebase/firestore"; +import { AuthContext } from "@/context/AuthProvider"; +import { SharedCompletedWorkout } from "@/types/firestore"; + +export const useFriendSharedCompletedWorkoutsQuery = ( + friendUid: string | null, +) => { + const user = useContext(AuthContext); + return useQuery({ + queryKey: ["friendSharedCompletedWorkouts", friendUid], + queryFn: async (): Promise => { + if (!user || !friendUid) return []; + const snap = await firestore() + .collection("users") + .doc(friendUid) + .collection("sharedWorkouts") + .get(); + return snap.docs.map((d) => d.data() as SharedCompletedWorkout); + }, + enabled: !!user && !!friendUid, + staleTime: 60_000, + }); +}; diff --git a/hooks/useFriendSharedCustomExercisesQuery.ts b/hooks/useFriendSharedCustomExercisesQuery.ts new file mode 100644 index 00000000..aad72046 --- /dev/null +++ b/hooks/useFriendSharedCustomExercisesQuery.ts @@ -0,0 +1,25 @@ +import { useContext } from "react"; +import { useQuery } from "@tanstack/react-query"; +import firestore from "@react-native-firebase/firestore"; +import { AuthContext } from "@/context/AuthProvider"; +import { SharedCustomExercise } from "@/types/firestore"; + +export const useFriendSharedCustomExercisesQuery = ( + friendUid: string | null, +) => { + const user = useContext(AuthContext); + return useQuery({ + queryKey: ["friendSharedCustomExercises", friendUid], + queryFn: async (): Promise => { + if (!user || !friendUid) return []; + const snap = await firestore() + .collection("users") + .doc(friendUid) + .collection("sharedCustomExercises") + .get(); + return snap.docs.map((d) => d.data() as SharedCustomExercise); + }, + enabled: !!user && !!friendUid, + staleTime: 60_000, + }); +}; diff --git a/hooks/useFriendSharedMeasurementsQuery.ts b/hooks/useFriendSharedMeasurementsQuery.ts new file mode 100644 index 00000000..9e142eff --- /dev/null +++ b/hooks/useFriendSharedMeasurementsQuery.ts @@ -0,0 +1,23 @@ +import { useContext } from "react"; +import { useQuery } from "@tanstack/react-query"; +import firestore from "@react-native-firebase/firestore"; +import { AuthContext } from "@/context/AuthProvider"; +import { SharedMeasurement } from "@/types/firestore"; + +export const useFriendSharedMeasurementsQuery = (friendUid: string | null) => { + const user = useContext(AuthContext); + return useQuery({ + queryKey: ["friendSharedMeasurements", friendUid], + queryFn: async (): Promise => { + if (!user || !friendUid) return []; + const snap = await firestore() + .collection("users") + .doc(friendUid) + .collection("sharedMeasurements") + .get(); + return snap.docs.map((d) => d.data() as SharedMeasurement); + }, + enabled: !!user && !!friendUid, + staleTime: 60_000, + }); +}; diff --git a/hooks/useFriendSharedPlansQuery.ts b/hooks/useFriendSharedPlansQuery.ts new file mode 100644 index 00000000..df0277ae --- /dev/null +++ b/hooks/useFriendSharedPlansQuery.ts @@ -0,0 +1,23 @@ +import { useContext } from "react"; +import { useQuery } from "@tanstack/react-query"; +import firestore from "@react-native-firebase/firestore"; +import { AuthContext } from "@/context/AuthProvider"; +import { SharedPlan } from "@/types/firestore"; + +export const useFriendSharedPlansQuery = (friendUid: string | null) => { + const user = useContext(AuthContext); + return useQuery({ + queryKey: ["friendSharedPlans", friendUid], + queryFn: async (): Promise => { + if (!user || !friendUid) return []; + const snap = await firestore() + .collection("users") + .doc(friendUid) + .collection("sharedPlans") + .get(); + return snap.docs.map((d) => d.data() as SharedPlan); + }, + enabled: !!user && !!friendUid, + staleTime: 60_000, + }); +}; diff --git a/hooks/useFriendSharedStandaloneWorkoutsQuery.ts b/hooks/useFriendSharedStandaloneWorkoutsQuery.ts new file mode 100644 index 00000000..9bd13e40 --- /dev/null +++ b/hooks/useFriendSharedStandaloneWorkoutsQuery.ts @@ -0,0 +1,25 @@ +import { useContext } from "react"; +import { useQuery } from "@tanstack/react-query"; +import firestore from "@react-native-firebase/firestore"; +import { AuthContext } from "@/context/AuthProvider"; +import { SharedStandaloneWorkout } from "@/types/firestore"; + +export const useFriendSharedStandaloneWorkoutsQuery = ( + friendUid: string | null, +) => { + const user = useContext(AuthContext); + return useQuery({ + queryKey: ["friendSharedStandaloneWorkouts", friendUid], + queryFn: async (): Promise => { + if (!user || !friendUid) return []; + const snap = await firestore() + .collection("users") + .doc(friendUid) + .collection("sharedStandaloneWorkouts") + .get(); + return snap.docs.map((d) => d.data() as SharedStandaloneWorkout); + }, + enabled: !!user && !!friendUid, + staleTime: 60_000, + }); +}; diff --git a/hooks/useFriendSharedStrengthQuery.ts b/hooks/useFriendSharedStrengthQuery.ts new file mode 100644 index 00000000..18c2a1af --- /dev/null +++ b/hooks/useFriendSharedStrengthQuery.ts @@ -0,0 +1,23 @@ +import { useContext } from "react"; +import { useQuery } from "@tanstack/react-query"; +import firestore from "@react-native-firebase/firestore"; +import { AuthContext } from "@/context/AuthProvider"; +import { SharedStrengthPR } from "@/types/firestore"; + +export const useFriendSharedStrengthQuery = (friendUid: string | null) => { + const user = useContext(AuthContext); + return useQuery({ + queryKey: ["friendSharedStrength", friendUid], + queryFn: async (): Promise => { + if (!user || !friendUid) return []; + const snap = await firestore() + .collection("users") + .doc(friendUid) + .collection("sharedStrength") + .get(); + return snap.docs.map((d) => d.data() as SharedStrengthPR); + }, + enabled: !!user && !!friendUid, + staleTime: 60_000, + }); +}; diff --git a/hooks/useImportCustomExerciseMutation.ts b/hooks/useImportCustomExerciseMutation.ts new file mode 100644 index 00000000..bfc8f639 --- /dev/null +++ b/hooks/useImportCustomExerciseMutation.ts @@ -0,0 +1,42 @@ +import { useMutation, useQueryClient } from "@tanstack/react-query"; +import Bugsnag from "@bugsnag/expo"; +import { openDatabase } from "@/utils/database"; +import { SharedCustomExercise } from "@/types/firestore"; + +export const useImportCustomExerciseMutation = () => { + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: async (exercise: SharedCustomExercise): Promise => { + const db = await openDatabase("userData.db"); + const existing = await db.getFirstAsync<{ exercise_id: number }>( + "SELECT exercise_id FROM exercises WHERE app_exercise_id IS NULL AND name = ? LIMIT 1", + [exercise.name], + ); + if (existing) return existing.exercise_id; + + const result = await db.runAsync( + `INSERT INTO exercises (app_exercise_id, name, body_part, target_muscle, equipment, secondary_muscles, description, tracking_type, is_unilateral, double_weight, animated_url) + VALUES (NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, + [ + exercise.name, + exercise.bodyPart, + exercise.targetMuscle, + exercise.equipment, + JSON.stringify(exercise.secondaryMuscles), + exercise.description, + exercise.trackingType, + exercise.isUnilateral ? 1 : 0, + exercise.doubleWeight ? 1 : 0, + exercise.animatedUrl, + ], + ); + return result.lastInsertRowId; + }, + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ["exercises"] }); + }, + onError: (error: Error) => { + Bugsnag.notify(error); + }, + }); +}; diff --git a/hooks/useImportPlanMutation.ts b/hooks/useImportPlanMutation.ts new file mode 100644 index 00000000..10e3e791 --- /dev/null +++ b/hooks/useImportPlanMutation.ts @@ -0,0 +1,61 @@ +import { useMutation, useQueryClient } from "@tanstack/react-query"; +import Bugsnag from "@bugsnag/expo"; +import { openDatabase } from "@/utils/database"; +import { ensureAppExercisesExist } from "@/utils/loadPremadePlans"; +import { resolveExerciseId } from "@/utils/importUtils"; +import { SharedPlan } from "@/types/firestore"; + +export const useImportPlanMutation = () => { + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: async (plan: SharedPlan): Promise => { + const db = await openDatabase("userData.db"); + + const appExerciseIds = plan.workouts + .flatMap((w) => w.exercises) + .map((e) => e.appExerciseId) + .filter((id): id is number => id !== null); + await ensureAppExercisesExist(db, appExerciseIds); + + let newPlanId = 0; + await db.withExclusiveTransactionAsync(async (txn) => { + const planResult = await txn.runAsync( + `INSERT INTO user_plans (name, image_url) VALUES (?, ?)`, + [plan.name, plan.imageUrl ?? null], + ); + newPlanId = planResult.lastInsertRowId; + + for (const [workoutOrder, workout] of plan.workouts.entries()) { + const workoutResult = await txn.runAsync( + `INSERT INTO user_workouts (plan_id, name, workout_order) VALUES (?, ?, ?)`, + [newPlanId, workout.name, workoutOrder], + ); + const workoutId = workoutResult.lastInsertRowId; + + for (const [exerciseOrder, exercise] of workout.exercises.entries()) { + const exerciseId = await resolveExerciseId(txn, exercise); + await txn.runAsync( + `INSERT INTO user_workout_exercises (workout_id, exercise_id, sets, exercise_order, superset_group_id, tracking_type_override) VALUES (?, ?, ?, ?, ?, ?)`, + [ + workoutId, + exerciseId, + JSON.stringify(exercise.sets), + exerciseOrder, + exercise.supersetGroupId ?? null, + exercise.trackingTypeOverride ?? null, + ], + ); + } + } + }); + return newPlanId; + }, + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ["plans"] }); + queryClient.invalidateQueries({ queryKey: ["allPlans"] }); + }, + onError: (error: Error) => { + Bugsnag.notify(error); + }, + }); +}; diff --git a/hooks/useImportStandaloneWorkoutMutation.ts b/hooks/useImportStandaloneWorkoutMutation.ts new file mode 100644 index 00000000..084f41bc --- /dev/null +++ b/hooks/useImportStandaloneWorkoutMutation.ts @@ -0,0 +1,51 @@ +import { useMutation, useQueryClient } from "@tanstack/react-query"; +import Bugsnag from "@bugsnag/expo"; +import { openDatabase } from "@/utils/database"; +import { ensureAppExercisesExist } from "@/utils/loadPremadePlans"; +import { resolveExerciseId } from "@/utils/importUtils"; +import { SharedStandaloneWorkout } from "@/types/firestore"; + +export const useImportStandaloneWorkoutMutation = () => { + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: async (workout: SharedStandaloneWorkout): Promise => { + const db = await openDatabase("userData.db"); + + const appExerciseIds = workout.exercises + .map((e) => e.appExerciseId) + .filter((id): id is number => id !== null); + await ensureAppExercisesExist(db, appExerciseIds); + + let newWorkoutId = 0; + await db.withExclusiveTransactionAsync(async (txn) => { + const workoutResult = await txn.runAsync( + `INSERT INTO user_workouts (plan_id, name, workout_order) VALUES (NULL, ?, 0)`, + [workout.name], + ); + newWorkoutId = workoutResult.lastInsertRowId; + + for (const [exerciseOrder, exercise] of workout.exercises.entries()) { + const exerciseId = await resolveExerciseId(txn, exercise); + await txn.runAsync( + `INSERT INTO user_workout_exercises (workout_id, exercise_id, sets, exercise_order, superset_group_id, tracking_type_override) VALUES (?, ?, ?, ?, ?, ?)`, + [ + newWorkoutId, + exerciseId, + JSON.stringify(exercise.sets), + exerciseOrder, + exercise.supersetGroupId ?? null, + exercise.trackingTypeOverride ?? null, + ], + ); + } + }); + return newWorkoutId; + }, + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ["standaloneWorkouts"] }); + }, + onError: (error: Error) => { + Bugsnag.notify(error); + }, + }); +}; diff --git a/hooks/usePlanPublishMutation.ts b/hooks/usePlanPublishMutation.ts new file mode 100644 index 00000000..1af798ec --- /dev/null +++ b/hooks/usePlanPublishMutation.ts @@ -0,0 +1,29 @@ +import { useMutation, useQueryClient } from "@tanstack/react-query"; +import { useContext } from "react"; +import { AuthContext } from "@/context/AuthProvider"; +import Bugsnag from "@bugsnag/expo"; +import { publishPlan, unpublishPlan } from "@/utils/sharing"; + +export const usePlanPublishMutation = (planId: number) => { + const user = useContext(AuthContext); + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: async (publish: boolean) => { + if (!user) throw new Error("Not authenticated"); + if (publish) { + await publishPlan(user.uid, planId); + } else { + await unpublishPlan(user.uid, planId); + } + return publish; + }, + onSuccess: (published) => { + queryClient.setQueryData(["planPublished", planId], published); + queryClient.invalidateQueries({ queryKey: ["publishedPlanIds"] }); + }, + onError: (error: Error) => { + Bugsnag.notify(error); + }, + }); +}; diff --git a/hooks/usePlanPublishQuery.ts b/hooks/usePlanPublishQuery.ts new file mode 100644 index 00000000..87c65283 --- /dev/null +++ b/hooks/usePlanPublishQuery.ts @@ -0,0 +1,24 @@ +import { useQuery } from "@tanstack/react-query"; +import firestore from "@react-native-firebase/firestore"; +import { useContext } from "react"; +import { AuthContext } from "@/context/AuthProvider"; + +export const usePlanPublishQuery = (planId: number | null) => { + const user = useContext(AuthContext); + + return useQuery({ + queryKey: ["planPublished", planId], + queryFn: async () => { + if (!user || !planId) return false; + const doc = await firestore() + .collection("users") + .doc(user.uid) + .collection("sharedPlans") + .doc(String(planId)) + .get(); + return doc.exists(); + }, + enabled: !!user && !!planId, + staleTime: Infinity, + }); +}; diff --git a/hooks/usePrivacySettingsMutation.ts b/hooks/usePrivacySettingsMutation.ts new file mode 100644 index 00000000..cc90cb18 --- /dev/null +++ b/hooks/usePrivacySettingsMutation.ts @@ -0,0 +1,26 @@ +import { useMutation } from "@tanstack/react-query"; +import firestore from "@react-native-firebase/firestore"; +import Bugsnag from "@bugsnag/expo"; +import { useContext } from "react"; +import { AuthContext } from "@/context/AuthProvider"; +import type { FirestorePrivateSettings } from "@/types/firestore"; + +export const usePrivacySettingsMutation = () => { + const user = useContext(AuthContext); + + return useMutation({ + mutationFn: async (patch: Partial) => { + if (!user) + throw new Error("usePrivacySettingsMutation: user not authenticated"); + await firestore() + .collection("users") + .doc(user.uid) + .collection("private") + .doc("settings") + .update(patch); + }, + onError: (error: Error) => { + Bugsnag.notify(error); + }, + }); +}; diff --git a/hooks/usePublishedPlanIdsQuery.ts b/hooks/usePublishedPlanIdsQuery.ts new file mode 100644 index 00000000..50f1308a --- /dev/null +++ b/hooks/usePublishedPlanIdsQuery.ts @@ -0,0 +1,23 @@ +import { useQuery } from "@tanstack/react-query"; +import firestore from "@react-native-firebase/firestore"; +import { useContext } from "react"; +import { AuthContext } from "@/context/AuthProvider"; + +export const usePublishedPlanIdsQuery = () => { + const user = useContext(AuthContext); + + return useQuery({ + queryKey: ["publishedPlanIds", user?.uid], + queryFn: async (): Promise => { + if (!user) return []; + const snap = await firestore() + .collection("users") + .doc(user.uid) + .collection("sharedPlans") + .get(); + return snap.docs.map((d) => d.id); + }, + enabled: !!user, + staleTime: 60_000, + }); +}; diff --git a/hooks/usePublishedWorkoutIdsQuery.ts b/hooks/usePublishedWorkoutIdsQuery.ts new file mode 100644 index 00000000..4b8240f4 --- /dev/null +++ b/hooks/usePublishedWorkoutIdsQuery.ts @@ -0,0 +1,23 @@ +import { useQuery } from "@tanstack/react-query"; +import firestore from "@react-native-firebase/firestore"; +import { useContext } from "react"; +import { AuthContext } from "@/context/AuthProvider"; + +export const usePublishedWorkoutIdsQuery = () => { + const user = useContext(AuthContext); + + return useQuery({ + queryKey: ["publishedWorkoutIds", user?.uid], + queryFn: async (): Promise => { + if (!user) return []; + const snap = await firestore() + .collection("users") + .doc(user.uid) + .collection("sharedStandaloneWorkouts") + .get(); + return snap.docs.map((d) => d.id); + }, + enabled: !!user, + staleTime: 60_000, + }); +}; diff --git a/hooks/useRemoveFriendMutation.ts b/hooks/useRemoveFriendMutation.ts new file mode 100644 index 00000000..b1f356c8 --- /dev/null +++ b/hooks/useRemoveFriendMutation.ts @@ -0,0 +1,14 @@ +import { useMutation } from "@tanstack/react-query"; +import { useContext } from "react"; +import { AuthContext } from "../context/AuthProvider"; +import { removeFriend } from "../utils/friends"; + +export const useRemoveFriendMutation = () => { + const user = useContext(AuthContext); + return useMutation({ + mutationFn: (friendUid: string) => { + if (!user) throw new Error("Not authenticated"); + return removeFriend(user.uid, friendUid); + }, + }); +}; diff --git a/hooks/useSaveCompletedWorkoutMutation.ts b/hooks/useSaveCompletedWorkoutMutation.ts index 0a703d72..fe9cac44 100644 --- a/hooks/useSaveCompletedWorkoutMutation.ts +++ b/hooks/useSaveCompletedWorkoutMutation.ts @@ -1,5 +1,10 @@ import { useMutation, useQueryClient } from "@tanstack/react-query"; +import { useContext } from "react"; import { saveCompletedWorkout, SavedWorkout } from "@/utils/database"; +import { AuthContext } from "@/context/AuthProvider"; +import { useSocialStore } from "@/store/socialStore"; +import Bugsnag from "@bugsnag/expo"; +import { pushCompletedWorkout, pushStrengthPRs } from "@/utils/sharing"; const saveCompletedWorkoutWithConversion = async ( completedWorkoutData: SavedWorkout, @@ -37,6 +42,8 @@ export const useSaveCompletedWorkoutMutation = ( distanceUnit: string = "m", ) => { const queryClient = useQueryClient(); + const user = useContext(AuthContext); + const { privacySettings } = useSocialStore(); return useMutation({ mutationFn: (completedWorkoutData: SavedWorkout) => { return saveCompletedWorkoutWithConversion( @@ -45,12 +52,29 @@ export const useSaveCompletedWorkoutMutation = ( distanceUnit, ); }, - onSuccess: () => { + onSuccess: (completedWorkoutId, completedWorkoutData) => { queryClient.invalidateQueries({ queryKey: ["completedWorkouts"] }); queryClient.invalidateQueries({ queryKey: ["trackedExercises"] }); queryClient.invalidateQueries({ queryKey: ["globalExerciseHistoryForSession", weightUnit, distanceUnit], }); + + if (!user) return; + + if (privacySettings?.shareCompletedWorkouts) { + pushCompletedWorkout(user.uid, completedWorkoutId).catch((err) => + Bugsnag.notify(err), + ); + } + + if (privacySettings?.shareStrengthProgress) { + const exerciseIds = completedWorkoutData.exercises.map( + (e) => e.exercise_id, + ); + pushStrengthPRs(user.uid, exerciseIds).catch((err) => + Bugsnag.notify(err), + ); + } }, }); }; diff --git a/hooks/useSendFriendRequestMutation.ts b/hooks/useSendFriendRequestMutation.ts new file mode 100644 index 00000000..d387112e --- /dev/null +++ b/hooks/useSendFriendRequestMutation.ts @@ -0,0 +1,14 @@ +import { useMutation } from "@tanstack/react-query"; +import { useContext } from "react"; +import { AuthContext } from "../context/AuthProvider"; +import { sendFriendRequest } from "../utils/friends"; + +export const useSendFriendRequestMutation = () => { + const user = useContext(AuthContext); + return useMutation({ + mutationFn: (toUid: string) => { + if (!user) throw new Error("Not authenticated"); + return sendFriendRequest(user.uid, toUid); + }, + }); +}; diff --git a/hooks/useSocialListeners.ts b/hooks/useSocialListeners.ts new file mode 100644 index 00000000..4ad2a7b7 --- /dev/null +++ b/hooks/useSocialListeners.ts @@ -0,0 +1,165 @@ +import { useEffect, useContext } from "react"; +import firestore from "@react-native-firebase/firestore"; +import { AuthContext } from "../context/AuthProvider"; +import { + useSocialStore, + PendingRequest, + SentRequest, +} from "../store/socialStore"; +import { FriendInfo, FirestorePrivateSettings } from "../types/firestore"; +import Bugsnag from "@bugsnag/expo"; + +export const useSocialListeners = () => { + const user = useContext(AuthContext); + const { + setPendingRequests, + setSentRequests, + setFriends, + setPrivacySettings, + } = useSocialStore(); + + useEffect(() => { + if (!user) { + setPendingRequests([]); + setSentRequests([]); + setFriends([]); + setPrivacySettings(null); + return; + } + + const db = firestore(); + + // Incoming pending requests + const unsubPending = db + .collection("friendRequests") + .where("to", "==", user.uid) + .where("status", "==", "pending") + .onSnapshot( + async (snapshot) => { + try { + const requests: PendingRequest[] = await Promise.all( + snapshot.docs.map(async (doc) => { + const data = doc.data(); + const senderDoc = await db + .collection("users") + .doc(data.from) + .get(); + const sender = senderDoc.data(); + return { + id: doc.id, + fromUid: data.from, + displayName: sender?.displayName ?? "", + email: sender?.email ?? "", + photoURL: sender?.photoURL ?? "", + createdAt: data.createdAt?.toDate() ?? new Date(), + }; + }), + ); + setPendingRequests(requests); + } catch (error) { + Bugsnag.notify(error as Error); + } + }, + (error) => { + Bugsnag.notify(error); + }, + ); + + // Outgoing sent requests (still pending) + const unsubSent = db + .collection("friendRequests") + .where("from", "==", user.uid) + .where("status", "==", "pending") + .onSnapshot( + async (snapshot) => { + try { + const requests: SentRequest[] = await Promise.all( + snapshot.docs.map(async (doc) => { + const data = doc.data(); + const receiverDoc = await db + .collection("users") + .doc(data.to) + .get(); + const receiver = receiverDoc.data(); + return { + id: doc.id, + toUid: data.to, + displayName: receiver?.displayName ?? "", + email: receiver?.email ?? "", + photoURL: receiver?.photoURL ?? "", + createdAt: data.createdAt?.toDate() ?? new Date(), + }; + }), + ); + setSentRequests(requests); + } catch (error) { + Bugsnag.notify(error as Error); + } + }, + (error) => { + Bugsnag.notify(error); + }, + ); + + // Friends list + const unsubFriends = db + .collection("users") + .doc(user.uid) + .collection("friends") + .onSnapshot( + async (snapshot) => { + try { + const friends: FriendInfo[] = await Promise.all( + snapshot.docs.map(async (doc) => { + const data = doc.data(); + const friendDoc = await db + .collection("users") + .doc(doc.id) + .get(); + const friend = friendDoc.data(); + return { + uid: doc.id, + displayName: friend?.displayName ?? "", + email: friend?.email ?? "", + photoURL: friend?.photoURL ?? "", + since: data.since, + }; + }), + ); + setFriends(friends); + } catch (error) { + Bugsnag.notify(error as Error); + } + }, + (error) => { + Bugsnag.notify(error); + }, + ); + + // Privacy settings + const unsubSettings = db + .collection("users") + .doc(user.uid) + .collection("private") + .doc("settings") + .onSnapshot( + (doc) => { + if (doc.exists()) { + setPrivacySettings(doc.data() as FirestorePrivateSettings); + } else { + setPrivacySettings(null); + } + }, + (error) => { + Bugsnag.notify(error); + }, + ); + + return () => { + unsubPending(); + unsubSent(); + unsubFriends(); + unsubSettings(); + }; + }, [user?.uid]); +}; diff --git a/hooks/useWorkoutPublishMutation.ts b/hooks/useWorkoutPublishMutation.ts new file mode 100644 index 00000000..b92e61e1 --- /dev/null +++ b/hooks/useWorkoutPublishMutation.ts @@ -0,0 +1,32 @@ +import { useMutation, useQueryClient } from "@tanstack/react-query"; +import { useContext } from "react"; +import { AuthContext } from "@/context/AuthProvider"; +import Bugsnag from "@bugsnag/expo"; +import { + publishStandaloneWorkout, + unpublishStandaloneWorkout, +} from "@/utils/sharing"; + +export const useWorkoutPublishMutation = (workoutId: number) => { + const user = useContext(AuthContext); + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: async (publish: boolean) => { + if (!user) throw new Error("Not authenticated"); + if (publish) { + await publishStandaloneWorkout(user.uid, workoutId); + } else { + await unpublishStandaloneWorkout(user.uid, workoutId); + } + return publish; + }, + onSuccess: (published) => { + queryClient.setQueryData(["workoutPublished", workoutId], published); + queryClient.invalidateQueries({ queryKey: ["publishedWorkoutIds"] }); + }, + onError: (error: Error) => { + Bugsnag.notify(error); + }, + }); +}; diff --git a/hooks/useWorkoutPublishQuery.ts b/hooks/useWorkoutPublishQuery.ts new file mode 100644 index 00000000..52589fc7 --- /dev/null +++ b/hooks/useWorkoutPublishQuery.ts @@ -0,0 +1,24 @@ +import { useQuery } from "@tanstack/react-query"; +import firestore from "@react-native-firebase/firestore"; +import { useContext } from "react"; +import { AuthContext } from "@/context/AuthProvider"; + +export const useWorkoutPublishQuery = (workoutId: number | null) => { + const user = useContext(AuthContext); + + return useQuery({ + queryKey: ["workoutPublished", workoutId], + queryFn: async () => { + if (!user || !workoutId) return false; + const doc = await firestore() + .collection("users") + .doc(user.uid) + .collection("sharedStandaloneWorkouts") + .doc(String(workoutId)) + .get(); + return doc.exists(); + }, + enabled: !!user && !!workoutId, + staleTime: Infinity, + }); +}; diff --git a/locales/de/messages.js b/locales/de/messages.js index 48cd394a..bf64932e 100644 --- a/locales/de/messages.js +++ b/locales/de/messages.js @@ -1 +1 @@ -/*eslint-disable*/module.exports={messages:JSON.parse("{\"-2Ut5a\":[\"Der Einblicke-Streifen oben auf dem Statistiken-Tab gibt vier schnelle Highlights für den ausgewählten Zeitraum: deine durchschnittlichen Trainings pro Woche, deinen größten Kraftzuwachs bei verfolgten Übungen, das Körperteil, das du am meisten trainiert hast, und deine aktuelle Wochenserie. Diese werden nach jedem Training automatisch aktualisiert.\"],\"-5kO8P\":[\"Samstag\"],\"-BjMj_\":[\"Training erstellen\"],\"-FjWgX\":[\"Do\"],\"-Tpjjs\":[[\"0\"],\" Sätze\"],\"-WSEJS\":[\"Training löschen\"],\"-Xejuf\":[\"Hüften\"],\"-XvJee\":[\"Bestwert \",[\"0\"],[\"weightUnit\"],\" × \",[\"1\"]],\"-svcUj\":[\"Dieses Training speichern?\"],\"03mQOq\":[\"Plan konnte nicht aktiviert werden: \",[\"0\"]],\"06EUQy\":[\"Bester PR aller Zeiten\"],\"0EHHPz\":[\"Adduktoren\"],\"0EPpEZ\":[\"Eigenen Messwert hinzufügen\"],\"0EcUWz\":[\"Änderungen verwerfen?\"],\"0OeId4\":[\"Eigenen Plan erstellen\"],\"0P1btN\":[\"\\n🔔 Neu: Übungstimer-Töne!\\n\\nDer Übungstimer gibt jetzt Audiosignale aus, damit du auf Kurs bleibst. Ein Countdown-Piep, wenn der Timer sich null nähert, und ein Sound, wenn du dein Ziel erreichst. Schalte jeden Ton unabhängig in den Einstellungen ein oder aus.\\n\"],\"0SaB4K\":[\"Aufwärmsatz\"],\"0U938S\":[\"Wähle mindestens einen Tag aus\"],\"0V9gKq\":[\"\\n🔵 Neu: Übungstimer-Fenster!\\n\\nZeitbasierte Übungen zeigen jetzt ein eigenes Countdown-Fenster mit einem Fortschrittsring, damit du deinen Einsatz leicht verfolgen und bei zeitgesteuerten Sätzen im Rhythmus bleiben kannst.\\n\"],\"0caMy7\":[\"Verlauf\"],\"0dHvKo\":[\"Zielmuskel:\"],\"0eRpDV\":[\"Schwer, nah am Limit\"],\"0f7U0k\":[\"Mi\"],\"0tJJBW\":[\"Zurück: \"],\"0vGEy2\":[\"\\n📊 Neu: Verbesserter Statistiken-Bildschirm!\\n\\nDer Statistiken-Bildschirm wurde mit einem neuen Look und verbesserten Einblicken neu gestaltet. Erkunde deine Trainingshistorie mit besseren Diagrammen, klareren Zusammenfassungen und detaillierteren Aufschlüsselungen deines Fortschritts über die Zeit.\\n\"],\"14ytif\":[\"Training starten\"],\"1DPB1m\":[\"\\n🗂️ Neu: Fünf neue vorgefertigte Trainingspläne!\\n\\nFünf neue sofort einsatzbereite Pläne sind jetzt verfügbar: 5-Tage-Bro-Split, 5-Tage-Push/Pull/Beine, 6-Tage-Split, Körpergewicht und Nur Kurzhanteln. Ob du zuhause oder im Gym trainierst, es gibt einen Plan, mit dem du sofort loslegen kannst.\\n\"],\"1FnEj9\":[\"Körpermaße\"],\"1Kx4Hp\":[\"Fehler beim Abrufen von \",[\"0\"],\": \",[\"1\"]],\"1Mx10o\":[\"Statistiken anzeigen\"],\"1QfxQT\":[\"Schließen\"],\"1Se9J7\":[\"Heimtrainer\"],\"1UzENP\":[\"Nein\"],\"1gbc4_\":[\"Neues Training\"],\"1hW6-f\":[\"Einige Bilder konnten nach mehreren Versuchen nicht heruntergeladen werden. Fehlgeschlagene Übungs-IDs: \",[\"0\"]],\"1j3Ob3\":[\"Trainingskalender\"],\"1mm2JF\":[\"Deltamuskeln\"],\"296mtr\":[\"Trapezstange\"],\"29Hx9U\":[\"Statistiken\"],\"2FYpfJ\":[\"Mehr\"],\"2ZZM6V\":[\"Core\"],\"2bnWaQ\":[[\"completedCount\"],\"/\",[\"0\"],\" Sätze abgeschlossen\"],\"2cupe5\":[\"Auf alle \",[\"0\"],\" Sätze anwenden\"],\"2dPYb7\":[\"Noch keine Messungen. Erfasse deinen ersten Eintrag oben.\"],\"2dX9Kv\":[\"Rücken\"],\"2eB2c7\":[\"Trainiere ohne Plan! Erstelle eigenständige Trainings außerhalb deiner Trainingspläne, perfekt für Mobilitätssessions, Aufwärmen oder alles Spontane.\\n\\nOder starte direkt ein Schnelltraining vom Startbildschirm, füge Übungen unterwegs hinzu, und speichere es optional als eigenständiges Training, wenn du fertig bist.\"],\"2gSypt\":[\"Gerät *\"],\"2j0v05\":[\"Alle Bilder erfolgreich heruntergeladen!\"],\"2lfUf3\":[[\"streak\",\"plural\",{\"one\":[\"#\",\" Woche in Folge\"],\"other\":[\"#\",\" Wochen in Folge\"]}]],\"2saL1j\":[\"1RM\"],\"2vS4Oc\":[\"Leicht, hätte mehr gekonnt\"],\"2wR0QE\":[\"Übung hinzufügen\"],\"30xwUM\":[\"Möchtest du wirklich alle animierten Bilder löschen? Einzelbilder werden beim Anzeigen automatisch erneut heruntergeladen.\"],\"39y5bn\":[\"Freitag\"],\"3A79ox\":[\"Gewicht reduzieren\"],\"3L-1Z1\":[\"Fehler beim Laden der Übungen: \",[\"0\"]],\"3RoflF\":[\"\\n📈 Neu: Übungshistorie in der Infoansicht!\\n\\nDie Übungsinfoansicht enthält jetzt eine vollständige Übungshistorie mit Gewicht, Wiederholungen, Zeit und Distanz für jeden Satz aus vergangenen Einheiten. Zugriff während eines Trainings, über deinen Plan oder überall dort, wo Übungsinfos verfügbar sind.\\n\"],\"3ezHPX\":[\"Ton nach der Pause abspielen\"],\"3hJ166\":[\"\\n🔍 Verbessert: Intelligentere Übungssuche & einfacher Zugriff auf die Übungsbibliothek!\\n\\nDie Übungssuche erkennt jetzt gängige Abkürzungen wie RDL, OHP, DB und KB, korrigiert kleine Tippfehler und sortiert die Ergebnisse nach Relevanz, sodass die beste Übereinstimmung immer zuerst erscheint.\\n\\nDu kannst die vollständige Übungsbibliothek jederzeit über das Menü durchsuchen, ohne dich in einem Training oder Plan befinden zu müssen.\\n\"],\"3hJypY\":[\"Einblicke\"],\"43lYJ-\":[\"Willkommen\",[\"userName\"]],\"4BgR4M\":[\"Du hast dein Wochenziel erreicht. Unglaubliche Leistung!\"],\"4GTHgi\":[\"Übungstimer-Countdown\"],\"4M4P8M\":[\"Keine Werte eingegeben\"],\"4OjqAQ\":[\"Weiter bearbeiten\"],\"4_WLmI\":[\"Körpergewicht\"],\"4j0zbV\":[\"Plan wird gespeichert...\"],\"4jkyRj\":[\"Aufwärmen\"],\"4mrNi3\":[[\"suggestedRepsMin\"],\"-\",[\"suggestedRepsMax\"],\" Wdh. vorgeschlagen\"],\"4oRoD4\":[\"Konfiguriere Gewichts-, Größen- und Distanzeinheiten, Standard-Sätze pro Übung, Standard-Pausenzeit und die Gewichtserhöhung der ±-Schaltflächen während einer Einheit. Passe die Schaltflächengröße (Standard, Groß oder Sehr groß) an und aktiviere Bildschirm eingeschaltet lassen, damit das Display nicht mitten im Training ausgeht. Unter Statistiken kannst du Aufwärmsätze vom Volumen ausschließen, Wiederholungen für einseitige Übungen verdoppeln oder das Gewicht für gepaarte Geräte verdoppeln, nützlich wenn du das Gewicht pro Kurzhantel statt das Gesamtgewicht protokollierst. Lege hier dein Körpergewicht fest, es wird zur Berechnung der effektiven Last bei Assistenzübungen verwendet.\"],\"4sGdeG\":[\"Körperfett\"],\"50_FGa\":[\"Übung\"],\"538Jsv\":[\"Training abbrechen\"],\"58iwz8\":[\"Fehler beim Laden der Pläne\"],\"5SgD0L\":[\"Du hast nicht gespeicherte Änderungen. Möchtest du sie wirklich verwerfen?\"],\"5Z05pb\":[\"Tippe, um Hilfethemen zu filtern\"],\"5aB9II\":[\"Zeit für deinen nächsten Satz!\"],\"5b4J4v\":[\"Gesamt\"],\"5lWFkC\":[\"Anmelden\"],\"5w2VTM\":[\"Möchtest du wirklich alle animierten Bilder herunterladen? Das kann eine Weile dauern.\"],\"5yIPLp\":[\"Hoppla!\"],\"66llpx\":[\"Bild hinzufügen\"],\"699xiu\":[\"Möchtest du die Sicherung wirklich wiederherstellen?\"],\"6Bqki7\":[\"Wochenziel erreicht!\"],\"6Hcqaf\":[\"\\n↕️ Neu: Trainings in deinem Plan neu anordnen!\\n\\nDu kannst Trainings jetzt direkt in der Planerstellungsansicht und auf den Trainingskarten neu anordnen und hast so die volle Kontrolle über die Struktur deines Trainingsplans.\\n\"],\"6MR2yM\":[\"Durchsuche fast 1.000 Übungen und filtere nach Körperteil, Zielmuskel oder Gerät. Nutze die Sortier-Chips oben, um Übungen nach Standard, Aktiver Plan, Zuletzt oder Häufig zu sortieren, damit die für dich relevantesten Übungen zuerst erscheinen. Wenn du eine Übung ersetzt, wählt der Filter automatisch den passenden Zielmuskel vor, damit du schneller Alternativen findest. Tippe auf eine Übung, um die animierte Demo, die angesprochenen Muskeln und eine vollständige Historie jeder Durchführung mit Gewicht, Wiederholungen, Zeit oder Distanz pro Satz anzuzeigen. Lade alle Übungsanimationen (~100 MB) in den Einstellungen für den Offline-Zugriff herunter.\"],\"6XIVae\":[\"Gewicht erhöhen\"],\"6_dCYd\":[\"Übersicht\"],\"6g63at\":[\"Pläne erkunden\"],\"6glEtt\":[\"Noch in der Erholung. Gewicht erstmal halten.\"],\"6igHT6\":[\"Training bearbeiten\"],\"6lAGPA\":[\"Füge ein Training hinzu, um loszulegen\"],\"6lv7us\":[\"Gewicht (\",[\"weightUnitLabel\"],\")\"],\"6q7I63\":[\"Taille\"],\"6u9LvN\":[[\"days\",\"plural\",{\"one\":[\"vor \",\"#\",\" Tag\"],\"other\":[\"vor \",\"#\",\" Tagen\"]}]],\"6uHnph\":[\"Zeit (Std:Min)\"],\"6vinCF\":[\"Tracking-Typ *\"],\"6z9W13\":[\"Neu starten\"],\"716aO7\":[\"Am meisten trainiert\"],\"75Qc-e\":[\"Wiederholungen ×2 für Volumen zählen, wenn die Einstellung aktiviert ist\"],\"77kllS\":[\"Bestwert \",[\"0\"],\" Wdh.\"],\"7F8buC\":[\"Unterarme\"],\"7FYy4K\":[\"Fehler beim Speichern des Trainings\"],\"7LBKtm\":[\"Kein Training verfügbar\"],\"7LLkrj\":[\"Griffmuskeln\"],\"7MuXko\":[\"Persönlich\"],\"7P_9OY\":[\"Di\"],\"7YT_7y\":[\"Wdh.\"],\"7Z9Tzs\":[\"Wirbelsäule\"],\"7eMo-U\":[\"Zur Startseite\"],\"7hAJKI\":[[\"0\",\"plural\",{\"one\":[\"Satz\"],\"other\":[\"Sätze\"]}]],\"7iTVa8\":[\"Sekundäre Muskeln\"],\"7p3sn_\":[\"Zeit: \",[\"0\"]],\"7x42zy\":[\"Keine Daten für diesen Zeitraum\"],\"7xB0qQ\":[\"Zielmuskel *\"],\"87VAxI\":[\"Übungsinfo\"],\"8Mlj-A\":[\"Wiederholungsziel nicht erreicht. Erstmal halten.\"],\"8Rd3od\":[\"Möchtest du dieses Training wirklich abbrechen und löschen?\"],\"8V8f_Q\":[\"Aktuell \",[\"metricLabel\"],\": \",[\"0\"]],\"8YBh-G\":[\"Wiederholungen ×2 für diese Übungen zählen\"],\"8ZJ9dh\":[\"Gewichtserfassung für Körpergewichtsübungen\"],\"8ZU8FI\":[\"Fehler beim Laden der Statistiken. Bitte versuche es erneut.\"],\"8_MCsG\":[\"\\n💾 Neu: Plan- und Trainingsentwürfe speichern und fortsetzen!\\n\\nDeine Arbeit in den Plan- und Trainings-Editoren wird jetzt automatisch als Entwurf gespeichert. Wenn du mittendrin abbrichst, wirst du gefragt, ob du weitermachen oder den Entwurf verwerfen möchtest, damit du deinen Fortschritt nie versehentlich verlierst.\\n\"],\"8aTiea\":[\"Anpassung\"],\"8cA6YX\":[\"Verfolge deine Körperzusammensetzung im Zeitverlauf im Bereich Messungen des Stats-Tabs. Verwende das Formular „Eintrag erfassen“, um Werte für jeden aktiven Messwert einzutragen, und tippe dann auf einen vergangenen Eintrag in der Verlaufsliste, um ihn anzusehen oder zu bearbeiten. Tippe auf dem Eintragsdetailbildschirm auf einen Messwert-Chip, um das Diagramm zwischen verschiedenen Messwerten zu wechseln, und nutze die Zeitbereichsauswahl zum Vergrößern oder Verkleinern. Messwerte sind in drei Typen unterteilt: Masse (Gewicht, in kg oder lbs), Länge (Umfänge wie Taille und Hüften, in cm oder Zoll) und Prozent (Körperfettanteil). Einheiten folgen deinen Gewichts- und Größeneinstellungen. Tippe auf „Messwerte verwalten“ oben im Bereich „Eintrag erfassen“, um zu steuern, welche Messwerte im Formular erscheinen. Integrierte Messwerte können ein- oder ausgeschaltet werden; du kannst auch eigene Messwerte erstellen und deren Typ auswählen. Eigene Messwerte können jederzeit ausgeblendet werden, und deine historischen Daten bleiben stets erhalten.\"],\"8jcZyX\":[\"Integrierte Messwerte\"],\"8mjpCE\":[\"MuscleQuest-Einführung\"],\"8uqQSD\":[\"Nicht alle Sätze geschafft\"],\"8yLreB\":[\"für \",[\"0\"],\"s \"],\"8yw7nc\":[\"Regenerations-Check-in\"],\"91hJvI\":[\"Ziel: \",[\"distanceMin\"],\" \",[\"distanceUnit\"]],\"94FTWy\":[\"Löschen abgeschlossen\"],\"95IyBI\":[\"Körpergewichtsübungen wie Klimmzüge oder Dips erfassen standardmäßig nur Wiederholungen. Wenn du zusätzliches Gewicht protokollieren möchtest, z. B. einen Gewichtsgürtel oder eine Gewichtsweste, öffne die Satzübersicht für diese Übung im Trainings- oder Planeditor und aktiviere Gewicht erfassen. Die Einstellung wird pro Training gespeichert, sodass manche Trainings nur Körpergewicht verwenden und andere die zusätzliche Last erfassen können. Fortschrittsgraphen und Historie spiegeln das protokollierte Gewicht wider, sobald die Einstellung aktiviert ist.\"],\"97-TIS\":[\"Du hast nicht alle Sätze geschafft. Gewicht wird leicht reduziert.\"],\"9C6X7Q\":[\"Änderungen verwerfen\"],\"9EGOsa\":[\"Kabelzug\"],\"9H3-WL\":[\"\\n⚙️ Neu: Drei neue Statistikeinstellungen!\\n\\nPasse an, wie dein Volumen und deine Statistiken berechnet werden, mit drei neuen Optionen in den Einstellungen:\\n\\n• Aufwärmsätze aus den Statistiken ausschließen, damit sie deine Zahlen nicht verfälschen.\\n• Kurzhanteln automatisch doppelt gewichten, sodass du das Gewicht einer Kurzhantel eingeben und das Gesamtgewicht automatisch berechnen lassen kannst.\\n• Wiederholungen für einseitige Arm-/Beinübungen verdoppeln, damit unilaterale Bewegungen korrekt in deinem Gesamtvolumen gezählt werden.\\n\"],\"9LmK3L\":[\"Bilder von Unsplash\"],\"9XoWik\":[\"Serratus anterior\"],\"9eQmcp\":[[\"0\"],\" Tage pro Woche\"],\"A-gAFO\":[\"Erstelle eigene Übungen über die Übungsauswahl. Gib einen Namen, ein optionales Bild, Körperteil, Zielmuskeln, sekundäre Muskeln und Gerät an. Wähle einen Tracking-Typ: Gewicht + Wdh., Zeit, Distanz, nur Wdh. oder Assistenz (berücksichtigt dein Körpergewicht für Bewegungen wie assistierte Klimmzüge). Aktiviere Einseitig für Einarm- oder Einbeinübungen; Wiederholungen können in den Statistiken automatisch verdoppelt werden. Aktiviere Gepaarte Geräte, wenn du das Gewicht eines Geräts statt des Gesamtgewichts protokollierst, zum Beispiel wenn du 20 kg für eine Kurzhantel eingibst und die App 40 kg für dein Volumen zählt.\"],\"A1-VaP\":[\"Latissimus dorsi\"],\"A1_kH4\":[\"Übungstimer\"],\"A1taO8\":[\"Suchen\"],\"AWokve\":[\"Historie aus demselben Training\"],\"AeXO77\":[\"Konto\"],\"AqyJQg\":[\"Feedback nach Übungen\"],\"Ayx1au\":[\"Möchtest du diesen Plan wirklich löschen?\"],\"B8ZQ8n\":[\"Min. Wdh.\"],\"B9LtU1\":[\"Du hast nicht gespeicherte Änderungen aus deiner letzten Sitzung. Möchtest du fortfahren?\"],\"BGO6Rp\":[\"Wie fühlen sich diese Muskeln seit deiner letzten Einheit an?\"],\"BTqs-Z\":[[\"0\",\"plural\",{\"one\":[\"#\",\" Satz\"],\"other\":[\"#\",\" Sätze\"]}]],\"BZDlVl\":[\"Hüftbeuger\"],\"BaG4Vp\":[\"Häufig\"],\"BdnYlL\":[\"Ø Dauer\"],\"BpTc_M\":[\"Hilfe durchsuchen\"],\"Bqo02Q\":[\"Timer starten\"],\"BrHgnn\":[\"\\n⏱️ Neu: Einstellbarer Pausentimer!\\n\\nEin neues Einblendmenü lässt dich die Pausendauer während des Trainings spontan anpassen. Deine individuelle Pausenzeit wird pro Satz gespeichert, sodass jeder Satz genau weiß, wie lange du pausieren möchtest.\\n\"],\"BwTx3c\":[\"Möchtest du \",[\"0\"],\" wirklich entfernen?\"],\"C4GKOD\":[[\"repRange\"],\" Wdh., \"],\"CCTop_\":[\"Zuletzt\"],\"CE-M2e\":[\"Info\"],\"CV6Ez2\":[\"Tippe in den Einstellungen auf Mit Google anmelden, um dein Konto zu verbinden. Die Anmeldung ermöglicht Cloud-Sicherungen, damit deine Daten sicher sind, wenn du das Gerät wechselst oder die App neu installierst, und dein Name wird in der Startbildschirmbegrüßung angezeigt. Die App funktioniert vollständig offline ohne Anmeldung, aber Cloud-Sicherungen sind nicht verfügbar. Deine Daten werden lokal auf deinem Gerät gespeichert und nicht mit anderen geteilt, sofern du es nicht selbst tust.\"],\"CZKXmk\":[\"Knöchel\"],\"CaKjcv\":[\"Schnelltraining\"],\"CghlOu\":[\"Unterer Bauch\"],\"CiUwqB\":[\"Zu den Trainings\"],\"D0GOrZ\":[\"Du musst dich anmelden, um diese Funktion zu nutzen\"],\"D3h1sn\":[\"Arbeits-\"],\"D45Cr4\":[\"Sekundäre Muskeln auswählen\"],\"D89zck\":[\"So\"],\"DBC3t5\":[\"Sonntag\"],\"DIS-zd\":[\"Plan konnte nicht gelöscht werden: \",[\"0\"]],\"DJMHhb\":[\"Letzte Einheit war ein Deload. Vergleich übersprungen.\"],\"DNhKLr\":[\"\\n🎯 Verbessert: Intelligentere Übungsfilter!\\n\\nWenn du eine Übung ersetzt, wählt der Filter jetzt automatisch den passenden Zielmuskel vor. Es werden nur relevante Filter basierend auf deiner aktuellen Auswahl angezeigt, sodass du deutlich schneller die richtige Alternative findest.\\n\"],\"DPfwMq\":[\"Fertig\"],\"DTtUaj\":[\"Gib mindestens einen Messwert ein.\"],\"DWFuyG\":[\"Übung entfernen\"],\"DYOFso\":[\"Knöchelstabilisatoren\"],\"DdBQBl\":[\"Wochenplan\"],\"Dh5Ge5\":[\"Schmerzen oder Formprobleme?\"],\"Di-cgt\":[\"Willkommen bei MuscleQuest!\"],\"DqgDEk\":[\"Aktuellste aus beliebigem Training\"],\"Dvc8Qg\":[\"Beschreibung:\"],\"Dy8Cvh\":[\"Quadrizeps\"],\"Dy_8Fq\":[\"SCHLIESSEN\"],\"E3kRqj\":[[\"uniqueWorkoutDaysCount\"],\" / \",[\"0\"],\" Trainingstage\"],\"EANWES\":[\"Verlauf konnte nicht geladen werden\"],\"EMyNOr\":[[\"0\"],\" \",[\"1\"],\" (für Assistenzübungen verwendet)\"],\"E_QGRL\":[\"Deaktiviert\"],\"Ef7StM\":[\"Unbekannt\"],\"EfdYnO\":[[\"0\"],[\"distanceUnit\"]],\"EkVHAp\":[\"Pausentimer-Schritt\"],\"EoQHhQ\":[\"Laufband\"],\"Euo2Um\":[\"Zeit (Min:Sek)\"],\"F37c1s\":[\"Einstellungen öffnen\"],\"F6pfE9\":[\"Aktiv\"],\"FCGpHg\":[\"Noch keine Übungen in diesem Training.\"],\"FHIDZO\":[\"Speichern und auswählen\"],\"FPsvA8\":[\"Verstanden!\"],\"Fb5zs_\":[\"\\n⚖️ Neu: Gewicht erfassen für Körpergewichtsübungen!\\n\\nFür Körpergewichtsübungen wie Klimmzüge oder Dips kannst du jetzt die Gewichtserfassung pro Training aktivieren. Perfekt für gewichtete Varianten, um das zusätzliche Gewicht zu protokollieren und den Fortschritt über Zeit zu verfolgen.\\n\"],\"Fe0wLe\":[\"Supersätze\"],\"FnTClW\":[\"Du erreichst die Ziele schon zu leicht. Zeit, ein bisschen mehr Gewicht hinzuzufügen.\"],\"Fp1hl-\":[\"Plan wird geladen...\"],\"FwCUad\":[\"Gerät ist erforderlich.\"],\"G-iXUH\":[\"Schultern\"],\"G2R9Qq\":[\"Handbeuger\"],\"G3myU-\":[\"Dienstag\"],\"G49bAb\":[\"Hebelmaschine\"],\"G6rTvo\":[\"Verfolgen (\",[\"0\"],\")\"],\"GCV1HM\":[\"Angemeldet als \",[\"0\"]],\"GCqPY4\":[\"Der Startbildschirm zeigt deinen Fortschritt in Richtung deines wöchentlichen Trainingsziels, also die Anzahl der Tage, an denen du pro Woche trainieren möchtest, festgelegt in den Einstellungen. Ein Streifen oben verfolgt, wie viele Tage du abgeschlossen hast, und hebt jeden abgeschlossenen Tag hervor. Darunter werden die Trainings deines aktiven Plans mit ihrem Abschlussstatus für die Woche aufgelistet; tippe auf Starten bei einem Training, um zu beginnen. Die darunter angezeigte Karte ändert sich je nach Status: Eine Fortsetzen-Karte erscheint, wenn eine Einheit läuft, eine Ruhetag-Karte wird an Tagen ohne geplantes Training angezeigt, und eine Training-abgeschlossen-Karte bestätigt, dass die heutige Einheit abgeschlossen ist. Wenn du dein Wochenziel erreichst, erscheint eine Wochenzusammenfassungskarte mit Gesamttrainings, Sätzen und Volumen der Woche sowie deiner Serie, die die Anzahl aufeinanderfolgender Wochen zählt, in denen du dein Ziel erreicht hast.\"],\"GGqR7k\":[\"Einzel- & Schnelltrainings\"],\"GLJjec\":[\"Bis zum Versagen\"],\"GLm0-9\":[\"Schmerzen oder Formprobleme\"],\"GNurdZ\":[\"Übung löschen\"],\"GPeIuw\":[\"Distanz\"],\"GS7yxz\":[\"Berechtigung erforderlich\"],\"GSOeV2\":[\"Oberschenkelrückseite\"],\"GVN2lL\":[\"Übung erstellen\"],\"GWvJTL\":[\"Passt so\"],\"GX9tlq\":[\"Nacken\"],\"Gd-KuS\":[\"Messwerte verwalten\"],\"Gf9sn6\":[\"Sicherungen werden gesucht...\"],\"GhCGeL\":[\"Sätze\"],\"GksdwI\":[\"Beste PR-Sätze\"],\"HNWkJr\":[\"\\n📏 Neu: Distanzverfolgung für eigene Übungen!\\n\\nEigene Übungen können jetzt den Tracking-Typ Distanz verwenden, perfekt für Ausdauer- und Konditionsbewegungen wie Laufen, Rudern oder Schlittendrücken. Protokolliere die Distanz für deine Sätze und erhalte Einblicke in deinen Fortschritt wie bei jeder anderen Übung.\\n\"],\"HYL9fJ\":[\"Trage nur eine Seite bei Einarm-/Einbeinübungen ein\"],\"Hp6ceF\":[\"Dein Training konnte nicht gespeichert werden. Bitte versuche es später erneut.\"],\"HpK_8d\":[\"Neu laden\"],\"Hplwk7\":[\"Wird wiederhergestellt. Bitte warten...\"],\"I2Hpku\":[\"Gewicht erfassen\"],\"ICkQNB\":[\"Erinnerungszeit\"],\"IFowGw\":[\"Seil\"],\"IHMx9j\":[\"Wochenserie\"],\"ILE1kp\":[\"Arme\"],\"IRiG-a\":[\"Nach Pause vibrieren\"],\"IUwGEM\":[\"Änderungen speichern\"],\"IXxATP\":[\"Eigene Übungen\"],\"IbbuFX\":[\"Wird gelöscht. Bitte warten...\"],\"IuXB4Q\":[\"Notiz hinzufügen...\"],\"Izf0kk\":[\"Keine früheren Gewichtsdaten. Erstmal halten.\"],\"JE-yVp\":[\"Messwerte verwalten\"],\"JR5hAM\":[\"1 J.\"],\"JTkSvz\":[\"Möchtest du dieses Training wirklich entfernen?\"],\"JVKmoO\":[\"Das Update konnte nicht heruntergeladen werden. Prüfe deine Internetverbindung und öffne die App erneut, um es nochmal zu versuchen.\"],\"JW7_2_\":[\"Download fehlgeschlagen\"],\"JWTR_A\":[\"Beim Herunterladen der Bilder ist ein Fehler aufgetreten.\"],\"JYRqp5\":[\"Sa\"],\"JbvV5d\":[\"Wische während einer Einheit nach links/rechts oder nutze die Pfeilschaltflächen, um zwischen Sätzen zu wechseln. Gib Gewicht und Wiederholungen ein und tippe dann auf Satz abschließen. Die gesamte vergangene Zeit wird durchgehend in der Kopfzeile angezeigt. Du kannst den Anfasser einer Übungskarte ziehen, um Übungen während der Einheit neu anzuordnen. Zeitbasierte Übungen haben eine Schaltfläche Timer starten, die einen Vorwärts-Timer mit einem Fortschrittsring öffnet, der anzeigt, wann du deine Zielzeit erreichst, du kannst aber so lange weitermachen wie du möchtest. Notizen können pro Übung über das Notizensymbol in der Übungsüberschrift, pro Training über den Trainingsübersichtsbildschirm oder pro Plan über den Planübersichtsbildschirm hinzugefügt werden. Wenn du während einer Einheit Übungen oder Sätze hinzufügst, entfernst oder neu anordnest, wirst du am Ende gefragt, ob du diese Änderungen im ursprünglichen Training oder Plan speichern möchtest.\"],\"JfDOWo\":[\"Das Update ist bereit, aber die App konnte nicht automatisch neu gestartet werden. Tippe die Schaltfläche unten, oder schließe die App und öffne sie manuell erneut.\"],\"JkpsKr\":[\"Wird heruntergeladen. Bitte warten...\"],\"JmZ_-d\":[\"Beenden\"],\"JsIy35\":[\"Du hast diesen Plan aktiviert.\"],\"JumwGu\":[\"Cardio\"],\"Jv9TrU\":[\"Schräge Bauchmuskeln\"],\"KIL-9T\":[\"Weiter: \"],\"KKalG-\":[\"Hefte Übungen im Statistiken-Tab an, um ihre Kraftentwicklung über die Zeit zu verfolgen. Jede verfolgte Übung zeigt ein Diagramm deiner Leistung im gewählten Zeitraum, deinen persönlichen Rekord aller Zeiten, deine besten Sätze und eine Liste aktueller Einheiten mit dem besten Satz pro Tag. Diagramme werden nach jedem Training, das die Übung enthält, automatisch aktualisiert.\"],\"KM1Iw2\":[\"MuscleQuest\"],\"KSqQx0\":[\"Max. Wdh.\"],\"Km7tR4\":[\"Kauf mir einen Kaffee\"],\"KmiPdE\":[\"Kurzhantel\"],\"KxWSWU\":[\"Bildschirm während des Trainings eingeschaltet lassen\"],\"LAC2eo\":[\"Trainingserinnerungen\"],\"LAHzG1\":[\"Anzeigen/Bearbeiten\"],\"LIrnc0\":[\"Noch keine Übungen hinzugefügt\"],\"LZKayn\":[\"Hilfe durchsuchen...\"],\"LcPJBt\":[\"abgeschlossene Trainings\"],\"LhMjLm\":[\"Zeit\"],\"LyPttd\":[\"Brust\"],\"M0GVkz\":[\"Wähle einen Tag, um Trainings anzuzeigen.\"],\"M1POMr\":[\"Übungsbibliothek\"],\"M4hMaA\":[\"Gib einen Namen für den eigenen Messwert ein.\"],\"M57U8X\":[\"Fasse zwei Übungen zu einem Supersatz zusammen, damit sie während einer Einheit automatisch abwechseln, ideal zum Kombinieren antagonistischer Muskeln oder für effizientes Trainieren zwischen Sätzen. Tippe auf das Drei-Punkte-Menü einer Übung im Trainings-Editor und wähle Supersatz erstellen, dann wähle die zweite Übung. Ein farbiges Label zeigt in der gesamten App, zu welchem Supersatz jede Übung gehört. Wenn du einen Satz einer Übung abschließt, wechselt die App direkt zum Supersatz-Partner.\"],\"MEt7-_\":[\"Schollenmuskel\"],\"MHk_Wu\":[\"Eintrag nicht gefunden.\"],\"MLQOxI\":[\"Hintere Schulter\"],\"MM-MTF\":[\"Supersatz \",[\"0\"]],\"MQ9jL7\":[\"Noch ein Training bis zu deinem Ziel!\"],\"MQA2H9\":[\"Plan löschen\"],\"MTqmCb\":[\"Neue Funktionen anfragen oder abstimmen\"],\"McFNQO\":[\"Verfolge deine Fitnessreise mit detaillierten Statistiken und Einblicken. Behalte die Trainingshistorie im Blick, analysiere deine Körperteil-Splits und visualisiere Fortschritte über Zeit mit Übungsfortschrittsgraphen.\"],\"MmDz7_\":[\"Hochladen. Bitte warten...\"],\"N4e_z1\":[\"Pausenzeit: \",[\"restMinutes\"],\":\",[\"0\"]],\"N85c_3\":[\"Training entfernen\"],\"NC2AI2\":[\"Länge\"],\"NIuBdI\":[\"Vorgefertigte Pläne\"],\"NKdWDE\":[\"Herz-Kreislauf-System\"],\"NLBiJk\":[\"Eintrag erfassen\"],\"NPG8SK\":[\"Körpergewicht\"],\"NQJHen\":[\"Möchtest du dieses Training wirklich neu starten?\"],\"NVOqiK\":[\"Melde dich an, um deine Daten zu sichern\"],\"NXoGPK\":[\"Übung bearbeiten\"],\"Ne5n-8\":[\"Persönliche Notizen hinzufügen\"],\"NnRCUm\":[[\"0\"],\"s\"],\"Ns5WaC\":[\"Keine Sicherungen gefunden\"],\"Nu4oKW\":[\"Beschreibung\"],\"O1GFNQ\":[\"Alle Zielmuskeln\"],\"O2TAe0\":[\"Langhantel\"],\"O2wCGL\":[\"Countdown-Töne abspielen (Übungstimer)\"],\"Otd3xX\":[\"Eine Deload-Woche ist eine geplante Erholungswoche, in der du mit reduzierter Intensität trainierst, damit sich dein Körper vor dem nächsten Trainingsblock vollständig erholen kann. Tippe auf Als Deload-Woche markieren in der Planübersicht, um die aktuelle Woche als Deload zu kennzeichnen. Während der Deload aktiv ist, erscheint der Feedbackbogen nach Übungen nicht und es werden keine neuen Progressionszustände erstellt oder aktualisiert, sodass deine Vorschlagshistorie durch die leichteren Einheiten nicht gestört wird. Der Deload wird automatisch zu Beginn der folgenden Woche zurückgesetzt und normales Feedback sowie Fortschritts-Tracking werden ohne manuellen Eingriff fortgesetzt. Wenn du deine Meinung änderst, kannst du erneut auf den Button tippen, während der Deload aktiv ist, um ihn aufzuheben.\"],\"Ov8o8m\":[\"Plan starten\"],\"OwNTSr\":[\"Im Plan speichern\"],\"Owchfv\":[\"Zuletzt verwendet\"],\"OzAZw8\":[\"Dieser Bildschirm existiert nicht.\"],\"P0mjNu\":[\"Eintrag löschen\"],\"P0svFp\":[\"Pause\"],\"P1svYv\":[\"Bauch\"],\"P247ya\":[\"Körperteil *\"],\"P3nVsi\":[\"\\n📅 Neu: Wochenplan für deinen Trainingsplan!\\n\\nDu kannst jetzt direkt im Plan-Editor bestimmten Wochentagen Trainings zuweisen. Tippe auf einen Tag, um ein Training auszuwählen oder ihn als Ruhetag zu markieren. Nutze die Auto-Vorschlag-Schaltfläche, um sofort einen ausgewogenen Wochenplan basierend auf deinem Wochenziel zu erstellen.\\n\"],\"P3omNB\":[\"Wähle ein Training zur Anzeige\"],\"PBt59F\":[\"Lieblingsübungen\"],\"PFcCy0\":[\"x \",[\"0\"],\" Wdh. \"],\"PHWHEO\":[\"Alle übernehmen\"],\"PITZNx\":[\"Brust\"],\"PN5Zzf\":[\"Gewichtseinheit\"],\"PNapeY\":[\"+ Hinzufügen\"],\"POx12e\":[\"\\n↕️ Neu: Übungen in der Trainingsübersicht neu anordnen!\\n\\nDu kannst jetzt Übungen und Supersätze per Drag-and-drop direkt in der Trainingsübersicht während einer Trainingseinheit neu anordnen.\\n\"],\"PSNHRi\":[\"* Funktionen in Entwicklung\"],\"P_0oX-\":[\"Assistenz\"],\"PiK6Ld\":[\"Sa\"],\"PruBpO\":[\"Bist du sicher, dass du diesen Messeintrag löschen möchtest?\"],\"Q1Lq8I\":[\"Gesamtzeit\"],\"Q2QJ28\":[\"Ziel-erreicht-Ton abspielen (Übungstimer)\"],\"Q8bEQa\":[\"Beim Löschen der Bilder ist ein Fehler aufgetreten.\"],\"Q9qAkA\":[\"Geschätzte Dauer: \",[\"0\"]],\"QENBWX\":[\"Trizeps\"],\"Qdwk82\":[\"Kurzhantel-Gewichtsschritt\"],\"Qjp-BQ\":[\"Satz hinzufügen\"],\"QlT4B5\":[\"Letzte Einheiten\"],\"Qmbwcr\":[\"Plan bearbeiten\"],\"QoHy-T\":[[\"weeks\",\"plural\",{\"one\":[\"vor \",\"#\",\" Woche\"],\"other\":[\"vor \",\"#\",\" Wochen\"]}]],\"QrwEaQ\":[\"Brustmuskeln\"],\"QzJCdZ\":[\"Lats\"],\"R-ABt9\":[\"Wochenziel\"],\"R0gwbc\":[\"Bizeps\"],\"RCk1J0\":[\"Schlittenmaschine\"],\"RGfnXX\":[\"(bis zum Versagen)\"],\"RIHmRj\":[\"Gutes Tempo. Versuch vor dem Gewicht eine Wiederholung pro Satz hinzuzufügen.\"],\"RM5DG6\":[\"Verfolgte Übungen\"],\"RN4XJV\":[\"Ruhetag\"],\"RU6ELr\":[\"Statistiken & Verlauf\"],\"RXkbtG\":[\"Nächstes Mal mehr fordern?\"],\"RY_JyV\":[\"Unterer Rücken\"],\"R_h8B2\":[\"Am häufigsten verwendet\"],\"Rc-8oy\":[\"Update wird heruntergeladen\"],\"RmahBs\":[[\"0\"],\": \",[\"best\"],\"s (+\",[\"delta\"],\"s, \",[\"pctStr\"],\")\"],\"Rr5U7J\":[\"Abgeschlossene Sätze erscheinen hier\"],\"Rwc-xL\":[\"Zeit-PR\"],\"RxzN1M\":[\"Aktiviert\"],\"S2uNE5\":[\"Bearbeitung fortsetzen?\"],\"SEyweA\":[\"\\n🐛 Behoben: Verschiedene Fehlerbehebungen und Verbesserungen!\\n\\nBehoben: Pausentimer-Benachrichtigung wurde nicht korrekt ausgelöst, Übungsname wurde in der Trainingsansicht falsch umgebrochen, die Breite des Trainingsabschlusskreises war falsch, Notizen wurden beim Tippen nicht korrekt aktualisiert und Trainingsdetails öffneten sich manchmal im falschen Tab. Trainings werden dank interner Leistungsverbesserungen jetzt schneller geladen.\\n\"],\"SGISp8\":[\"Du hast alles am Limit geschafft. Bleib hier und mach es dir zu eigen.\"],\"SRhtpX\":[\"Unterarme\"],\"SUd4dA\":[\"\\n📏 Neu: Körpermaße!\\n\\nVerfolge deine Körperzusammensetzung neben deinem Training im neuen Bereich Messungen im Stats-Tab.\\n\\n• Gewicht, Körperfettanteil, Taille, Hüften, Brust und mehr erfassen\\n• Vergangene Einträge antippen, um Werte zu bearbeiten oder ein Diagramm anzusehen\\n• Messgrößen verwalten und eigene hinzufügen\\n• Einheiten folgen deinen Gewichts- und Größeneinstellungen\\n\"],\"SWtay1\":[\"Nachdem du den letzten Arbeitssatz einer Übung abgeschlossen hast, erscheint ein Feedbackbogen mit zwei Fragen. Die erste fragt, wie sich die Anstrengung angefühlt hat: Leicht (du hättest mehr tun können), Passt so, Schwer (nah an deinem Limit) oder Nicht alle Sätze geschafft. Die zweite fragt nach Schmerzen: Keine Schmerzen, Leichtes Unbehagen oder Schmerzen oder Formprobleme. Wenn du Leicht antwortest, erscheint eine dritte Frage, ob du dich beim nächsten Mal mehr fordern möchtest. So kannst du die aktuelle Last bewusst beibehalten, auch wenn sich eine Einheit leicht angefühlt hat, und das System respektiert deine Entscheidung. Wenn du Schmerzen antwortest, kannst du in einem optionalen Textfeld notieren, wo du es gespürt hast. Der Bogen kann auch ohne Antworten geschlossen werden, falls du für diese Übung in dieser Einheit kein Feedback erfassen möchtest.\"],\"SZw9tS\":[\"Details anzeigen\"],\"SadoC9\":[\"Smith-Maschine\"],\"SbGW67\":[\" (bis zum Versagen) \"],\"ScJ9fj\":[\"Datenschutzrichtlinie\"],\"SlfejT\":[\"Fehler\"],\"SmkA26\":[\"1RM \",[\"0\"],\" \",[\"unit\"]],\"SoWD_0\":[\"Satz speichern\"],\"SrVzRe\":[\"Prozent\"],\"St3y2e\":[\"Name erforderlich\"],\"SvOMfA\":[[\"0\"],\" Trainings\"],\"T0cOwV\":[\"Satz löschen\"],\"T7QVyK\":[\"Wenn du ein Training öffnest, das Übungen enthält, die du kürzlich trainiert hast, erscheint ein Regenerations-Check-in-Bogen, falls diese Übungen einen ausstehenden Progressionsvorschlag haben und deine letzte Einheit mindestens 12 Stunden zurückliegt. Für jede relevante Muskelgruppe wählst du eine von drei Optionen: Frisch (vollständig erholt), Leichter Muskelkater oder Noch sehr starker Muskelkater. Wenn ein Muskel als noch sehr starker Muskelkater markiert wird, wird jeder aufwärtsgerichtete Progressionsvorschlag für Übungen, die diesen Muskel trainieren, pausiert und bei der aktuellen Last gehalten, bis du zu Beginn der folgenden Einheit neu bewertest. Frisch oder Leichter Muskelkater beeinflusst Vorschläge nicht. Tippe auf Jetzt überspringen, um den Check-in ganz zu umgehen; ein übersprungener Check-in wird wie frische Erholung behandelt, ausstehende Vorschläge bleiben unverändert.\"],\"TBTwj-\":[\"MuscleQuest auf Instagram folgen\"],\"TJLDrx\":[\"Gewicht für Volumenberechnungen verdoppeln\"],\"T_qHwF\":[\"Unterschenkel\"],\"Ta25TG\":[\"Noch kein Verlauf\"],\"TpqeIh\":[\"Fehler: \",[\"0\"]],\"Tz0i8g\":[\"Einstellungen\"],\"TzLpDD\":[\"\\n🏋️ Neu: Einzeltrainings und Schnelltrainings!\\n\\nErstelle eigenständige Trainings außerhalb deiner Trainingspläne, perfekt für flexible Trainingseinheiten, Mobilitätsarbeit oder spontane Sessions. Du findest sie auf dem Pläne-Bildschirm.\\n\\nOder starte ein Schnelltraining direkt vom Startbildschirm, füge Übungen spontan hinzu und speichere es am Ende optional als eigenständiges Training.\\n\"],\"U0HZma\":[\"Tracking\"],\"U4QKsL\":[\"Einführung ein-/ausblenden\"],\"U8BTVm\":[\"Verbleibende Pausenzeit:\"],\"UCtAiM\":[\"Um Pausentimer-Benachrichtigungen zu aktivieren, erteile Benachrichtigungsberechtigungen in deinen Geräteeinstellungen.\"],\"UD8kHo\":[\"Weiter: \",[\"workoutName\"],\" am \",[\"0\"]],\"URmyfc\":[\"Details\"],\"US8F_H\":[\"Mehr Wiederholungen vorgeschlagen\"],\"USXXjt\":[\"Keine Ergebnisse für „\",[\"query\"],\"“\"],\"U_-GrY\":[\"Bitte warten, während die neueste Version heruntergeladen wird...\"],\"UlnAQR\":[\"Training konnte nicht gelöscht werden. Bitte versuche es erneut.\"],\"UneMBz\":[\"Aktiver Plan\"],\"UnnFak\":[\"Toller Start in die Woche!\"],\"Uorrgj\":[\"Rhomboiden\"],\"Uu14s5\":[[\"0\",\"plural\",{\"one\":[\"#\",\" Satz\"],\"other\":[\"#\",\" Sätze\"]}]],\"UyvU3-\":[\"Hilfe & Info\"],\"UzNvmf\":[\"• Daten sichern und wiederherstellen\"],\"V6wjuJ\":[\"Tracking-Typ ist erforderlich.\"],\"V6xf0O\":[\"Diese Übung ist bereits in deinem Training. Bitte wähle eine andere.\"],\"V8MVAm\":[\"obere Brust\"],\"V8dVu4\":[\"\\n🔗 Neu: Supersätze!\\n\\nVerbinde zwei Übungen direkt im Plan-Editor zu einem Supersatz. Die Sätze beider Übungen werden synchron gehalten, und Supersätze sind überall in der App mit einem visuellen Indikator klar gruppiert.\\n\"],\"V8yTm6\":[\"Suche löschen\"],\"VAcXNz\":[\"Mittwoch\"],\"VCJb5r\":[\"Satz \",[\"0\"],\" von \",[\"totalSets\"]],\"VDkJml\":[\"Adaptive Progression analysiert dein Anstrengungsfeedback über aufeinanderfolgende Einheiten und schlägt vor, wann du dein Gewicht, deine Wiederholungen oder Sätze erhöhen solltest. Aktiviere es in den Einstellungen unter Adaptive Progression. Sobald aktiviert, erscheint nach jeder Übung in planbasierten Trainings eine kurze Feedbackabfrage. Das System benötigt zwei Einheiten mit demselben Signal, bevor es eine Steigerung empfiehlt, sodass einmalige leichte Tage herausgefiltert werden und eine gleichbleibende Leistung vor einem Vorschlag sichergestellt wird. Schmerzen oder nicht abgeschlossene Sätze werden sofort berücksichtigt, unabhängig von deiner Einheitenhistorie. Ein Vorschlag wird deinem Training nie ohne deine ausdrückliche Bestätigung angewendet. Du kannst auch deinen bevorzugten Gewichtsschritt pro Gerätekategorie im selben Abschnitt der Einstellungen konfigurieren, zum Beispiel 2,5 kg für Langhantelübungen und 2,0 kg für Kurzhanteln.\"],\"VFlRXJ\":[\"Diesmal so weiterhalten.\"],\"VhVOxx\":[\"Deine Reise nach Swoletown beginnt heute!\"],\"VhfZbD\":[\"Größe: ~100 MB\"],\"W-pY1H\":[\"Eigene Übung konnte nicht gespeichert werden. Bitte versuche es erneut.\"],\"W0qDyY\":[\"Startbildschirm & Wochenziel\"],\"W3QcBP\":[\"Planübersicht\"],\"W3u9nh\":[\"Bis zum Versagen, \"],\"WDciil\":[\"\\n📋 Neu: \\\"Mehr\\\"-Menü und Hilfe & Info-Bereich!\\n\\nEs gibt einen neuen \\\"Mehr\\\"-Tab in der Navigationsleiste. Tippe darauf, um ein Einblendmenü zu öffnen, in dem du Einstellungen und einen brandneuen Hilfe & Info-Bereich findest.\\n\\nDie Einstellungen wurden von der Tab-Leiste hierher verschoben, und Hilfe & Info deckt alles ab, von Plänen und Trainings bis hin zu Statistiken und deinem Konto, mit einer Suchleiste, um schnell Antworten zu finden.\\n\"],\"WHwUfF\":[\"Fehler beim Laden der Übungsdetails\"],\"WIbOhZ\":[\"Adaptive Progression\"],\"WJp2MH\":[\"Größeneinheit\"],\"WKHqM-\":[\"Gewicht\"],\"WOi4Vm\":[\"Name *\"],\"WSzg3A\":[\"Distanz (\",[\"distanceUnit\"],\")\"],\"WU-3OC\":[\"Einarmig / einbeinig\"],\"WaIjmh\":[\"Wade (R)\"],\"WoEX6M\":[\"Gewichts- und Wiederholungsanpassungen vorschlagen\"],\"WzcO-J\":[\"Plan erstellen\"],\"X9kySA\":[\"Favoriten\"],\"X9r6cu\":[[\"goal\",\"plural\",{\"one\":[[\"completed\"],\" von \",\"#\",\" Training diese Woche\"],\"other\":[[\"completed\"],\" von \",\"#\",\" Trainings diese Woche\"]}]],\"XHHEUg\":[\"Plan anpassen\"],\"XJQdl_\":[\"Hintergrundbenachrichtigung nach Pause senden\"],\"XNRDYn\":[\"Handstrecker\"],\"XdavYY\":[\"Trainings\"],\"Xdcdfd\":[\"Sätze & Übungen\"],\"XoEooZ\":[\"Zeit (s)\"],\"Xu14OQ\":[[\"0\",\"plural\",{\"one\":[\"#\",\" Wdh.\"],\"other\":[\"#\",\" Wdh.\"]}]],\"Xu2iGM\":[\"Gewicht hinzufügen\"],\"Xv4OIW\":[\"Training läuft\"],\"Xwd4Hm\":[\"Rotatorenmanschette\"],\"Y6QE0T\":[\"Gerät auswählen\"],\"YANNVr\":[\"Training\"],\"YDnEIW\":[\"Bester Zuwachs\"],\"YIix5Y\":[\"Suchen...\"],\"YLIqcF\":[\"Willkommen zurück\",[\"userName\"]],\"YXJbW8\":[\"Eigenständige Trainings existieren außerhalb von Plänen und erscheinen neben deinen Plänen auf dem Pläne-Bildschirm. Erstelle eines, indem du auf Neues Training tippst, einen Namen vergibst und Übungen hinzufügst; du kannst es jederzeit starten, ohne einen aktiven Plan zu benötigen. Eine geschätzte Dauer wird bei jedem eigenständigen Training angezeigt, damit du deine Zeit vor dem Start planen kannst. Schnelltrainings ermöglichen dir, eine Einheit sofort vom Startbildschirm aus zu starten: Tippe auf Schnelltraining, füge Übungen unterwegs hinzu, und am Ende kannst du es als eigenständiges Training für die Zukunft speichern oder einfach verwerfen. Wie Pläne speichert der Trainings-Editor automatisch einen Entwurf, damit du sicher gehen und zurückkehren kannst, ohne deine Arbeit zu verlieren.\"],\"YYzBv9\":[\"Mo\"],\"YekWWq\":[[\"0\",\"plural\",{\"one\":[\"#\",\" Wdh.\"],\"other\":[\"#\",\" Wdh.\"]}]],\"YiPU_R\":[\"Schultern\"],\"YnHdfF\":[\"Satz \",[\"0\"]],\"Yr-t8O\":[\"Füße\"],\"YuP-pS\":[\"„\",[\"label\"],\"“ wird aus dem Eingabeformular ausgeblendet. Deine historischen Daten bleiben erhalten.\"],\"Z3FXyt\":[\"Wird geladen...\"],\"Z8RW4m\":[\"Nachdem du ein Training abgeschlossen hast, zeigt die Trainingsübersicht eine Karte für die nächste Einheit mit umsetzbaren Vorschlägen für deine Übungen. Jede Zeile zeigt den Namen der Übung, die vorgeschlagene Änderung (ein neues Zielgewicht, einen breiteren Wiederholungsbereich oder einen Hinweis zur Gewichtsreduzierung) und eine kurze Erklärung, warum die Änderung vorgeschlagen wird. Tippe auf Übernehmen, um den Vorschlag für die nächste Einheit anzuwenden, oder auf Ablehnen, um ihn zu ignorieren. Angenommene Vorschläge werden beim nächsten Öffnen des Trainings automatisch in die Gewichts- und Wiederholungsfelder vorgefüllt, sodass du die Einheit bereits mit der richtigen Last startest. Der Button Alle übernehmen oben wendet alle Vorschläge auf einmal an. Vorschläge, die empfehlen, die aktuelle Last beizubehalten, erscheinen nicht in der Karte, da hierfür keine Aktion erforderlich ist.\"],\"ZAWGCX\":[[\"0\"],\" Sekunden\"],\"ZAvcCf\":[[\"0\"],[\"weightUnit\"],\" × \",[\"1\"]],\"ZI8idP\":[\"Frisch, vollständig erholt\"],\"Zm9Eu3\":[\"Schaltflächengröße beim Training\"],\"Zvc_N1\":[\"1RM (\",[\"weightUnitLabel\"],\")\"],\"_-nVtu\":[\"Hat sich leicht angefühlt. Erstmal halten und nächste Einheit bestätigen.\"],\"_2fO4v\":[\"Trainingsübersicht\"],\"_D5y8a\":[\"Standard-Sätze\"],\"_K9jUO\":[\"Oberkörperergometer\"],\"_P2B4j\":[[\"biggestGainLabel\"],\" 1RM\"],\"_RhvUo\":[\"Einstellungen\"],\"_UGS0C\":[\"Trainingsname\"],\"_W-KPJ\":[\"Noch keine Messungen. Tippe, um deinen ersten Eintrag zu erfassen.\"],\"_WRCmH\":[[\"0\"],\" \",[\"1\"],\" | \",[\"2\"],\" Wdh.\"],\"_XczSN\":[\"Zielmuskel auswählen\"],\"_Xvx5t\":[\"\\n📈 Neu: Adaptive Progression!\\n\\nMuscleQuest kann dir jetzt vorschlagen, wann du dein Gewicht oder deine Wiederholungen erhöhen solltest, basierend auf dem Gefühl deiner Einheiten. Beantworte nach jeder Übung zwei kurze Fragen zu Anstrengung und Schmerzen. Sobald du dasselbe Signal zwei Einheiten in Folge gemeldet hast, schlägt die App eine Änderung vor. Alle Vorschläge erscheinen im Trainingsübersichtsbildschirm, wo du jeden einzeln annehmen oder ablehnen kannst. Angenommene Vorschläge werden automatisch in deine nächste Einheit vorgefüllt.\\n\\nEin Regenerations-Check-in zu Beginn deines nächsten Trainings lässt dich Muskelkater einbeziehen, bevor ein Vorschlag angewendet wird. Du kannst auch eine ganze Woche als Deload in der Planübersicht markieren, was Feedback und Fortschritts-Tracking für diese Woche pausiert.\\n\\nAktiviere es in den Einstellungen unter Adaptive Progression und konfiguriere deinen bevorzugten Gewichtsschritt pro Gerätekategorie.\\n\"],\"_cF7Rs\":[\"Volumen\"],\"_f5DAr\":[\"Abgeschlossen am: \",[\"formattedDate\"]],\"a2Fu8q\":[\"Du kannst dich jederzeit über die Einstellungsseite anmelden, wenn du es jetzt überspringen möchtest.\"],\"a5BPTT\":[\"Kettlebell\"],\"a8TA11\":[\"Nächste Einheit\"],\"aAIQg2\":[\"Erscheinungsbild\"],\"aMwZcE\":[\"Oberarm (L)\"],\"aN_GPe\":[\"Wo hast du es gespürt?\"],\"ahW3x6\":[\"\\n📅 Neu: Trainingskalender!\\n\\nTippe auf das Kalendersymbol im Bereich Trainingshistorie auf dem Statistiken-Tab, um deine Trainingshistorie nach Datum zu durchsuchen. Tage mit Trainings sind hervorgehoben, und ein Tippen auf einen Tag zeigt die an diesem Datum protokollierten Einheiten.\\n\"],\"aj6ZJx\":[\"Mit Google anmelden\"],\"b3e7Re\":[\"App neu starten\"],\"b9OAHS\":[\"Aufwärmsatz hinzufügen\"],\"bFeIdj\":[\"Dropsatz\"],\"bQdjFX\":[[\"0\"],\" Notiz\"],\"bRAv_4\":[\"Training \",[\"0\"]],\"bZS72M\":[[\"setsCount\",\"plural\",{\"one\":[\"#\",\" Satz\"],\"other\":[\"#\",\" Sätze\"]}]],\"bosqpS\":[\"Noch keine Trainings abgeschlossen. Starte dein erstes Training!\"],\"bqb_ci\":[\"\\n🐛 Behoben: Schaltflächen in der Trainingsansicht und Satz-Bearbeiten-Fenster!\\n\\nEin Fehler wurde behoben, bei dem alle Schaltflächen (erhöhen/verringern, nächster/vorheriger Satz, Satz abschließen) nach dem Abschließen eines Satzes nicht mehr funktionierten. Außerdem wurde ein Fehler im Satz-Bearbeiten-Fenster behoben. Satzübergänge erfolgen jetzt sofort für einen flüssigeren Trainingsablauf.\\n\"],\"bwd2oE\":[\"Pausentimer beendet!\"],\"bzSI52\":[\"Verwerfen\"],\"c2TGz5\":[[\"completed\"],\" Trainings diese Woche. Du hast dein Ziel geknackt!\"],\"cCbON-\":[\"\\n🔥 Verbessert: Aufwärmsatz-Verwaltung!\\n\\nAufwärmsätze werden visuell gruppiert und getrennt von Arbeitssätzen dargestellt, und \\\"Auf alle anwenden\\\" ermöglicht das gleichzeitige Bearbeiten von Aufwärm- oder Arbeitssätzen unabhängig voneinander.\\n\"],\"cF5b-5\":[[\"weeklyGoal\",\"plural\",{\"one\":[\"Auto-Vorschlag (\",\"#\",\" Tag)\"],\"other\":[\"Auto-Vorschlag (\",\"#\",\" Tage)\"]}]],\"cI6f7l\":[\"30 T.\"],\"cU45Co\":[\"Training hinzufügen\"],\"cUD6H0\":[\"Mach dich bereit...\"],\"cUY9dI\":[\"Möchtest du diese Übung wirklich löschen?\"],\"ckJ-os\":[\"Muskeln\"],\"cnGeoo\":[\"Löschen\"],\"crwali\":[\"Erinnerungen\"],\"ctrAML\":[\"Vergiss nicht, deinen Fortschritt zu verfolgen!\"],\"cyR8-W\":[\"\\n🕐 Neu: Geschätzte Trainingsdauer!\\n\\nJede Trainingskarte zeigt jetzt eine geschätzte Dauer an, damit du deine Einheiten auf einen Blick planen kannst, bevor du startest.\\n\"],\"d1z1ZY\":[\"Der Pausentimer startet nach jedem Satz automatisch und zählt bis null herunter. Jeder Satz merkt sich seine eigene Pausendauer, sodass verschiedene Sätze innerhalb derselben Übung unterschiedliche Pausenzeiten haben können. Nutze die ±-Schaltflächen, um die verbleibende Zeit während der Pause spontan anzupassen. Konfiguriere die Standard-Pausendauer, den Timer-Schritt und ob am Ende ein Sound, eine Vibration oder eine Hintergrundbenachrichtigung ausgelöst wird; jede Option ist in den Einstellungen unabhängig umschaltbar.\"],\"dEgA5A\":[\"Abbrechen\"],\"dH9Y4t\":[\"Keine Trainings an diesem Tag.\"],\"dVK-Er\":[\"Es ist ein Darstellungsfehler aufgetreten. Drücke die Schaltfläche, um neu zu laden.\"],\"dXCD6-\":[\"Alle Übungsanimationen herunterladen\"],\"dXoieq\":[\"Zusammenfassung\"],\"dYOPCE\":[\"Assistenz \",[\"0\"],\" \",[\"1\"],\" | Widerstand \",[\"2\"],\" \",[\"3\"],\" | \",[\"4\"],\" Wdh.\"],\"dbWo0h\":[\"Mit Google anmelden\"],\"deoJBi\":[[\"0\"],\" Wdh.\"],\"dfunKV\":[\"Gewicht/Wdh.\"],\"dpOqdQ\":[\"Bis zum Versagen\"],\"dqjuBA\":[\"90 T.\"],\"dx0cCC\":[\"Halt den Schwung aufrecht!\"],\"e0dGJ7\":[\"Vorteile der Anmeldung:\"],\"e0l-Z0\":[[\"scheduledDays\",\"plural\",{\"one\":[\"#\",\" Tag/Woche\"],\"other\":[\"#\",\" Tage/Woche\"]}]],\"e5h2IT\":[[\"0\"],\" Notizen\"],\"e9qdcV\":[\"Leichtes Unbehagen\"],\"eLA0I2\":[\"Bilder herunterladen\"],\"eQm4BH\":[\"Nach dem Beenden eines Trainings zeigt ein Übersichtsbildschirm die Gesamtdauer, abgeschlossene Sätze und das Gesamtvolumen. Wenn du dasselbe Training schon früher gemacht hast, zeigt eine Vergleichszeile, wie jede Kennzahl zur vorherigen Einheit abschneidet. Ein Wochenzielbanner zeigt, wie viele Einheiten du diese Woche im Vergleich zu deinem Ziel protokolliert hast. Tippe auf eine Übung in der Liste, um sie aufzuklappen und jeden Satz im Detail zu prüfen. Beim Abschließen eines Schnelltrainings wirst du gefragt, ob du es als eigenständiges Training für die Zukunft speichern oder verwerfen möchtest.\"],\"eYbd7b\":[\"So\"],\"ecUA8p\":[\"Heute\"],\"ehOkF-\":[\"Grundlagen\"],\"emOtYn\":[\"Vorgefertigte Pläne\"],\"ez-cQL\":[\"\\n🔔 Neu: Trainings-Erinnerungsbenachrichtigungen!\\n\\nVerpasse keine Einheit mehr. Richte Erinnerungsbenachrichtigungen für deine Trainings direkt in der App ein. Wähle die Tage, an denen du erinnert werden möchtest, und lege eine Uhrzeit fest.\\n\"],\"f2yjAZ\":[\"Keine Schmerzen\"],\"f7pPKh\":[\"Oberschenkel (L)\"],\"f8Vl8d\":[\"Name des Messwerts\"],\"fFHHFp\":[\"Messungen\"],\"fPpo2L\":[\"Supersatz\"],\"fSu2Jl\":[\"Eine neue Version wurde heruntergeladen. Tippe die Schaltfläche unten, um die App neu zu starten und das Update anzuwenden.\"],\"fXVIZq\":[\"Werte\"],\"f_bxrN\":[\"Name ist erforderlich.\"],\"feWdkU\":[\"Training neu starten\"],\"fj5byd\":[\"k.A.\"],\"fpMgHS\":[\"Mo\"],\"fqSfXY\":[\"Ersetzen\"],\"fsJAR5\":[\"Langhantel-Gewichtsschritt\"],\"ftiGCv\":[\"Alle Geräte\"],\"fvyzOr\":[\"oberer Rücken\"],\"g36TSx\":[\"Distanzeinheit\"],\"g3UF2V\":[\"Übernehmen\"],\"gCVtjC\":[[\"0\"],\" Sätze\"],\"gEOgEq\":[[\"0\"],\" Übungen\",[\"1\"]],\"gQYPDg\":[\"−\",[\"restTimerIncrement\"],\"s\"],\"gTdjGc\":[\"Training konnte nicht gelöscht werden. Bitte versuche es erneut.\"],\"giOl9F\":[\"Oberschenkel (R)\"],\"gkn1WJ\":[\"Übung bereits hinzugefügt\"],\"gzBfh2\":[\"Keine Sätze verfügbar\"],\"h-DKuf\":[\"vs. letztes \\\"\",[\"0\"],\"\\\"\"],\"h2ALJf\":[\"Gesäß\"],\"h7CU4q\":[\"Wie hat sich das angefühlt?\"],\"hBjQ0O\":[[\"0\",\"plural\",{\"one\":[\"#\",\" Training\"],\"other\":[\"#\",\" Trainings\"]}]],\"hF_t4W\":[\"Volumen (\",[\"volumeUnit\"],\")\"],\"hLONcx\":[\"Sichern und wiederherstellen\"],\"hPXEuO\":[\"Gepaart mit \",[\"0\"]],\"hXzOVo\":[\"Weiter\"],\"hnJ2UC\":[\"Brachialis\"],\"hnlGzG\":[\"Jetzt überspringen\"],\"hnrFBk\":[\"Erinnerungstage\"],\"hpsdvR\":[\"\\n📋 Neu: Trainingsdetails vom Startbildschirm anzeigen!\\n\\nDu kannst jetzt auf ein beliebiges kürzliches Training auf dem Startbildschirm tippen, um alle Details anzuzeigen. Jede Trainings- und Satzübersicht hat außerdem eine neue Details-Schaltfläche für schnellen Zugriff auf Übungsinformationen.\\n\"],\"hsoeHo\":[\"Trainingsdetails\"],\"hty0d5\":[\"Montag\"],\"hvfche\":[[\"scheduledCount\",\"plural\",{\"one\":[\"#\",\" Tag/Woche\"],\"other\":[\"#\",\" Tage/Woche\"]}]],\"i-tNaY\":[\"Assistenz/Wdh.\"],\"i09UfG\":[\"Gerät:\"],\"i0qMbr\":[\"Startseite\"],\"i4Vk1Q\":[\"Übungen des aktiven Plans\"],\"i6f8rt\":[\"Training wird gestartet...\"],\"iGokZG\":[\"Kabel-Gewichtsschritt\"],\"iHmyze\":[\"Übungen\"],\"iQyKX1\":[\"Du hast dich fürs Halten entschieden. Gewicht bleibt so.\"],\"iV1Jat\":[\"Möchtest du diesen Satz wirklich löschen?\"],\"iYfCFU\":[\"Einführung auf Startbildschirm anzeigen\"],\"i_48Se\":[\"Aktiver Plan: \",[\"0\"]],\"i_nB8P\":[\"Kein Zeitplan festgelegt\"],\"ifRQL2\":[\"Dropsatz, \"],\"ikOJPT\":[\"Schienbeine\"],\"irLwtB\":[\"Trainingsplan\"],\"irrqfe\":[\"Eigene Messwerte\"],\"iuwbqi\":[\"Training konnte nicht gespeichert werden. Bitte versuche es erneut.\"],\"ivpCYv\":[\"Änderungen verwerfen?\"],\"j-MPXl\":[\"Sichern & Wiederherstellen\"],\"jDTG0T\":[\"Progressionsvorschläge\"],\"jDh_CH\":[\"Pläne sind strukturierte Trainingsprogramme aus mehreren Trainings. Um einen zu erstellen, gehe zum Pläne-Tab, tippe auf Neuer Plan, gib einen Namen ein und wähle ein Titelbild. Füge Trainings zum Plan hinzu und dann Übungen zu jedem Training mit Ziel-Sätzen und Wiederholungen. Nutze die Hoch/Runter-Pfeile auf einer Trainingskarte, um sie neu anzuordnen, oder die X-Schaltfläche, um sie zu entfernen, beide befinden sich oben rechts auf der Karte. Weise Trainings im Zeitplan-Editor bestimmten Wochentagen zu: Tippe auf einen Tag, um ein Training auszuwählen oder ihn als Ruhetag zu lassen, und nutze den Auto-Vorschlag, um sie gleichmäßig zu verteilen. Wenn dein Plan fertig ist, öffne ihn und tippe auf Aktivieren. Du kannst vom Planübersichtsbildschirm auch Notizen zum Plan hinzufügen. Jede Trainingskarte zeigt eine geschätzte Dauer neben der Übungsanzahl, damit du die Länge der Einheit auf einen Blick abschätzen kannst. Nutze die Ansichtssymbole neben der Überschrift „Deine Trainingspläne“, um zwischen Karussell-, Listen- und Rasteransicht zu wechseln; deine gewählte Ansicht wird automatisch gespeichert. Dein Fortschritt im Plan-Editor wird automatisch als Entwurf gespeichert, wenn du ihn mittendrin verlässt, wirst du gefragt, ob du weitermachen oder verwerfen und vom letzten gespeicherten Stand starten möchtest.\"],\"jYjrmQ\":[\"Letzte Sicherung: \",[\"0\"]],\"jfzZZ0\":[\"Anmeldung überspringen\"],\"jpVuia\":[\"Änderungen im Training speichern?\"],\"jxTU3u\":[\"Treppensteiger\"],\"jzJENZ\":[\"Deinen Fortschritt verfolgen\"],\"k4kpgL\":[\"Willkommen bei MuscleQuest, deinem persönlichen Krafttrainingsbegleiter. Nutze diesen Leitfaden, um die Funktionen zu entdecken und das Beste aus deinem Training herauszuholen.\"],\"k7Oi68\":[\"Oberschenkel\"],\"kDJ_Ja\":[\"Solide Einheit. Gewicht beibehalten.\"],\"kFoQmI\":[\"Abduktoren\"],\"kILzHz\":[\"Hinzufügen (\",[\"0\"],\")\"],\"kQe_xM\":[\"Schmerzen gemeldet. Gewicht bleibt unverändert, bis es dir besser geht.\"],\"kSi1ha\":[\"+\",[\"suggestedWeight\"],[\"unit\"],\" vorgeschlagen\"],\"kdwbaT\":[\"Alle überspringen\"],\"kf4tdd\":[\"Tracking-Typ auswählen\"],\"kfxr8q\":[\"\\n📊 Neu: Trainingsübersicht!\\n\\nNach dem Abschließen eines Trainings siehst du jetzt eine vollständige Übersicht deiner Einheit: Gesamtdauer, Sätze und Volumen sowie einen Vergleich mit deiner vorherigen Einheit. Tippe auf eine Übung, um ihre einzelnen Sätze und Gewichte anzuzeigen.\\n\"],\"kg0oKA\":[\" (bis zum Versagen)\"],\"kkDQ8m\":[\"Donnerstag\"],\"konUZ1\":[\"Standard-Pausenzeit\"],\"kvpjYu\":[\"Übungsname eingeben\"],\"l1P93s\":[\"Gewicht pro Hantel/Kabel eingeben, nicht gesamt\"],\"l75CjT\":[\"Ja\"],\"lWy5a1\":[\"Pläne\"],\"lY9GM0\":[\"Zielmuskel ist erforderlich.\"],\"lkz6PL\":[\"Dauer\"],\"llGZy3\":[\"Noch keine Übungen verfolgt. Tippe auf + Hinzufügen, um zu starten.\"],\"loRbvf\":[\"Zur Startseite!\"],\"m0YANP\":[\"Du kannst diesen Einführungsbildschirm jederzeit über die Einstellungsseite im Bereich Darstellung ausblenden. Wenn du die Einführung erneut ansehen möchtest, kannst du sie dort wieder aktivieren.\"],\"m16xKo\":[\"Hinzufügen\"],\"mAoTHw\":[\"Einige Bilder konnten nicht gelöscht werden. Fehlgeschlagene Übungs-IDs: \",[\"0\"]],\"mDmPnX\":[\"Pro Woche (Ø)\"],\"mEQ95z\":[\"Bild konnte nicht gespeichert werden. Bitte versuche es erneut.\"],\"mF1US0\":[\"Immer aktuellste Übungshistorie verwenden\"],\"mFQ4KK\":[\"Gewicht für Volumen verdoppeln, wenn die Einstellung aktiviert ist\"],\"mK5j7_\":[\"\\n🔃 Neu: Übungsbibliothek sortieren!\\n\\nDie Übungsbibliothek hat jetzt Sortier-Chips, damit du Übungen schneller findest. Sortiere nach Standard, Aktiver Plan, Zuletzt oder Häufig, um die für dich relevantesten Übungen oben zu sehen.\\n\"],\"mRTnNi\":[\"Gepaarte Geräte\"],\"mSit7t\":[\"Daten konnten nicht abgerufen werden. Bitte versuche es erneut.\"],\"mSj_dN\":[[\"0\",\"plural\",{\"one\":[\"+\",\"#\",\" mehr\"],\"other\":[\"+\",\"#\",\" mehr\"]}]],\"mT57-Q\":[\"Zu den Einstellungen\"],\"mob_am\":[\"Fr\"],\"mwX_w0\":[\"Bild ändern\"],\"mzI_c-\":[\"Herunterladen\"],\"n00ykB\":[\"Deine Trainings\"],\"n1BXGc\":[\"Trainings-Split (nach Sätzen)\"],\"nAEGxm\":[\"Ja, mehr herausfordern\"],\"nJSX83\":[\"Trainingserinnerungen\"],\"nO6sra\":[[\"0\"],\": \",[\"best\"],\" \",[\"best\",\"plural\",{\"one\":[\"Wdh.\"],\"other\":[\"Wdh.\"]}],\" (+\",[\"delta\"],\", \",[\"pctStr\"],\")\"],\"nPGn3W\":[\"Aufwärmen, \"],\"nkkWxK\":[\"Starte deine Fitnessreise mit professionell gestalteten Trainingsplänen. Wähle aus einer Vielzahl von Optionen, die auf verschiedene Ziele und Erfahrungsstufen zugeschnitten sind. \"],\"nmdLhD\":[\"Wdh.: \",[\"repRange\"]],\"o2XlZw\":[\"Möchtest du dieses Training wirklich löschen? Diese Aktion kann nicht rückgängig gemacht werden.\"],\"oB9lvM\":[\"Aufwärmsätze aus den Statistiken ausschließen\"],\"oOHOWH\":[\"\\n✨ Neu: Animationen in der Trainingseinheit!\\n\\nDas Wechseln zwischen Sätzen erfolgt jetzt mit flüssigen Übergangsanimationen. Wische nach links oder rechts, um zwischen Sätzen zu wechseln, oder nutze die vorhandenen Pfeilschaltflächen für denselben Effekt.\\n\"],\"oOYj_W\":[\"Trainings konnten nicht geladen werden\"],\"oRTTfk\":[\"Der Statistiken-Tab zeigt Gesamttrainings, Gesamtvolumen, Gesamtzeit und durchschnittliche Einheitsdauer über einen auswählbaren Zeitraum, mit einer Periode-zu-Periode-Differenz für jede Kennzahl. Diagramme zeigen wöchentliches Volumen und deinen Trainings-Split nach Körperteil. Durchsuche deine vollständige Trainingshistorie und tippe auf eine Einheit, um jeden Satz im Detail einzusehen, einschließlich Gewichte, Wiederholungen, Zeit oder Distanz. Du kannst abgeschlossene Trainings vom Verlaufsdetailsbildschirm bearbeiten oder löschen. Tippe auf das Kalendersymbol im Bereich Trainingshistorie, um eine Kalenderansicht zu öffnen: Tage mit Trainings sind mit einem gelben Kreis hervorgehoben, und ein Tippen auf einen Tag zeigt die an diesem Datum protokollierten Trainings.\"],\"oRvy2V\":[\"Übungs-Tracking\"],\"oXsjxN\":[\"Wade (L)\"],\"oYZpj8\":[\"• Herausforderungen und Abzeichen *\"],\"ocEDZS\":[\"Satz entfernen\"],\"oeF-HP\":[\"Anmeldung fehlgeschlagen. Bitte versuche es erneut.\"],\"oeeBm6\":[\"\\n🔔 Neu: In-App-Update-Benachrichtigungen!\\n\\nEin neues Update-Fenster erscheint jetzt, wenn ein Over-the-Air-Update verfügbar ist, damit du immer weißt, wann Verbesserungen heruntergeladen wurden und bereit zur Anwendung sind.\\n\"],\"ofVE0I\":[\"Löscht das Suchfeld\"],\"oiHVLP\":[\"Supersatz entfernen\"],\"oqKRAn\":[\"Jeder Satz kann als Aufwärmsatz, Dropsatz, bis zum Versagen oder eine beliebige Kombination davon markiert werden. Das Badge neben einem Satz zeigt seinen aktuellen Typ. Um den Typ während einer Einheit zu ändern, tippe auf das Menü (⋮) und schalte die entsprechende Option ein oder aus. Beim Erstellen eines Plans nutze die Checkboxen im Satz-Editor; tippe auf Aufwärmsatz hinzufügen, um einen dedizierten Aufwärmsatz oben in der Liste einzufügen. Aufwärmsätze werden visuell gruppiert und von Arbeitssätzen getrennt, und die Option Auf alle anwenden im Bearbeitungsfenster betrifft nur Sätze desselben Typs. Aufwärmsätze können in den Einstellungen von Volumen- und Statistikberechnungen ausgeschlossen werden.\"],\"oqUOKk\":[\"Dropsatz\"],\"osILGh\":[\"Zieldistanz (\",[\"distanceUnit\"],\")\"],\"ovBPCi\":[\"Standard\"],\"ovGl86\":[\"(bis zum Versagen) \"],\"p5nYkr\":[\"Alle anzeigen\"],\"p72uBF\":[\"Keine Trainingspläne gefunden\"],\"p8F9k_\":[\"Hals\"],\"pBGx0B\":[\"\\n🗂️ Neu: Planansichtsoptionen!\\n\\nDer Pläne-Bildschirm hat jetzt drei Anzeigemodi. Nutze die Symbole neben der Überschrift „Deine Trainingspläne“, um zwischen Karussell-, Listen- und Rasteransicht zu wechseln. Deine bevorzugte Darstellung wird automatisch gespeichert.\\n\"],\"pE7tOx\":[\"Aktives Training\"],\"pIX6X7\":[\"MuscleQuest auf Instagram\"],\"pIuJtP\":[\"Training nicht gefunden.\"],\"pY_gY7\":[\"Wiederholungs-PR\"],\"p_C-3G\":[\"Leichter Muskelkater\"],\"pbzA-s\":[\"Optionale Beschreibung\"],\"pfXEaj\":[\"Körpergewicht\"],\"pkD36F\":[\"Möchtest du \\\"\",[\"0\"],\"\\\" wirklich löschen?\"],\"poLmqL\":[\"Vom Gerät auswählen\"],\"psxXnW\":[\"Melde dich in den Einstellungen mit Google an, um Cloud-Sicherungen all deiner Trainingsdaten zu aktivieren. Tippe jederzeit auf Sichern, um eine Momentaufnahme zu speichern; das Datum deiner letzten Sicherung wird unter der Schaltfläche angezeigt. Tippe auf Wiederherstellen, um deine neueste Sicherung herunterzuladen und anzuwenden; bestätige die Eingabeaufforderung und die App lädt mit deinen wiederhergestellten Daten neu. Deine Sicherungen werden sicher gespeichert und sind mit deinem Google-Konto verknüpft. Wenn du das Gerät wechselst oder die App neu installierst, melde dich einfach mit demselben Google-Konto an und tippe auf Wiederherstellen.\"],\"pvW0MQ\":[\"Satz abschließen\"],\"pwfNCc\":[\"+\",[\"restTimerIncrement\"],\"s\"],\"pz0gzh\":[\"Messwert ausblenden\"],\"pzA-xG\":[\"Halte wichtige Hinweise, Erinnerungen und persönliche Erkenntnisse für deine Übungen, Trainings und Trainingspläne fest. Bleib fokussiert und verfeinere deine Technik mit eigenen Notizen auf deiner Fitnessreise. Notizen werden automatisch gespeichert, wenn du fertig bist.\"],\"q3pTrs\":[\"Alle Bilder erfolgreich gelöscht!\"],\"qIATCE\":[\"\\n📋 Verbessert: Intelligenteres Vorbefüllen mit Trainingshistorie!\\n\\nSatzfelder werden jetzt intelligenter vorbefüllt. Hat eine Übung keine Historie im aktuellen Training, wird automatisch auf die letzte Ausführung dieser Übung aus einer beliebigen Einheit zurückgegriffen. Du startest also immer mit einer sinnvollen Referenz.\\n\\nEine neue Einstellung im Bereich „Training\\\" ermöglicht es, stets die aktuellste Historie aus allen Trainings zu verwenden, unabhängig davon, aus welcher Routine sie stammt.\\n\"],\"qJb6G2\":[\"Erneut versuchen\"],\"qQ5ALI\":[\"Änderungen im Plan speichern?\"],\"qQ8Xkc\":[\"Maschinen-Gewichtsschritt\"],\"qQLn75\":[\"Körperteil auswählen\"],\"qUSLnH\":[\"Beschreibung eingeben\"],\"qZMNNX\":[\"Oberarm (R)\"],\"qaT7mT\":[\"Du verlierst alles, was du bisher eingegeben hast.\"],\"qdalvN\":[\"Deload-Woche aktiv. Vergleich pausiert.\"],\"qeygIa\":[\"Mi\"],\"qlKdB2\":[\"Nein, so lassen\"],\"qtNMEu\":[\"Quads\"],\"qvcKXF\":[\"Tolle Arbeit heute!\"],\"qvolLq\":[\"Masse\"],\"rCROTr\":[\"Kauf mir einen Kaffee\"],\"rLgPvm\":[\"Sichern\"],\"rPj8yN\":[\"Weitere Übungen\"],\"rZzMre\":[\"Oberarme\"],\"rickIy\":[\"Training wird gespeichert...\"],\"rlNJuG\":[\"Eintragsdetails\"],\"rtypiF\":[\"🎉 Neuigkeiten\"],\"rzjsxH\":[\"Zeit (Minuten:Sekunden)\"],\"s53UX_\":[\"Volumen pro Woche (\",[\"volumeUnit\"],\")\"],\"s6qW4K\":[\"Der Tracking-Typ kann nach der Erstellung nicht mehr geändert werden.\"],\"sAkBSh\":[[\"0\",\"plural\",{\"one\":[\"#\",\" Übung\"],\"other\":[\"#\",\" Übungen\"]}]],\"sHe-bW\":[\"Gib einen Namen ein, um es als wiederverwendbares Training zu speichern.\"],\"sRh2_9\":[\"Deine Trainingspläne\"],\"sey42b\":[\"Training abgeschlossen!\"],\"slcKOz\":[\"Um Trainingserinnerungen zu aktivieren, erteile Benachrichtigungsberechtigungen in deinen Geräteeinstellungen.\"],\"spvawa\":[\"Deload-Trainings aus Übungsstatistiken ausschließen\"],\"t-VWgS\":[\"Trainings pro Woche\"],\"t1WtPm\":[\"vs. PR\"],\"t7OD9_\":[\"Trapez\"],\"t9rBTs\":[[\"0\"],\": \",[\"best\"],[\"unit\"],\" (+\",[\"delta\"],[\"unit\"],\", \",[\"pctStr\"],\")\"],\"tCHU1b\":[\"Körperteile\"],\"tLdxsV\":[\"MuscleQuest.app\"],\"tXkhj_\":[\"Starten\"],\"t_YqKh\":[\"Entfernen\"],\"tcZ16z\":[\"\\n💾 Neu: Trainingsänderungen in deinen Plan zurückspeichern!\\n\\nWenn du eine Einheit beendest, in der du Übungen oder Sätze hinzugefügt, entfernt oder neu angeordnet hast, wirst du gefragt, ob du diese Änderungen in den ursprünglichen Plan oder das eigenständige Training zurückspeichern möchtest, damit dein Training automatisch aktuell bleibt.\\n\"],\"tfDRzk\":[\"Speichern\"],\"tj-hng\":[\"Handgelenke\"],\"tlcz2i\":[\"Keine Daten für diesen Zeitraum.\"],\"twA2hZ\":[\"Beine\"],\"tyb5gZ\":[\"Pausenzeit (Minuten:Sekunden)\"],\"u0F1Ey\":[\"Do\"],\"u0Vng2\":[\"Noch sehr starker Muskelkater\"],\"u16ECS\":[\"Download abgeschlossen\"],\"uGkCJQ\":[\"EZ-Stange\"],\"uIVkKI\":[\"Anmelden\"],\"uP80lb\":[\"Update bereit\"],\"ue_JxE\":[\"Satzübersicht\"],\"ufHAsd\":[\"Name des Trainingsplans\"],\"uyJsf6\":[\"Über\"],\"v2e7py\":[\"Plan erstellen\"],\"v39wLo\":[\"Fortsetzen\"],\"v67n_r\":[\"Richte wiederkehrende Trainingserinnerungen in den Einstellungen ein. Wähle die Wochentage, an denen du erinnert werden möchtest, über die Tag-Chips aus und lege eine Uhrzeit fest. Du erhältst eine Benachrichtigung zu dieser Uhrzeit an jedem ausgewählten Tag. Die Benachrichtigungsberechtigung muss erteilt sein, damit Erinnerungen funktionieren.\"],\"vCrBBg\":[\"Übernimm die volle Kontrolle über dein Training, indem du deinen eigenen personalisierten Plan erstellst. Wähle Übungen, lege Wiederholungsbereiche, Pausenzeiten und mehr fest, um einen Plan zu erstellen, der perfekt zu deinen Fitnesszielen passt.\"],\"vFte8a\":[\"Supersatz erstellen\"],\"vLSd93\":[\"Satztypen\"],\"vLyv1R\":[\"Ausblenden\"],\"vPWLpz\":[\"Maßeinheiten\"],\"vV1rrV\":[[\"suggestedRepsMin\"],\" Wdh. vorgeschlagen\"],\"vbOlQu\":[\"Bild konnte nicht ausgewählt werden. Bitte versuche es erneut.\"],\"vbfDgJ\":[\"Noch keine Trainings\"],\"vcpc5o\":[\"Menü schließen\"],\"vmatEA\":[\"Daten werden geladen, bitte warten...\"],\"vq2WxD\":[\"Di\"],\"vqV9pV\":[\"Neuer Plan\"],\"vyQFtJ\":[[\"0\"],\" abgeschlossen!\"],\"w55mIe\":[\"aktiver Plan\"],\"w95UZr\":[\"Bestwert \",[\"maxDist\"],[\"distanceUnit\"]],\"wBAK8Q\":[\"Körperteil ist erforderlich.\"],\"wL3cK8\":[\"Aktuell\"],\"wL7wrB\":[\"Gewichtsschritt\"],\"wUwyC0\":[\"Serie\"],\"wYwS57\":[\"Einstellungen anpassen\"],\"wckWOP\":[\"Verwalten\"],\"wgbq86\":[\"Neustart fehlgeschlagen\"],\"wpLp4M\":[\"Assistenz\"],\"wvxWx2\":[\"Trapezmuskel\"],\"wxKcF0\":[\"Über den Entwickler\"],\"x5LlnE\":[\"Statistikoptionen\"],\"xGVfLh\":[\"Fortfahren\"],\"xM_hqb\":[\"Assistenz \"],\"xMidTh\":[\"Alle Körperteile\"],\"xRGBk4\":[\"Fertige Pläne erkunden\"],\"xVhQZV\":[\"Fr\"],\"xYxQCZ\":[[\"0\"],\" \",[\"1\"]],\"xx7Wjz\":[\"Übungsdetails konnten nicht geladen werden.\"],\"y04OSh\":[\"Trainingshistorie\"],\"y3CwcG\":[\"Bestwert \",[\"maxTime\"],\"s\"],\"y8le-Z\":[\"Training\"],\"yAeHP4\":[\"Keine Daten verfügbar.\"],\"yBSiRY\":[\"Deload-Woche\"],\"yKu_3Y\":[\"Wiederherstellen\"],\"yUWaVv\":[\"Crosstrainer\"],\"yWCES-\":[\"Sekundäre Muskeln:\"],\"y_0uwd\":[\"Gestern\"],\"y_f0Ik\":[\"Öffnet sich in deinem Browser\"],\"yf16RU\":[\"Aufwärmen\"],\"ygCKqB\":[\"Stopp\"],\"yhrNcC\":[\"Fehler beim Speichern des Bildes\"],\"ykve2U\":[\"Satz hinzufügen\"],\"yu1K_Z\":[\"Keine Sätze\"],\"z1-0FW\":[\"Verfolge deine Trainings, behalte den Fortschritt im Blick und erreiche deine Fitnessziele. MuscleQuest macht deine Fitnessreise einfach und effektiv.\\n\\nWische durch die Einführungskarten, um mehr über die App zu erfahren.\"],\"z44QLk\":[\"Sicherung wiederherstellen\"],\"z5uobd\":[\"Tippe auf das Sternsymbol oben rechts in einer Übungsinfoansicht, um sie als Favorit zu markieren. Favoritisierte Übungen erscheinen oben in der Übungsauswahl beim Erstellen oder Bearbeiten von Trainings, damit die Übungen, die du am häufigsten verwendest, immer schnell erreichbar sind.\"],\"zAhZMD\":[\"• Trainingspläne mit anderen teilen *\"],\"zAt78k\":[\"Pausentimer\"],\"zDq2cZ\":[\"Taille\"],\"zEHmq8\":[\"Der Pläne-Tab enthält eine Bibliothek vorgefertigter Trainingsprogramme, die du sofort starten kannst. Scrolle an Deine Trainingspläne vorbei, um den Bereich Vorgefertigte Pläne zu finden. Tippe auf ein Programm, um seine Trainings und den Zeitplan in der Vorschau anzuzeigen, dann tippe auf Aktivieren, um es zu deinem aktiven Plan zu machen. Du kannst einen vorgefertigten Plan bearbeiten, um Übungen, Sätze oder den Wochenplan anzupassen. Dabei wird eine Kopie des vorgefertigten Plans erstellt, die du ohne Auswirkungen auf das Original ändern kannst, sodass du bei Bedarf immer zur Standardversion zurückkehren kannst.\"],\"zIFP3N\":[\"Lege dein wöchentliches Trainingsziel fest und gib dein Körpergewicht ein, um genaue Statistiken und Empfehlungen zu erhalten. Du kannst auch deine Gewichtserhöhungseinstellungen anpassen, bevorzugte Einheiten wählen und vieles mehr.\"],\"zNnnyF\":[\"Waden\"],\"zOwYV3\":[\"Du hast dieses Training geändert. Änderungen für zukünftige Sitzungen speichern?\"],\"zga9sT\":[\"OK\"],\"zhIkkH\":[\"Ziel: \",[\"goalLabel\"],[\"0\"]],\"zsaR7t\":[\"Gerät & Tracking\"],\"zt6jiv\":[\"Kein Fortschritts-Tracking für diesen Übungstyp.\"],\"zuwyEJ\":[\"Füge Übungen hinzu, um loszulegen\"],\"zzDlyQ\":[\"Erfolg\"]}")}; \ No newline at end of file +/*eslint-disable*/module.exports={messages:JSON.parse("{\"-2Ut5a\":[\"Der Einblicke-Streifen oben auf dem Statistiken-Tab gibt vier schnelle Highlights für den ausgewählten Zeitraum: deine durchschnittlichen Trainings pro Woche, deinen größten Kraftzuwachs bei verfolgten Übungen, das Körperteil, das du am meisten trainiert hast, und deine aktuelle Wochenserie. Diese werden nach jedem Training automatisch aktualisiert.\"],\"-5kO8P\":[\"Samstag\"],\"-BjMj_\":[\"Training erstellen\"],\"-FjWgX\":[\"Do\"],\"-Tpjjs\":[[\"0\"],\" Sätze\"],\"-WSEJS\":[\"Training löschen\"],\"-Xejuf\":[\"Hüften\"],\"-XvJee\":[\"Bestwert \",[\"0\"],[\"weightUnit\"],\" × \",[\"1\"]],\"-rhD7g\":[\"Keine ausstehenden Freundschaftsanfragen.\"],\"-svcUj\":[\"Dieses Training speichern?\"],\"03mQOq\":[\"Plan konnte nicht aktiviert werden: \",[\"0\"]],\"06EUQy\":[\"Bester PR aller Zeiten\"],\"0EHHPz\":[\"Adduktoren\"],\"0EPpEZ\":[\"Eigenen Messwert hinzufügen\"],\"0EcUWz\":[\"Änderungen verwerfen?\"],\"0OeId4\":[\"Eigenen Plan erstellen\"],\"0P1btN\":[\"\\n🔔 Neu: Übungstimer-Töne!\\n\\nDer Übungstimer gibt jetzt Audiosignale aus, damit du auf Kurs bleibst. Ein Countdown-Piep, wenn der Timer sich null nähert, und ein Sound, wenn du dein Ziel erreichst. Schalte jeden Ton unabhängig in den Einstellungen ein oder aus.\\n\"],\"0SaB4K\":[\"Aufwärmsatz\"],\"0U938S\":[\"Wähle mindestens einen Tag aus\"],\"0V9gKq\":[\"\\n🔵 Neu: Übungstimer-Fenster!\\n\\nZeitbasierte Übungen zeigen jetzt ein eigenes Countdown-Fenster mit einem Fortschrittsring, damit du deinen Einsatz leicht verfolgen und bei zeitgesteuerten Sätzen im Rhythmus bleiben kannst.\\n\"],\"0caMy7\":[\"Verlauf\"],\"0dHvKo\":[\"Zielmuskel:\"],\"0eRpDV\":[\"Schwer, nah am Limit\"],\"0f7U0k\":[\"Mi\"],\"0tJJBW\":[\"Zurück: \"],\"0vGEy2\":[\"\\n📊 Neu: Verbesserter Statistiken-Bildschirm!\\n\\nDer Statistiken-Bildschirm wurde mit einem neuen Look und verbesserten Einblicken neu gestaltet. Erkunde deine Trainingshistorie mit besseren Diagrammen, klareren Zusammenfassungen und detaillierteren Aufschlüsselungen deines Fortschritts über die Zeit.\\n\"],\"14ytif\":[\"Training starten\"],\"1DF4Ah\":[\"Alle geteilten Daten löschen\"],\"1DPB1m\":[\"\\n🗂️ Neu: Fünf neue vorgefertigte Trainingspläne!\\n\\nFünf neue sofort einsatzbereite Pläne sind jetzt verfügbar: 5-Tage-Bro-Split, 5-Tage-Push/Pull/Beine, 6-Tage-Split, Körpergewicht und Nur Kurzhanteln. Ob du zuhause oder im Gym trainierst, es gibt einen Plan, mit dem du sofort loslegen kannst.\\n\"],\"1FnEj9\":[\"Körpermaße\"],\"1Kx4Hp\":[\"Fehler beim Abrufen von \",[\"0\"],\": \",[\"1\"]],\"1Mx10o\":[\"Statistiken anzeigen\"],\"1QfxQT\":[\"Schließen\"],\"1Se9J7\":[\"Heimtrainer\"],\"1UzENP\":[\"Nein\"],\"1gbc4_\":[\"Neues Training\"],\"1hW6-f\":[\"Einige Bilder konnten nach mehreren Versuchen nicht heruntergeladen werden. Fehlgeschlagene Übungs-IDs: \",[\"0\"]],\"1j3Ob3\":[\"Trainingskalender\"],\"1mm2JF\":[\"Deltamuskeln\"],\"296mtr\":[\"Trapezstange\"],\"29Hx9U\":[\"Statistiken\"],\"2FYpfJ\":[\"Mehr\"],\"2ZZM6V\":[\"Core\"],\"2bnWaQ\":[[\"completedCount\"],\"/\",[\"0\"],\" Sätze abgeschlossen\"],\"2cupe5\":[\"Auf alle \",[\"0\"],\" Sätze anwenden\"],\"2dPYb7\":[\"Noch keine Messungen. Erfasse deinen ersten Eintrag oben.\"],\"2dX9Kv\":[\"Rücken\"],\"2eB2c7\":[\"Trainiere ohne Plan! Erstelle eigenständige Trainings außerhalb deiner Trainingspläne, perfekt für Mobilitätssessions, Aufwärmen oder alles Spontane.\\n\\nOder starte direkt ein Schnelltraining vom Startbildschirm, füge Übungen unterwegs hinzu, und speichere es optional als eigenständiges Training, wenn du fertig bist.\"],\"2gSypt\":[\"Gerät *\"],\"2j0v05\":[\"Alle Bilder erfolgreich heruntergeladen!\"],\"2lfUf3\":[[\"streak\",\"plural\",{\"one\":[\"#\",\" Woche in Folge\"],\"other\":[\"#\",\" Wochen in Folge\"]}]],\"2saL1j\":[\"1RM\"],\"2vS4Oc\":[\"Leicht, hätte mehr gekonnt\"],\"2wR0QE\":[\"Übung hinzufügen\"],\"30xwUM\":[\"Möchtest du wirklich alle animierten Bilder löschen? Einzelbilder werden beim Anzeigen automatisch erneut heruntergeladen.\"],\"39y5bn\":[\"Freitag\"],\"3A79ox\":[\"Gewicht reduzieren\"],\"3L-1Z1\":[\"Fehler beim Laden der Übungen: \",[\"0\"]],\"3RoflF\":[\"\\n📈 Neu: Übungshistorie in der Infoansicht!\\n\\nDie Übungsinfoansicht enthält jetzt eine vollständige Übungshistorie mit Gewicht, Wiederholungen, Zeit und Distanz für jeden Satz aus vergangenen Einheiten. Zugriff während eines Trainings, über deinen Plan oder überall dort, wo Übungsinfos verfügbar sind.\\n\"],\"3ezHPX\":[\"Ton nach der Pause abspielen\"],\"3hJ166\":[\"\\n🔍 Verbessert: Intelligentere Übungssuche & einfacher Zugriff auf die Übungsbibliothek!\\n\\nDie Übungssuche erkennt jetzt gängige Abkürzungen wie RDL, OHP, DB und KB, korrigiert kleine Tippfehler und sortiert die Ergebnisse nach Relevanz, sodass die beste Übereinstimmung immer zuerst erscheint.\\n\\nDu kannst die vollständige Übungsbibliothek jederzeit über das Menü durchsuchen, ohne dich in einem Training oder Plan befinden zu müssen.\\n\"],\"3hJypY\":[\"Einblicke\"],\"43lYJ-\":[\"Willkommen\",[\"userName\"]],\"4BgR4M\":[\"Du hast dein Wochenziel erreicht. Unglaubliche Leistung!\"],\"4GTHgi\":[\"Übungstimer-Countdown\"],\"4M4P8M\":[\"Keine Werte eingegeben\"],\"4OjqAQ\":[\"Weiter bearbeiten\"],\"4Y9aig\":[\"Aktualisiert \",[\"0\"]],\"4_WLmI\":[\"Körpergewicht\"],\"4j0zbV\":[\"Plan wird gespeichert...\"],\"4jkyRj\":[\"Aufwärmen\"],\"4mrNi3\":[[\"suggestedRepsMin\"],\"-\",[\"suggestedRepsMax\"],\" Wdh. vorgeschlagen\"],\"4oRoD4\":[\"Konfiguriere Gewichts-, Größen- und Distanzeinheiten, Standard-Sätze pro Übung, Standard-Pausenzeit und die Gewichtserhöhung der ±-Schaltflächen während einer Einheit. Passe die Schaltflächengröße (Standard, Groß oder Sehr groß) an und aktiviere Bildschirm eingeschaltet lassen, damit das Display nicht mitten im Training ausgeht. Unter Statistiken kannst du Aufwärmsätze vom Volumen ausschließen, Wiederholungen für einseitige Übungen verdoppeln oder das Gewicht für gepaarte Geräte verdoppeln, nützlich wenn du das Gewicht pro Kurzhantel statt das Gesamtgewicht protokollierst. Lege hier dein Körpergewicht fest, es wird zur Berechnung der effektiven Last bei Assistenzübungen verwendet.\"],\"4sGdeG\":[\"Körperfett\"],\"5-5naM\":[\"Freunde & Social\"],\"50_FGa\":[\"Übung\"],\"538Jsv\":[\"Training abbrechen\"],\"58iwz8\":[\"Fehler beim Laden der Pläne\"],\"5Hrw0r\":[\"Zu meinen Trainings hinzufügen\"],\"5SgD0L\":[\"Du hast nicht gespeicherte Änderungen. Möchtest du sie wirklich verwerfen?\"],\"5Z05pb\":[\"Tippe, um Hilfethemen zu filtern\"],\"5aB9II\":[\"Zeit für deinen nächsten Satz!\"],\"5b4J4v\":[\"Gesamt\"],\"5lWFkC\":[\"Anmelden\"],\"5w2VTM\":[\"Möchtest du wirklich alle animierten Bilder herunterladen? Das kann eine Weile dauern.\"],\"5yIPLp\":[\"Hoppla!\"],\"66llpx\":[\"Bild hinzufügen\"],\"699xiu\":[\"Möchtest du die Sicherung wirklich wiederherstellen?\"],\"6Bqki7\":[\"Wochenziel erreicht!\"],\"6Hcqaf\":[\"\\n↕️ Neu: Trainings in deinem Plan neu anordnen!\\n\\nDu kannst Trainings jetzt direkt in der Planerstellungsansicht und auf den Trainingskarten neu anordnen und hast so die volle Kontrolle über die Struktur deines Trainingsplans.\\n\"],\"6MR2yM\":[\"Durchsuche fast 1.000 Übungen und filtere nach Körperteil, Zielmuskel oder Gerät. Nutze die Sortier-Chips oben, um Übungen nach Standard, Aktiver Plan, Zuletzt oder Häufig zu sortieren, damit die für dich relevantesten Übungen zuerst erscheinen. Wenn du eine Übung ersetzt, wählt der Filter automatisch den passenden Zielmuskel vor, damit du schneller Alternativen findest. Tippe auf eine Übung, um die animierte Demo, die angesprochenen Muskeln und eine vollständige Historie jeder Durchführung mit Gewicht, Wiederholungen, Zeit oder Distanz pro Satz anzuzeigen. Lade alle Übungsanimationen (~100 MB) in den Einstellungen für den Offline-Zugriff herunter.\"],\"6XIVae\":[\"Gewicht erhöhen\"],\"6_dCYd\":[\"Übersicht\"],\"6g63at\":[\"Pläne erkunden\"],\"6glEtt\":[\"Noch in der Erholung. Gewicht erstmal halten.\"],\"6igHT6\":[\"Training bearbeiten\"],\"6lAGPA\":[\"Füge ein Training hinzu, um loszulegen\"],\"6lv7us\":[\"Gewicht (\",[\"weightUnitLabel\"],\")\"],\"6q7I63\":[\"Taille\"],\"6u9LvN\":[[\"days\",\"plural\",{\"one\":[\"vor \",\"#\",\" Tag\"],\"other\":[\"vor \",\"#\",\" Tagen\"]}]],\"6uHnph\":[\"Zeit (Std:Min)\"],\"6vinCF\":[\"Tracking-Typ *\"],\"6z9W13\":[\"Neu starten\"],\"716aO7\":[\"Am meisten trainiert\"],\"75Qc-e\":[\"Wiederholungen ×2 für Volumen zählen, wenn die Einstellung aktiviert ist\"],\"77kllS\":[\"Bestwert \",[\"0\"],\" Wdh.\"],\"7F8buC\":[\"Unterarme\"],\"7FYy4K\":[\"Fehler beim Speichern des Trainings\"],\"7LBKtm\":[\"Kein Training verfügbar\"],\"7LLkrj\":[\"Griffmuskeln\"],\"7MuXko\":[\"Persönlich\"],\"7P_9OY\":[\"Di\"],\"7YT_7y\":[\"Wdh.\"],\"7Z9Tzs\":[\"Wirbelsäule\"],\"7eMo-U\":[\"Zur Startseite\"],\"7hAJKI\":[[\"0\",\"plural\",{\"one\":[\"Satz\"],\"other\":[\"Sätze\"]}]],\"7iTVa8\":[\"Sekundäre Muskeln\"],\"7p3sn_\":[\"Zeit: \",[\"0\"]],\"7x42zy\":[\"Keine Daten für diesen Zeitraum\"],\"7xB0qQ\":[\"Zielmuskel *\"],\"87VAxI\":[\"Übungsinfo\"],\"8BG66J\":[\"Noch keine abgeschlossenen Trainings geteilt\"],\"8JaOZF\":[\"Freundesprofil\"],\"8Mlj-A\":[\"Wiederholungsziel nicht erreicht. Erstmal halten.\"],\"8Rd3od\":[\"Möchtest du dieses Training wirklich abbrechen und löschen?\"],\"8V8f_Q\":[\"Aktuell \",[\"metricLabel\"],\": \",[\"0\"]],\"8YBh-G\":[\"Wiederholungen ×2 für diese Übungen zählen\"],\"8ZJ9dh\":[\"Gewichtserfassung für Körpergewichtsübungen\"],\"8ZU8FI\":[\"Fehler beim Laden der Statistiken. Bitte versuche es erneut.\"],\"8_MCsG\":[\"\\n💾 Neu: Plan- und Trainingsentwürfe speichern und fortsetzen!\\n\\nDeine Arbeit in den Plan- und Trainings-Editoren wird jetzt automatisch als Entwurf gespeichert. Wenn du mittendrin abbrichst, wirst du gefragt, ob du weitermachen oder den Entwurf verwerfen möchtest, damit du deinen Fortschritt nie versehentlich verlierst.\\n\"],\"8aTiea\":[\"Anpassung\"],\"8cA6YX\":[\"Verfolge deine Körperzusammensetzung im Zeitverlauf im Bereich Messungen des Stats-Tabs. Verwende das Formular „Eintrag erfassen“, um Werte für jeden aktiven Messwert einzutragen, und tippe dann auf einen vergangenen Eintrag in der Verlaufsliste, um ihn anzusehen oder zu bearbeiten. Tippe auf dem Eintragsdetailbildschirm auf einen Messwert-Chip, um das Diagramm zwischen verschiedenen Messwerten zu wechseln, und nutze die Zeitbereichsauswahl zum Vergrößern oder Verkleinern. Messwerte sind in drei Typen unterteilt: Masse (Gewicht, in kg oder lbs), Länge (Umfänge wie Taille und Hüften, in cm oder Zoll) und Prozent (Körperfettanteil). Einheiten folgen deinen Gewichts- und Größeneinstellungen. Tippe auf „Messwerte verwalten“ oben im Bereich „Eintrag erfassen“, um zu steuern, welche Messwerte im Formular erscheinen. Integrierte Messwerte können ein- oder ausgeschaltet werden; du kannst auch eigene Messwerte erstellen und deren Typ auswählen. Eigene Messwerte können jederzeit ausgeblendet werden, und deine historischen Daten bleiben stets erhalten.\"],\"8jcZyX\":[\"Integrierte Messwerte\"],\"8mjpCE\":[\"MuscleQuest-Einführung\"],\"8uqQSD\":[\"Nicht alle Sätze geschafft\"],\"8wbSm2\":[\"Noch keine Kraftdaten geteilt\"],\"8yLreB\":[\"für \",[\"0\"],\"s \"],\"8yw7nc\":[\"Regenerations-Check-in\"],\"91hJvI\":[\"Ziel: \",[\"distanceMin\"],\" \",[\"distanceUnit\"]],\"94FTWy\":[\"Löschen abgeschlossen\"],\"95IyBI\":[\"Körpergewichtsübungen wie Klimmzüge oder Dips erfassen standardmäßig nur Wiederholungen. Wenn du zusätzliches Gewicht protokollieren möchtest, z. B. einen Gewichtsgürtel oder eine Gewichtsweste, öffne die Satzübersicht für diese Übung im Trainings- oder Planeditor und aktiviere Gewicht erfassen. Die Einstellung wird pro Training gespeichert, sodass manche Trainings nur Körpergewicht verwenden und andere die zusätzliche Last erfassen können. Fortschrittsgraphen und Historie spiegeln das protokollierte Gewicht wider, sobald die Einstellung aktiviert ist.\"],\"97-TIS\":[\"Du hast nicht alle Sätze geschafft. Gewicht wird leicht reduziert.\"],\"9Anet0\":[\"Gerät\"],\"9C6X7Q\":[\"Änderungen verwerfen\"],\"9EGOsa\":[\"Kabelzug\"],\"9H3-WL\":[\"\\n⚙️ Neu: Drei neue Statistikeinstellungen!\\n\\nPasse an, wie dein Volumen und deine Statistiken berechnet werden, mit drei neuen Optionen in den Einstellungen:\\n\\n• Aufwärmsätze aus den Statistiken ausschließen, damit sie deine Zahlen nicht verfälschen.\\n• Kurzhanteln automatisch doppelt gewichten, sodass du das Gewicht einer Kurzhantel eingeben und das Gesamtgewicht automatisch berechnen lassen kannst.\\n• Wiederholungen für einseitige Arm-/Beinübungen verdoppeln, damit unilaterale Bewegungen korrekt in deinem Gesamtvolumen gezählt werden.\\n\"],\"9HyV9h\":[\"Aktivieren, um jedem eigenständigen Training einen Veröffentlichungsschalter hinzuzufügen.\"],\"9LmK3L\":[\"Bilder von Unsplash\"],\"9XoWik\":[\"Serratus anterior\"],\"9eQmcp\":[[\"0\"],\" Tage pro Woche\"],\"A-gAFO\":[\"Erstelle eigene Übungen über die Übungsauswahl. Gib einen Namen, ein optionales Bild, Körperteil, Zielmuskeln, sekundäre Muskeln und Gerät an. Wähle einen Tracking-Typ: Gewicht + Wdh., Zeit, Distanz, nur Wdh. oder Assistenz (berücksichtigt dein Körpergewicht für Bewegungen wie assistierte Klimmzüge). Aktiviere Einseitig für Einarm- oder Einbeinübungen; Wiederholungen können in den Statistiken automatisch verdoppelt werden. Aktiviere Gepaarte Geräte, wenn du das Gewicht eines Geräts statt des Gesamtgewichts protokollierst, zum Beispiel wenn du 20 kg für eine Kurzhantel eingibst und die App 40 kg für dein Volumen zählt.\"],\"A1-VaP\":[\"Latissimus dorsi\"],\"A1_kH4\":[\"Übungstimer\"],\"A1taO8\":[\"Suchen\"],\"ATGYL1\":[\"E-Mail-Adresse\"],\"AWokve\":[\"Historie aus demselben Training\"],\"AeXO77\":[\"Konto\"],\"AqyJQg\":[\"Feedback nach Übungen\"],\"Ayx1au\":[\"Möchtest du diesen Plan wirklich löschen?\"],\"B8ZQ8n\":[\"Min. Wdh.\"],\"B9LtU1\":[\"Du hast nicht gespeicherte Änderungen aus deiner letzten Sitzung. Möchtest du fortfahren?\"],\"BEVzjL\":[\"Import fehlgeschlagen\"],\"BGO6Rp\":[\"Wie fühlen sich diese Muskeln seit deiner letzten Einheit an?\"],\"BTqs-Z\":[[\"0\",\"plural\",{\"one\":[\"#\",\" Satz\"],\"other\":[\"#\",\" Sätze\"]}]],\"BZDlVl\":[\"Hüftbeuger\"],\"BaG4Vp\":[\"Häufig\"],\"BdnYlL\":[\"Ø Dauer\"],\"BpTc_M\":[\"Hilfe durchsuchen\"],\"Bqo02Q\":[\"Timer starten\"],\"BrHgnn\":[\"\\n⏱️ Neu: Einstellbarer Pausentimer!\\n\\nEin neues Einblendmenü lässt dich die Pausendauer während des Trainings spontan anpassen. Deine individuelle Pausenzeit wird pro Satz gespeichert, sodass jeder Satz genau weiß, wie lange du pausieren möchtest.\\n\"],\"BwTx3c\":[\"Möchtest du \",[\"0\"],\" wirklich entfernen?\"],\"C4GKOD\":[[\"repRange\"],\" Wdh., \"],\"CCTop_\":[\"Zuletzt\"],\"CE-M2e\":[\"Info\"],\"CFL873\":[\"Aktivieren, um abgeschlossene Trainings automatisch zu teilen.\"],\"CV6Ez2\":[\"Tippe in den Einstellungen auf Mit Google anmelden, um dein Konto zu verbinden. Die Anmeldung ermöglicht Cloud-Sicherungen, damit deine Daten sicher sind, wenn du das Gerät wechselst oder die App neu installierst, und dein Name wird in der Startbildschirmbegrüßung angezeigt. Die App funktioniert vollständig offline ohne Anmeldung, aber Cloud-Sicherungen sind nicht verfügbar. Deine Daten werden lokal auf deinem Gerät gespeichert und nicht mit anderen geteilt, sofern du es nicht selbst tust.\"],\"CZKXmk\":[\"Knöchel\"],\"CaKjcv\":[\"Schnelltraining\"],\"CghlOu\":[\"Unterer Bauch\"],\"CiUwqB\":[\"Zu den Trainings\"],\"CxQnhY\":[\"\\n👥 Neu: Freunde & Social Sharing!\\n\\nFüge Freunde hinzu, indem du nach ihrem Nutzernamen im Freunde-Tab im Menü suchst. Sende eine Anfrage – sobald sie angenommen wird, könnt ihr gegenseitig eure geteilten Inhalte durchstöbern. Ein Badge am Freunde-Menüpunkt zeigt ausstehende eingehende Anfragen.\\n\\nTeile deine Pläne, eigenständigen Trainings, eigene Übungen, Körpermaße und Kraft-PRs, indem du in der jeweiligen Ansicht oder in den Datenschutzeinstellungen im Konto-Bereich der Einstellungen den Teilen-Schalter aktivierst. Geteilte Inhalte werden automatisch synchronisiert, wenn sie sich ändern, und ein Wolken-Symbol auf Plan- und Trainingskarten zeigt an, was gerade veröffentlicht ist. Du kannst alle geteilten Daten einer Kategorie jederzeit über die Datenschutzeinstellungen löschen.\\n\\nTippe auf den Namen eines akzeptierten Freundes, um sein Profil zu öffnen und seine Pläne, eigenständigen Trainings oder eigenen Übungen direkt in deine eigene Bibliothek zu importieren.\\n\"],\"D-GweR\":[\"Melde dich an, um die Freunde-Funktion zu nutzen.\"],\"D0GOrZ\":[\"Du musst dich anmelden, um diese Funktion zu nutzen\"],\"D3h1sn\":[\"Arbeits-\"],\"D45Cr4\":[\"Sekundäre Muskeln auswählen\"],\"D89zck\":[\"So\"],\"DBC3t5\":[\"Sonntag\"],\"DIS-zd\":[\"Plan konnte nicht gelöscht werden: \",[\"0\"]],\"DJMHhb\":[\"Letzte Einheit war ein Deload. Vergleich übersprungen.\"],\"DNhKLr\":[\"\\n🎯 Verbessert: Intelligentere Übungsfilter!\\n\\nWenn du eine Übung ersetzt, wählt der Filter jetzt automatisch den passenden Zielmuskel vor. Es werden nur relevante Filter basierend auf deiner aktuellen Auswahl angezeigt, sodass du deutlich schneller die richtige Alternative findest.\\n\"],\"DPfwMq\":[\"Fertig\"],\"DTtUaj\":[\"Gib mindestens einen Messwert ein.\"],\"DWFuyG\":[\"Übung entfernen\"],\"DYOFso\":[\"Knöchelstabilisatoren\"],\"DdBQBl\":[\"Wochenplan\"],\"Dh5Ge5\":[\"Schmerzen oder Formprobleme?\"],\"Di-cgt\":[\"Willkommen bei MuscleQuest!\"],\"DqgDEk\":[\"Aktuellste aus beliebigem Training\"],\"Dvc8Qg\":[\"Beschreibung:\"],\"Dy8Cvh\":[\"Quadrizeps\"],\"Dy_8Fq\":[\"SCHLIESSEN\"],\"E3kRqj\":[[\"uniqueWorkoutDaysCount\"],\" / \",[\"0\"],\" Trainingstage\"],\"EANWES\":[\"Verlauf konnte nicht geladen werden\"],\"EHgz6Q\":[\"Freigabe konnte nicht aktualisiert werden. Bitte versuche es erneut.\"],\"EMyNOr\":[[\"0\"],\" \",[\"1\"],\" (für Assistenzübungen verwendet)\"],\"E_QGRL\":[\"Deaktiviert\"],\"Ed3YeG\":[\"Jedes Training, das du abschließt, wird automatisch geteilt.\"],\"Ef7StM\":[\"Unbekannt\"],\"EfdYnO\":[[\"0\"],[\"distanceUnit\"]],\"EjAXiq\":[\"Adaptive Progression (Beta)\"],\"EkVHAp\":[\"Pausentimer-Schritt\"],\"EoQHhQ\":[\"Laufband\"],\"Euo2Um\":[\"Zeit (Min:Sek)\"],\"F37c1s\":[\"Einstellungen öffnen\"],\"F6pfE9\":[\"Aktiv\"],\"FCGpHg\":[\"Noch keine Übungen in diesem Training.\"],\"FHIDZO\":[\"Speichern und auswählen\"],\"FPsvA8\":[\"Verstanden!\"],\"FXHR4B\":[\"Körperteil\"],\"Fb5zs_\":[\"\\n⚖️ Neu: Gewicht erfassen für Körpergewichtsübungen!\\n\\nFür Körpergewichtsübungen wie Klimmzüge oder Dips kannst du jetzt die Gewichtserfassung pro Training aktivieren. Perfekt für gewichtete Varianten, um das zusätzliche Gewicht zu protokollieren und den Fortschritt über Zeit zu verfolgen.\\n\"],\"Fe0wLe\":[\"Supersätze\"],\"FnTClW\":[\"Du erreichst die Ziele schon zu leicht. Zeit, ein bisschen mehr Gewicht hinzuzufügen.\"],\"Fp1hl-\":[\"Plan wird geladen...\"],\"FwCUad\":[\"Gerät ist erforderlich.\"],\"G-iXUH\":[\"Schultern\"],\"G1onOm\":[\"Alle geteilten Daten löschen?\"],\"G2R9Qq\":[\"Handbeuger\"],\"G2nnKc\":[\"Zu meinen Plänen hinzufügen\"],\"G3myU-\":[\"Dienstag\"],\"G49bAb\":[\"Hebelmaschine\"],\"G4JNdR\":[\"Übung nicht gefunden.\"],\"G6rTvo\":[\"Verfolgen (\",[\"0\"],\")\"],\"GB-X8R\":[\"Von Freunden importieren\"],\"GCV1HM\":[\"Angemeldet als \",[\"0\"]],\"GCqPY4\":[\"Der Startbildschirm zeigt deinen Fortschritt in Richtung deines wöchentlichen Trainingsziels, also die Anzahl der Tage, an denen du pro Woche trainieren möchtest, festgelegt in den Einstellungen. Ein Streifen oben verfolgt, wie viele Tage du abgeschlossen hast, und hebt jeden abgeschlossenen Tag hervor. Darunter werden die Trainings deines aktiven Plans mit ihrem Abschlussstatus für die Woche aufgelistet; tippe auf Starten bei einem Training, um zu beginnen. Die darunter angezeigte Karte ändert sich je nach Status: Eine Fortsetzen-Karte erscheint, wenn eine Einheit läuft, eine Ruhetag-Karte wird an Tagen ohne geplantes Training angezeigt, und eine Training-abgeschlossen-Karte bestätigt, dass die heutige Einheit abgeschlossen ist. Wenn du dein Wochenziel erreichst, erscheint eine Wochenzusammenfassungskarte mit Gesamttrainings, Sätzen und Volumen der Woche sowie deiner Serie, die die Anzahl aufeinanderfolgender Wochen zählt, in denen du dein Ziel erreicht hast.\"],\"GGqR7k\":[\"Einzel- & Schnelltrainings\"],\"GLJjec\":[\"Bis zum Versagen\"],\"GLm0-9\":[\"Schmerzen oder Formprobleme\"],\"GNurdZ\":[\"Übung löschen\"],\"GPeIuw\":[\"Distanz\"],\"GS7yxz\":[\"Berechtigung erforderlich\"],\"GSOeV2\":[\"Oberschenkelrückseite\"],\"GVN2lL\":[\"Übung erstellen\"],\"GWvJTL\":[\"Passt so\"],\"GX9tlq\":[\"Nacken\"],\"Gd-KuS\":[\"Messwerte verwalten\"],\"Gf9sn6\":[\"Sicherungen werden gesucht...\"],\"GhCGeL\":[\"Sätze\"],\"GksdwI\":[\"Beste PR-Sätze\"],\"HNWkJr\":[\"\\n📏 Neu: Distanzverfolgung für eigene Übungen!\\n\\nEigene Übungen können jetzt den Tracking-Typ Distanz verwenden, perfekt für Ausdauer- und Konditionsbewegungen wie Laufen, Rudern oder Schlittendrücken. Protokolliere die Distanz für deine Sätze und erhalte Einblicke in deinen Fortschritt wie bei jeder anderen Übung.\\n\"],\"HYL9fJ\":[\"Trage nur eine Seite bei Einarm-/Einbeinübungen ein\"],\"Hp6ceF\":[\"Dein Training konnte nicht gespeichert werden. Bitte versuche es später erneut.\"],\"HpK_8d\":[\"Neu laden\"],\"Hplwk7\":[\"Wird wiederhergestellt. Bitte warten...\"],\"I2Hpku\":[\"Gewicht erfassen\"],\"ICkQNB\":[\"Erinnerungszeit\"],\"IFowGw\":[\"Seil\"],\"IHMx9j\":[\"Wochenserie\"],\"ILE1kp\":[\"Arme\"],\"INkdlR\":[\"Noch keine Freunde. Suche per E-Mail, um jemanden hinzuzufügen.\"],\"IRiG-a\":[\"Nach Pause vibrieren\"],\"IUwGEM\":[\"Änderungen speichern\"],\"IXxATP\":[\"Eigene Übungen\"],\"IbbuFX\":[\"Wird gelöscht. Bitte warten...\"],\"IuXB4Q\":[\"Notiz hinzufügen...\"],\"Izf0kk\":[\"Keine früheren Gewichtsdaten. Erstmal halten.\"],\"JE-yVp\":[\"Messwerte verwalten\"],\"JR5hAM\":[\"1 J.\"],\"JTkSvz\":[\"Möchtest du dieses Training wirklich entfernen?\"],\"JVKmoO\":[\"Das Update konnte nicht heruntergeladen werden. Prüfe deine Internetverbindung und öffne die App erneut, um es nochmal zu versuchen.\"],\"JW7_2_\":[\"Download fehlgeschlagen\"],\"JWTR_A\":[\"Beim Herunterladen der Bilder ist ein Fehler aufgetreten.\"],\"JYRqp5\":[\"Sa\"],\"JbvV5d\":[\"Wische während einer Einheit nach links/rechts oder nutze die Pfeilschaltflächen, um zwischen Sätzen zu wechseln. Gib Gewicht und Wiederholungen ein und tippe dann auf Satz abschließen. Die gesamte vergangene Zeit wird durchgehend in der Kopfzeile angezeigt. Du kannst den Anfasser einer Übungskarte ziehen, um Übungen während der Einheit neu anzuordnen. Zeitbasierte Übungen haben eine Schaltfläche Timer starten, die einen Vorwärts-Timer mit einem Fortschrittsring öffnet, der anzeigt, wann du deine Zielzeit erreichst, du kannst aber so lange weitermachen wie du möchtest. Notizen können pro Übung über das Notizensymbol in der Übungsüberschrift, pro Training über den Trainingsübersichtsbildschirm oder pro Plan über den Planübersichtsbildschirm hinzugefügt werden. Wenn du während einer Einheit Übungen oder Sätze hinzufügst, entfernst oder neu anordnest, wirst du am Ende gefragt, ob du diese Änderungen im ursprünglichen Training oder Plan speichern möchtest.\"],\"JfDOWo\":[\"Das Update ist bereit, aber die App konnte nicht automatisch neu gestartet werden. Tippe die Schaltfläche unten, oder schließe die App und öffne sie manuell erneut.\"],\"JkpsKr\":[\"Wird heruntergeladen. Bitte warten...\"],\"JmZ_-d\":[\"Beenden\"],\"JsIy35\":[\"Du hast diesen Plan aktiviert.\"],\"JumwGu\":[\"Cardio\"],\"Jv9TrU\":[\"Schräge Bauchmuskeln\"],\"KIL-9T\":[\"Weiter: \"],\"KKalG-\":[\"Hefte Übungen im Statistiken-Tab an, um ihre Kraftentwicklung über die Zeit zu verfolgen. Jede verfolgte Übung zeigt ein Diagramm deiner Leistung im gewählten Zeitraum, deinen persönlichen Rekord aller Zeiten, deine besten Sätze und eine Liste aktueller Einheiten mit dem besten Satz pro Tag. Diagramme werden nach jedem Training, das die Übung enthält, automatisch aktualisiert.\"],\"KM1Iw2\":[\"MuscleQuest\"],\"KSqQx0\":[\"Max. Wdh.\"],\"Km7tR4\":[\"Kauf mir einen Kaffee\"],\"KmiPdE\":[\"Kurzhantel\"],\"KxWSWU\":[\"Bildschirm während des Trainings eingeschaltet lassen\"],\"LAC2eo\":[\"Trainingserinnerungen\"],\"LAHzG1\":[\"Anzeigen/Bearbeiten\"],\"LIrnc0\":[\"Noch keine Übungen hinzugefügt\"],\"LLt1-u\":[\"Einseitig\"],\"LZKayn\":[\"Hilfe durchsuchen...\"],\"LcPJBt\":[\"abgeschlossene Trainings\"],\"LhMjLm\":[\"Zeit\"],\"LyPttd\":[\"Brust\"],\"M0GVkz\":[\"Wähle einen Tag, um Trainings anzuzeigen.\"],\"M1POMr\":[\"Übungsbibliothek\"],\"M4hMaA\":[\"Gib einen Namen für den eigenen Messwert ein.\"],\"M57U8X\":[\"Fasse zwei Übungen zu einem Supersatz zusammen, damit sie während einer Einheit automatisch abwechseln, ideal zum Kombinieren antagonistischer Muskeln oder für effizientes Trainieren zwischen Sätzen. Tippe auf das Drei-Punkte-Menü einer Übung im Trainings-Editor und wähle Supersatz erstellen, dann wähle die zweite Übung. Ein farbiges Label zeigt in der gesamten App, zu welchem Supersatz jede Übung gehört. Wenn du einen Satz einer Übung abschließt, wechselt die App direkt zum Supersatz-Partner.\"],\"MEt7-_\":[\"Schollenmuskel\"],\"MHk_Wu\":[\"Eintrag nicht gefunden.\"],\"MLQOxI\":[\"Hintere Schulter\"],\"MM-MTF\":[\"Supersatz \",[\"0\"]],\"MQ9jL7\":[\"Noch ein Training bis zu deinem Ziel!\"],\"MQA2H9\":[\"Plan löschen\"],\"MTqmCb\":[\"Neue Funktionen anfragen oder abstimmen\"],\"McFNQO\":[\"Verfolge deine Fitnessreise mit detaillierten Statistiken und Einblicken. Behalte die Trainingshistorie im Blick, analysiere deine Körperteil-Splits und visualisiere Fortschritte über Zeit mit Übungsfortschrittsgraphen.\"],\"MmDz7_\":[\"Hochladen. Bitte warten...\"],\"N4e_z1\":[\"Pausenzeit: \",[\"restMinutes\"],\":\",[\"0\"]],\"N5Cyfw\":[\"Freunde seit \",[\"0\"]],\"N85c_3\":[\"Training entfernen\"],\"NC2AI2\":[\"Länge\"],\"NIuBdI\":[\"Vorgefertigte Pläne\"],\"NKdWDE\":[\"Herz-Kreislauf-System\"],\"NLBiJk\":[\"Eintrag erfassen\"],\"NLYLjM\":[\"Sätze\"],\"NPG8SK\":[\"Körpergewicht\"],\"NQJHen\":[\"Möchtest du dieses Training wirklich neu starten?\"],\"NVOqiK\":[\"Melde dich an, um deine Daten zu sichern\"],\"NXoGPK\":[\"Übung bearbeiten\"],\"Ne5n-8\":[\"Persönliche Notizen hinzufügen\"],\"NnRCUm\":[[\"0\"],\"s\"],\"Ns5WaC\":[\"Keine Sicherungen gefunden\"],\"Nu4oKW\":[\"Beschreibung\"],\"O1GFNQ\":[\"Alle Zielmuskeln\"],\"O1xiRM\":[\"Wdh.\"],\"O2TAe0\":[\"Langhantel\"],\"O2wCGL\":[\"Countdown-Töne abspielen (Übungstimer)\"],\"ODbgw_\":[\"Damit werden alle Inhalte entfernt, die du mit Freunden geteilt hast. Deine Freunde und Freundesliste sind davon nicht betroffen.\"],\"OdFJle\":[\"Aktivieren, um eigene Übungen automatisch zu teilen.\"],\"Otd3xX\":[\"Eine Deload-Woche ist eine geplante Erholungswoche, in der du mit reduzierter Intensität trainierst, damit sich dein Körper vor dem nächsten Trainingsblock vollständig erholen kann. Tippe auf Als Deload-Woche markieren in der Planübersicht, um die aktuelle Woche als Deload zu kennzeichnen. Während der Deload aktiv ist, erscheint der Feedbackbogen nach Übungen nicht und es werden keine neuen Progressionszustände erstellt oder aktualisiert, sodass deine Vorschlagshistorie durch die leichteren Einheiten nicht gestört wird. Der Deload wird automatisch zu Beginn der folgenden Woche zurückgesetzt und normales Feedback sowie Fortschritts-Tracking werden ohne manuellen Eingriff fortgesetzt. Wenn du deine Meinung änderst, kannst du erneut auf den Button tippen, während der Deload aktiv ist, um ihn aufzuheben.\"],\"Ov8o8m\":[\"Plan starten\"],\"OwNTSr\":[\"Im Plan speichern\"],\"Owchfv\":[\"Zuletzt verwendet\"],\"OzAZw8\":[\"Dieser Bildschirm existiert nicht.\"],\"P0mjNu\":[\"Eintrag löschen\"],\"P0svFp\":[\"Pause\"],\"P1svYv\":[\"Bauch\"],\"P247ya\":[\"Körperteil *\"],\"P3NwXY\":[\"Training teilen\"],\"P3nVsi\":[\"\\n📅 Neu: Wochenplan für deinen Trainingsplan!\\n\\nDu kannst jetzt direkt im Plan-Editor bestimmten Wochentagen Trainings zuweisen. Tippe auf einen Tag, um ein Training auszuwählen oder ihn als Ruhetag zu markieren. Nutze die Auto-Vorschlag-Schaltfläche, um sofort einen ausgewogenen Wochenplan basierend auf deinem Wochenziel zu erstellen.\\n\"],\"P3omNB\":[\"Wähle ein Training zur Anzeige\"],\"PBt59F\":[\"Lieblingsübungen\"],\"PFcCy0\":[\"x \",[\"0\"],\" Wdh. \"],\"PHWHEO\":[\"Alle übernehmen\"],\"PITZNx\":[\"Brust\"],\"PN5Zzf\":[\"Gewichtseinheit\"],\"PNapeY\":[\"+ Hinzufügen\"],\"POx12e\":[\"\\n↕️ Neu: Übungen in der Trainingsübersicht neu anordnen!\\n\\nDu kannst jetzt Übungen und Supersätze per Drag-and-drop direkt in der Trainingsübersicht während einer Trainingseinheit neu anordnen.\\n\"],\"PSNHRi\":[\"* Funktionen in Entwicklung\"],\"PWfg7v\":[\"Anfragen\"],\"P_0oX-\":[\"Assistenz\"],\"PeTE4m\":[\"Plan nicht gefunden.\"],\"PiK6Ld\":[\"Sa\"],\"PruBpO\":[\"Bist du sicher, dass du diesen Messeintrag löschen möchtest?\"],\"Q1Lq8I\":[\"Gesamtzeit\"],\"Q2QJ28\":[\"Ziel-erreicht-Ton abspielen (Übungstimer)\"],\"Q8bEQa\":[\"Beim Löschen der Bilder ist ein Fehler aufgetreten.\"],\"Q9qAkA\":[\"Geschätzte Dauer: \",[\"0\"]],\"QENBWX\":[\"Trizeps\"],\"QOTvot\":[\"Inhalte teilen\"],\"Qdwk82\":[\"Kurzhantel-Gewichtsschritt\"],\"Qjp-BQ\":[\"Satz hinzufügen\"],\"QlT4B5\":[\"Letzte Einheiten\"],\"Qmbwcr\":[\"Plan bearbeiten\"],\"QoHy-T\":[[\"weeks\",\"plural\",{\"one\":[\"vor \",\"#\",\" Woche\"],\"other\":[\"vor \",\"#\",\" Wochen\"]}]],\"QrwEaQ\":[\"Brustmuskeln\"],\"QzJCdZ\":[\"Lats\"],\"R-ABt9\":[\"Wochenziel\"],\"R0gwbc\":[\"Bizeps\"],\"RAMaAx\":[\"Eingehend\"],\"RCk1J0\":[\"Schlittenmaschine\"],\"RGfnXX\":[\"(bis zum Versagen)\"],\"RIHmRj\":[\"Gutes Tempo. Versuch vor dem Gewicht eine Wiederholung pro Satz hinzuzufügen.\"],\"RM5DG6\":[\"Verfolgte Übungen\"],\"RN4XJV\":[\"Ruhetag\"],\"RU6ELr\":[\"Statistiken & Verlauf\"],\"RXkbtG\":[\"Nächstes Mal mehr fordern?\"],\"RY_JyV\":[\"Unterer Rücken\"],\"R_h8B2\":[\"Am häufigsten verwendet\"],\"Rc-8oy\":[\"Update wird heruntergeladen\"],\"RmahBs\":[[\"0\"],\": \",[\"best\"],\"s (+\",[\"delta\"],\"s, \",[\"pctStr\"],\")\"],\"Rr5U7J\":[\"Abgeschlossene Sätze erscheinen hier\"],\"Rwc-xL\":[\"Zeit-PR\"],\"RxzN1M\":[\"Aktiviert\"],\"S2uNE5\":[\"Bearbeitung fortsetzen?\"],\"SEyweA\":[\"\\n🐛 Behoben: Verschiedene Fehlerbehebungen und Verbesserungen!\\n\\nBehoben: Pausentimer-Benachrichtigung wurde nicht korrekt ausgelöst, Übungsname wurde in der Trainingsansicht falsch umgebrochen, die Breite des Trainingsabschlusskreises war falsch, Notizen wurden beim Tippen nicht korrekt aktualisiert und Trainingsdetails öffneten sich manchmal im falschen Tab. Trainings werden dank interner Leistungsverbesserungen jetzt schneller geladen.\\n\"],\"SGISp8\":[\"Du hast alles am Limit geschafft. Bleib hier und mach es dir zu eigen.\"],\"SRhtpX\":[\"Unterarme\"],\"SUd4dA\":[\"\\n📏 Neu: Körpermaße!\\n\\nVerfolge deine Körperzusammensetzung neben deinem Training im neuen Bereich Messungen im Stats-Tab.\\n\\n• Gewicht, Körperfettanteil, Taille, Hüften, Brust und mehr erfassen\\n• Vergangene Einträge antippen, um Werte zu bearbeiten oder ein Diagramm anzusehen\\n• Messgrößen verwalten und eigene hinzufügen\\n• Einheiten folgen deinen Gewichts- und Größeneinstellungen\\n\"],\"SWtay1\":[\"Nachdem du den letzten Arbeitssatz einer Übung abgeschlossen hast, erscheint ein Feedbackbogen mit zwei Fragen. Die erste fragt, wie sich die Anstrengung angefühlt hat: Leicht (du hättest mehr tun können), Passt so, Schwer (nah an deinem Limit) oder Nicht alle Sätze geschafft. Die zweite fragt nach Schmerzen: Keine Schmerzen, Leichtes Unbehagen oder Schmerzen oder Formprobleme. Wenn du Leicht antwortest, erscheint eine dritte Frage, ob du dich beim nächsten Mal mehr fordern möchtest. So kannst du die aktuelle Last bewusst beibehalten, auch wenn sich eine Einheit leicht angefühlt hat, und das System respektiert deine Entscheidung. Wenn du Schmerzen antwortest, kannst du in einem optionalen Textfeld notieren, wo du es gespürt hast. Der Bogen kann auch ohne Antworten geschlossen werden, falls du für diese Übung in dieser Einheit kein Feedback erfassen möchtest.\"],\"SZw9tS\":[\"Details anzeigen\"],\"SadoC9\":[\"Smith-Maschine\"],\"SbGW67\":[\" (bis zum Versagen) \"],\"ScJ9fj\":[\"Datenschutzrichtlinie\"],\"SdpDoo\":[\"Abgeschlossene Trainings mit Freunden teilen\"],\"SlfejT\":[\"Fehler\"],\"SmkA26\":[\"1RM \",[\"0\"],\" \",[\"unit\"]],\"SoWD_0\":[\"Satz speichern\"],\"SrVzRe\":[\"Prozent\"],\"St3y2e\":[\"Name erforderlich\"],\"SvOMfA\":[[\"0\"],\" Trainings\"],\"SzQe8k\":[\"Zu meinen Übungen hinzufügen\"],\"T0cOwV\":[\"Satz löschen\"],\"T7QVyK\":[\"Wenn du ein Training öffnest, das Übungen enthält, die du kürzlich trainiert hast, erscheint ein Regenerations-Check-in-Bogen, falls diese Übungen einen ausstehenden Progressionsvorschlag haben und deine letzte Einheit mindestens 12 Stunden zurückliegt. Für jede relevante Muskelgruppe wählst du eine von drei Optionen: Frisch (vollständig erholt), Leichter Muskelkater oder Noch sehr starker Muskelkater. Wenn ein Muskel als noch sehr starker Muskelkater markiert wird, wird jeder aufwärtsgerichtete Progressionsvorschlag für Übungen, die diesen Muskel trainieren, pausiert und bei der aktuellen Last gehalten, bis du zu Beginn der folgenden Einheit neu bewertest. Frisch oder Leichter Muskelkater beeinflusst Vorschläge nicht. Tippe auf Jetzt überspringen, um den Check-in ganz zu umgehen; ein übersprungener Check-in wird wie frische Erholung behandelt, ausstehende Vorschläge bleiben unverändert.\"],\"TBTwj-\":[\"MuscleQuest auf Instagram folgen\"],\"TJLDrx\":[\"Gewicht für Volumenberechnungen verdoppeln\"],\"T_qHwF\":[\"Unterschenkel\"],\"Ta25TG\":[\"Noch kein Verlauf\"],\"Tfzp6S\":[\"Kraft-PRs mit Freunden teilen\"],\"TpqeIh\":[\"Fehler: \",[\"0\"]],\"Tz0i8g\":[\"Einstellungen\"],\"TzLpDD\":[\"\\n🏋️ Neu: Einzeltrainings und Schnelltrainings!\\n\\nErstelle eigenständige Trainings außerhalb deiner Trainingspläne, perfekt für flexible Trainingseinheiten, Mobilitätsarbeit oder spontane Sessions. Du findest sie auf dem Pläne-Bildschirm.\\n\\nOder starte ein Schnelltraining direkt vom Startbildschirm, füge Übungen spontan hinzu und speichere es am Ende optional als eigenständiges Training.\\n\"],\"U0HZma\":[\"Tracking\"],\"U4QKsL\":[\"Einführung ein-/ausblenden\"],\"U8BTVm\":[\"Verbleibende Pausenzeit:\"],\"UCtAiM\":[\"Um Pausentimer-Benachrichtigungen zu aktivieren, erteile Benachrichtigungsberechtigungen in deinen Geräteeinstellungen.\"],\"UD8kHo\":[\"Weiter: \",[\"workoutName\"],\" am \",[\"0\"]],\"URmyfc\":[\"Details\"],\"US8F_H\":[\"Mehr Wiederholungen vorgeschlagen\"],\"USXXjt\":[\"Keine Ergebnisse für „\",[\"query\"],\"“\"],\"U_-GrY\":[\"Bitte warten, während die neueste Version heruntergeladen wird...\"],\"UbRKMZ\":[\"Ausstehend\"],\"UlnAQR\":[\"Training konnte nicht gelöscht werden. Bitte versuche es erneut.\"],\"UneMBz\":[\"Aktiver Plan\"],\"UnnFak\":[\"Toller Start in die Woche!\"],\"Uorrgj\":[\"Rhomboiden\"],\"Uu14s5\":[[\"0\",\"plural\",{\"one\":[\"#\",\" Satz\"],\"other\":[\"#\",\" Sätze\"]}]],\"UyvU3-\":[\"Hilfe & Info\"],\"UzNvmf\":[\"• Daten sichern und wiederherstellen\"],\"V6wjuJ\":[\"Tracking-Typ ist erforderlich.\"],\"V6xf0O\":[\"Diese Übung ist bereits in deinem Training. Bitte wähle eine andere.\"],\"V8MVAm\":[\"obere Brust\"],\"V8dVu4\":[\"\\n🔗 Neu: Supersätze!\\n\\nVerbinde zwei Übungen direkt im Plan-Editor zu einem Supersatz. Die Sätze beider Übungen werden synchron gehalten, und Supersätze sind überall in der App mit einem visuellen Indikator klar gruppiert.\\n\"],\"V8yTm6\":[\"Suche löschen\"],\"VAcXNz\":[\"Mittwoch\"],\"VCJb5r\":[\"Satz \",[\"0\"],\" von \",[\"totalSets\"]],\"VDkJml\":[\"Adaptive Progression analysiert dein Anstrengungsfeedback über aufeinanderfolgende Einheiten und schlägt vor, wann du dein Gewicht, deine Wiederholungen oder Sätze erhöhen solltest. Aktiviere es in den Einstellungen unter Adaptive Progression. Sobald aktiviert, erscheint nach jeder Übung in planbasierten Trainings eine kurze Feedbackabfrage. Das System benötigt zwei Einheiten mit demselben Signal, bevor es eine Steigerung empfiehlt, sodass einmalige leichte Tage herausgefiltert werden und eine gleichbleibende Leistung vor einem Vorschlag sichergestellt wird. Schmerzen oder nicht abgeschlossene Sätze werden sofort berücksichtigt, unabhängig von deiner Einheitenhistorie. Ein Vorschlag wird deinem Training nie ohne deine ausdrückliche Bestätigung angewendet. Du kannst auch deinen bevorzugten Gewichtsschritt pro Gerätekategorie im selben Abschnitt der Einstellungen konfigurieren, zum Beispiel 2,5 kg für Langhantelübungen und 2,0 kg für Kurzhanteln.\"],\"VFlRXJ\":[\"Diesmal so weiterhalten.\"],\"VJVR1o\":[\"Plan teilen\"],\"VcD4kW\":[\"Dieser Freund hat noch keine Inhalte geteilt.\"],\"VhVOxx\":[\"Deine Reise nach Swoletown beginnt heute!\"],\"VhfZbD\":[\"Größe: ~100 MB\"],\"W-pY1H\":[\"Eigene Übung konnte nicht gespeichert werden. Bitte versuche es erneut.\"],\"W0qDyY\":[\"Startbildschirm & Wochenziel\"],\"W3QcBP\":[\"Planübersicht\"],\"W3u9nh\":[\"Bis zum Versagen, \"],\"WDciil\":[\"\\n📋 Neu: \\\"Mehr\\\"-Menü und Hilfe & Info-Bereich!\\n\\nEs gibt einen neuen \\\"Mehr\\\"-Tab in der Navigationsleiste. Tippe darauf, um ein Einblendmenü zu öffnen, in dem du Einstellungen und einen brandneuen Hilfe & Info-Bereich findest.\\n\\nDie Einstellungen wurden von der Tab-Leiste hierher verschoben, und Hilfe & Info deckt alles ab, von Plänen und Trainings bis hin zu Statistiken und deinem Konto, mit einer Suchleiste, um schnell Antworten zu finden.\\n\"],\"WHwUfF\":[\"Fehler beim Laden der Übungsdetails\"],\"WIbOhZ\":[\"Adaptive Progression\"],\"WJp2MH\":[\"Größeneinheit\"],\"WKHqM-\":[\"Gewicht\"],\"WMvAhQ\":[\"Eigene Übungen, die du erstellst oder bearbeitest, werden automatisch geteilt.\"],\"WOi4Vm\":[\"Name *\"],\"WSzg3A\":[\"Distanz (\",[\"distanceUnit\"],\")\"],\"WU-3OC\":[\"Einarmig / einbeinig\"],\"WaIjmh\":[\"Wade (R)\"],\"Wjxizh\":[\"Alle geteilten Daten wurden entfernt.\"],\"WoEX6M\":[\"Gewichts- und Wiederholungsanpassungen vorschlagen\"],\"WzcO-J\":[\"Plan erstellen\"],\"X9kySA\":[\"Favoriten\"],\"X9r6cu\":[[\"goal\",\"plural\",{\"one\":[[\"completed\"],\" von \",\"#\",\" Training diese Woche\"],\"other\":[[\"completed\"],\" von \",\"#\",\" Trainings diese Woche\"]}]],\"XBUsEY\":[\"Zielmuskel\"],\"XHHEUg\":[\"Plan anpassen\"],\"XJQdl_\":[\"Hintergrundbenachrichtigung nach Pause senden\"],\"XNRDYn\":[\"Handstrecker\"],\"XdavYY\":[\"Trainings\"],\"Xdcdfd\":[\"Sätze & Übungen\"],\"XoEooZ\":[\"Zeit (s)\"],\"Xu14OQ\":[[\"0\",\"plural\",{\"one\":[\"#\",\" Wdh.\"],\"other\":[\"#\",\" Wdh.\"]}]],\"Xu2iGM\":[\"Gewicht hinzufügen\"],\"Xv4OIW\":[\"Training läuft\"],\"Xwd4Hm\":[\"Rotatorenmanschette\"],\"Y35ibG\":[\"Kraft-PRs werden nach jedem Training automatisch geteilt.\"],\"Y6QE0T\":[\"Gerät auswählen\"],\"YANNVr\":[\"Training\"],\"YDnEIW\":[\"Bester Zuwachs\"],\"YIix5Y\":[\"Suchen...\"],\"YLIqcF\":[\"Willkommen zurück\",[\"userName\"]],\"YXJbW8\":[\"Eigenständige Trainings existieren außerhalb von Plänen und erscheinen neben deinen Plänen auf dem Pläne-Bildschirm. Erstelle eines, indem du auf Neues Training tippst, einen Namen vergibst und Übungen hinzufügst; du kannst es jederzeit starten, ohne einen aktiven Plan zu benötigen. Eine geschätzte Dauer wird bei jedem eigenständigen Training angezeigt, damit du deine Zeit vor dem Start planen kannst. Schnelltrainings ermöglichen dir, eine Einheit sofort vom Startbildschirm aus zu starten: Tippe auf Schnelltraining, füge Übungen unterwegs hinzu, und am Ende kannst du es als eigenständiges Training für die Zukunft speichern oder einfach verwerfen. Wie Pläne speichert der Trainings-Editor automatisch einen Entwurf, damit du sicher gehen und zurückkehren kannst, ohne deine Arbeit zu verlieren.\"],\"YYzBv9\":[\"Mo\"],\"YekWWq\":[[\"0\",\"plural\",{\"one\":[\"#\",\" Wdh.\"],\"other\":[\"#\",\" Wdh.\"]}]],\"YiPU_R\":[\"Schultern\"],\"YnHdfF\":[\"Satz \",[\"0\"]],\"Yr-t8O\":[\"Füße\"],\"YuP-pS\":[\"„\",[\"label\"],\"“ wird aus dem Eingabeformular ausgeblendet. Deine historischen Daten bleiben erhalten.\"],\"Z3FXyt\":[\"Wird geladen...\"],\"Z8RW4m\":[\"Nachdem du ein Training abgeschlossen hast, zeigt die Trainingsübersicht eine Karte für die nächste Einheit mit umsetzbaren Vorschlägen für deine Übungen. Jede Zeile zeigt den Namen der Übung, die vorgeschlagene Änderung (ein neues Zielgewicht, einen breiteren Wiederholungsbereich oder einen Hinweis zur Gewichtsreduzierung) und eine kurze Erklärung, warum die Änderung vorgeschlagen wird. Tippe auf Übernehmen, um den Vorschlag für die nächste Einheit anzuwenden, oder auf Ablehnen, um ihn zu ignorieren. Angenommene Vorschläge werden beim nächsten Öffnen des Trainings automatisch in die Gewichts- und Wiederholungsfelder vorgefüllt, sodass du die Einheit bereits mit der richtigen Last startest. Der Button Alle übernehmen oben wendet alle Vorschläge auf einmal an. Vorschläge, die empfehlen, die aktuelle Last beizubehalten, erscheinen nicht in der Karte, da hierfür keine Aktion erforderlich ist.\"],\"ZARyDw\":[\"Freunde hinzufügen\"],\"ZAWGCX\":[[\"0\"],\" Sekunden\"],\"ZAvcCf\":[[\"0\"],[\"weightUnit\"],\" × \",[\"1\"]],\"ZI8idP\":[\"Frisch, vollständig erholt\"],\"Zm9Eu3\":[\"Schaltflächengröße beim Training\"],\"Zv7vjq\":[\"Pläne mit Freunden teilen\"],\"Zvc_N1\":[\"1RM (\",[\"weightUnitLabel\"],\")\"],\"_-nVtu\":[\"Hat sich leicht angefühlt. Erstmal halten und nächste Einheit bestätigen.\"],\"_2fO4v\":[\"Trainingsübersicht\"],\"_D5y8a\":[\"Standard-Sätze\"],\"_K9jUO\":[\"Oberkörperergometer\"],\"_P2B4j\":[[\"biggestGainLabel\"],\" 1RM\"],\"_RhvUo\":[\"Einstellungen\"],\"_UGS0C\":[\"Trainingsname\"],\"_W-KPJ\":[\"Noch keine Messungen. Tippe, um deinen ersten Eintrag zu erfassen.\"],\"_WRCmH\":[[\"0\"],\" \",[\"1\"],\" | \",[\"2\"],\" Wdh.\"],\"_XczSN\":[\"Zielmuskel auswählen\"],\"_cF7Rs\":[\"Volumen\"],\"_f5DAr\":[\"Abgeschlossen am: \",[\"formattedDate\"]],\"a2Fu8q\":[\"Du kannst dich jederzeit über die Einstellungsseite anmelden, wenn du es jetzt überspringen möchtest.\"],\"a5BPTT\":[\"Kettlebell\"],\"a8SF50\":[\"Fügt einen Veröffentlichungsschalter pro Training hinzu.\"],\"a8TA11\":[\"Nächste Einheit\"],\"a99tuk\":[\"Aktivieren, um jedem Plan einen Veröffentlichungsschalter hinzuzufügen.\"],\"aAIQg2\":[\"Erscheinungsbild\"],\"aMwZcE\":[\"Oberarm (L)\"],\"aN_GPe\":[\"Wo hast du es gespürt?\"],\"aRwEh5\":[\"Eigene Übungen mit Freunden teilen\"],\"ahW3x6\":[\"\\n📅 Neu: Trainingskalender!\\n\\nTippe auf das Kalendersymbol im Bereich Trainingshistorie auf dem Statistiken-Tab, um deine Trainingshistorie nach Datum zu durchsuchen. Tage mit Trainings sind hervorgehoben, und ein Tippen auf einen Tag zeigt die an diesem Datum protokollierten Einheiten.\\n\"],\"aj6ZJx\":[\"Mit Google anmelden\"],\"b3e7Re\":[\"App neu starten\"],\"b63Dw_\":[\"Kein Nutzer mit dieser E-Mail-Adresse gefunden.\"],\"b9OAHS\":[\"Aufwärmsatz hinzufügen\"],\"bFeIdj\":[\"Dropsatz\"],\"bQdjFX\":[[\"0\"],\" Notiz\"],\"bRAv_4\":[\"Training \",[\"0\"]],\"bZS72M\":[[\"setsCount\",\"plural\",{\"one\":[\"#\",\" Satz\"],\"other\":[\"#\",\" Sätze\"]}]],\"bosqpS\":[\"Noch keine Trainings abgeschlossen. Starte dein erstes Training!\"],\"bqb_ci\":[\"\\n🐛 Behoben: Schaltflächen in der Trainingsansicht und Satz-Bearbeiten-Fenster!\\n\\nEin Fehler wurde behoben, bei dem alle Schaltflächen (erhöhen/verringern, nächster/vorheriger Satz, Satz abschließen) nach dem Abschließen eines Satzes nicht mehr funktionierten. Außerdem wurde ein Fehler im Satz-Bearbeiten-Fenster behoben. Satzübergänge erfolgen jetzt sofort für einen flüssigeren Trainingsablauf.\\n\"],\"bwd2oE\":[\"Pausentimer beendet!\"],\"bzSI52\":[\"Verwerfen\"],\"c2TGz5\":[[\"completed\"],\" Trainings diese Woche. Du hast dein Ziel geknackt!\"],\"c7AAAa\":[\"\\n📈 Beta: Adaptive Progression!\\n\\nMuscleQuest kann dir jetzt vorschlagen, wann du dein Gewicht oder deine Wiederholungen erhöhen solltest, basierend auf dem Gefühl deiner Einheiten. Beantworte nach jeder Übung zwei kurze Fragen zu Anstrengung und Schmerzen. Sobald du dasselbe Signal zwei Einheiten in Folge gemeldet hast, schlägt die App eine Änderung vor. Alle Vorschläge erscheinen im Trainingsübersichtsbildschirm, wo du jeden einzeln annehmen oder ablehnen kannst. Angenommene Vorschläge werden automatisch in deine nächste Einheit vorgefüllt.\\n\\nEin Regenerations-Check-in zu Beginn deines nächsten Trainings lässt dich Muskelkater einbeziehen, bevor ein Vorschlag angewendet wird. Du kannst auch eine ganze Woche als Deload in der Planübersicht markieren, was Feedback und Fortschritts-Tracking für diese Woche pausiert.\\n\\nAktiviere es in den Einstellungen unter Adaptive Progression und konfiguriere deinen bevorzugten Gewichtsschritt pro Gerätekategorie.\\n\"],\"cCbON-\":[\"\\n🔥 Verbessert: Aufwärmsatz-Verwaltung!\\n\\nAufwärmsätze werden visuell gruppiert und getrennt von Arbeitssätzen dargestellt, und \\\"Auf alle anwenden\\\" ermöglicht das gleichzeitige Bearbeiten von Aufwärm- oder Arbeitssätzen unabhängig voneinander.\\n\"],\"cF5b-5\":[[\"weeklyGoal\",\"plural\",{\"one\":[\"Auto-Vorschlag (\",\"#\",\" Tag)\"],\"other\":[\"Auto-Vorschlag (\",\"#\",\" Tage)\"]}]],\"cI6f7l\":[\"30 T.\"],\"cU45Co\":[\"Training hinzufügen\"],\"cUD6H0\":[\"Mach dich bereit...\"],\"cUY9dI\":[\"Möchtest du diese Übung wirklich löschen?\"],\"ckJ-os\":[\"Muskeln\"],\"cnGeoo\":[\"Löschen\"],\"crwali\":[\"Erinnerungen\"],\"ctrAML\":[\"Vergiss nicht, deinen Fortschritt zu verfolgen!\"],\"cyR8-W\":[\"\\n🕐 Neu: Geschätzte Trainingsdauer!\\n\\nJede Trainingskarte zeigt jetzt eine geschätzte Dauer an, damit du deine Einheiten auf einen Blick planen kannst, bevor du startest.\\n\"],\"d1z1ZY\":[\"Der Pausentimer startet nach jedem Satz automatisch und zählt bis null herunter. Jeder Satz merkt sich seine eigene Pausendauer, sodass verschiedene Sätze innerhalb derselben Übung unterschiedliche Pausenzeiten haben können. Nutze die ±-Schaltflächen, um die verbleibende Zeit während der Pause spontan anzupassen. Konfiguriere die Standard-Pausendauer, den Timer-Schritt und ob am Ende ein Sound, eine Vibration oder eine Hintergrundbenachrichtigung ausgelöst wird; jede Option ist in den Einstellungen unabhängig umschaltbar.\"],\"dEgA5A\":[\"Abbrechen\"],\"dH9Y4t\":[\"Keine Trainings an diesem Tag.\"],\"dVK-Er\":[\"Es ist ein Darstellungsfehler aufgetreten. Drücke die Schaltfläche, um neu zu laden.\"],\"dXCD6-\":[\"Alle Übungsanimationen herunterladen\"],\"dXoieq\":[\"Zusammenfassung\"],\"dYOPCE\":[\"Assistenz \",[\"0\"],\" \",[\"1\"],\" | Widerstand \",[\"2\"],\" \",[\"3\"],\" | \",[\"4\"],\" Wdh.\"],\"dbWo0h\":[\"Mit Google anmelden\"],\"deoJBi\":[[\"0\"],\" Wdh.\"],\"dfunKV\":[\"Gewicht/Wdh.\"],\"dpOqdQ\":[\"Bis zum Versagen\"],\"dqjuBA\":[\"90 T.\"],\"dx0cCC\":[\"Halt den Schwung aufrecht!\"],\"e0dGJ7\":[\"Vorteile der Anmeldung:\"],\"e0l-Z0\":[[\"scheduledDays\",\"plural\",{\"one\":[\"#\",\" Tag/Woche\"],\"other\":[\"#\",\" Tage/Woche\"]}]],\"e52k4Y\":[\"Öffne den Freunde-Tab im Menü, um deine Verbindungen zu verwalten. Nutze die Suchleiste, um andere Nutzer per Nutzernamen zu finden und eine Freundschaftsanfrage zu senden. Eingehende Anfragen erscheinen im Tab Anfragen; tippe auf Übernehmen zum Bestätigen oder Ablehnen zum Ignorieren. Ein Badge am Freunde-Menüpunkt zeigt, wie viele Anfragen noch ausstehen. Sobald eine Anfrage angenommen wurde, erscheinen beide Nutzer in der Freundesliste des anderen und können gegenseitig die geteilten Inhalte einsehen.\"],\"e5h2IT\":[[\"0\"],\" Notizen\"],\"e9qdcV\":[\"Leichtes Unbehagen\"],\"eLA0I2\":[\"Bilder herunterladen\"],\"eQm4BH\":[\"Nach dem Beenden eines Trainings zeigt ein Übersichtsbildschirm die Gesamtdauer, abgeschlossene Sätze und das Gesamtvolumen. Wenn du dasselbe Training schon früher gemacht hast, zeigt eine Vergleichszeile, wie jede Kennzahl zur vorherigen Einheit abschneidet. Ein Wochenzielbanner zeigt, wie viele Einheiten du diese Woche im Vergleich zu deinem Ziel protokolliert hast. Tippe auf eine Übung in der Liste, um sie aufzuklappen und jeden Satz im Detail zu prüfen. Beim Abschließen eines Schnelltrainings wirst du gefragt, ob du es als eigenständiges Training für die Zukunft speichern oder verwerfen möchtest.\"],\"eYbd7b\":[\"So\"],\"ecUA8p\":[\"Heute\"],\"ehOkF-\":[\"Grundlagen\"],\"emOtYn\":[\"Vorgefertigte Pläne\"],\"enD4RG\":[\"Übung konnte nicht hinzugefügt werden. Bitte versuche es erneut.\"],\"ez-cQL\":[\"\\n🔔 Neu: Trainings-Erinnerungsbenachrichtigungen!\\n\\nVerpasse keine Einheit mehr. Richte Erinnerungsbenachrichtigungen für deine Trainings direkt in der App ein. Wähle die Tage, an denen du erinnert werden möchtest, und lege eine Uhrzeit fest.\\n\"],\"f2yjAZ\":[\"Keine Schmerzen\"],\"f7pPKh\":[\"Oberschenkel (L)\"],\"f8Vl8d\":[\"Name des Messwerts\"],\"fFHHFp\":[\"Messungen\"],\"fPpo2L\":[\"Supersatz\"],\"fQWEzC\":[\"Noch keine Pläne geteilt\"],\"fSu2Jl\":[\"Eine neue Version wurde heruntergeladen. Tippe die Schaltfläche unten, um die App neu zu starten und das Update anzuwenden.\"],\"fWsBTs\":[\"Etwas ist schiefgelaufen. Bitte versuche es erneut.\"],\"fXVIZq\":[\"Werte\"],\"f_bxrN\":[\"Name ist erforderlich.\"],\"feWdkU\":[\"Training neu starten\"],\"fj5byd\":[\"k.A.\"],\"fpMgHS\":[\"Mo\"],\"fqSfXY\":[\"Ersetzen\"],\"fsJAR5\":[\"Langhantel-Gewichtsschritt\"],\"ftiGCv\":[\"Alle Geräte\"],\"fvyzOr\":[\"oberer Rücken\"],\"g36TSx\":[\"Distanzeinheit\"],\"g3UF2V\":[\"Übernehmen\"],\"g3cPNV\":[\"Aktivieren, um Körpermaße automatisch zu teilen.\"],\"gCVtjC\":[[\"0\"],\" Sätze\"],\"gEOgEq\":[[\"0\"],\" Übungen\",[\"1\"]],\"gQYPDg\":[\"−\",[\"restTimerIncrement\"],\"s\"],\"gTdjGc\":[\"Training konnte nicht gelöscht werden. Bitte versuche es erneut.\"],\"giOl9F\":[\"Oberschenkel (R)\"],\"gkn1WJ\":[\"Übung bereits hinzugefügt\"],\"gloTI5\":[\"Tippe auf einen beliebigen akzeptierten Freund in deiner Freundesliste, um sein Profil zu öffnen. Sein Profil zeigt die Pläne, eigenständigen Trainings und eigenen Übungen, die er geteilt hat. Tippe bei einem Eintrag auf Importieren, um ihn direkt in deine eigene Bibliothek hinzuzufügen. Importierte Pläne und Trainings werden als neue Kopien gespeichert, die du frei bearbeiten kannst, ohne das Original zu beeinflussen. Importierte eigene Übungen werden deiner Übungsbibliothek hinzugefügt und sind sofort beim Erstellen von Trainings verfügbar.\"],\"gzBfh2\":[\"Keine Sätze verfügbar\"],\"h-DKuf\":[\"vs. letztes \\\"\",[\"0\"],\"\\\"\"],\"h2ALJf\":[\"Gesäß\"],\"h69WC6\":[\"Gesendet\"],\"h7CU4q\":[\"Wie hat sich das angefühlt?\"],\"hBjQ0O\":[[\"0\",\"plural\",{\"one\":[\"#\",\" Training\"],\"other\":[\"#\",\" Trainings\"]}]],\"hF_t4W\":[\"Volumen (\",[\"volumeUnit\"],\")\"],\"hLONcx\":[\"Sichern und wiederherstellen\"],\"hPXEuO\":[\"Gepaart mit \",[\"0\"]],\"hXzOVo\":[\"Weiter\"],\"hnJ2UC\":[\"Brachialis\"],\"hnlGzG\":[\"Jetzt überspringen\"],\"hnrFBk\":[\"Erinnerungstage\"],\"hp8OtS\":[\"Hinzugefügt\"],\"hpsdvR\":[\"\\n📋 Neu: Trainingsdetails vom Startbildschirm anzeigen!\\n\\nDu kannst jetzt auf ein beliebiges kürzliches Training auf dem Startbildschirm tippen, um alle Details anzuzeigen. Jede Trainings- und Satzübersicht hat außerdem eine neue Details-Schaltfläche für schnellen Zugriff auf Übungsinformationen.\\n\"],\"hsoeHo\":[\"Trainingsdetails\"],\"hty0d5\":[\"Montag\"],\"hupMcg\":[\"Freund entfernen? Diese Person kann deine geteilten Inhalte dann nicht mehr sehen.\"],\"hvfche\":[[\"scheduledCount\",\"plural\",{\"one\":[\"#\",\" Tag/Woche\"],\"other\":[\"#\",\" Tage/Woche\"]}]],\"i-mS1s\":[\"Bereits geteilte Daten bleiben für deine Freunde sichtbar, bis du sie unten löschst.\"],\"i-tNaY\":[\"Assistenz/Wdh.\"],\"i09UfG\":[\"Gerät:\"],\"i0qMbr\":[\"Startseite\"],\"i4Vk1Q\":[\"Übungen des aktiven Plans\"],\"i6f8rt\":[\"Training wird gestartet...\"],\"iGokZG\":[\"Kabel-Gewichtsschritt\"],\"iHjmbB\":[\"Zu meinen Plänen hinzugefügt\"],\"iHmyze\":[\"Übungen\"],\"iO73Kk\":[\"Du kannst Pläne, eigenständige Trainings, eigene Übungen, Körpermaße und Kraft-PRs mit deinen Freunden teilen. Alle fünf Kategorien haben einen globalen Schalter in den Datenschutzeinstellungen im Konto-Bereich der Einstellungen. Wenn du den globalen Schalter für eine Kategorie aktivierst, werden alle Elemente dieser Kategorie geteilt und neue Daten werden automatisch synchronisiert, wenn sie sich ändern. Pläne und eigenständige Trainings haben zusätzlich einen individuellen Teilen-Schalter in der Übersicht jedes Eintrags, sodass du bestimmte Pläne oder Trainings veröffentlichen kannst, ohne alles zu teilen. Ein Wolken-Symbol auf der Plan- oder Trainingskarte bestätigt, dass er aktuell veröffentlicht ist. Um geteilte Daten zu entfernen, deaktiviere den Schalter in den Datenschutzeinstellungen und tippe auf Geteilte Daten löschen für diese Kategorie. Du kannst auch alle geteilten Daten jeder Kategorie über denselben Bildschirm löschen.\"],\"iQyKX1\":[\"Du hast dich fürs Halten entschieden. Gewicht bleibt so.\"],\"iV1Jat\":[\"Möchtest du diesen Satz wirklich löschen?\"],\"iYfCFU\":[\"Einführung auf Startbildschirm anzeigen\"],\"i_48Se\":[\"Aktiver Plan: \",[\"0\"]],\"i_nB8P\":[\"Kein Zeitplan festgelegt\"],\"ifRQL2\":[\"Dropsatz, \"],\"ikOJPT\":[\"Schienbeine\"],\"irLwtB\":[\"Trainingsplan\"],\"irrqfe\":[\"Eigene Messwerte\"],\"iuwbqi\":[\"Training konnte nicht gespeichert werden. Bitte versuche es erneut.\"],\"ivpCYv\":[\"Änderungen verwerfen?\"],\"j-MPXl\":[\"Sichern & Wiederherstellen\"],\"jDTG0T\":[\"Progressionsvorschläge\"],\"jDh_CH\":[\"Pläne sind strukturierte Trainingsprogramme aus mehreren Trainings. Um einen zu erstellen, gehe zum Pläne-Tab, tippe auf Neuer Plan, gib einen Namen ein und wähle ein Titelbild. Füge Trainings zum Plan hinzu und dann Übungen zu jedem Training mit Ziel-Sätzen und Wiederholungen. Nutze die Hoch/Runter-Pfeile auf einer Trainingskarte, um sie neu anzuordnen, oder die X-Schaltfläche, um sie zu entfernen, beide befinden sich oben rechts auf der Karte. Weise Trainings im Zeitplan-Editor bestimmten Wochentagen zu: Tippe auf einen Tag, um ein Training auszuwählen oder ihn als Ruhetag zu lassen, und nutze den Auto-Vorschlag, um sie gleichmäßig zu verteilen. Wenn dein Plan fertig ist, öffne ihn und tippe auf Aktivieren. Du kannst vom Planübersichtsbildschirm auch Notizen zum Plan hinzufügen. Jede Trainingskarte zeigt eine geschätzte Dauer neben der Übungsanzahl, damit du die Länge der Einheit auf einen Blick abschätzen kannst. Nutze die Ansichtssymbole neben der Überschrift „Deine Trainingspläne“, um zwischen Karussell-, Listen- und Rasteransicht zu wechseln; deine gewählte Ansicht wird automatisch gespeichert. Dein Fortschritt im Plan-Editor wird automatisch als Entwurf gespeichert, wenn du ihn mittendrin verlässt, wirst du gefragt, ob du weitermachen oder verwerfen und vom letzten gespeicherten Stand starten möchtest.\"],\"jYjrmQ\":[\"Letzte Sicherung: \",[\"0\"]],\"jbq7j2\":[\"Ablehnen\"],\"jfzZZ0\":[\"Anmeldung überspringen\"],\"jpVuia\":[\"Änderungen im Training speichern?\"],\"jxTU3u\":[\"Treppensteiger\"],\"jzJENZ\":[\"Deinen Fortschritt verfolgen\"],\"k4kpgL\":[\"Willkommen bei MuscleQuest, deinem persönlichen Krafttrainingsbegleiter. Nutze diesen Leitfaden, um die Funktionen zu entdecken und das Beste aus deinem Training herauszuholen.\"],\"k5alGf\":[\"Noch keine Trainings geteilt\"],\"k7Oi68\":[\"Oberschenkel\"],\"kDJ_Ja\":[\"Solide Einheit. Gewicht beibehalten.\"],\"kFoQmI\":[\"Abduktoren\"],\"kILzHz\":[\"Hinzufügen (\",[\"0\"],\")\"],\"kQe_xM\":[\"Schmerzen gemeldet. Gewicht bleibt unverändert, bis es dir besser geht.\"],\"kSi1ha\":[\"+\",[\"suggestedWeight\"],[\"unit\"],\" vorgeschlagen\"],\"kdwbaT\":[\"Alle überspringen\"],\"kf4tdd\":[\"Tracking-Typ auswählen\"],\"kfxr8q\":[\"\\n📊 Neu: Trainingsübersicht!\\n\\nNach dem Abschließen eines Trainings siehst du jetzt eine vollständige Übersicht deiner Einheit: Gesamtdauer, Sätze und Volumen sowie einen Vergleich mit deiner vorherigen Einheit. Tippe auf eine Übung, um ihre einzelnen Sätze und Gewichte anzuzeigen.\\n\"],\"kg0oKA\":[\" (bis zum Versagen)\"],\"kkDQ8m\":[\"Donnerstag\"],\"konUZ1\":[\"Standard-Pausenzeit\"],\"kvpjYu\":[\"Übungsname eingeben\"],\"l1P93s\":[\"Gewicht pro Hantel/Kabel eingeben, nicht gesamt\"],\"l75CjT\":[\"Ja\"],\"lWy5a1\":[\"Pläne\"],\"lY9GM0\":[\"Zielmuskel ist erforderlich.\"],\"lkz6PL\":[\"Dauer\"],\"llGZy3\":[\"Noch keine Übungen verfolgt. Tippe auf + Hinzufügen, um zu starten.\"],\"loRbvf\":[\"Zur Startseite!\"],\"m0YANP\":[\"Du kannst diesen Einführungsbildschirm jederzeit über die Einstellungsseite im Bereich Darstellung ausblenden. Wenn du die Einführung erneut ansehen möchtest, kannst du sie dort wieder aktivieren.\"],\"m16xKo\":[\"Hinzufügen\"],\"m2QQkt\":[\"Zu meinen Trainings hinzugefügt\"],\"m66_4D\":[\"Tracking-Typ\"],\"mAoTHw\":[\"Einige Bilder konnten nicht gelöscht werden. Fehlgeschlagene Übungs-IDs: \",[\"0\"]],\"mDmPnX\":[\"Pro Woche (Ø)\"],\"mEQ95z\":[\"Bild konnte nicht gespeichert werden. Bitte versuche es erneut.\"],\"mF1US0\":[\"Immer aktuellste Übungshistorie verwenden\"],\"mFQ4KK\":[\"Gewicht für Volumen verdoppeln, wenn die Einstellung aktiviert ist\"],\"mK5j7_\":[\"\\n🔃 Neu: Übungsbibliothek sortieren!\\n\\nDie Übungsbibliothek hat jetzt Sortier-Chips, damit du Übungen schneller findest. Sortiere nach Standard, Aktiver Plan, Zuletzt oder Häufig, um die für dich relevantesten Übungen oben zu sehen.\\n\"],\"mRTnNi\":[\"Gepaarte Geräte\"],\"mSit7t\":[\"Daten konnten nicht abgerufen werden. Bitte versuche es erneut.\"],\"mSj_dN\":[[\"0\",\"plural\",{\"one\":[\"+\",\"#\",\" mehr\"],\"other\":[\"+\",\"#\",\" mehr\"]}]],\"mT57-Q\":[\"Zu den Einstellungen\"],\"mob_am\":[\"Fr\"],\"mwX_w0\":[\"Bild ändern\"],\"mzI_c-\":[\"Herunterladen\"],\"n00ykB\":[\"Deine Trainings\"],\"n1BXGc\":[\"Trainings-Split (nach Sätzen)\"],\"n1ekoW\":[\"Anmelden\"],\"nAEGxm\":[\"Ja, mehr herausfordern\"],\"nJSX83\":[\"Trainingserinnerungen\"],\"nO6sra\":[[\"0\"],\": \",[\"best\"],\" \",[\"best\",\"plural\",{\"one\":[\"Wdh.\"],\"other\":[\"Wdh.\"]}],\" (+\",[\"delta\"],\", \",[\"pctStr\"],\")\"],\"nPGn3W\":[\"Aufwärmen, \"],\"nkkWxK\":[\"Starte deine Fitnessreise mit professionell gestalteten Trainingsplänen. Wähle aus einer Vielzahl von Optionen, die auf verschiedene Ziele und Erfahrungsstufen zugeschnitten sind. \"],\"nmdLhD\":[\"Wdh.: \",[\"repRange\"]],\"nmvpnF\":[\"Noch keine eigenen Übungen geteilt\"],\"o2XlZw\":[\"Möchtest du dieses Training wirklich löschen? Diese Aktion kann nicht rückgängig gemacht werden.\"],\"oB9lvM\":[\"Aufwärmsätze aus den Statistiken ausschließen\"],\"oOHOWH\":[\"\\n✨ Neu: Animationen in der Trainingseinheit!\\n\\nDas Wechseln zwischen Sätzen erfolgt jetzt mit flüssigen Übergangsanimationen. Wische nach links oder rechts, um zwischen Sätzen zu wechseln, oder nutze die vorhandenen Pfeilschaltflächen für denselben Effekt.\\n\"],\"oOYj_W\":[\"Trainings konnten nicht geladen werden\"],\"oRTTfk\":[\"Der Statistiken-Tab zeigt Gesamttrainings, Gesamtvolumen, Gesamtzeit und durchschnittliche Einheitsdauer über einen auswählbaren Zeitraum, mit einer Periode-zu-Periode-Differenz für jede Kennzahl. Diagramme zeigen wöchentliches Volumen und deinen Trainings-Split nach Körperteil. Durchsuche deine vollständige Trainingshistorie und tippe auf eine Einheit, um jeden Satz im Detail einzusehen, einschließlich Gewichte, Wiederholungen, Zeit oder Distanz. Du kannst abgeschlossene Trainings vom Verlaufsdetailsbildschirm bearbeiten oder löschen. Tippe auf das Kalendersymbol im Bereich Trainingshistorie, um eine Kalenderansicht zu öffnen: Tage mit Trainings sind mit einem gelben Kreis hervorgehoben, und ein Tippen auf einen Tag zeigt die an diesem Datum protokollierten Trainings.\"],\"oRvy2V\":[\"Übungs-Tracking\"],\"oXsjxN\":[\"Wade (L)\"],\"oYZpj8\":[\"• Herausforderungen und Abzeichen *\"],\"ocEDZS\":[\"Satz entfernen\"],\"oeF-HP\":[\"Anmeldung fehlgeschlagen. Bitte versuche es erneut.\"],\"oeeBm6\":[\"\\n🔔 Neu: In-App-Update-Benachrichtigungen!\\n\\nEin neues Update-Fenster erscheint jetzt, wenn ein Over-the-Air-Update verfügbar ist, damit du immer weißt, wann Verbesserungen heruntergeladen wurden und bereit zur Anwendung sind.\\n\"],\"ofVE0I\":[\"Löscht das Suchfeld\"],\"oiHVLP\":[\"Supersatz entfernen\"],\"oqKRAn\":[\"Jeder Satz kann als Aufwärmsatz, Dropsatz, bis zum Versagen oder eine beliebige Kombination davon markiert werden. Das Badge neben einem Satz zeigt seinen aktuellen Typ. Um den Typ während einer Einheit zu ändern, tippe auf das Menü (⋮) und schalte die entsprechende Option ein oder aus. Beim Erstellen eines Plans nutze die Checkboxen im Satz-Editor; tippe auf Aufwärmsatz hinzufügen, um einen dedizierten Aufwärmsatz oben in der Liste einzufügen. Aufwärmsätze werden visuell gruppiert und von Arbeitssätzen getrennt, und die Option Auf alle anwenden im Bearbeitungsfenster betrifft nur Sätze desselben Typs. Aufwärmsätze können in den Einstellungen von Volumen- und Statistikberechnungen ausgeschlossen werden.\"],\"oqUOKk\":[\"Dropsatz\"],\"osILGh\":[\"Zieldistanz (\",[\"distanceUnit\"],\")\"],\"os_BJP\":[\"Noch keine Messungen geteilt\"],\"ovBPCi\":[\"Standard\"],\"ovGl86\":[\"(bis zum Versagen) \"],\"p5nYkr\":[\"Alle anzeigen\"],\"p72uBF\":[\"Keine Trainingspläne gefunden\"],\"p8F9k_\":[\"Hals\"],\"pB7xVW\":[\"Kraft-PRs\"],\"pBGx0B\":[\"\\n🗂️ Neu: Planansichtsoptionen!\\n\\nDer Pläne-Bildschirm hat jetzt drei Anzeigemodi. Nutze die Symbole neben der Überschrift „Deine Trainingspläne“, um zwischen Karussell-, Listen- und Rasteransicht zu wechseln. Deine bevorzugte Darstellung wird automatisch gespeichert.\\n\"],\"pE7tOx\":[\"Aktives Training\"],\"pIX6X7\":[\"MuscleQuest auf Instagram\"],\"pIuJtP\":[\"Training nicht gefunden.\"],\"pY_gY7\":[\"Wiederholungs-PR\"],\"p_C-3G\":[\"Leichter Muskelkater\"],\"pbzA-s\":[\"Optionale Beschreibung\"],\"pfXEaj\":[\"Körpergewicht\"],\"pkD36F\":[\"Möchtest du \\\"\",[\"0\"],\"\\\" wirklich löschen?\"],\"poLmqL\":[\"Vom Gerät auswählen\"],\"psxXnW\":[\"Melde dich in den Einstellungen mit Google an, um Cloud-Sicherungen all deiner Trainingsdaten zu aktivieren. Tippe jederzeit auf Sichern, um eine Momentaufnahme zu speichern; das Datum deiner letzten Sicherung wird unter der Schaltfläche angezeigt. Tippe auf Wiederherstellen, um deine neueste Sicherung herunterzuladen und anzuwenden; bestätige die Eingabeaufforderung und die App lädt mit deinen wiederhergestellten Daten neu. Deine Sicherungen werden sicher gespeichert und sind mit deinem Google-Konto verknüpft. Wenn du das Gerät wechselst oder die App neu installierst, melde dich einfach mit demselben Google-Konto an und tippe auf Wiederherstellen.\"],\"pvW0MQ\":[\"Satz abschließen\"],\"pwfNCc\":[\"+\",[\"restTimerIncrement\"],\"s\"],\"pz0gzh\":[\"Messwert ausblenden\"],\"pzA-xG\":[\"Halte wichtige Hinweise, Erinnerungen und persönliche Erkenntnisse für deine Übungen, Trainings und Trainingspläne fest. Bleib fokussiert und verfeinere deine Technik mit eigenen Notizen auf deiner Fitnessreise. Notizen werden automatisch gespeichert, wenn du fertig bist.\"],\"q3pTrs\":[\"Alle Bilder erfolgreich gelöscht!\"],\"qIATCE\":[\"\\n📋 Verbessert: Intelligenteres Vorbefüllen mit Trainingshistorie!\\n\\nSatzfelder werden jetzt intelligenter vorbefüllt. Hat eine Übung keine Historie im aktuellen Training, wird automatisch auf die letzte Ausführung dieser Übung aus einer beliebigen Einheit zurückgegriffen. Du startest also immer mit einer sinnvollen Referenz.\\n\\nEine neue Einstellung im Bereich „Training\\\" ermöglicht es, stets die aktuellste Historie aus allen Trainings zu verwenden, unabhängig davon, aus welcher Routine sie stammt.\\n\"],\"qJb6G2\":[\"Erneut versuchen\"],\"qP4pOu\":[\"Körpermaße mit Freunden teilen\"],\"qQ5ALI\":[\"Änderungen im Plan speichern?\"],\"qQ8Xkc\":[\"Maschinen-Gewichtsschritt\"],\"qQLn75\":[\"Körperteil auswählen\"],\"qUSLnH\":[\"Beschreibung eingeben\"],\"qZMNNX\":[\"Oberarm (R)\"],\"qaT7mT\":[\"Du verlierst alles, was du bisher eingegeben hast.\"],\"qdLLeB\":[\"Letzte Trainings\"],\"qdalvN\":[\"Deload-Woche aktiv. Vergleich pausiert.\"],\"qeygIa\":[\"Mi\"],\"qlKdB2\":[\"Nein, so lassen\"],\"qtNMEu\":[\"Quads\"],\"qvcKXF\":[\"Tolle Arbeit heute!\"],\"qvolLq\":[\"Masse\"],\"rCROTr\":[\"Kauf mir einen Kaffee\"],\"rLgPvm\":[\"Sichern\"],\"rPj8yN\":[\"Weitere Übungen\"],\"rXJFNV\":[\"Eigenständige Trainings mit Freunden teilen\"],\"rZzMre\":[\"Oberarme\"],\"rickIy\":[\"Training wird gespeichert...\"],\"rjGI_Q\":[\"Datenschutz\"],\"rlNJuG\":[\"Eintragsdetails\"],\"rtypiF\":[\"🎉 Neuigkeiten\"],\"rzjsxH\":[\"Zeit (Minuten:Sekunden)\"],\"s53UX_\":[\"Volumen pro Woche (\",[\"volumeUnit\"],\")\"],\"s6qW4K\":[\"Der Tracking-Typ kann nach der Erstellung nicht mehr geändert werden.\"],\"sAkBSh\":[[\"0\",\"plural\",{\"one\":[\"#\",\" Übung\"],\"other\":[\"#\",\" Übungen\"]}]],\"sHe-bW\":[\"Gib einen Namen ein, um es als wiederverwendbares Training zu speichern.\"],\"sOXSnZ\":[\"Übungsdetails\"],\"sRh2_9\":[\"Deine Trainingspläne\"],\"scHKm4\":[\"Eigenständige Trainings\"],\"sey42b\":[\"Training abgeschlossen!\"],\"slcKOz\":[\"Um Trainingserinnerungen zu aktivieren, erteile Benachrichtigungsberechtigungen in deinen Geräteeinstellungen.\"],\"spvawa\":[\"Deload-Trainings aus Übungsstatistiken ausschließen\"],\"t-VWgS\":[\"Trainings pro Woche\"],\"t1WtPm\":[\"vs. PR\"],\"t5tvzw\":[\"Fügt einen Veröffentlichungsschalter pro Plan hinzu.\"],\"t7OD9_\":[\"Trapez\"],\"t9rBTs\":[[\"0\"],\": \",[\"best\"],[\"unit\"],\" (+\",[\"delta\"],[\"unit\"],\", \",[\"pctStr\"],\")\"],\"tBmnPU\":[\"Freunde\"],\"tCHU1b\":[\"Körperteile\"],\"tLdxsV\":[\"MuscleQuest.app\"],\"tXYsgg\":[\"Jeder Messeintrag, den du erfasst, wird automatisch geteilt.\"],\"tXkhj_\":[\"Starten\"],\"t_YqKh\":[\"Entfernen\"],\"tcZ16z\":[\"\\n💾 Neu: Trainingsänderungen in deinen Plan zurückspeichern!\\n\\nWenn du eine Einheit beendest, in der du Übungen oder Sätze hinzugefügt, entfernt oder neu angeordnet hast, wirst du gefragt, ob du diese Änderungen in den ursprünglichen Plan oder das eigenständige Training zurückspeichern möchtest, damit dein Training automatisch aktuell bleibt.\\n\"],\"tfDRzk\":[\"Speichern\"],\"tj-hng\":[\"Handgelenke\"],\"tlcz2i\":[\"Keine Daten für diesen Zeitraum.\"],\"twA2hZ\":[\"Beine\"],\"tyb5gZ\":[\"Pausenzeit (Minuten:Sekunden)\"],\"u0F1Ey\":[\"Do\"],\"u0Vng2\":[\"Noch sehr starker Muskelkater\"],\"u16ECS\":[\"Download abgeschlossen\"],\"uGkCJQ\":[\"EZ-Stange\"],\"uIVkKI\":[\"Anmelden\"],\"uP80lb\":[\"Update bereit\"],\"ue_JxE\":[\"Satzübersicht\"],\"ufHAsd\":[\"Name des Trainingsplans\"],\"uyJsf6\":[\"Über\"],\"v2e7py\":[\"Plan erstellen\"],\"v39wLo\":[\"Fortsetzen\"],\"v67n_r\":[\"Richte wiederkehrende Trainingserinnerungen in den Einstellungen ein. Wähle die Wochentage, an denen du erinnert werden möchtest, über die Tag-Chips aus und lege eine Uhrzeit fest. Du erhältst eine Benachrichtigung zu dieser Uhrzeit an jedem ausgewählten Tag. Die Benachrichtigungsberechtigung muss erteilt sein, damit Erinnerungen funktionieren.\"],\"vCrBBg\":[\"Übernimm die volle Kontrolle über dein Training, indem du deinen eigenen personalisierten Plan erstellst. Wähle Übungen, lege Wiederholungsbereiche, Pausenzeiten und mehr fest, um einen Plan zu erstellen, der perfekt zu deinen Fitnesszielen passt.\"],\"vFte8a\":[\"Supersatz erstellen\"],\"vLSd93\":[\"Satztypen\"],\"vLyv1R\":[\"Ausblenden\"],\"vPWLpz\":[\"Maßeinheiten\"],\"vV1rrV\":[[\"suggestedRepsMin\"],\" Wdh. vorgeschlagen\"],\"vbOlQu\":[\"Bild konnte nicht ausgewählt werden. Bitte versuche es erneut.\"],\"vbfDgJ\":[\"Noch keine Trainings\"],\"vcpc5o\":[\"Menü schließen\"],\"vmatEA\":[\"Daten werden geladen, bitte warten...\"],\"vq2WxD\":[\"Di\"],\"vqV9pV\":[\"Neuer Plan\"],\"vyQFtJ\":[[\"0\"],\" abgeschlossen!\"],\"w55mIe\":[\"aktiver Plan\"],\"w95UZr\":[\"Bestwert \",[\"maxDist\"],[\"distanceUnit\"]],\"wBAK8Q\":[\"Körperteil ist erforderlich.\"],\"wL3cK8\":[\"Aktuell\"],\"wL7wrB\":[\"Gewichtsschritt\"],\"wUwyC0\":[\"Serie\"],\"wYwS57\":[\"Einstellungen anpassen\"],\"wckWOP\":[\"Verwalten\"],\"wgbq86\":[\"Neustart fehlgeschlagen\"],\"wiIJoN\":[\"Plandetails\"],\"wpLp4M\":[\"Assistenz\"],\"wvxWx2\":[\"Trapezmuskel\"],\"wxKcF0\":[\"Über den Entwickler\"],\"x5LlnE\":[\"Statistikoptionen\"],\"xGVfLh\":[\"Fortfahren\"],\"xM_hqb\":[\"Assistenz \"],\"xMidTh\":[\"Alle Körperteile\"],\"xRGBk4\":[\"Fertige Pläne erkunden\"],\"xVhQZV\":[\"Fr\"],\"xYxQCZ\":[[\"0\"],\" \",[\"1\"]],\"xx7Wjz\":[\"Übungsdetails konnten nicht geladen werden.\"],\"y04OSh\":[\"Trainingshistorie\"],\"y3CwcG\":[\"Bestwert \",[\"maxTime\"],\"s\"],\"y8le-Z\":[\"Training\"],\"yAeHP4\":[\"Keine Daten verfügbar.\"],\"yBSiRY\":[\"Deload-Woche\"],\"yKu_3Y\":[\"Wiederherstellen\"],\"yUWaVv\":[\"Crosstrainer\"],\"yWCES-\":[\"Sekundäre Muskeln:\"],\"y_0uwd\":[\"Gestern\"],\"y_f0Ik\":[\"Öffnet sich in deinem Browser\"],\"yf16RU\":[\"Aufwärmen\"],\"ygCKqB\":[\"Stopp\"],\"yhrNcC\":[\"Fehler beim Speichern des Bildes\"],\"ykve2U\":[\"Satz hinzufügen\"],\"ysv0WA\":[\"Zu meinen Übungen hinzugefügt\"],\"yu1K_Z\":[\"Keine Sätze\"],\"z1-0FW\":[\"Verfolge deine Trainings, behalte den Fortschritt im Blick und erreiche deine Fitnessziele. MuscleQuest macht deine Fitnessreise einfach und effektiv.\\n\\nWische durch die Einführungskarten, um mehr über die App zu erfahren.\"],\"z44QLk\":[\"Sicherung wiederherstellen\"],\"z5uobd\":[\"Tippe auf das Sternsymbol oben rechts in einer Übungsinfoansicht, um sie als Favorit zu markieren. Favoritisierte Übungen erscheinen oben in der Übungsauswahl beim Erstellen oder Bearbeiten von Trainings, damit die Übungen, die du am häufigsten verwendest, immer schnell erreichbar sind.\"],\"zAhZMD\":[\"• Trainingspläne mit anderen teilen *\"],\"zAt78k\":[\"Pausentimer\"],\"zDq2cZ\":[\"Taille\"],\"zEHmq8\":[\"Der Pläne-Tab enthält eine Bibliothek vorgefertigter Trainingsprogramme, die du sofort starten kannst. Scrolle an Deine Trainingspläne vorbei, um den Bereich Vorgefertigte Pläne zu finden. Tippe auf ein Programm, um seine Trainings und den Zeitplan in der Vorschau anzuzeigen, dann tippe auf Aktivieren, um es zu deinem aktiven Plan zu machen. Du kannst einen vorgefertigten Plan bearbeiten, um Übungen, Sätze oder den Wochenplan anzupassen. Dabei wird eine Kopie des vorgefertigten Plans erstellt, die du ohne Auswirkungen auf das Original ändern kannst, sodass du bei Bedarf immer zur Standardversion zurückkehren kannst.\"],\"zIFP3N\":[\"Lege dein wöchentliches Trainingsziel fest und gib dein Körpergewicht ein, um genaue Statistiken und Empfehlungen zu erhalten. Du kannst auch deine Gewichtserhöhungseinstellungen anpassen, bevorzugte Einheiten wählen und vieles mehr.\"],\"zNnnyF\":[\"Waden\"],\"zOwYV3\":[\"Du hast dieses Training geändert. Änderungen für zukünftige Sitzungen speichern?\"],\"zeFzVj\":[\"Aktivieren, um Kraft-PRs nach jedem Training automatisch zu teilen.\"],\"zga9sT\":[\"OK\"],\"zhIkkH\":[\"Ziel: \",[\"goalLabel\"],[\"0\"]],\"zsaR7t\":[\"Gerät & Tracking\"],\"zt6jiv\":[\"Kein Fortschritts-Tracking für diesen Übungstyp.\"],\"zuwyEJ\":[\"Füge Übungen hinzu, um loszulegen\"],\"zzDlyQ\":[\"Erfolg\"]}")}; \ No newline at end of file diff --git a/locales/de/messages.po b/locales/de/messages.po index 72963b00..debaf205 100644 --- a/locales/de/messages.po +++ b/locales/de/messages.po @@ -165,6 +165,28 @@ msgstr "" "Ein Fehler wurde behoben, bei dem alle Schaltflächen (erhöhen/verringern, nächster/vorheriger Satz, Satz abschließen) nach dem Abschließen eines Satzes nicht mehr funktionierten. Außerdem wurde ein Fehler im Satz-Bearbeiten-Fenster behoben. Satzübergänge erfolgen jetzt sofort für einen flüssigeren Trainingsablauf.\n" "" +#: constants/WhatsNew.ts:305 +msgid "" +"\n" +"👥 New: Friends & Social Sharing!\n" +"\n" +"Add friends by searching for their username from the Friends tab in the menu. Send a request, and once accepted you can browse each other's shared content. A badge on the Friends menu item shows pending incoming requests.\n" +"\n" +"Share your plans, standalone workouts, custom exercises, body measurements, and strength PRs by toggling Share in the relevant screen or from Privacy Settings in the Account section of Settings. Shared content syncs automatically whenever it changes, and a cloud icon on plan and workout cards shows what is currently published. You can delete all shared data for any category from Privacy Settings at any time.\n" +"\n" +"Tap any accepted friend's name to open their profile and import their plans, standalone workouts, or custom exercises directly into your own library.\n" +"" +msgstr "" +"\n" +"👥 Neu: Freunde & Social Sharing!\n" +"\n" +"Füge Freunde hinzu, indem du nach ihrem Nutzernamen im Freunde-Tab im Menü suchst. Sende eine Anfrage – sobald sie angenommen wird, könnt ihr gegenseitig eure geteilten Inhalte durchstöbern. Ein Badge am Freunde-Menüpunkt zeigt ausstehende eingehende Anfragen.\n" +"\n" +"Teile deine Pläne, eigenständigen Trainings, eigene Übungen, Körpermaße und Kraft-PRs, indem du in der jeweiligen Ansicht oder in den Datenschutzeinstellungen im Konto-Bereich der Einstellungen den Teilen-Schalter aktivierst. Geteilte Inhalte werden automatisch synchronisiert, wenn sie sich ändern, und ein Wolken-Symbol auf Plan- und Trainingskarten zeigt an, was gerade veröffentlicht ist. Du kannst alle geteilten Daten einer Kategorie jederzeit über die Datenschutzeinstellungen löschen.\n" +"\n" +"Tippe auf den Namen eines akzeptierten Freundes, um sein Profil zu öffnen und seine Pläne, eigenständigen Trainings oder eigenen Übungen direkt in deine eigene Bibliothek zu importieren.\n" +"" + #: constants/WhatsNew.ts:204 msgid "" "\n" @@ -224,7 +246,7 @@ msgstr "" #: constants/WhatsNew.ts:293 msgid "" "\n" -"📈 New: Adaptive Progression!\n" +"📈 Beta: Adaptive Progression!\n" "\n" "MuscleQuest can now suggest when to increase your weight or reps based on how your sessions feel. After each exercise, answer two quick questions about effort and pain. Once you have reported the same signal for two sessions in a row, the app suggests a change. All suggestions appear in the Workout Summary screen, where you can accept or dismiss each one individually. Accepted suggestions are pre-filled into your next session automatically.\n" "\n" @@ -234,7 +256,7 @@ msgid "" "" msgstr "" "\n" -"📈 Neu: Adaptive Progression!\n" +"📈 Beta: Adaptive Progression!\n" "\n" "MuscleQuest kann dir jetzt vorschlagen, wann du dein Gewicht oder deine Wiederholungen erhöhen solltest, basierend auf dem Gefühl deiner Einheiten. Beantworte nach jeder Übung zwei kurze Fragen zu Anstrengung und Schmerzen. Sobald du dasselbe Signal zwei Einheiten in Folge gemeldet hast, schlägt die App eine Änderung vor. Alle Vorschläge erscheinen im Trainingsübersichtsbildschirm, wo du jeden einzeln annehmen oder ablehnen kannst. Angenommene Vorschläge werden automatisch in deine nächste Einheit vorgefüllt.\n" "\n" @@ -531,11 +553,11 @@ msgstr "" "Der Pläne-Bildschirm hat jetzt drei Anzeigemodi. Nutze die Symbole neben der Überschrift „Deine Trainingspläne“, um zwischen Karussell-, Listen- und Rasteransicht zu wechseln. Deine bevorzugte Darstellung wird automatisch gespeichert.\n" "" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:179 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:191 msgid " (to Failure)" msgstr " (bis zum Versagen)" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:186 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:198 msgid " (to Failure) " msgstr " (bis zum Versagen) " @@ -581,7 +603,7 @@ msgid "{0, plural, one {# Set} other {# Sets}}" msgstr "{0, plural, one {# Satz} other {# Sätze}}" #. placeholder {0}: plan.workouts.length -#: components/TrainingPlanListItem.tsx:60 +#: components/TrainingPlanListItem.tsx:71 msgid "{0, plural, one {# workout} other {# workouts}}" msgstr "{0, plural, one {# Training} other {# Trainings}}" @@ -597,13 +619,13 @@ msgstr "{0, plural, one {Satz} other {Sätze}}" #. placeholder {0}: settings?.weightIncrement #. placeholder {1}: settings?.weightUnit -#: app/(app)/settings.tsx:758 +#: app/(app)/settings.tsx:794 msgid "{0} {1}" msgstr "{0} {1}" #. placeholder {0}: settings?.bodyWeight #. placeholder {1}: settings?.weightUnit -#: app/(app)/settings.tsx:583 +#: app/(app)/settings.tsx:619 msgid "{0} {1} (used for assisted exercises)" msgstr "{0} {1} (für Assistenzübungen verwendet)" @@ -620,7 +642,7 @@ msgid "{0} Complete!" msgstr "{0} abgeschlossen!" #. placeholder {0}: settings?.weeklyGoal -#: app/(app)/settings.tsx:561 +#: app/(app)/settings.tsx:597 msgid "{0} days per week" msgstr "{0} Tage pro Woche" @@ -628,7 +650,7 @@ msgstr "{0} Tage pro Woche" #. placeholder {0}: workout.exercises.length #. placeholder {1}: estimate ? ` · ~${formatDurationEstimate(estimate)}` : "" #. placeholder {1}: estimate ? ` · ~${formatDurationEstimateCompact(estimate)}` : "" -#: app/(app)/(tabs)/(plans)/overview.tsx:78 +#: app/(app)/(tabs)/(plans)/overview.tsx:82 #: app/(app)/(tabs)/index.tsx:57 msgid "{0} Exercises{1}" msgstr "{0} Übungen{1}" @@ -650,18 +672,18 @@ msgstr "{0} Wdh." #. placeholder {0}: settings?.restTimerIncrement #. placeholder {0}: settings?.timerCountdown || "5" -#: app/(app)/settings.tsx:786 -#: app/(app)/settings.tsx:812 +#: app/(app)/settings.tsx:822 +#: app/(app)/settings.tsx:848 msgid "{0} seconds" msgstr "{0} Sekunden" #. placeholder {0}: settings?.defaultSets -#: app/(app)/settings.tsx:1369 +#: app/(app)/settings.tsx:1408 msgid "{0} sets" msgstr "{0} Sätze" #. placeholder {0}: item.sets.length -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:176 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:188 #: components/WorkoutDetailsScreen.tsx:141 msgid "{0} Sets" msgstr "{0} Sätze" @@ -786,7 +808,7 @@ msgid "+ Add" msgstr "+ Hinzufügen" #: app/(app)/(workout)/index.tsx:1153 -#: app/(app)/(workout)/workout-session.tsx:1559 +#: app/(app)/(workout)/workout-session.tsx:1591 msgid "+{restTimerIncrement}s" msgstr "+{restTimerIncrement}s" @@ -795,7 +817,7 @@ msgid "+{suggestedWeight}{unit} suggested" msgstr "+{suggestedWeight}{unit} vorgeschlagen" #: app/(app)/(workout)/index.tsx:1142 -#: app/(app)/(workout)/workout-session.tsx:1548 +#: app/(app)/(workout)/workout-session.tsx:1580 msgid "−{restTimerIncrement}s" msgstr "−{restTimerIncrement}s" @@ -836,7 +858,7 @@ msgstr "Eine Deload-Woche ist eine geplante Erholungswoche, in der du mit reduzi msgid "A new version has been downloaded. Tap the button below to restart and apply the update." msgstr "Eine neue Version wurde heruntergeladen. Tippe die Schaltfläche unten, um die App neu zu starten und das Update anzuwenden." -#: app/_layout.tsx:91 +#: app/_layout.tsx:97 msgid "A render error has occurred. Press the button to reload." msgstr "Es ist ein Darstellungsfehler aufgetreten. Drücke die Schaltfläche, um neu zu laden." @@ -844,15 +866,15 @@ msgstr "Es ist ein Darstellungsfehler aufgetreten. Drücke die Schaltfläche, um msgid "abductors" msgstr "Abduktoren" -#: app/(app)/settings.tsx:1560 +#: app/(app)/settings.tsx:1873 msgid "About" msgstr "Über" -#: components/ExerciseFeedbackSheet.tsx:37 +#: components/ExerciseFeedbackSheet.tsx:38 msgid "About right" msgstr "Passt so" -#: app/(app)/settings.tsx:1649 +#: app/(app)/settings.tsx:1962 msgid "About the developer" msgstr "Über den Entwickler" @@ -860,6 +882,7 @@ msgstr "Über den Entwickler" msgid "abs" msgstr "Bauch" +#: components/friends/FriendRequestItem.tsx:47 #: components/ProgressionSummaryCard.tsx:145 msgid "Accept" msgstr "Übernehmen" @@ -868,13 +891,13 @@ msgstr "Übernehmen" msgid "Accept all" msgstr "Alle übernehmen" -#: constants/HelpData.ts:164 +#: constants/HelpData.ts:184 msgid "Account" msgstr "Konto" -#: app/(app)/(tabs)/(plans)/overview.tsx:222 -#: components/TrainingPlanCard.tsx:80 -#: components/TrainingPlanListItem.tsx:54 +#: app/(app)/(tabs)/(plans)/overview.tsx:233 +#: components/TrainingPlanCard.tsx:83 +#: components/TrainingPlanListItem.tsx:56 msgid "Active" msgstr "Aktiv" @@ -899,16 +922,23 @@ msgstr "Aktiver Plan: {0}" msgid "Active Workout" msgstr "Aktives Training" -#: app/(app)/settings.tsx:1076 #: constants/HelpData.ts:64 msgid "Adaptive Progression" msgstr "Adaptive Progression" +#: app/(app)/settings.tsx:1112 +msgid "Adaptive Progression (beta)" +msgstr "Adaptive Progression (Beta)" + #: constants/HelpData.ts:69 msgid "Adaptive Progression analyses your effort feedback over consecutive sessions and suggests when to increase your weight, reps, or sets. Enable it in Settings under Adaptive Progression. Once on, a short feedback prompt appears after each exercise in plan-based workouts. The engine requires two sessions with the same signal before recommending an upward change, filtering out one-off easy days and ensuring consistent performance before suggesting an increase. Pain or failed sets act immediately regardless of your session history. A suggestion is never applied to your workout without your explicit approval. You can also configure your preferred load increment per equipment category in the same section of Settings, for example 2.5 kg for barbell exercises and 2.0 kg for dumbbells." msgstr "Adaptive Progression analysiert dein Anstrengungsfeedback über aufeinanderfolgende Einheiten und schlägt vor, wann du dein Gewicht, deine Wiederholungen oder Sätze erhöhen solltest. Aktiviere es in den Einstellungen unter Adaptive Progression. Sobald aktiviert, erscheint nach jeder Übung in planbasierten Trainings eine kurze Feedbackabfrage. Das System benötigt zwei Einheiten mit demselben Signal, bevor es eine Steigerung empfiehlt, sodass einmalige leichte Tage herausgefiltert werden und eine gleichbleibende Leistung vor einem Vorschlag sichergestellt wird. Schmerzen oder nicht abgeschlossene Sätze werden sofort berücksichtigt, unabhängig von deiner Einheitenhistorie. Ein Vorschlag wird deinem Training nie ohne deine ausdrückliche Bestätigung angewendet. Du kannst auch deinen bevorzugten Gewichtsschritt pro Gerätekategorie im selben Abschnitt der Einstellungen konfigurieren, zum Beispiel 2,5 kg für Langhantelübungen und 2,0 kg für Kurzhanteln." #: app/(app)/(tabs)/(stats)/measurements-manage.tsx:167 +#: app/(app)/friend-profile.tsx:218 +#: app/(app)/friend-profile.tsx:310 +#: app/(app)/friend-profile.tsx:397 +#: app/(app)/friends.tsx:291 #: components/Notes.tsx:87 msgid "Add" msgstr "Hinzufügen" @@ -944,7 +974,7 @@ msgstr "Übung hinzufügen" msgid "Add exercises to get started" msgstr "Füge Übungen hinzu, um loszulegen" -#: app/(app)/custom-exercise.tsx:324 +#: app/(app)/custom-exercise.tsx:350 msgid "Add Image" msgstr "Bild hinzufügen" @@ -957,6 +987,18 @@ msgstr "Persönliche Notizen hinzufügen" msgid "Add Set" msgstr "Satz hinzufügen" +#: app/(app)/friend-exercise.tsx:161 +msgid "Add to my exercises" +msgstr "Zu meinen Übungen hinzufügen" + +#: app/(app)/friend-plan.tsx:177 +msgid "Add to my plans" +msgstr "Zu meinen Plänen hinzufügen" + +#: app/(app)/friend-workout.tsx:136 +msgid "Add to my workouts" +msgstr "Zu meinen Trainings hinzufügen" + #: app/(app)/(create-plan)/sets-overview.tsx:257 msgid "Add Warm-up" msgstr "Aufwärmsatz hinzufügen" @@ -969,6 +1011,28 @@ msgstr "Gewicht hinzufügen" msgid "Add Workout" msgstr "Training hinzufügen" +#: app/(app)/friend-profile.tsx:216 +#: app/(app)/friend-profile.tsx:308 +#: app/(app)/friend-profile.tsx:395 +msgid "Added" +msgstr "Hinzugefügt" + +#: app/(app)/friend-exercise.tsx:159 +msgid "Added to my exercises" +msgstr "Zu meinen Übungen hinzugefügt" + +#: app/(app)/friend-plan.tsx:175 +msgid "Added to my plans" +msgstr "Zu meinen Plänen hinzugefügt" + +#: app/(app)/friend-workout.tsx:134 +msgid "Added to my workouts" +msgstr "Zu meinen Trainings hinzugefügt" + +#: constants/HelpData.ts:168 +msgid "Adding Friends" +msgstr "Freunde hinzufügen" + #: constants/dbTranslations.ts:22 msgid "adductors" msgstr "Adduktoren" @@ -1003,6 +1067,10 @@ msgstr "Alle Bilder erfolgreich gelöscht!" msgid "All images downloaded successfully!" msgstr "Alle Bilder erfolgreich heruntergeladen!" +#: app/(app)/settings.tsx:98 +msgid "All shared data has been removed." +msgstr "Alle geteilten Daten wurden entfernt." + #: components/FilterRow.tsx:62 #: components/FilterRow.tsx:114 #: components/FilterRow.tsx:204 @@ -1017,7 +1085,7 @@ msgstr "Gesamt" msgid "All-time PR" msgstr "Bester PR aller Zeiten" -#: app/(app)/settings.tsx:974 +#: app/(app)/settings.tsx:1010 msgid "Always use most recent exercise history" msgstr "Immer aktuellste Übungshistorie verwenden" @@ -1037,11 +1105,11 @@ msgstr "Knöchelstabilisatoren" msgid "ankles" msgstr "Knöchel" -#: components/ExerciseFeedbackSheet.tsx:191 +#: components/ExerciseFeedbackSheet.tsx:205 msgid "Any pain or form breakdown?" msgstr "Schmerzen oder Formprobleme?" -#: app/(app)/settings.tsx:1440 +#: app/(app)/settings.tsx:1479 msgid "Appearance" msgstr "Erscheinungsbild" @@ -1055,7 +1123,7 @@ msgid "Are you sure you want to cancel and delete this workout?" msgstr "Möchtest du dieses Training wirklich abbrechen und löschen?" #. placeholder {0}: workout?.name ?? "" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:81 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:93 msgid "Are you sure you want to delete \"{0}\"?" msgstr "Möchtest du \"{0}\" wirklich löschen?" @@ -1071,11 +1139,11 @@ msgstr "Möchtest du diese Übung wirklich löschen?" msgid "Are you sure you want to delete this measurement entry?" msgstr "Bist du sicher, dass du diesen Messeintrag löschen möchtest?" -#: app/(app)/(tabs)/(plans)/overview.tsx:118 +#: app/(app)/(tabs)/(plans)/overview.tsx:129 msgid "Are you sure you want to delete this plan?" msgstr "Möchtest du diesen Plan wirklich löschen?" -#: app/(app)/(workout)/workout-session.tsx:710 +#: app/(app)/(workout)/workout-session.tsx:717 msgid "Are you sure you want to delete this set?" msgstr "Möchtest du diesen Satz wirklich löschen?" @@ -1100,7 +1168,7 @@ msgstr "Möchtest du dieses Training wirklich entfernen?" msgid "Are you sure you want to restart this workout?" msgstr "Möchtest du dieses Training wirklich neu starten?" -#: app/(app)/settings.tsx:460 +#: app/(app)/settings.tsx:496 msgid "Are you sure you want to restore the backup?" msgstr "Möchtest du die Sicherung wirklich wiederherstellen?" @@ -1129,7 +1197,7 @@ msgstr "Assistenz" msgid "assistance " msgstr "Assistenz " -#: app/(app)/custom-exercise.tsx:63 +#: app/(app)/custom-exercise.tsx:68 msgid "Assistance/Reps" msgstr "Assistenz/Wdh." @@ -1142,15 +1210,15 @@ msgstr "Ø Dauer" msgid "back" msgstr "Rücken" -#: app/(app)/settings.tsx:622 +#: app/(app)/settings.tsx:658 msgid "Backup" msgstr "Sichern" -#: constants/HelpData.ts:173 +#: constants/HelpData.ts:193 msgid "Backup & Restore" msgstr "Sichern & Wiederherstellen" -#: app/(app)/settings.tsx:600 +#: app/(app)/settings.tsx:636 msgid "Backup and restore" msgstr "Sichern und wiederherstellen" @@ -1158,11 +1226,11 @@ msgstr "Sichern und wiederherstellen" msgid "barbell" msgstr "Langhantel" -#: app/(app)/settings.tsx:1122 +#: app/(app)/settings.tsx:1160 msgid "Barbell load increment" msgstr "Langhantel-Gewichtsschritt" -#: app/(app)/custom-exercise.tsx:309 +#: app/(app)/custom-exercise.tsx:335 msgid "Basics" msgstr "Grundlagen" @@ -1202,15 +1270,20 @@ msgid "Body Fat" msgstr "Körperfett" #: app/(app)/(tabs)/(stats)/index.tsx:553 +#: app/(app)/friend-profile.tsx:458 #: constants/HelpData.ts:143 msgid "Body Measurements" msgstr "Körpermaße" -#: app/(app)/custom-exercise.tsx:372 +#: app/(app)/friend-exercise.tsx:70 +msgid "Body Part" +msgstr "Körperteil" + +#: app/(app)/custom-exercise.tsx:398 msgid "Body Part *" msgstr "Körperteil *" -#: app/(app)/custom-exercise.tsx:201 +#: app/(app)/custom-exercise.tsx:206 msgid "Body part is required." msgstr "Körperteil ist erforderlich." @@ -1222,7 +1295,7 @@ msgstr "Körperteile" msgid "body weight" msgstr "Körpergewicht" -#: app/(app)/settings.tsx:580 +#: app/(app)/settings.tsx:616 msgid "Body weight" msgstr "Körpergewicht" @@ -1246,15 +1319,15 @@ msgstr "Durchsuche fast 1.000 Übungen und filtere nach Körperteil, Zielmuskel msgid "Built-in Metrics" msgstr "Integrierte Messwerte" -#: app/(app)/settings.tsx:1484 +#: app/(app)/settings.tsx:1523 msgid "Button size during workout" msgstr "Schaltflächengröße beim Training" -#: app/(app)/settings.tsx:1596 +#: app/(app)/settings.tsx:1909 msgid "Buy me a coffee" msgstr "Kauf mir einen Kaffee" -#: components/AppMenu.tsx:202 +#: components/AppMenu.tsx:220 msgid "Buy Me a Coffee" msgstr "Kauf mir einen Kaffee" @@ -1262,7 +1335,7 @@ msgstr "Kauf mir einen Kaffee" msgid "cable" msgstr "Kabelzug" -#: app/(app)/settings.tsx:1176 +#: app/(app)/settings.tsx:1214 msgid "Cable load increment" msgstr "Kabel-Gewichtsschritt" @@ -1281,17 +1354,19 @@ msgstr "Waden" #: app/(app)/(create-plan)/create-workout.tsx:174 #: app/(app)/(create-plan)/create.tsx:234 #: app/(app)/(create-plan)/create.tsx:279 -#: app/(app)/(tabs)/(plans)/overview.tsx:121 -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:83 +#: app/(app)/(tabs)/(plans)/overview.tsx:132 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:95 #: app/(app)/(tabs)/(stats)/history-details.tsx:173 #: app/(app)/(tabs)/(stats)/measurements-detail.tsx:118 #: app/(app)/(tabs)/(stats)/measurements-manage.tsx:85 #: app/(app)/(workout)/index.tsx:405 #: app/(app)/(workout)/index.tsx:1007 -#: app/(app)/(workout)/workout-session.tsx:711 -#: app/(app)/settings.tsx:387 -#: app/(app)/settings.tsx:462 +#: app/(app)/(workout)/workout-session.tsx:718 +#: app/(app)/settings.tsx:90 +#: app/(app)/settings.tsx:423 +#: app/(app)/settings.tsx:498 #: components/EditSetModal.tsx:454 +#: components/friends/FriendListItem.tsx:24 #: components/SettingsModal.tsx:282 #: components/WorkoutCard.tsx:87 #: hooks/useImageManagement.ts:25 @@ -1315,11 +1390,11 @@ msgstr "Cardio" msgid "cardiovascular system" msgstr "Herz-Kreislauf-System" -#: app/(app)/custom-exercise.tsx:324 +#: app/(app)/custom-exercise.tsx:350 msgid "Change Image" msgstr "Bild ändern" -#: app/(app)/settings.tsx:606 +#: app/(app)/settings.tsx:642 msgid "Checking for backups..." msgstr "Sicherungen werden gesucht..." @@ -1344,8 +1419,8 @@ msgstr "Suche löschen" msgid "Clears the search field" msgstr "Löscht das Suchfeld" -#: components/AppMenu.tsx:146 -#: components/AppMenu.tsx:168 +#: components/AppMenu.tsx:156 +#: components/AppMenu.tsx:178 msgid "Close menu" msgstr "Menü schließen" @@ -1383,15 +1458,19 @@ msgstr "Bearbeitung fortsetzen?" msgid "core" msgstr "Core" -#: components/ExerciseFeedbackSheet.tsx:39 +#: app/(app)/friend-exercise.tsx:143 +msgid "Could not add this exercise. Please try again." +msgstr "Übung konnte nicht hinzugefügt werden. Bitte versuche es erneut." + +#: components/ExerciseFeedbackSheet.tsx:40 msgid "Couldn't finish all sets" msgstr "Nicht alle Sätze geschafft" -#: app/(app)/custom-exercise.tsx:508 +#: app/(app)/custom-exercise.tsx:534 msgid "Count reps ×2 for volume when the setting is enabled" msgstr "Wiederholungen ×2 für Volumen zählen, wenn die Einstellung aktiviert ist" -#: app/(app)/settings.tsx:1035 +#: app/(app)/settings.tsx:1071 msgid "Counting reps ×2 for these exercises" msgstr "Wiederholungen ×2 für diese Übungen zählen" @@ -1404,7 +1483,7 @@ msgid "Create a Plan" msgstr "Plan erstellen" #: app/(app)/(create-plan)/exercises.tsx:360 -#: app/(app)/custom-exercise.tsx:71 +#: app/(app)/custom-exercise.tsx:76 msgid "Create Exercise" msgstr "Übung erstellen" @@ -1426,10 +1505,15 @@ msgstr "Training erstellen" msgid "Create your own exercises from the exercise picker. Give it a name, an optional image, body part, target muscles, secondary muscles, and equipment. Choose a tracking type: weight + reps, time, distance, reps only, or assisted (which factors in your body weight for movements like assisted pull-ups). Toggle Unilateral for single-arm or single-leg exercises; reps can be automatically doubled in your stats. Toggle Paired Implements if you track the weight of one implement rather than the total: for example, if you log 20 kg for one dumbbell, the app counts 40 kg toward your volume." msgstr "Erstelle eigene Übungen über die Übungsauswahl. Gib einen Namen, ein optionales Bild, Körperteil, Zielmuskeln, sekundäre Muskeln und Gerät an. Wähle einen Tracking-Typ: Gewicht + Wdh., Zeit, Distanz, nur Wdh. oder Assistenz (berücksichtigt dein Körpergewicht für Bewegungen wie assistierte Klimmzüge). Aktiviere Einseitig für Einarm- oder Einbeinübungen; Wiederholungen können in den Statistiken automatisch verdoppelt werden. Aktiviere Gepaarte Geräte, wenn du das Gewicht eines Geräts statt des Gesamtgewichts protokollierst, zum Beispiel wenn du 20 kg für eine Kurzhantel eingibst und die App 40 kg für dein Volumen zählt." +#: app/(app)/friend-profile.tsx:326 #: constants/HelpData.ts:113 msgid "Custom Exercises" msgstr "Eigene Übungen" +#: app/(app)/settings.tsx:1701 +msgid "Custom exercises you create or edit are shared automatically." +msgstr "Eigene Übungen, die du erstellst oder bearbeitest, werden automatisch geteilt." + #: app/(app)/(tabs)/(stats)/measurements-manage.tsx:204 msgid "Custom Metrics" msgstr "Eigene Messwerte" @@ -1438,7 +1522,7 @@ msgstr "Eigene Messwerte" msgid "Customisation" msgstr "Anpassung" -#: app/(app)/(tabs)/(plans)/overview.tsx:306 +#: app/(app)/(tabs)/(plans)/overview.tsx:351 msgid "Customise Plan" msgstr "Plan anpassen" @@ -1446,30 +1530,43 @@ msgstr "Plan anpassen" msgid "Customise Your Settings" msgstr "Einstellungen anpassen" +#: components/friends/FriendRequestItem.tsx:56 +msgid "Decline" +msgstr "Ablehnen" + #: components/ExerciseSortChips.tsx:27 msgid "Default" msgstr "Standard" -#: app/(app)/settings.tsx:1392 +#: app/(app)/settings.tsx:1431 msgid "Default rest time" msgstr "Standard-Pausenzeit" -#: app/(app)/settings.tsx:1366 +#: app/(app)/settings.tsx:1405 msgid "Default sets" msgstr "Standard-Sätze" -#: app/(app)/(tabs)/(plans)/overview.tsx:125 -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:85 +#: app/(app)/(tabs)/(plans)/overview.tsx:136 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:97 #: app/(app)/(tabs)/(stats)/history-details.tsx:175 #: app/(app)/(tabs)/(stats)/measurements-detail.tsx:120 #: app/(app)/(workout)/index.tsx:407 #: app/(app)/(workout)/index.tsx:629 -#: app/(app)/(workout)/workout-session.tsx:713 +#: app/(app)/(workout)/workout-session.tsx:720 +#: app/(app)/settings.tsx:92 #: components/WorkoutCard.tsx:298 #: hooks/useImageManagement.ts:46 msgid "Delete" msgstr "Löschen" +#: app/(app)/settings.tsx:1862 +msgid "Delete all shared data" +msgstr "Alle geteilten Daten löschen" + +#: app/(app)/settings.tsx:87 +msgid "Delete all shared data?" +msgstr "Alle geteilten Daten löschen?" + #: hooks/useImageManagement.ts:103 msgid "Delete Complete" msgstr "Löschen abgeschlossen" @@ -1483,25 +1580,25 @@ msgstr "Eintrag löschen" msgid "Delete Exercise" msgstr "Übung löschen" -#: app/(app)/(tabs)/(plans)/overview.tsx:117 +#: app/(app)/(tabs)/(plans)/overview.tsx:128 msgid "Delete Plan" msgstr "Plan löschen" -#: app/(app)/(workout)/workout-session.tsx:710 +#: app/(app)/(workout)/workout-session.tsx:717 #: components/SessionSetInfo.tsx:251 msgid "Delete Set" msgstr "Satz löschen" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:80 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:92 #: app/(app)/(tabs)/(stats)/history-details.tsx:170 msgid "Delete Workout" msgstr "Training löschen" -#: app/(app)/settings.tsx:1427 +#: app/(app)/settings.tsx:1466 msgid "Deleting. Please wait..." msgstr "Wird gelöscht. Bitte warten..." -#: app/(app)/(tabs)/(plans)/overview.tsx:265 +#: app/(app)/(tabs)/(plans)/overview.tsx:276 #: app/(app)/(tabs)/index.tsx:472 #: constants/HelpData.ts:88 msgid "Deload Week" @@ -1519,7 +1616,8 @@ msgstr "Deltamuskeln" msgid "delts" msgstr "Schultern" -#: app/(app)/custom-exercise.tsx:347 +#: app/(app)/custom-exercise.tsx:373 +#: app/(app)/friend-exercise.tsx:109 msgid "Description" msgstr "Beschreibung" @@ -1531,19 +1629,19 @@ msgstr "Beschreibung:" msgid "Details" msgstr "Details" -#: app/(app)/settings.tsx:831 -#: app/(app)/settings.tsx:856 -#: app/(app)/settings.tsx:881 -#: app/(app)/settings.tsx:904 -#: app/(app)/settings.tsx:929 -#: app/(app)/settings.tsx:954 -#: app/(app)/settings.tsx:1011 -#: app/(app)/settings.tsx:1036 -#: app/(app)/settings.tsx:1061 -#: app/(app)/settings.tsx:1093 -#: app/(app)/settings.tsx:1227 -#: app/(app)/settings.tsx:1258 -#: app/(app)/settings.tsx:1455 +#: app/(app)/settings.tsx:867 +#: app/(app)/settings.tsx:892 +#: app/(app)/settings.tsx:917 +#: app/(app)/settings.tsx:940 +#: app/(app)/settings.tsx:965 +#: app/(app)/settings.tsx:990 +#: app/(app)/settings.tsx:1047 +#: app/(app)/settings.tsx:1072 +#: app/(app)/settings.tsx:1097 +#: app/(app)/settings.tsx:1129 +#: app/(app)/settings.tsx:1265 +#: app/(app)/settings.tsx:1297 +#: app/(app)/settings.tsx:1494 msgid "Disabled" msgstr "Deaktiviert" @@ -1552,7 +1650,7 @@ msgstr "Deaktiviert" #: app/(app)/(workout)/index.tsx:808 #: app/(app)/(workout)/index.tsx:841 #: app/(app)/(workout)/index.tsx:1037 -#: app/(app)/custom-exercise.tsx:85 +#: app/(app)/custom-exercise.tsx:90 msgid "Discard" msgstr "Verwerfen" @@ -1561,7 +1659,7 @@ msgstr "Verwerfen" msgid "Discard Changes" msgstr "Änderungen verwerfen" -#: app/(app)/custom-exercise.tsx:80 +#: app/(app)/custom-exercise.tsx:85 msgid "Discard changes?" msgstr "Änderungen verwerfen?" @@ -1576,12 +1674,12 @@ msgstr "Änderungen verwerfen?" msgid "Dismiss" msgstr "Schließen" -#: app/(app)/(tabs)/(plans)/overview.tsx:320 +#: app/(app)/(tabs)/(plans)/overview.tsx:365 msgid "DISMISS" msgstr "SCHLIESSEN" #: app/(app)/(tabs)/(stats)/edit-history.tsx:268 -#: app/(app)/custom-exercise.tsx:66 +#: app/(app)/custom-exercise.tsx:71 msgid "Distance" msgstr "Distanz" @@ -1591,21 +1689,22 @@ msgstr "Distanz" msgid "Distance ({distanceUnit})" msgstr "Distanz ({distanceUnit})" -#: app/(app)/settings.tsx:697 +#: app/(app)/settings.tsx:733 msgid "Distance unit" msgstr "Distanzeinheit" #: app/(app)/(workout)/workout-summary.tsx:656 -#: components/ExerciseFeedbackSheet.tsx:261 +#: app/(app)/settings.tsx:98 +#: components/ExerciseFeedbackSheet.tsx:275 #: components/RecoveryCheckInSheet.tsx:191 msgid "Done" msgstr "Fertig" -#: app/(app)/custom-exercise.tsx:528 +#: app/(app)/custom-exercise.tsx:554 msgid "Double the weight for volume when the setting is enabled" msgstr "Gewicht für Volumen verdoppeln, wenn die Einstellung aktiviert ist" -#: app/(app)/settings.tsx:1060 +#: app/(app)/settings.tsx:1096 msgid "Doubling weight for volume calculations" msgstr "Gewicht für Volumenberechnungen verdoppeln" @@ -1613,7 +1712,7 @@ msgstr "Gewicht für Volumenberechnungen verdoppeln" msgid "Download" msgstr "Herunterladen" -#: app/(app)/settings.tsx:1409 +#: app/(app)/settings.tsx:1448 msgid "Download all exercise animations" msgstr "Alle Übungsanimationen herunterladen" @@ -1635,7 +1734,7 @@ msgstr "Bilder herunterladen" msgid "Downloading Update" msgstr "Update wird heruntergeladen" -#: app/(app)/settings.tsx:1426 +#: app/(app)/settings.tsx:1465 msgid "Downloading. Please wait..." msgstr "Wird heruntergeladen. Bitte warten..." @@ -1657,7 +1756,7 @@ msgstr "Dropsatz, " msgid "dumbbell" msgstr "Kurzhantel" -#: app/(app)/settings.tsx:1149 +#: app/(app)/settings.tsx:1187 msgid "Dumbbell load increment" msgstr "Kurzhantel-Gewichtsschritt" @@ -1670,25 +1769,33 @@ msgstr "Dauer" msgid "During a session, swipe left/right or use the arrow buttons to move between sets. Enter your weight and reps, then tap Complete Set. The total elapsed time is shown in the header throughout. You can drag the handle on any exercise card to reorder exercises while the session is in progress. Time-based exercises have a Start Timer button that opens a count-up timer with a progress ring that shows you when you hit your goal time but you can keep going as long as you like. Notes can be added per-exercise via the notes icon in the exercise header, per workout from the workout overview screen, or per plan from the plan overview screen. If you add, remove, or reorder exercises or sets during a session, you will be prompted at the end to save those changes back to the original workout or plan." msgstr "Wische während einer Einheit nach links/rechts oder nutze die Pfeilschaltflächen, um zwischen Sätzen zu wechseln. Gib Gewicht und Wiederholungen ein und tippe dann auf Satz abschließen. Die gesamte vergangene Zeit wird durchgehend in der Kopfzeile angezeigt. Du kannst den Anfasser einer Übungskarte ziehen, um Übungen während der Einheit neu anzuordnen. Zeitbasierte Übungen haben eine Schaltfläche Timer starten, die einen Vorwärts-Timer mit einem Fortschrittsring öffnet, der anzeigt, wann du deine Zielzeit erreichst, du kannst aber so lange weitermachen wie du möchtest. Notizen können pro Übung über das Notizensymbol in der Übungsüberschrift, pro Training über den Trainingsübersichtsbildschirm oder pro Plan über den Planübersichtsbildschirm hinzugefügt werden. Wenn du während einer Einheit Übungen oder Sätze hinzufügst, entfernst oder neu anordnest, wirst du am Ende gefragt, ob du diese Änderungen im ursprünglichen Training oder Plan speichern möchtest." +#: app/(app)/settings.tsx:1783 +msgid "Each measurement entry you record is shared automatically." +msgstr "Jeder Messeintrag, den du erfasst, wird automatisch geteilt." + #: constants/HelpData.ts:99 msgid "Each set can be flagged as a Warm-up, Drop Set, To Failure, or any combination of these. The badge shown next to a set displays its current type. To change the type during a session, tap the menu (⋮) and toggle the relevant option on or off. When building a plan, use the checkboxes in the set editor; tap Add Warm-up to insert a dedicated warm-up set at the top of the list. Warm-up sets are visually grouped and separated from working sets, and the Apply to All option in the edit modal only affects sets of the same type. Warm-up sets can be excluded from volume and stats calculations in Settings." msgstr "Jeder Satz kann als Aufwärmsatz, Dropsatz, bis zum Versagen oder eine beliebige Kombination davon markiert werden. Das Badge neben einem Satz zeigt seinen aktuellen Typ. Um den Typ während einer Einheit zu ändern, tippe auf das Menü (⋮) und schalte die entsprechende Option ein oder aus. Beim Erstellen eines Plans nutze die Checkboxen im Satz-Editor; tippe auf Aufwärmsatz hinzufügen, um einen dedizierten Aufwärmsatz oben in der Liste einzufügen. Aufwärmsätze werden visuell gruppiert und von Arbeitssätzen getrennt, und die Option Auf alle anwenden im Bearbeitungsfenster betrifft nur Sätze desselben Typs. Aufwärmsätze können in den Einstellungen von Volumen- und Statistikberechnungen ausgeschlossen werden." -#: components/ExerciseFeedbackSheet.tsx:36 +#: app/(app)/settings.tsx:1743 +msgid "Each workout you complete is shared automatically." +msgstr "Jedes Training, das du abschließt, wird automatisch geteilt." + +#: components/ExerciseFeedbackSheet.tsx:37 msgid "Easy, could do more" msgstr "Leicht, hätte mehr gekonnt" -#: app/(app)/custom-exercise.tsx:71 +#: app/(app)/custom-exercise.tsx:76 #: app/(app)/exercise-info.tsx:307 msgid "Edit Exercise" msgstr "Übung bearbeiten" -#: app/(app)/(tabs)/(plans)/overview.tsx:308 +#: app/(app)/(tabs)/(plans)/overview.tsx:353 msgid "Edit Plan" msgstr "Plan bearbeiten" #: app/(app)/(create-plan)/create-workout.tsx:247 -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:276 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:328 #: app/(app)/(tabs)/(stats)/_layout.tsx:22 msgid "Edit Workout" msgstr "Training bearbeiten" @@ -1697,24 +1804,60 @@ msgstr "Training bearbeiten" msgid "elliptical machine" msgstr "Crosstrainer" +#: app/(app)/friends.tsx:209 +msgid "Email address" +msgstr "E-Mail-Adresse" + #: constants/HelpData.ts:159 msgid "Enable recurring workout reminders from Settings. Select the days of the week you want to be reminded using the day chips and choose a time. You will receive a notification at that time on each selected day. Notification permission must be granted for reminders to work." msgstr "Richte wiederkehrende Trainingserinnerungen in den Einstellungen ein. Wähle die Wochentage, an denen du erinnert werden möchtest, über die Tag-Chips aus und lege eine Uhrzeit fest. Du erhältst eine Benachrichtigung zu dieser Uhrzeit an jedem ausgewählten Tag. Die Benachrichtigungsberechtigung muss erteilt sein, damit Erinnerungen funktionieren." -#: app/(app)/settings.tsx:830 -#: app/(app)/settings.tsx:855 -#: app/(app)/settings.tsx:880 -#: app/(app)/settings.tsx:904 -#: app/(app)/settings.tsx:928 -#: app/(app)/settings.tsx:953 -#: app/(app)/settings.tsx:1010 -#: app/(app)/settings.tsx:1092 -#: app/(app)/settings.tsx:1226 -#: app/(app)/settings.tsx:1258 -#: app/(app)/settings.tsx:1455 +#: app/(app)/settings.tsx:1628 +msgid "Enable to add a publish toggle to each plan." +msgstr "Aktivieren, um jedem Plan einen Veröffentlichungsschalter hinzuzufügen." + +#: app/(app)/settings.tsx:1666 +msgid "Enable to add a publish toggle to each standalone workout." +msgstr "Aktivieren, um jedem eigenständigen Training einen Veröffentlichungsschalter hinzuzufügen." + +#: app/(app)/settings.tsx:1708 +msgid "Enable to automatically share custom exercises you create or edit." +msgstr "Aktivieren, um eigene Übungen automatisch zu teilen." + +#: app/(app)/settings.tsx:1790 +msgid "Enable to automatically share each body measurement you record." +msgstr "Aktivieren, um Körpermaße automatisch zu teilen." + +#: app/(app)/settings.tsx:1749 +msgid "Enable to automatically share each workout you complete." +msgstr "Aktivieren, um abgeschlossene Trainings automatisch zu teilen." + +#: app/(app)/settings.tsx:1832 +msgid "Enable to automatically share strength PRs after each workout." +msgstr "Aktivieren, um Kraft-PRs nach jedem Training automatisch zu teilen." + +#: app/(app)/settings.tsx:866 +#: app/(app)/settings.tsx:891 +#: app/(app)/settings.tsx:916 +#: app/(app)/settings.tsx:940 +#: app/(app)/settings.tsx:964 +#: app/(app)/settings.tsx:989 +#: app/(app)/settings.tsx:1046 +#: app/(app)/settings.tsx:1128 +#: app/(app)/settings.tsx:1264 +#: app/(app)/settings.tsx:1297 +#: app/(app)/settings.tsx:1494 msgid "Enabled" msgstr "Aktiviert" +#: app/(app)/settings.tsx:1624 +msgid "Enables a per-plan publish toggle." +msgstr "Fügt einen Veröffentlichungsschalter pro Plan hinzu." + +#: app/(app)/settings.tsx:1662 +msgid "Enables a per-workout publish toggle." +msgstr "Fügt einen Veröffentlichungsschalter pro Training hinzu." + #: app/(app)/(tabs)/(stats)/measurements-manage.tsx:65 msgid "Enter a name for the custom metric." msgstr "Gib einen Namen für den eigenen Messwert ein." @@ -1723,15 +1866,15 @@ msgstr "Gib einen Namen für den eigenen Messwert ein." msgid "Enter at least one measurement to log." msgstr "Gib mindestens einen Messwert ein." -#: app/(app)/custom-exercise.tsx:350 +#: app/(app)/custom-exercise.tsx:376 msgid "Enter description" msgstr "Beschreibung eingeben" -#: app/(app)/custom-exercise.tsx:331 +#: app/(app)/custom-exercise.tsx:357 msgid "Enter exercise name" msgstr "Übungsname eingeben" -#: app/(app)/settings.tsx:1056 +#: app/(app)/settings.tsx:1092 msgid "Enter weight per dumbbell/cable, not total" msgstr "Gewicht pro Hantel/Kabel eingeben, nicht gesamt" @@ -1743,15 +1886,19 @@ msgstr "Eintragsdetails" msgid "Entry not found." msgstr "Eintrag nicht gefunden." -#: app/(app)/custom-exercise.tsx:442 +#: app/(app)/friend-exercise.tsx:64 +msgid "Equipment" +msgstr "Gerät" + +#: app/(app)/custom-exercise.tsx:468 msgid "Equipment *" msgstr "Gerät *" -#: app/(app)/custom-exercise.tsx:438 +#: app/(app)/custom-exercise.tsx:464 msgid "Equipment & Tracking" msgstr "Gerät & Tracking" -#: app/(app)/custom-exercise.tsx:203 +#: app/(app)/custom-exercise.tsx:208 msgid "Equipment is required." msgstr "Gerät ist erforderlich." @@ -1760,13 +1907,13 @@ msgid "Equipment:" msgstr "Gerät:" #: app/(app)/(create-plan)/image-search.tsx:43 -#: app/(app)/(tabs)/(plans)/overview.tsx:134 -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:94 +#: app/(app)/(tabs)/(plans)/overview.tsx:145 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:106 #: app/(app)/(workout)/index.tsx:871 #: app/(app)/(workout)/index.tsx:1065 -#: app/(app)/custom-exercise.tsx:129 -#: app/(app)/custom-exercise.tsx:178 -#: app/(app)/custom-exercise.tsx:286 +#: app/(app)/custom-exercise.tsx:134 +#: app/(app)/custom-exercise.tsx:183 +#: app/(app)/custom-exercise.tsx:312 #: app/login.tsx:69 #: components/FilterRow.tsx:86 #: components/FilterRow.tsx:132 @@ -1795,7 +1942,7 @@ msgstr "Fehler beim Laden der Übungsdetails" msgid "Error loading exercises: {0}" msgstr "Fehler beim Laden der Übungen: {0}" -#: app/(app)/(tabs)/(plans)/index.tsx:93 +#: app/(app)/(tabs)/(plans)/index.tsx:97 msgid "Error loading plans" msgstr "Fehler beim Laden der Pläne" @@ -1809,8 +1956,8 @@ msgstr "Fehler beim Speichern des Trainings" #. placeholder {0}: error.message #. placeholder {0}: settingsError.message -#: app/(app)/(tabs)/(plans)/overview.tsx:174 -#: app/(app)/(workout)/workout-session.tsx:1355 +#: app/(app)/(tabs)/(plans)/overview.tsx:185 +#: app/(app)/(workout)/workout-session.tsx:1386 #: components/WorkoutDetailsScreen.tsx:175 msgid "Error: {0}" msgstr "Fehler: {0}" @@ -1820,15 +1967,15 @@ msgstr "Fehler: {0}" msgid "Estimated Duration: {0}" msgstr "Geschätzte Dauer: {0}" -#: app/(app)/settings.tsx:1222 +#: app/(app)/settings.tsx:1260 msgid "Exclude deload workouts from exercise stats" msgstr "Deload-Trainings aus Übungsstatistiken ausschließen" -#: app/(app)/settings.tsx:1006 +#: app/(app)/settings.tsx:1042 msgid "Exclude warmup sets from stats" msgstr "Aufwärmsätze aus den Statistiken ausschließen" -#: app/(app)/settings.tsx:1349 +#: app/(app)/settings.tsx:1388 msgid "Exercise" msgstr "Übung" @@ -1839,21 +1986,29 @@ msgstr "Übung" msgid "Exercise Already Added" msgstr "Übung bereits hinzugefügt" -#: app/(app)/_layout.tsx:37 +#: app/(app)/_layout.tsx:59 +msgid "Exercise Details" +msgstr "Übungsdetails" + +#: app/(app)/_layout.tsx:39 msgid "Exercise Info" msgstr "Übungsinfo" -#: app/(app)/_layout.tsx:44 -#: components/AppMenu.tsx:184 +#: app/(app)/_layout.tsx:46 +#: components/AppMenu.tsx:202 #: constants/HelpData.ts:103 msgid "Exercise Library" msgstr "Übungsbibliothek" +#: app/(app)/friend-exercise.tsx:47 +msgid "Exercise not found." +msgstr "Übung nicht gefunden." + #: components/ExerciseTimerModal.tsx:159 msgid "Exercise Timer" msgstr "Übungstimer" -#: app/(app)/settings.tsx:809 +#: app/(app)/settings.tsx:845 msgid "Exercise timer countdown" msgstr "Übungstimer-Countdown" @@ -1881,12 +2036,12 @@ msgid "ez barbell" msgstr "EZ-Stange" #. placeholder {0}: error.message -#: app/(app)/(tabs)/(plans)/overview.tsx:155 +#: app/(app)/(tabs)/(plans)/overview.tsx:166 msgid "Failed to activate this plan: {0}" msgstr "Plan konnte nicht aktiviert werden: {0}" #. placeholder {0}: error.message -#: app/(app)/(tabs)/(plans)/overview.tsx:135 +#: app/(app)/(tabs)/(plans)/overview.tsx:146 msgid "Failed to delete plan: {0}" msgstr "Plan konnte nicht gelöscht werden: {0}" @@ -1894,17 +2049,17 @@ msgstr "Plan konnte nicht gelöscht werden: {0}" msgid "Failed to delete the workout. Please try again." msgstr "Training konnte nicht gelöscht werden. Bitte versuche es erneut." -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:95 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:107 msgid "Failed to delete workout. Please try again." msgstr "Training konnte nicht gelöscht werden. Bitte versuche es erneut." -#: app/(app)/custom-exercise.tsx:129 +#: app/(app)/custom-exercise.tsx:134 #: components/FilterRow.tsx:86 #: components/FilterRow.tsx:132 msgid "Failed to fetch data. Please try again." msgstr "Daten konnten nicht abgerufen werden. Bitte versuche es erneut." -#: app/(app)/custom-exercise.tsx:178 +#: app/(app)/custom-exercise.tsx:183 msgid "Failed to load exercise details." msgstr "Übungsdetails konnten nicht geladen werden." @@ -1912,7 +2067,7 @@ msgstr "Übungsdetails konnten nicht geladen werden." msgid "Failed to load history" msgstr "Verlauf konnte nicht geladen werden" -#: app/(app)/(tabs)/(plans)/index.tsx:147 +#: app/(app)/(tabs)/(plans)/index.tsx:153 msgid "Failed to load workouts" msgstr "Trainings konnten nicht geladen werden" @@ -1920,11 +2075,11 @@ msgstr "Trainings konnten nicht geladen werden" msgid "Failed to pick image. Please try again." msgstr "Bild konnte nicht ausgewählt werden. Bitte versuche es erneut." -#: app/(app)/custom-exercise.tsx:287 +#: app/(app)/custom-exercise.tsx:313 msgid "Failed to save custom exercise. Please try again." msgstr "Eigene Übung konnte nicht gespeichert werden. Bitte versuche es erneut." -#: app/(app)/custom-exercise.tsx:226 +#: app/(app)/custom-exercise.tsx:231 msgid "Failed to save the image. Please try again." msgstr "Bild konnte nicht gespeichert werden. Bitte versuche es erneut." @@ -1937,6 +2092,10 @@ msgstr "Training konnte nicht gespeichert werden. Bitte versuche es erneut." msgid "Failed to sign in. Please try again." msgstr "Anmeldung fehlgeschlagen. Bitte versuche es erneut." +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:304 +msgid "Failed to update sharing. Please try again." +msgstr "Freigabe konnte nicht aktualisiert werden. Bitte versuche es erneut." + #: components/ExerciseList.tsx:41 msgid "Favorites" msgstr "Favoriten" @@ -1957,7 +2116,7 @@ msgstr "Hat sich leicht angefühlt. Erstmal halten und nächste Einheit bestäti msgid "Finish" msgstr "Beenden" -#: app/(app)/settings.tsx:1632 +#: app/(app)/settings.tsx:1945 msgid "Follow MuscleQuest on Instagram" msgstr "MuscleQuest auf Instagram folgen" @@ -1970,7 +2129,7 @@ msgstr "für {0}s " msgid "forearms" msgstr "Unterarme" -#: app/(app)/settings.tsx:53 +#: app/(app)/settings.tsx:56 msgid "Fr" msgstr "Fr" @@ -1993,6 +2152,27 @@ msgstr "Fr" msgid "Friday" msgstr "Freitag" +#: app/(app)/_layout.tsx:50 +msgid "Friend Profile" +msgstr "Freundesprofil" + +#: app/(app)/friends.tsx:39 +#: app/(app)/friends.tsx:58 +#: app/(app)/friends.tsx:69 +#: app/(app)/friends.tsx:264 +#: components/AppMenu.tsx:194 +msgid "Friends" +msgstr "Freunde" + +#: constants/HelpData.ts:164 +msgid "Friends & Social" +msgstr "Freunde & Social" + +#. placeholder {0}: formatDistanceToNow(friend.since.toDate(), { addSuffix: true }) +#: app/(app)/friend-profile.tsx:121 +msgid "Friends since {0}" +msgstr "Freunde seit {0}" + #: components/ExerciseTimerModal.tsx:165 msgid "Get Ready..." msgstr "Mach dich bereit..." @@ -2060,12 +2240,12 @@ msgstr "Fasse zwei Übungen zu einem Supersatz zusammen, damit sie während eine msgid "hamstrings" msgstr "Oberschenkelrückseite" -#: components/ExerciseFeedbackSheet.tsx:38 +#: components/ExerciseFeedbackSheet.tsx:39 msgid "Hard, near limit" msgstr "Schwer, nah am Limit" -#: app/(app)/_layout.tsx:41 -#: components/AppMenu.tsx:194 +#: app/(app)/_layout.tsx:43 +#: components/AppMenu.tsx:212 msgid "Help & Info" msgstr "Hilfe & Info" @@ -2112,11 +2292,11 @@ msgstr "Startbildschirm & Wochenziel" msgid "How are these muscles feeling since your last session?" msgstr "Wie fühlen sich diese Muskeln seit deiner letzten Einheit an?" -#: components/ExerciseFeedbackSheet.tsx:173 +#: components/ExerciseFeedbackSheet.tsx:187 msgid "How did that feel?" msgstr "Wie hat sich das angefühlt?" -#: app/(app)/custom-exercise.tsx:225 +#: app/(app)/custom-exercise.tsx:230 msgid "Image Save Error" msgstr "Fehler beim Speichern des Bildes" @@ -2124,6 +2304,19 @@ msgstr "Fehler beim Speichern des Bildes" msgid "Images by Unsplash" msgstr "Bilder von Unsplash" +#: app/(app)/friend-exercise.tsx:142 +msgid "Import failed" +msgstr "Import fehlgeschlagen" + +#: constants/HelpData.ts:178 +msgid "Importing from Friends" +msgstr "Von Freunden importieren" + +#: app/(app)/friends.tsx:278 +#: app/(app)/friends.tsx:331 +msgid "Incoming" +msgstr "Eingehend" + #: app/(app)/exercise-info.tsx:202 msgid "Info" msgstr "Info" @@ -2137,11 +2330,11 @@ msgstr "Einblicke" msgid "Jumpstart your fitness journey with professionally designed training plans. Choose from a variety of options tailored to different goals and experience levels. " msgstr "Starte deine Fitnessreise mit professionell gestalteten Trainingsplänen. Wähle aus einer Vielzahl von Optionen, die auf verschiedene Ziele und Erfahrungsstufen zugeschnitten sind. " -#: app/(app)/custom-exercise.tsx:83 +#: app/(app)/custom-exercise.tsx:88 msgid "Keep editing" msgstr "Weiter bearbeiten" -#: app/(app)/settings.tsx:949 +#: app/(app)/settings.tsx:985 msgid "Keep screen on during workout" msgstr "Bildschirm während des Trainings eingeschaltet lassen" @@ -2154,7 +2347,7 @@ msgid "kettlebell" msgstr "Kettlebell" #. placeholder {0}: lastBackupDate.toLocaleDateString() -#: app/(app)/settings.tsx:608 +#: app/(app)/settings.tsx:644 msgid "Last backup: {0}" msgstr "Letzte Sicherung: {0}" @@ -2195,15 +2388,15 @@ msgstr "Hebelmaschine" msgid "Load up" msgstr "Gewicht erhöhen" -#: app/_layout.tsx:199 +#: app/_layout.tsx:213 msgid "Loading data, please wait..." msgstr "Daten werden geladen, bitte warten..." -#: app/(app)/(tabs)/(plans)/overview.tsx:187 +#: app/(app)/(tabs)/(plans)/overview.tsx:198 msgid "Loading Plan..." msgstr "Plan wird geladen..." -#: app/(app)/(tabs)/(plans)/overview.tsx:166 +#: app/(app)/(tabs)/(plans)/overview.tsx:177 #: components/WorkoutDetailsScreen.tsx:166 msgid "Loading..." msgstr "Wird geladen..." @@ -2213,11 +2406,11 @@ msgstr "Wird geladen..." msgid "Log Entry" msgstr "Eintrag erfassen" -#: app/(app)/settings.tsx:528 +#: app/(app)/settings.tsx:564 msgid "Log in to secure your data" msgstr "Melde dich an, um deine Daten zu sichern" -#: app/(app)/settings.tsx:1031 +#: app/(app)/settings.tsx:1067 msgid "Log one side only for single-arm/leg exercises" msgstr "Trage nur eine Seite bei Einarm-/Einbeinübungen ein" @@ -2237,7 +2430,7 @@ msgstr "Unterer Rücken" msgid "lower legs" msgstr "Unterschenkel" -#: app/(app)/settings.tsx:1203 +#: app/(app)/settings.tsx:1241 msgid "Machine load increment" msgstr "Maschinen-Gewichtsschritt" @@ -2281,11 +2474,11 @@ msgstr "Leichter Muskelkater" msgid "Min Reps" msgstr "Min. Wdh." -#: components/ExerciseFeedbackSheet.tsx:46 +#: components/ExerciseFeedbackSheet.tsx:47 msgid "Minor discomfort" msgstr "Leichtes Unbehagen" -#: app/(app)/settings.tsx:49 +#: app/(app)/settings.tsx:52 msgid "Mo" msgstr "Mo" @@ -2328,15 +2521,15 @@ msgstr "MuscleQuest" msgid "MuscleQuest Introduction" msgstr "MuscleQuest-Einführung" -#: app/(app)/settings.tsx:1613 +#: app/(app)/settings.tsx:1926 msgid "MuscleQuest.app" msgstr "MuscleQuest.app" -#: components/AppMenu.tsx:208 +#: components/AppMenu.tsx:226 msgid "MuscleQuest's Instagram" msgstr "MuscleQuest auf Instagram" -#: app/(app)/custom-exercise.tsx:368 +#: app/(app)/custom-exercise.tsx:394 msgid "Muscles" msgstr "Muskeln" @@ -2344,11 +2537,11 @@ msgstr "Muskeln" msgid "N/A" msgstr "k.A." -#: app/(app)/custom-exercise.tsx:328 +#: app/(app)/custom-exercise.tsx:354 msgid "Name *" msgstr "Name *" -#: app/(app)/custom-exercise.tsx:200 +#: app/(app)/custom-exercise.tsx:205 msgid "Name is required." msgstr "Name ist erforderlich." @@ -2364,11 +2557,11 @@ msgstr "Nacken" msgid "Neck" msgstr "Hals" -#: app/(app)/(tabs)/(plans)/index.tsx:118 +#: app/(app)/(tabs)/(plans)/index.tsx:122 msgid "New Plan" msgstr "Neuer Plan" -#: app/(app)/(tabs)/(plans)/index.tsx:110 +#: app/(app)/(tabs)/(plans)/index.tsx:114 msgid "New Workout" msgstr "Neues Training" @@ -2380,8 +2573,8 @@ msgstr "Weiter" msgid "Next Session" msgstr "Nächste Einheit" -#: app/(app)/(workout)/workout-session.tsx:1415 -#: app/(app)/(workout)/workout-session.tsx:1502 +#: app/(app)/(workout)/workout-session.tsx:1446 +#: app/(app)/(workout)/workout-session.tsx:1533 msgid "Next: " msgstr "Weiter: " @@ -2396,10 +2589,18 @@ msgstr "Weiter: {workoutName} am {0}" msgid "No" msgstr "Nein" -#: app/(app)/settings.tsx:609 +#: app/(app)/settings.tsx:645 msgid "No backups found" msgstr "Keine Sicherungen gefunden" +#: app/(app)/friend-profile.tsx:423 +msgid "No completed workouts shared yet" +msgstr "Noch keine abgeschlossenen Trainings geteilt" + +#: app/(app)/friend-profile.tsx:336 +msgid "No custom exercises shared yet" +msgstr "Noch keine eigenen Übungen geteilt" + #: components/charts/BodyPartChart.tsx:198 msgid "No data available." msgstr "Keine Daten verfügbar." @@ -2416,7 +2617,7 @@ msgstr "Keine Daten für diesen Zeitraum." msgid "No exercises added yet" msgstr "Noch keine Übungen hinzugefügt" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:252 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:264 msgid "No exercises in this workout yet." msgstr "Noch keine Übungen in diesem Training." @@ -2424,10 +2625,18 @@ msgstr "Noch keine Übungen in diesem Training." msgid "No exercises tracked yet. Tap + Add to start." msgstr "Noch keine Übungen verfolgt. Tippe auf + Hinzufügen, um zu starten." +#: app/(app)/friends.tsx:141 +msgid "No friends yet. Search by email to add someone." +msgstr "Noch keine Freunde. Suche per E-Mail, um jemanden hinzuzufügen." + #: app/(app)/exercise-info.tsx:407 msgid "No history yet" msgstr "Noch kein Verlauf" +#: app/(app)/friend-profile.tsx:468 +msgid "No measurements shared yet" +msgstr "Noch keine Messungen geteilt" + #: app/(app)/(tabs)/(stats)/measurements.tsx:265 msgid "No measurements yet. Log your first entry above." msgstr "Noch keine Messungen. Erfasse deinen ersten Eintrag oben." @@ -2436,10 +2645,18 @@ msgstr "Noch keine Messungen. Erfasse deinen ersten Eintrag oben." msgid "No measurements yet. Tap to log your first entry." msgstr "Noch keine Messungen. Tippe, um deinen ersten Eintrag zu erfassen." -#: components/ExerciseFeedbackSheet.tsx:45 +#: components/ExerciseFeedbackSheet.tsx:46 msgid "No pain" msgstr "Keine Schmerzen" +#: app/(app)/friends.tsx:317 +msgid "No pending friend requests." +msgstr "Keine ausstehenden Freundschaftsanfragen." + +#: app/(app)/friend-profile.tsx:156 +msgid "No plans shared yet" +msgstr "Noch keine Pläne geteilt" + #: components/ProgressionSummaryCard.tsx:26 msgid "No prior weight data. Hold steady for now." msgstr "Keine früheren Gewichtsdaten. Erstmal halten." @@ -2456,7 +2673,7 @@ msgstr "Keine Ergebnisse für „{query}“" msgid "No schedule set" msgstr "Kein Zeitplan festgelegt" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:176 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:188 msgid "No Sets" msgstr "Keine Sätze" @@ -2465,10 +2682,18 @@ msgstr "Keine Sätze" msgid "No Sets Available" msgstr "Keine Sätze verfügbar" -#: components/PlanList.tsx:46 +#: app/(app)/friend-profile.tsx:501 +msgid "No strength data shared yet" +msgstr "Noch keine Kraftdaten geteilt" + +#: components/PlanList.tsx:50 msgid "No training plans found" msgstr "Keine Trainingspläne gefunden" +#: app/(app)/friends.tsx:228 +msgid "No user found with that email address." +msgstr "Kein Nutzer mit dieser E-Mail-Adresse gefunden." + #: app/(app)/(tabs)/(stats)/measurements.tsx:131 msgid "No values entered" msgstr "Keine Werte eingegeben" @@ -2485,11 +2710,15 @@ msgstr "Noch keine Trainings abgeschlossen. Starte dein erstes Training!" msgid "No workouts on this day." msgstr "Keine Trainings an diesem Tag." -#: app/(app)/(tabs)/(plans)/index.tsx:160 +#: app/(app)/friend-profile.tsx:244 +msgid "No workouts shared yet" +msgstr "Noch keine Trainings geteilt" + +#: app/(app)/(tabs)/(plans)/index.tsx:166 msgid "No workouts yet" msgstr "Noch keine Trainings" -#: components/ExerciseFeedbackSheet.tsx:221 +#: components/ExerciseFeedbackSheet.tsx:235 msgid "No, keep it the same" msgstr "Nein, so lassen" @@ -2503,10 +2732,10 @@ msgstr "Schräge Bauchmuskeln" #: app/(app)/(workout)/exercises.tsx:109 #: app/(app)/(workout)/exercises.tsx:130 #: app/(app)/(workout)/index.tsx:873 -#: app/(app)/custom-exercise.tsx:130 -#: app/(app)/custom-exercise.tsx:179 -#: app/(app)/custom-exercise.tsx:227 -#: app/(app)/custom-exercise.tsx:288 +#: app/(app)/custom-exercise.tsx:135 +#: app/(app)/custom-exercise.tsx:184 +#: app/(app)/custom-exercise.tsx:232 +#: app/(app)/custom-exercise.tsx:314 #: app/login.tsx:70 #: components/FilterRow.tsx:87 #: components/FilterRow.tsx:133 @@ -2521,16 +2750,20 @@ msgstr "Noch ein Training bis zu deinem Ziel!" msgid "Oops!" msgstr "Hoppla!" -#: app/(app)/settings.tsx:386 +#: app/(app)/settings.tsx:422 msgid "Open Settings" msgstr "Einstellungen öffnen" -#: components/AppMenu.tsx:204 -#: components/AppMenu.tsx:210 +#: constants/HelpData.ts:169 +msgid "Open the Friends tab from the menu to manage your connections. Use the search bar to find other users by username and send them a friend request. Incoming requests appear in the Requests tab; tap Accept to confirm or Decline to ignore. A badge on the Friends menu item shows how many pending requests are waiting. Once a request is accepted, both users appear in each other's Friends list and can view each other's shared content." +msgstr "Öffne den Freunde-Tab im Menü, um deine Verbindungen zu verwalten. Nutze die Suchleiste, um andere Nutzer per Nutzernamen zu finden und eine Freundschaftsanfrage zu senden. Eingehende Anfragen erscheinen im Tab Anfragen; tippe auf Übernehmen zum Bestätigen oder Ablehnen zum Ignorieren. Ein Badge am Freunde-Menüpunkt zeigt, wie viele Anfragen noch ausstehen. Sobald eine Anfrage angenommen wurde, erscheinen beide Nutzer in der Freundesliste des anderen und können gegenseitig die geteilten Inhalte einsehen." + +#: components/AppMenu.tsx:222 +#: components/AppMenu.tsx:228 msgid "Opens in your browser" msgstr "Öffnet sich in deinem Browser" -#: components/ExerciseFeedbackSheet.tsx:243 +#: components/ExerciseFeedbackSheet.tsx:257 msgid "Optional description" msgstr "Optionale Beschreibung" @@ -2543,7 +2776,7 @@ msgstr "Weitere Übungen" msgid "Overview" msgstr "Übersicht" -#: components/ExerciseFeedbackSheet.tsx:47 +#: components/ExerciseFeedbackSheet.tsx:48 msgid "Pain or form issues" msgstr "Schmerzen oder Formprobleme" @@ -2551,7 +2784,7 @@ msgstr "Schmerzen oder Formprobleme" msgid "Pain reported. Keeping load unchanged until you feel better." msgstr "Schmerzen gemeldet. Gewicht bleibt unverändert, bis es dir besser geht." -#: app/(app)/custom-exercise.tsx:525 +#: app/(app)/custom-exercise.tsx:551 #: app/(app)/exercise-info.tsx:277 msgid "Paired implements" msgstr "Gepaarte Geräte" @@ -2565,6 +2798,10 @@ msgstr "Gepaart mit {0}" msgid "pectorals" msgstr "Brustmuskeln" +#: app/(app)/friends.tsx:377 +msgid "Pending" +msgstr "Ausstehend" + #: components/stats/InsightsStrip.tsx:74 msgid "Per week (avg)" msgstr "Pro Woche (Ø)" @@ -2573,12 +2810,12 @@ msgstr "Pro Woche (Ø)" msgid "Percent" msgstr "Prozent" -#: app/(app)/settings.tsx:364 -#: app/(app)/settings.tsx:383 +#: app/(app)/settings.tsx:400 +#: app/(app)/settings.tsx:419 msgid "Permission Required" msgstr "Berechtigung erforderlich" -#: app/(app)/settings.tsx:511 +#: app/(app)/settings.tsx:547 msgid "Personal" msgstr "Persönlich" @@ -2586,12 +2823,21 @@ msgstr "Persönlich" msgid "Pin exercises in the Stats tab to track their strength progression over time. Each tracked exercise shows a chart of your performance over the selected time range, your all-time personal record, your top sets, and a list of recent sessions showing the best set per day. Charts update automatically after each workout that includes that exercise." msgstr "Hefte Übungen im Statistiken-Tab an, um ihre Kraftentwicklung über die Zeit zu verfolgen. Jede verfolgte Übung zeigt ein Diagramm deiner Leistung im gewählten Zeitraum, deinen persönlichen Rekord aller Zeiten, deine besten Sätze und eine Liste aktueller Einheiten mit dem besten Satz pro Tag. Diagramme werden nach jedem Training, das die Übung enthält, automatisch aktualisiert." +#: app/(app)/_layout.tsx:52 +msgid "Plan Details" +msgstr "Plandetails" + +#: app/(app)/friend-plan.tsx:56 +msgid "Plan not found." +msgstr "Plan nicht gefunden." + #: app/(app)/(tabs)/(plans)/_layout.tsx:17 msgid "Plan Overview" msgstr "Planübersicht" #: app/(app)/(tabs)/_layout.tsx:49 #: app/(app)/(tabs)/(plans)/_layout.tsx:16 +#: app/(app)/friend-profile.tsx:146 #: constants/HelpData.ts:28 msgid "Plans" msgstr "Pläne" @@ -2600,15 +2846,15 @@ msgstr "Pläne" msgid "Plans are structured training programmes made up of workouts. To create one, go to the Plans tab, tap New Plan, give it a name, and pick a cover image. Add workouts to the plan, then add exercises to each workout with target sets and reps. Use the up/down arrow buttons on a workout card to reorder it, or the X button to remove it; both are in the top right of the card. Assign workouts to specific days of the week in the schedule editor: tap any day to pick a workout or leave it as a rest day, and use the auto-suggest button to space them out evenly. Once your plan is ready, open it and tap Activate. You can also add notes to a plan from the plan overview screen. Each workout card shows an estimated duration alongside the exercise count so you can gauge the session length at a glance. Use the view icons next to the \"Your Training Plans\" heading to switch between Carousel, List, and Grid layouts; your chosen view is saved automatically. Your progress in the plan editor is automatically saved as a draft, so if you leave mid-edit you will be prompted to continue where you left off or discard and start from the last saved state." msgstr "Pläne sind strukturierte Trainingsprogramme aus mehreren Trainings. Um einen zu erstellen, gehe zum Pläne-Tab, tippe auf Neuer Plan, gib einen Namen ein und wähle ein Titelbild. Füge Trainings zum Plan hinzu und dann Übungen zu jedem Training mit Ziel-Sätzen und Wiederholungen. Nutze die Hoch/Runter-Pfeile auf einer Trainingskarte, um sie neu anzuordnen, oder die X-Schaltfläche, um sie zu entfernen, beide befinden sich oben rechts auf der Karte. Weise Trainings im Zeitplan-Editor bestimmten Wochentagen zu: Tippe auf einen Tag, um ein Training auszuwählen oder ihn als Ruhetag zu lassen, und nutze den Auto-Vorschlag, um sie gleichmäßig zu verteilen. Wenn dein Plan fertig ist, öffne ihn und tippe auf Aktivieren. Du kannst vom Planübersichtsbildschirm auch Notizen zum Plan hinzufügen. Jede Trainingskarte zeigt eine geschätzte Dauer neben der Übungsanzahl, damit du die Länge der Einheit auf einen Blick abschätzen kannst. Nutze die Ansichtssymbole neben der Überschrift „Deine Trainingspläne“, um zwischen Karussell-, Listen- und Rasteransicht zu wechseln; deine gewählte Ansicht wird automatisch gespeichert. Dein Fortschritt im Plan-Editor wird automatisch als Entwurf gespeichert, wenn du ihn mittendrin verlässt, wirst du gefragt, ob du weitermachen oder verwerfen und vom letzten gespeicherten Stand starten möchtest." -#: app/(app)/settings.tsx:826 +#: app/(app)/settings.tsx:862 msgid "Play countdown beeps (Exercise Timer)" msgstr "Countdown-Töne abspielen (Übungstimer)" -#: app/(app)/settings.tsx:851 +#: app/(app)/settings.tsx:887 msgid "Play goal achieved sound (Exercise Timer)" msgstr "Ziel-erreicht-Ton abspielen (Übungstimer)" -#: app/(app)/settings.tsx:901 +#: app/(app)/settings.tsx:937 msgid "Play sound after rest" msgstr "Ton nach der Pause abspielen" @@ -2620,7 +2866,7 @@ msgstr "Bitte warten, während die neueste Version heruntergeladen wird..." msgid "Post-Exercise Feedback" msgstr "Feedback nach Übungen" -#: app/(app)/(tabs)/(plans)/index.tsx:134 +#: app/(app)/(tabs)/(plans)/index.tsx:140 msgid "Premade plans" msgstr "Vorgefertigte Pläne" @@ -2628,12 +2874,20 @@ msgstr "Vorgefertigte Pläne" msgid "Premade Plans" msgstr "Vorgefertigte Pläne" -#: app/(app)/(workout)/workout-session.tsx:1417 -#: app/(app)/(workout)/workout-session.tsx:1504 +#: app/(app)/(workout)/workout-session.tsx:1448 +#: app/(app)/(workout)/workout-session.tsx:1535 msgid "Prev: " msgstr "Zurück: " -#: app/(app)/settings.tsx:1668 +#: app/(app)/settings.tsx:1604 +msgid "Previously shared data always remains visible to your friends until you delete it below." +msgstr "Bereits geteilte Daten bleiben für deine Freunde sichtbar, bis du sie unten löschst." + +#: app/(app)/settings.tsx:1601 +msgid "Privacy" +msgstr "Datenschutz" + +#: app/(app)/settings.tsx:1981 msgid "Privacy policy" msgstr "Datenschutzrichtlinie" @@ -2641,7 +2895,7 @@ msgstr "Datenschutzrichtlinie" msgid "Progression Suggestions" msgstr "Progressionsvorschläge" -#: components/ExerciseFeedbackSheet.tsx:211 +#: components/ExerciseFeedbackSheet.tsx:225 msgid "Push harder next time?" msgstr "Nächstes Mal mehr fordern?" @@ -2670,6 +2924,10 @@ msgstr "Zuletzt" msgid "Recent Sessions" msgstr "Letzte Einheiten" +#: app/(app)/friend-profile.tsx:413 +msgid "Recent Workouts" +msgstr "Letzte Trainings" + #: hooks/useExerciseSort.ts:57 msgid "Recently Used" msgstr "Zuletzt verwendet" @@ -2683,23 +2941,24 @@ msgstr "Regenerations-Check-in" msgid "Reduce load" msgstr "Gewicht reduzieren" -#: app/_layout.tsx:94 +#: app/_layout.tsx:100 msgid "Reload" msgstr "Neu laden" -#: app/(app)/settings.tsx:1280 +#: app/(app)/settings.tsx:1319 msgid "Reminder days" msgstr "Erinnerungstage" -#: app/(app)/settings.tsx:1335 +#: app/(app)/settings.tsx:1374 msgid "Reminder time" msgstr "Erinnerungszeit" -#: app/(app)/settings.tsx:1243 +#: app/(app)/settings.tsx:1282 msgid "Reminders" msgstr "Erinnerungen" #: app/(app)/(create-plan)/create.tsx:283 +#: components/friends/FriendListItem.tsx:26 #: components/WorkoutCard.tsx:89 msgid "Remove" msgstr "Entfernen" @@ -2717,6 +2976,10 @@ msgstr "Übung entfernen" msgid "Remove Superset" msgstr "Supersatz entfernen" +#: components/friends/FriendListItem.tsx:22 +msgid "Remove this friend? They will no longer be able to see your shared content." +msgstr "Freund entfernen? Diese Person kann deine geteilten Inhalte dann nicht mehr sehen." + #: app/(app)/(create-plan)/create.tsx:275 msgid "Remove Workout" msgstr "Training entfernen" @@ -2734,12 +2997,17 @@ msgstr "Wiederholungsziel nicht erreicht. Erstmal halten." msgid "Replace" msgstr "Ersetzen" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:186 +#: app/(app)/friend-plan.tsx:130 +#: app/(app)/friend-workout.tsx:89 +msgid "reps" +msgstr "Wdh." + +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:198 #: app/(app)/(tabs)/(stats)/edit-history.tsx:201 #: app/(app)/(tabs)/(stats)/edit-history.tsx:205 #: app/(app)/(tabs)/(stats)/edit-history.tsx:242 #: app/(app)/(tabs)/(stats)/edit-history.tsx:246 -#: app/(app)/custom-exercise.tsx:64 +#: app/(app)/custom-exercise.tsx:69 #: components/charts/ExerciseProgressionChart.tsx:377 #: components/SessionSetInfo.tsx:435 #: components/WorkoutCard.tsx:276 @@ -2751,10 +3019,14 @@ msgstr "Wdh." msgid "Reps: {repRange}" msgstr "Wdh.: {repRange}" -#: app/(app)/settings.tsx:1577 +#: app/(app)/settings.tsx:1890 msgid "Request or vote for new features" msgstr "Neue Funktionen anfragen oder abstimmen" +#: app/(app)/friends.tsx:62 +msgid "Requests" +msgstr "Anfragen" + #: app/(app)/(create-plan)/sets-overview.tsx:173 #: components/PlanScheduleEditor.tsx:94 #: components/PlanScheduleEditor.tsx:189 @@ -2771,7 +3043,7 @@ msgid "Rest Time (Minutes:Seconds)" msgstr "Pausenzeit (Minuten:Sekunden)" #: app/(app)/(workout)/index.tsx:1134 -#: app/(app)/(workout)/workout-session.tsx:1540 +#: app/(app)/(workout)/workout-session.tsx:1572 msgid "Rest Time Left:" msgstr "Verbleibende Pausenzeit:" @@ -2784,11 +3056,11 @@ msgstr "Pausenzeit: {restMinutes}:{0}" msgid "Rest Timer" msgstr "Pausentimer" -#: app/(app)/(workout)/workout-session.tsx:551 +#: app/(app)/(workout)/workout-session.tsx:558 msgid "Rest Timer Finished!" msgstr "Pausentimer beendet!" -#: app/(app)/settings.tsx:783 +#: app/(app)/settings.tsx:819 msgid "Rest timer increment" msgstr "Pausentimer-Schritt" @@ -2808,16 +3080,16 @@ msgstr "Neustart fehlgeschlagen" msgid "Restart Workout" msgstr "Training neu starten" -#: app/(app)/settings.tsx:464 -#: app/(app)/settings.tsx:625 +#: app/(app)/settings.tsx:500 +#: app/(app)/settings.tsx:661 msgid "Restore" msgstr "Wiederherstellen" -#: app/(app)/settings.tsx:459 +#: app/(app)/settings.tsx:495 msgid "Restore Backup" msgstr "Sicherung wiederherstellen" -#: app/(app)/settings.tsx:635 +#: app/(app)/settings.tsx:671 msgid "Restoring. Please wait..." msgstr "Wird wiederhergestellt. Bitte warten..." @@ -2837,7 +3109,7 @@ msgstr "Seil" msgid "rotator cuff" msgstr "Rotatorenmanschette" -#: app/(app)/settings.tsx:54 +#: app/(app)/settings.tsx:57 msgid "Sa" msgstr "Sa" @@ -2856,12 +3128,12 @@ msgstr "Samstag" #: app/(app)/(create-plan)/create.tsx:363 #: app/(app)/(workout)/index.tsx:843 #: app/(app)/(workout)/index.tsx:1071 -#: app/(app)/custom-exercise.tsx:549 +#: app/(app)/custom-exercise.tsx:575 #: components/SettingsModal.tsx:296 msgid "Save" msgstr "Speichern" -#: app/(app)/custom-exercise.tsx:549 +#: app/(app)/custom-exercise.tsx:575 msgid "Save and select" msgstr "Speichern und auswählen" @@ -2901,6 +3173,8 @@ msgstr "Training wird gespeichert..." #: app/(app)/(tabs)/(stats)/exercises.tsx:166 #: app/(app)/(workout)/exercises.tsx:233 #: app/(app)/exercise-library.tsx:91 +#: app/(app)/friends.tsx:59 +#: app/(app)/friends.tsx:219 msgid "Search" msgstr "Suchen" @@ -2912,13 +3186,14 @@ msgstr "Hilfe durchsuchen" msgid "Search help…" msgstr "Hilfe durchsuchen..." -#: app/(app)/custom-exercise.tsx:404 -#: app/(app)/custom-exercise.tsx:427 +#: app/(app)/custom-exercise.tsx:430 #: app/(app)/custom-exercise.tsx:453 +#: app/(app)/custom-exercise.tsx:479 msgid "Search..." msgstr "Suchen..." -#: app/(app)/custom-exercise.tsx:416 +#: app/(app)/custom-exercise.tsx:442 +#: app/(app)/friend-exercise.tsx:83 msgid "Secondary Muscles" msgstr "Sekundäre Muskeln" @@ -2934,34 +3209,39 @@ msgstr "Wähle einen Tag, um Trainings anzuzeigen." msgid "Select a workout to view" msgstr "Wähle ein Training zur Anzeige" -#: app/(app)/settings.tsx:1311 +#: app/(app)/settings.tsx:1350 msgid "Select at least one day" msgstr "Wähle mindestens einen Tag aus" -#: app/(app)/custom-exercise.tsx:382 +#: app/(app)/custom-exercise.tsx:408 msgid "Select body part" msgstr "Körperteil auswählen" -#: app/(app)/custom-exercise.tsx:454 +#: app/(app)/custom-exercise.tsx:480 msgid "Select equipment" msgstr "Gerät auswählen" -#: app/(app)/custom-exercise.tsx:428 +#: app/(app)/custom-exercise.tsx:454 msgid "Select secondary muscles" msgstr "Sekundäre Muskeln auswählen" -#: app/(app)/custom-exercise.tsx:405 +#: app/(app)/custom-exercise.tsx:431 msgid "Select target muscle" msgstr "Zielmuskel auswählen" -#: app/(app)/custom-exercise.tsx:475 +#: app/(app)/custom-exercise.tsx:501 msgid "Select tracking type" msgstr "Tracking-Typ auswählen" -#: app/(app)/settings.tsx:924 +#: app/(app)/settings.tsx:960 msgid "Send notification in background after rest" msgstr "Hintergrundbenachrichtigung nach Pause senden" +#: app/(app)/friends.tsx:271 +#: app/(app)/friends.tsx:344 +msgid "Sent" +msgstr "Gesendet" + #: constants/dbTranslations.ts:33 msgid "serratus anterior" msgstr "Serratus anterior" @@ -2990,6 +3270,11 @@ msgstr "Satztypen" msgid "Set your weekly workout goal and enter your body weight to get accurate stats and recommendations. You can also adjust your weight increment preferences, choose your preferred units, and much more." msgstr "Lege dein wöchentliches Trainingsziel fest und gib dein Körpergewicht ein, um genaue Statistiken und Empfehlungen zu erhalten. Du kannst auch deine Gewichtserhöhungseinstellungen anpassen, bevorzugte Einheiten wählen und vieles mehr." +#: app/(app)/friend-plan.tsx:124 +#: app/(app)/friend-workout.tsx:83 +msgid "sets" +msgstr "Sätze" + #: app/(app)/(workout)/workout-summary.tsx:574 #: app/(app)/(workout)/workout-summary.tsx:597 msgid "Sets" @@ -3007,12 +3292,48 @@ msgstr "Satzübersicht" msgid "settings" msgstr "Einstellungen" -#: app/(app)/_layout.tsx:40 -#: components/AppMenu.tsx:189 +#: app/(app)/_layout.tsx:42 +#: components/AppMenu.tsx:207 #: constants/HelpData.ts:153 msgid "Settings" msgstr "Einstellungen" +#: app/(app)/settings.tsx:1779 +msgid "Share body measurements with friends" +msgstr "Körpermaße mit Freunden teilen" + +#: app/(app)/settings.tsx:1739 +msgid "Share completed workouts with friends" +msgstr "Abgeschlossene Trainings mit Freunden teilen" + +#: app/(app)/settings.tsx:1697 +msgid "Share custom exercises with friends" +msgstr "Eigene Übungen mit Freunden teilen" + +#: app/(app)/(tabs)/(plans)/overview.tsx:306 +msgid "Share Plan" +msgstr "Plan teilen" + +#: app/(app)/settings.tsx:1620 +msgid "Share plans with friends" +msgstr "Pläne mit Freunden teilen" + +#: app/(app)/settings.tsx:1658 +msgid "Share standalone workouts with friends" +msgstr "Eigenständige Trainings mit Freunden teilen" + +#: app/(app)/settings.tsx:1821 +msgid "Share strength PRs with friends" +msgstr "Kraft-PRs mit Freunden teilen" + +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:291 +msgid "Share Workout" +msgstr "Training teilen" + +#: constants/HelpData.ts:173 +msgid "Sharing Your Content" +msgstr "Inhalte teilen" + #: constants/dbTranslations.ts:57 msgid "shins" msgstr "Schienbeine" @@ -3022,28 +3343,36 @@ msgstr "Schienbeine" msgid "shoulders" msgstr "Schultern" -#: app/(app)/settings.tsx:1452 +#: app/(app)/settings.tsx:1491 msgid "Show onboarding on home screen" msgstr "Einführung auf Startbildschirm anzeigen" -#: app/(app)/settings.tsx:532 +#: app/(app)/settings.tsx:568 msgid "Sign in" msgstr "Anmelden" -#: app/(app)/settings.tsx:525 +#: app/(app)/friends.tsx:51 +msgid "Sign In" +msgstr "Anmelden" + +#: app/(app)/friends.tsx:48 +msgid "Sign in to use the Friends feature." +msgstr "Melde dich an, um die Freunde-Funktion zu nutzen." + +#: app/(app)/settings.tsx:561 msgid "Sign in with Google" msgstr "Mit Google anmelden" -#: constants/HelpData.ts:174 +#: constants/HelpData.ts:194 msgid "Sign in with Google in Settings to enable cloud backups of all your workout data. Tap Backup at any time to save a snapshot; the date of your last backup is shown beneath the button. Tap Restore to download and apply your latest backup; confirm the prompt and the app will reload with your restored data. Your backups are stored securely and are tied to your Google account. If you switch devices or reinstall the app, simply sign in with the same Google account and tap Restore to get your data back." msgstr "Melde dich in den Einstellungen mit Google an, um Cloud-Sicherungen all deiner Trainingsdaten zu aktivieren. Tippe jederzeit auf Sichern, um eine Momentaufnahme zu speichern; das Datum deiner letzten Sicherung wird unter der Schaltfläche angezeigt. Tippe auf Wiederherstellen, um deine neueste Sicherung herunterzuladen und anzuwenden; bestätige die Eingabeaufforderung und die App lädt mit deinen wiederhergestellten Daten neu. Deine Sicherungen werden sicher gespeichert und sind mit deinem Google-Konto verknüpft. Wenn du das Gerät wechselst oder die App neu installierst, melde dich einfach mit demselben Google-Konto an und tippe auf Wiederherstellen." #. placeholder {0}: user.displayName || user.email -#: app/(app)/settings.tsx:538 +#: app/(app)/settings.tsx:574 msgid "Signed in as {0}" msgstr "Angemeldet als {0}" -#: constants/HelpData.ts:168 +#: constants/HelpData.ts:188 msgid "Signing In" msgstr "Anmelden" @@ -3051,16 +3380,16 @@ msgstr "Anmelden" msgid "Single & Quick Workouts" msgstr "Einzel- & Schnelltrainings" -#: app/(app)/custom-exercise.tsx:505 +#: app/(app)/custom-exercise.tsx:531 #: app/(app)/exercise-info.tsx:263 msgid "Single-arm / single-leg" msgstr "Einarmig / einbeinig" -#: app/(app)/settings.tsx:722 +#: app/(app)/settings.tsx:758 msgid "Size unit" msgstr "Größeneinheit" -#: app/(app)/settings.tsx:1412 +#: app/(app)/settings.tsx:1451 msgid "Size: ~100MB" msgstr "Größe: ~100 MB" @@ -3102,10 +3431,18 @@ msgstr "Einige Bilder konnten nicht gelöscht werden. Fehlgeschlagene Übungs-ID msgid "Some images failed to download after retries. Failed exercise IDs: {0}" msgstr "Einige Bilder konnten nach mehreren Versuchen nicht heruntergeladen werden. Fehlgeschlagene Übungs-IDs: {0}" +#: app/(app)/friends.tsx:237 +msgid "Something went wrong. Please try again." +msgstr "Etwas ist schiefgelaufen. Bitte versuche es erneut." + #: constants/dbTranslations.ts:34 msgid "spine" msgstr "Wirbelsäule" +#: app/(app)/friend-profile.tsx:234 +msgid "Standalone Workouts" +msgstr "Eigenständige Trainings" + #: constants/HelpData.ts:39 msgid "Standalone workouts live outside of plans and appear alongside your plans on the Plans screen. Create one by tapping New Workout, give it a name, and add exercises; you can run it at any time without needing an active plan. An estimated duration is shown on each standalone workout so you can plan your time before starting. Quick Workouts let you start a session immediately from the home screen: tap Quick Workout, add exercises as you go, and at the end you can save it as a standalone workout for future use or simply discard it. Like plans, the workout editor automatically saves a draft so you can safely leave and return without losing your work." msgstr "Eigenständige Trainings existieren außerhalb von Plänen und erscheinen neben deinen Plänen auf dem Pläne-Bildschirm. Erstelle eines, indem du auf Neues Training tippst, einen Namen vergibst und Übungen hinzufügst; du kannst es jederzeit starten, ohne einen aktiven Plan zu benötigen. Eine geschätzte Dauer wird bei jedem eigenständigen Training angezeigt, damit du deine Zeit vor dem Start planen kannst. Schnelltrainings ermöglichen dir, eine Einheit sofort vom Startbildschirm aus zu starten: Tippe auf Schnelltraining, füge Übungen unterwegs hinzu, und am Ende kannst du es als eigenständiges Training für die Zukunft speichern oder einfach verwerfen. Wie Pläne speichert der Trainings-Editor automatisch einen Entwurf, damit du sicher gehen und zurückkehren kannst, ohne deine Arbeit zu verlieren." @@ -3114,7 +3451,7 @@ msgstr "Eigenständige Trainings existieren außerhalb von Plänen und erscheine msgid "Start" msgstr "Starten" -#: app/(app)/(tabs)/(plans)/overview.tsx:282 +#: app/(app)/(tabs)/(plans)/overview.tsx:327 msgid "Start Plan" msgstr "Plan starten" @@ -3122,11 +3459,11 @@ msgstr "Plan starten" msgid "Start Timer" msgstr "Timer starten" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:267 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:319 msgid "Start Workout" msgstr "Training starten" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:223 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:235 #: app/(app)/(tabs)/index.tsx:306 msgid "Starting Workout..." msgstr "Training wird gestartet..." @@ -3137,7 +3474,7 @@ msgstr "Heimtrainer" #: app/(app)/(tabs)/_layout.tsx:74 #: app/(app)/(tabs)/(stats)/_layout.tsx:16 -#: app/(app)/settings.tsx:994 +#: app/(app)/settings.tsx:1030 msgid "Stats" msgstr "Statistiken" @@ -3145,7 +3482,7 @@ msgstr "Statistiken" msgid "Stats & History" msgstr "Statistiken & Verlauf" -#: app/(app)/custom-exercise.tsx:499 +#: app/(app)/custom-exercise.tsx:525 msgid "Stats Options" msgstr "Statistikoptionen" @@ -3169,7 +3506,15 @@ msgstr "Stopp" msgid "Streak" msgstr "Serie" -#: app/(app)/settings.tsx:55 +#: app/(app)/friend-profile.tsx:491 +msgid "Strength PRs" +msgstr "Kraft-PRs" + +#: app/(app)/settings.tsx:1825 +msgid "Strength PRs are shared automatically after each workout." +msgstr "Kraft-PRs werden nach jedem Training automatisch geteilt." + +#: app/(app)/settings.tsx:58 msgid "Su" msgstr "So" @@ -3178,7 +3523,7 @@ msgstr "So" msgid "Success" msgstr "Erfolg" -#: app/(app)/settings.tsx:1088 +#: app/(app)/settings.tsx:1124 msgid "Suggest load and rep adjustments" msgstr "Gewichts- und Wiederholungsanpassungen vorschlagen" @@ -3205,8 +3550,8 @@ msgstr "Supersatz" #. placeholder {0}: outgoingSnapshot.isFirstInSuperset ? "A" : "B" #. placeholder {0}: ss.isFirstInSuperset ? "A" : "B" -#: app/(app)/(workout)/workout-session.tsx:1405 -#: app/(app)/(workout)/workout-session.tsx:1491 +#: app/(app)/(workout)/workout-session.tsx:1436 +#: app/(app)/(workout)/workout-session.tsx:1522 msgid "Superset {0}" msgstr "Supersatz {0}" @@ -3218,7 +3563,11 @@ msgstr "Supersätze" msgid "Take full control of your training by designing your own personalised plan. Select exercises, set rep ranges, rest times, and more to create a plan that aligns perfectly with your fitness goals." msgstr "Übernimm die volle Kontrolle über dein Training, indem du deinen eigenen personalisierten Plan erstellst. Wähle Übungen, lege Wiederholungsbereiche, Pausenzeiten und mehr fest, um einen Plan zu erstellen, der perfekt zu deinen Fitnesszielen passt." -#: constants/HelpData.ts:169 +#: constants/HelpData.ts:179 +msgid "Tap any accepted friend in your Friends list to open their profile. Their profile shows the plans, standalone workouts, and custom exercises they have chosen to share. Tap Import on any item to add it directly to your own library. Imported plans and workouts are saved as new copies that you can edit freely without affecting the original. Imported custom exercises are added to your exercise library and available immediately when building workouts." +msgstr "Tippe auf einen beliebigen akzeptierten Freund in deiner Freundesliste, um sein Profil zu öffnen. Sein Profil zeigt die Pläne, eigenständigen Trainings und eigenen Übungen, die er geteilt hat. Tippe bei einem Eintrag auf Importieren, um ihn direkt in deine eigene Bibliothek hinzuzufügen. Importierte Pläne und Trainings werden als neue Kopien gespeichert, die du frei bearbeiten kannst, ohne das Original zu beeinflussen. Importierte eigene Übungen werden deiner Übungsbibliothek hinzugefügt und sind sofort beim Erstellen von Trainings verfügbar." + +#: constants/HelpData.ts:189 msgid "Tap Sign In With Google in Settings to connect your account. Signing in enables cloud backups so your data is safe if you switch devices or reinstall the app, and your name is shown in the home screen greeting. The app works fully offline without signing in, but cloud backups are unavailable. Your data is stored locally on your device and is not shared with anyone unless you choose to share it yourself." msgstr "Tippe in den Einstellungen auf Mit Google anmelden, um dein Konto zu verbinden. Die Anmeldung ermöglicht Cloud-Sicherungen, damit deine Daten sicher sind, wenn du das Gerät wechselst oder die App neu installierst, und dein Name wird in der Startbildschirmbegrüßung angezeigt. Die App funktioniert vollständig offline ohne Anmeldung, aber Cloud-Sicherungen sind nicht verfügbar. Deine Daten werden lokal auf deinem Gerät gespeichert und nicht mit anderen geteilt, sofern du es nicht selbst tust." @@ -3230,11 +3579,15 @@ msgstr "Tippe auf das Sternsymbol oben rechts in einer Übungsinfoansicht, um si msgid "Target Distance ({distanceUnit})" msgstr "Zieldistanz ({distanceUnit})" -#: app/(app)/custom-exercise.tsx:393 +#: app/(app)/friend-exercise.tsx:76 +msgid "Target Muscle" +msgstr "Zielmuskel" + +#: app/(app)/custom-exercise.tsx:419 msgid "Target Muscle *" msgstr "Zielmuskel *" -#: app/(app)/custom-exercise.tsx:202 +#: app/(app)/custom-exercise.tsx:207 msgid "Target muscle is required." msgstr "Zielmuskel ist erforderlich." @@ -3246,7 +3599,7 @@ msgstr "Zielmuskel:" msgid "Target: {distanceMin} {distanceUnit}" msgstr "Ziel: {distanceMin} {distanceUnit}" -#: app/(app)/settings.tsx:52 +#: app/(app)/settings.tsx:55 msgid "Th" msgstr "Do" @@ -3294,6 +3647,14 @@ msgstr "Oberschenkel (R)" msgid "This exercise is already in your workout. Please choose a different one." msgstr "Diese Übung ist bereits in deinem Training. Bitte wähle eine andere." +#: app/(app)/friend-profile.tsx:140 +msgid "This friend hasn't shared any content yet." +msgstr "Dieser Freund hat noch keine Inhalte geteilt." + +#: app/(app)/settings.tsx:88 +msgid "This removes all content you have shared with friends. Your friends and friend list are not affected." +msgstr "Damit werden alle Inhalte entfernt, die du mit Freunden geteilt hast. Deine Freunde und Freundesliste sind davon nicht betroffen." + #: app/(app)/+not-found.tsx:18 msgid "This screen doesn't exist." msgstr "Dieser Bildschirm existiert nicht." @@ -3309,7 +3670,7 @@ msgstr "Do" msgid "Thursday" msgstr "Donnerstag" -#: app/(app)/custom-exercise.tsx:65 +#: app/(app)/custom-exercise.tsx:70 #: components/WeeklySummaryCard.tsx:299 msgid "Time" msgstr "Zeit" @@ -3336,7 +3697,7 @@ msgstr "Zeit (s)" msgid "Time PR" msgstr "Zeit-PR" -#: app/(app)/(workout)/workout-session.tsx:552 +#: app/(app)/(workout)/workout-session.tsx:559 msgid "Time to do your next set!" msgstr "Zeit für deinen nächsten Satz!" @@ -3345,11 +3706,11 @@ msgstr "Zeit für deinen nächsten Satz!" msgid "Time: {0}" msgstr "Zeit: {0}" -#: app/(app)/settings.tsx:365 +#: app/(app)/settings.tsx:401 msgid "To enable rest timer notifications, grant notification permissions in your device settings." msgstr "Um Pausentimer-Benachrichtigungen zu aktivieren, erteile Benachrichtigungsberechtigungen in deinen Geräteeinstellungen." -#: app/(app)/settings.tsx:384 +#: app/(app)/settings.tsx:420 msgid "To enable workout reminders, grant notification permissions in your device settings." msgstr "Um Trainingserinnerungen zu aktivieren, erteile Benachrichtigungsberechtigungen in deinen Geräteeinstellungen." @@ -3414,15 +3775,19 @@ msgstr "Verfolgte Übungen" msgid "Tracking" msgstr "Tracking" -#: app/(app)/custom-exercise.tsx:465 +#: app/(app)/friend-exercise.tsx:90 +msgid "Tracking Type" +msgstr "Tracking-Typ" + +#: app/(app)/custom-exercise.tsx:491 msgid "Tracking Type *" msgstr "Tracking-Typ *" -#: app/(app)/custom-exercise.tsx:485 +#: app/(app)/custom-exercise.tsx:511 msgid "Tracking type cannot be changed after creation." msgstr "Der Tracking-Typ kann nach der Erstellung nicht mehr geändert werden." -#: app/(app)/custom-exercise.tsx:205 +#: app/(app)/custom-exercise.tsx:210 msgid "Tracking type is required." msgstr "Tracking-Typ ist erforderlich." @@ -3440,7 +3805,7 @@ msgstr "" msgid "Training" msgstr "Training" -#: components/TrainingPlanCard.tsx:74 +#: components/TrainingPlanCard.tsx:77 msgid "Training Plan" msgstr "Trainingsplan" @@ -3476,7 +3841,7 @@ msgstr "Trizeps" msgid "Try Again" msgstr "Erneut versuchen" -#: app/(app)/settings.tsx:50 +#: app/(app)/settings.tsx:53 msgid "Tu" msgstr "Di" @@ -3499,7 +3864,11 @@ msgstr "Tippe, um Hilfethemen zu filtern" msgid "Unable to save your workout. Please try again later." msgstr "Dein Training konnte nicht gespeichert werden. Bitte versuche es später erneut." -#: app/(app)/settings.tsx:650 +#: app/(app)/friend-exercise.tsx:97 +msgid "Unilateral" +msgstr "Einseitig" + +#: app/(app)/settings.tsx:686 msgid "Units of measurement" msgstr "Maßeinheiten" @@ -3511,7 +3880,17 @@ msgstr "Unbekannt" msgid "Update Ready" msgstr "Update bereit" -#: app/(app)/settings.tsx:634 +#. placeholder {0}: formatDistanceToNow(plan.updatedAt.toDate(), { addSuffix: true, }) +#. placeholder {0}: formatDistanceToNow(plan.updatedAt.toDate(), { addSuffix: true }) +#. placeholder {0}: formatDistanceToNow(workout.updatedAt.toDate(), { addSuffix: true, }) +#: app/(app)/friend-plan.tsx:75 +#: app/(app)/friend-profile.tsx:185 +#: app/(app)/friend-profile.tsx:276 +#: app/(app)/friend-workout.tsx:62 +msgid "Updated {0}" +msgstr "Aktualisiert {0}" + +#: app/(app)/settings.tsx:670 msgid "Uploading. Please wait..." msgstr "Hochladen. Bitte warten..." @@ -3543,11 +3922,11 @@ msgstr "obere Brust" msgid "upper legs" msgstr "Oberschenkel" -#: app/(app)/settings.tsx:979 +#: app/(app)/settings.tsx:1015 msgid "Using history from same workout" msgstr "Historie aus demselben Training" -#: app/(app)/settings.tsx:978 +#: app/(app)/settings.tsx:1014 msgid "Using most recent from any workout" msgstr "Aktuellste aus beliebigem Training" @@ -3555,7 +3934,7 @@ msgstr "Aktuellste aus beliebigem Training" msgid "Values" msgstr "Werte" -#: app/(app)/settings.tsx:876 +#: app/(app)/settings.tsx:912 msgid "Vibrate after rest" msgstr "Nach Pause vibrieren" @@ -3624,7 +4003,7 @@ msgstr "Aufwärmen, " msgid "warmup" msgstr "Aufwärmen" -#: app/(app)/settings.tsx:51 +#: app/(app)/settings.tsx:54 msgid "We" msgstr "Mi" @@ -3643,7 +4022,7 @@ msgstr "Mittwoch" msgid "Week streak" msgstr "Wochenserie" -#: app/(app)/settings.tsx:558 +#: app/(app)/settings.tsx:594 msgid "Weekly goal" msgstr "Wochenziel" @@ -3667,7 +4046,7 @@ msgstr "Gewicht" msgid "Weight ({weightUnitLabel})" msgstr "Gewicht ({weightUnitLabel})" -#: app/(app)/settings.tsx:755 +#: app/(app)/settings.tsx:791 msgid "Weight increment" msgstr "Gewichtsschritt" @@ -3675,11 +4054,11 @@ msgstr "Gewichtsschritt" msgid "Weight Tracking for Bodyweight Exercises" msgstr "Gewichtserfassung für Körpergewichtsübungen" -#: app/(app)/settings.tsx:670 +#: app/(app)/settings.tsx:706 msgid "Weight unit" msgstr "Gewichtseinheit" -#: app/(app)/custom-exercise.tsx:62 +#: app/(app)/custom-exercise.tsx:67 msgid "Weight/Reps" msgstr "Gewicht/Wdh." @@ -3703,7 +4082,7 @@ msgstr "Willkommen{userName}" msgid "When you open a workout that contains exercises you trained recently, a Recovery Check-in sheet appears if those exercises have a pending progression suggestion and your last session was at least 12 hours ago. For each relevant muscle group, you choose one of three options: Fresh (fully recovered), Mild soreness, or Still very sore. If a muscle is marked as still very sore, any upward progression suggestion for exercises targeting that muscle is paused and held at the current load until you re-evaluate at the start of the following session. Fresh or Mild soreness does not affect suggestions. Tap Skip for now to bypass the check-in entirely; a skipped check-in is treated the same as fresh recovery, so pending suggestions are unaffected." msgstr "Wenn du ein Training öffnest, das Übungen enthält, die du kürzlich trainiert hast, erscheint ein Regenerations-Check-in-Bogen, falls diese Übungen einen ausstehenden Progressionsvorschlag haben und deine letzte Einheit mindestens 12 Stunden zurückliegt. Für jede relevante Muskelgruppe wählst du eine von drei Optionen: Frisch (vollständig erholt), Leichter Muskelkater oder Noch sehr starker Muskelkater. Wenn ein Muskel als noch sehr starker Muskelkater markiert wird, wird jeder aufwärtsgerichtete Progressionsvorschlag für Übungen, die diesen Muskel trainieren, pausiert und bei der aktuellen Last gehalten, bis du zu Beginn der folgenden Einheit neu bewertest. Frisch oder Leichter Muskelkater beeinflusst Vorschläge nicht. Tippe auf Jetzt überspringen, um den Check-in ganz zu umgehen; ein übersprungener Check-in wird wie frische Erholung behandelt, ausstehende Vorschläge bleiben unverändert." -#: components/ExerciseFeedbackSheet.tsx:233 +#: components/ExerciseFeedbackSheet.tsx:247 msgid "Where did you feel it?" msgstr "Wo hast du es gespürt?" @@ -3713,7 +4092,7 @@ msgstr "Arbeits-" #: app/(app)/(tabs)/(plans)/_layout.tsx:18 #: app/(app)/(workout)/_layout.tsx:17 -#: app/(app)/settings.tsx:734 +#: app/(app)/settings.tsx:770 #: components/RestDayCard.tsx:41 #: components/WeeklyScheduleDisplay.tsx:88 #: components/WorkoutDoneCard.tsx:50 @@ -3736,7 +4115,8 @@ msgstr "Trainingskalender" msgid "Workout Complete!" msgstr "Training abgeschlossen!" -#: app/(app)/_layout.tsx:33 +#: app/(app)/_layout.tsx:35 +#: app/(app)/_layout.tsx:55 #: app/(app)/(tabs)/(stats)/_layout.tsx:19 msgid "Workout Details" msgstr "Trainingsdetails" @@ -3754,13 +4134,14 @@ msgstr "Training läuft" msgid "Workout name" msgstr "Trainingsname" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:54 -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:207 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:66 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:219 #: app/(app)/(workout)/workout-summary.tsx:518 +#: app/(app)/friend-workout.tsx:43 msgid "Workout not found." msgstr "Training nicht gefunden." -#: app/(app)/settings.tsx:1255 +#: app/(app)/settings.tsx:1294 msgid "Workout reminders" msgstr "Trainingserinnerungen" @@ -3804,7 +4185,7 @@ msgstr "x {0} Wdh. " msgid "Yes" msgstr "Ja" -#: components/ExerciseFeedbackSheet.tsx:215 +#: components/ExerciseFeedbackSheet.tsx:229 msgid "Yes, increase the challenge" msgstr "Ja, mehr herausfordern" @@ -3812,7 +4193,7 @@ msgstr "Ja, mehr herausfordern" msgid "Yesterday" msgstr "Gestern" -#: app/(app)/(tabs)/(plans)/overview.tsx:150 +#: app/(app)/(tabs)/(plans)/overview.tsx:161 msgid "You activated this plan." msgstr "Du hast diesen Plan aktiviert." @@ -3824,6 +4205,10 @@ msgstr "Du kannst diesen Einführungsbildschirm jederzeit über die Einstellungs msgid "You can login at any time from the settings screen, if you choose to skip it now." msgstr "Du kannst dich jederzeit über die Einstellungsseite anmelden, wenn du es jetzt überspringen möchtest." +#: constants/HelpData.ts:174 +msgid "You can share plans, standalone workouts, custom exercises, body measurements, and strength PRs with your friends. All five categories have a global toggle in Privacy Settings, found in the Account section of Settings. Enabling the global toggle for a category shares all items in that category and syncs new data automatically whenever it changes. Plans and standalone workouts also have an individual Share toggle on each item's overview screen, so you can publish specific plans or workouts without sharing everything. A cloud icon on the plan or workout card confirms it is currently published. To remove shared data, disable the toggle in Privacy Settings and tap Delete Shared Data for that category. You can also delete all shared data for every category from the same screen." +msgstr "Du kannst Pläne, eigenständige Trainings, eigene Übungen, Körpermaße und Kraft-PRs mit deinen Freunden teilen. Alle fünf Kategorien haben einen globalen Schalter in den Datenschutzeinstellungen im Konto-Bereich der Einstellungen. Wenn du den globalen Schalter für eine Kategorie aktivierst, werden alle Elemente dieser Kategorie geteilt und neue Daten werden automatisch synchronisiert, wenn sie sich ändern. Pläne und eigenständige Trainings haben zusätzlich einen individuellen Teilen-Schalter in der Übersicht jedes Eintrags, sodass du bestimmte Pläne oder Trainings veröffentlichen kannst, ohne alles zu teilen. Ein Wolken-Symbol auf der Plan- oder Trainingskarte bestätigt, dass er aktuell veröffentlicht ist. Um geteilte Daten zu entfernen, deaktiviere den Schalter in den Datenschutzeinstellungen und tippe auf Geteilte Daten löschen für diese Kategorie. Du kannst auch alle geteilten Daten jeder Kategorie über denselben Bildschirm löschen." + #: components/ProgressionSummaryCard.tsx:22 msgid "You chose to keep it steady. Hold this load." msgstr "Du hast dich fürs Halten entschieden. Gewicht bleibt so." @@ -3851,11 +4236,11 @@ msgstr "Du hast nicht gespeicherte Änderungen. Möchtest du sie wirklich verwer msgid "You modified this workout. Save those changes for future sessions?" msgstr "Du hast dieses Training geändert. Änderungen für zukünftige Sitzungen speichern?" -#: app/(app)/settings.tsx:604 +#: app/(app)/settings.tsx:640 msgid "You need to sign in to use this feature" msgstr "Du musst dich anmelden, um diese Funktion zu nutzen" -#: app/(app)/custom-exercise.tsx:81 +#: app/(app)/custom-exercise.tsx:86 msgid "You'll lose what you've entered so far." msgstr "Du verlierst alles, was du bisher eingegeben hast." @@ -3871,10 +4256,10 @@ msgstr "Du hast dein Wochenziel erreicht. Unglaubliche Leistung!" msgid "Your journey to Swoletown begins today!" msgstr "Deine Reise nach Swoletown beginnt heute!" -#: app/(app)/(tabs)/(plans)/index.tsx:126 +#: app/(app)/(tabs)/(plans)/index.tsx:130 msgid "Your training plans" msgstr "Deine Trainingspläne" -#: app/(app)/(tabs)/(plans)/index.tsx:141 +#: app/(app)/(tabs)/(plans)/index.tsx:147 msgid "Your workouts" msgstr "Deine Trainings" diff --git a/locales/en/messages.js b/locales/en/messages.js index f8610f4b..ef4bf2a5 100644 --- a/locales/en/messages.js +++ b/locales/en/messages.js @@ -1 +1 @@ -/*eslint-disable*/module.exports={messages:JSON.parse("{\"-2Ut5a\":[\"The Insights strip at the top of the Stats tab gives four at-a-glance highlights for the selected time range: your average workouts per week, your biggest strength gain across tracked exercises, the body part you have trained most, and your current weekly streak. These update automatically after each workout.\"],\"-5kO8P\":[\"Saturday\"],\"-BjMj_\":[\"Create Workout\"],\"-FjWgX\":[\"Thu\"],\"-Tpjjs\":[[\"0\"],\" sets\"],\"-WSEJS\":[\"Delete Workout\"],\"-Xejuf\":[\"Hips\"],\"-XvJee\":[\"best \",[\"0\"],[\"weightUnit\"],\" × \",[\"1\"]],\"-svcUj\":[\"Save this workout?\"],\"03mQOq\":[\"Failed to activate this plan: \",[\"0\"]],\"06EUQy\":[\"All-time PR\"],\"0EHHPz\":[\"adductors\"],\"0EPpEZ\":[\"Add custom metric\"],\"0EcUWz\":[\"Discard changes?\"],\"0OeId4\":[\"Create a Custom Plan\"],\"0P1btN\":[\"\\n🔔 New: Exercise Timer Sounds!\\n\\nThe exercise timer now plays audio cues to keep you on track. A countdown beep as the timer nears zero and a sound when you hit your goal. Toggle each sound independently in Settings.\\n\"],\"0SaB4K\":[\"Warm-up set\"],\"0U938S\":[\"Select at least one day\"],\"0V9gKq\":[\"\\n🔵 New: Exercise Timer Modal!\\n\\nTime-based exercises now show a dedicated countdown modal with a progress ring, making it easy to track your effort and stay on pace during timed sets.\\n\"],\"0caMy7\":[\"History\"],\"0dHvKo\":[\"Target muscle:\"],\"0eRpDV\":[\"Hard, near limit\"],\"0f7U0k\":[\"Wed\"],\"0tJJBW\":[\"Prev: \"],\"0vGEy2\":[\"\\n📊 New: Improved Stats Screen!\\n\\nThe stats screen has been redesigned with a fresh new look and improved insights. Explore your training history with better charts, clearer summaries, and more detailed breakdowns of your progress over time.\\n\"],\"14ytif\":[\"Start Workout\"],\"1DPB1m\":[\"\\n🗂️ New: Five New Premade Training Plans!\\n\\nFive new ready-to-use plans are now available: 5-Day Bro Split, 5-Day Push/Pull/Legs, 6-Day Split, Bodyweight, and Dumbbell Only. Whether you're training at home or in the gym, there's a plan to get you started straight away.\\n\"],\"1FnEj9\":[\"Body Measurements\"],\"1Kx4Hp\":[\"Error fetching \",[\"0\"],\": \",[\"1\"]],\"1Mx10o\":[\"View Stats\"],\"1QfxQT\":[\"Dismiss\"],\"1Se9J7\":[\"stationary bike\"],\"1UzENP\":[\"No\"],\"1gbc4_\":[\"New Workout\"],\"1hW6-f\":[\"Some images failed to download after retries. Failed exercise IDs: \",[\"0\"]],\"1j3Ob3\":[\"Workout Calendar\"],\"1mm2JF\":[\"deltoids\"],\"296mtr\":[\"trap bar\"],\"29Hx9U\":[\"Stats\"],\"2FYpfJ\":[\"More\"],\"2ZZM6V\":[\"core\"],\"2bnWaQ\":[[\"completedCount\"],\"/\",[\"0\"],\" sets completed\"],\"2cupe5\":[\"Apply to all \",[\"0\"],\" sets\"],\"2dPYb7\":[\"No measurements yet. Log your first entry above.\"],\"2dX9Kv\":[\"back\"],\"2eB2c7\":[\"Train without a plan! Create standalone workouts that live outside your training plans — perfect for mobility sessions, warm-ups, or anything ad hoc.\\n\\nOr jump straight into a Quick Workout from the home screen, add exercises on the fly, and optionally save it as a standalone workout when you're done.\"],\"2gSypt\":[\"Equipment *\"],\"2j0v05\":[\"All images downloaded successfully!\"],\"2lfUf3\":[[\"streak\",\"plural\",{\"one\":[\"#\",\" week in a row\"],\"other\":[\"#\",\" weeks in a row\"]}]],\"2saL1j\":[\"1RM\"],\"2vS4Oc\":[\"Easy, could do more\"],\"2wR0QE\":[\"Add Exercise\"],\"30xwUM\":[\"Are you sure you want to delete all animated images? Single images will be automatically re-downloaded when viewed.\"],\"39y5bn\":[\"Friday\"],\"3A79ox\":[\"Reduce load\"],\"3L-1Z1\":[\"Error loading exercises: \",[\"0\"]],\"3RoflF\":[\"\\n📈 New: Exercise History in the Info Screen!\\n\\nThe exercise info screen now includes a full history of every time you've performed that exercise, showing weights, reps, time, and distance for each set from past sessions. Access it during a workout, from your plan, or anywhere else exercise info is available.\\n\"],\"3ezHPX\":[\"Play sound after rest\"],\"3hJ166\":[\"\\n🔍 Improved: Smarter Exercise Search & Easy Access to the Exercise Library!\\n\\nExercise search now understands common abbreviations like RDL, OHP, DB, and KB, corrects minor typos, and ranks results by relevance so the best match always comes first.\\n\\nYou can also browse the full exercise library any time from the menu, without needing to be in a workout or plan.\\n\"],\"3hJypY\":[\"Insights\"],\"43lYJ-\":[\"Welcome\",[\"userName\"]],\"4BgR4M\":[\"You've hit your weekly goal. Incredible work!\"],\"4GTHgi\":[\"Exercise timer countdown\"],\"4M4P8M\":[\"No values entered\"],\"4OjqAQ\":[\"Keep editing\"],\"4_WLmI\":[\"body weight\"],\"4j0zbV\":[\"Saving Plan...\"],\"4jkyRj\":[\"warmup\"],\"4mrNi3\":[[\"suggestedRepsMin\"],\"-\",[\"suggestedRepsMax\"],\" reps suggested\"],\"4oRoD4\":[\"Configure weight, size, and distance units, default sets per exercise, default rest time, and the weight increment used by the ± buttons during a session. Adjust workout button size (Standard, Large, or XLarge) and toggle Keep Screen On to prevent the display sleeping mid-workout. Under Stats, you can exclude warmup sets from volume, double reps for unilateral exercises, or double the weight for paired implements, useful if you prefer logging per-dumbbell weight rather than the total. Set your body weight here; it is used to calculate effective load for assisted exercises.\"],\"4sGdeG\":[\"Body Fat\"],\"50_FGa\":[\"Exercise\"],\"538Jsv\":[\"Cancel Workout\"],\"58iwz8\":[\"Error loading plans\"],\"5SgD0L\":[\"You have unsaved changes. Are you sure you want to discard them?\"],\"5Z05pb\":[\"Type to filter help topics\"],\"5aB9II\":[\"Time to do your next set!\"],\"5b4J4v\":[\"All Time\"],\"5lWFkC\":[\"Sign in\"],\"5w2VTM\":[\"Are you sure you want to download all animated images? This may take a while.\"],\"5yIPLp\":[\"Oops!\"],\"66llpx\":[\"Add Image\"],\"699xiu\":[\"Are you sure you want to restore the backup?\"],\"6Bqki7\":[\"Weekly Goal Complete!\"],\"6Hcqaf\":[\"\\n↕️ New: Reorder Workouts in Your Plan!\\n\\nYou can now reorder workouts directly in the plan creation screen and workout cards, giving you full control over your training schedule layout.\\n\"],\"6MR2yM\":[\"Browse almost 1,000 exercises and filter by body part, target muscle, or equipment. Use the sort chips at the top to order exercises by Default, Active Plan, Recent, or Frequent, so the exercises most relevant to you appear first. When replacing an exercise, the filter automatically preselects the matching target muscle to help you find alternatives faster. Tap any exercise to view its animated demonstration, the muscles targeted, and a full history of every time you have performed it, including weights, reps, time, or distance per set. Download all exercise animations (~100 MB) in Settings for offline access.\"],\"6XIVae\":[\"Load up\"],\"6_dCYd\":[\"Overview\"],\"6g63at\":[\"Explore Plans\"],\"6glEtt\":[\"Still recovering. Hold this load for now.\"],\"6igHT6\":[\"Edit Workout\"],\"6lAGPA\":[\"Add a workout to get started\"],\"6lv7us\":[\"Weight (\",[\"weightUnitLabel\"],\")\"],\"6q7I63\":[\"waist\"],\"6u9LvN\":[[\"days\",\"plural\",{\"one\":[\"#\",\" day ago\"],\"other\":[\"#\",\" days ago\"]}]],\"6uHnph\":[\"Time (Hour:Min)\"],\"6vinCF\":[\"Tracking Type *\"],\"6z9W13\":[\"Restart\"],\"716aO7\":[\"Most trained\"],\"75Qc-e\":[\"Count reps ×2 for volume when the setting is enabled\"],\"77kllS\":[\"best \",[\"0\"],\" reps\"],\"7F8buC\":[\"lower arms\"],\"7FYy4K\":[\"Error saving workout\"],\"7LBKtm\":[\"No workout available\"],\"7LLkrj\":[\"grip muscles\"],\"7MuXko\":[\"Personal\"],\"7P_9OY\":[\"Tu\"],\"7YT_7y\":[\"Reps\"],\"7Z9Tzs\":[\"spine\"],\"7eMo-U\":[\"Go Home\"],\"7hAJKI\":[[\"0\",\"plural\",{\"one\":[\"set\"],\"other\":[\"sets\"]}]],\"7iTVa8\":[\"Secondary Muscles\"],\"7p3sn_\":[\"Time: \",[\"0\"]],\"7x42zy\":[\"No data for this period\"],\"7xB0qQ\":[\"Target Muscle *\"],\"87VAxI\":[\"Exercise Info\"],\"8Mlj-A\":[\"Rep target not met. Hold steady for now.\"],\"8Rd3od\":[\"Are you sure you want to cancel and delete this workout?\"],\"8V8f_Q\":[\"Latest \",[\"metricLabel\"],\": \",[\"0\"]],\"8YBh-G\":[\"Counting reps ×2 for these exercises\"],\"8ZJ9dh\":[\"Weight Tracking for Bodyweight Exercises\"],\"8ZU8FI\":[\"Error loading stats. Please try again.\"],\"8_MCsG\":[\"\\n💾 New: Save & Resume Plan and Workout Drafts!\\n\\nYour work in the plan and standalone workout editors is now automatically saved as a draft. If you leave mid-edit, you'll be prompted to continue where you left off or discard the draft, so you never lose progress by accident.\\n\"],\"8aTiea\":[\"Customisation\"],\"8cA6YX\":[\"Track your body composition over time from the Measurements section in the Stats tab. Use the Log Entry form to record values for any active metric, then tap a past entry in the History list to review or edit it. On the entry detail screen, tap a metric chip to switch the chart between different measurements and use the time range selector to zoom in or out. Metrics are split into three types: mass (weight, in kg or lbs), length (circumferences like waist and hips, in cm or in), and percentage (body fat). Units follow your weight and size preferences in Settings. To control which metrics appear in the entry form, tap Manage Metrics at the top of the Log Entry section. Built-in metrics can be toggled on or off; you can also create your own custom metrics and choose their type. Custom metrics can be hidden from the form at any time, and your historical data for them is always preserved.\"],\"8jcZyX\":[\"Built-in Metrics\"],\"8mjpCE\":[\"MuscleQuest Introduction\"],\"8uqQSD\":[\"Couldn't finish all sets\"],\"8yLreB\":[\"for \",[\"0\"],\"s \"],\"8yw7nc\":[\"Recovery Check-in\"],\"91hJvI\":[\"Target: \",[\"distanceMin\"],\" \",[\"distanceUnit\"]],\"94FTWy\":[\"Delete Complete\"],\"95IyBI\":[\"Bodyweight exercises like pull-ups or dips track reps only by default. If you want to log added weight, such as a weight belt or vest, open the sets overview for that exercise in the workout or plan editor and toggle Track Weight on. The toggle is saved per workout, so you can have some workouts use bodyweight-only and others track the additional load. Progression charts and history will reflect the logged weight once the toggle is on.\"],\"97-TIS\":[\"You couldn't complete all sets. Reducing load slightly for next time.\"],\"9C6X7Q\":[\"Discard Changes\"],\"9EGOsa\":[\"cable\"],\"9H3-WL\":[\"\\n⚙️ New: Three New Stats Settings!\\n\\nCustomise how your volume and stats are calculated with three new options in Settings:\\n\\n• Exclude warm-up sets from stats so they don't skew your numbers.\\n• Double dumbbell weight automatically, so you can log the weight of one dumbbell and have the total counted for you.\\n• Double reps for single arm/leg exercises, so unilateral movements are counted correctly in your volume totals.\\n\"],\"9LmK3L\":[\"Images by Unsplash\"],\"9XoWik\":[\"serratus anterior\"],\"9eQmcp\":[[\"0\"],\" days per week\"],\"A-gAFO\":[\"Create your own exercises from the exercise picker. Give it a name, an optional image, body part, target muscles, secondary muscles, and equipment. Choose a tracking type: weight + reps, time, distance, reps only, or assisted (which factors in your body weight for movements like assisted pull-ups). Toggle Unilateral for single-arm or single-leg exercises; reps can be automatically doubled in your stats. Toggle Paired Implements if you track the weight of one implement rather than the total: for example, if you log 20 kg for one dumbbell, the app counts 40 kg toward your volume.\"],\"A1-VaP\":[\"latissimus dorsi\"],\"A1_kH4\":[\"Exercise Timer\"],\"A1taO8\":[\"Search\"],\"AWokve\":[\"Using history from same workout\"],\"AeXO77\":[\"Account\"],\"AqyJQg\":[\"Post-Exercise Feedback\"],\"Ayx1au\":[\"Are you sure you want to delete this plan?\"],\"B8ZQ8n\":[\"Min Reps\"],\"B9LtU1\":[\"You have unsaved changes from your last session. Would you like to continue?\"],\"BGO6Rp\":[\"How are these muscles feeling since your last session?\"],\"BTqs-Z\":[[\"0\",\"plural\",{\"one\":[\"#\",\" Set\"],\"other\":[\"#\",\" Sets\"]}]],\"BZDlVl\":[\"hip flexors\"],\"BaG4Vp\":[\"Frequent\"],\"BdnYlL\":[\"Avg Duration\"],\"BpTc_M\":[\"Search help\"],\"Bqo02Q\":[\"Start Timer\"],\"BrHgnn\":[\"\\n⏱️ New: Adjustable Rest Timer!\\n\\nA new slide-in panel lets you fine-tune your rest duration on the fly during a workout. Your custom rest time is saved per set, so each set remembers exactly how long you like to rest.\\n\"],\"BwTx3c\":[\"Are you sure you want to remove \",[\"0\"],\"?\"],\"C4GKOD\":[[\"repRange\"],\" Reps, \"],\"CCTop_\":[\"Recent\"],\"CE-M2e\":[\"Info\"],\"CV6Ez2\":[\"Tap Sign In With Google in Settings to connect your account. Signing in enables cloud backups so your data is safe if you switch devices or reinstall the app, and your name is shown in the home screen greeting. The app works fully offline without signing in, but cloud backups are unavailable. Your data is stored locally on your device and is not shared with anyone unless you choose to share it yourself.\"],\"CZKXmk\":[\"ankles\"],\"CaKjcv\":[\"Quick Workout\"],\"CghlOu\":[\"lower abs\"],\"CiUwqB\":[\"Go to Workouts\"],\"D0GOrZ\":[\"You need to sign in to use this feature\"],\"D3h1sn\":[\"working\"],\"D45Cr4\":[\"Select secondary muscles\"],\"D89zck\":[\"Sun\"],\"DBC3t5\":[\"Sunday\"],\"DIS-zd\":[\"Failed to delete plan: \",[\"0\"]],\"DJMHhb\":[\"Last session was a deload — comparison skipped.\"],\"DNhKLr\":[\"\\n🎯 Improved: Smarter Exercise Filters!\\n\\nWhen replacing an exercise, the filter now automatically preselects the target muscle to match what you're replacing. Only relevant filters are shown based on your current selection, making it much faster to find the right alternative.\\n\"],\"DPfwMq\":[\"Done\"],\"DTtUaj\":[\"Enter at least one measurement to log.\"],\"DWFuyG\":[\"Remove Exercise\"],\"DYOFso\":[\"ankle stabilizers\"],\"DdBQBl\":[\"Weekly Schedule\"],\"Dh5Ge5\":[\"Any pain or form breakdown?\"],\"Di-cgt\":[\"Welcome to MuscleQuest!\"],\"DqgDEk\":[\"Using most recent from any workout\"],\"Dvc8Qg\":[\"Description:\"],\"Dy8Cvh\":[\"quadriceps\"],\"Dy_8Fq\":[\"DISMISS\"],\"E3kRqj\":[[\"uniqueWorkoutDaysCount\"],\" / \",[\"0\"],\" days worked out\"],\"EANWES\":[\"Failed to load history\"],\"EMyNOr\":[[\"0\"],\" \",[\"1\"],\" (used for assisted exercises)\"],\"E_QGRL\":[\"Disabled\"],\"Ef7StM\":[\"Unknown\"],\"EfdYnO\":[[\"0\"],[\"distanceUnit\"]],\"EkVHAp\":[\"Rest timer increment\"],\"EoQHhQ\":[\"treadmill\"],\"Euo2Um\":[\"Time (Min:Sec)\"],\"F37c1s\":[\"Open Settings\"],\"F6pfE9\":[\"Active\"],\"FCGpHg\":[\"No exercises in this workout yet.\"],\"FHIDZO\":[\"Save and select\"],\"FPsvA8\":[\"Got it!\"],\"Fb5zs_\":[\"\\n⚖️ New: Track Weight for Bodyweight Exercises!\\n\\nFor bodyweight exercises like pull-ups or dips, you can now toggle on weight tracking per workout. Perfect for weighted variations, so you can log the added weight and track progression over time.\\n\"],\"Fe0wLe\":[\"Supersets\"],\"FnTClW\":[\"You've been hitting targets easily. Time to add a little more weight.\"],\"Fp1hl-\":[\"Loading Plan...\"],\"FwCUad\":[\"Equipment is required.\"],\"G-iXUH\":[\"shoulders\"],\"G2R9Qq\":[\"wrist flexors\"],\"G3myU-\":[\"Tuesday\"],\"G49bAb\":[\"leverage machine\"],\"G6rTvo\":[\"Track (\",[\"0\"],\")\"],\"GCV1HM\":[\"Signed in as \",[\"0\"]],\"GCqPY4\":[\"The home screen shows your progress toward your weekly training goal, which is the number of days you want to work out each week, set in Settings. A strip at the top tracks how many days you have completed and highlights each completed day. Below it, your active plan's workouts are listed with their completion status for the week; tap Start on any workout to begin. The card displayed beneath changes with your status: a Resume card appears if a session is in progress, a Rest Day card shows on days with no scheduled workout, and a Workout Done card confirms today's session is complete. When you hit your weekly goal, a Weekly Summary card appears showing total workouts, sets, and volume for the week, plus your streak, which counts the number of consecutive weeks you have met your goal.\"],\"GGqR7k\":[\"Single & Quick Workouts\"],\"GLJjec\":[\"To Failure\"],\"GLm0-9\":[\"Pain or form issues\"],\"GNurdZ\":[\"Delete Exercise\"],\"GPeIuw\":[\"Distance\"],\"GS7yxz\":[\"Permission Required\"],\"GSOeV2\":[\"hamstrings\"],\"GVN2lL\":[\"Create Exercise\"],\"GWvJTL\":[\"About right\"],\"GX9tlq\":[\"neck\"],\"Gd-KuS\":[\"Manage metrics\"],\"Gf9sn6\":[\"Checking for backups...\"],\"GhCGeL\":[\"Sets\"],\"GksdwI\":[\"Top PR Sets\"],\"HNWkJr\":[\"\\n📏 New: Distance Tracking for Custom Exercises!\\n\\nCustom exercises can now use a distance tracking type, perfect for cardio and conditioning movements like runs, rows, or sled pushes. Log distance for your sets and get insights on progression just like any other exercise.\\n\"],\"HYL9fJ\":[\"Log one side only for single-arm/leg exercises\"],\"Hp6ceF\":[\"Unable to save your workout. Please try again later.\"],\"HpK_8d\":[\"Reload\"],\"Hplwk7\":[\"Restoring. Please wait...\"],\"I2Hpku\":[\"Track Weight\"],\"ICkQNB\":[\"Reminder time\"],\"IFowGw\":[\"rope\"],\"IHMx9j\":[\"Week streak\"],\"ILE1kp\":[\"arms\"],\"IRiG-a\":[\"Vibrate after rest\"],\"IUwGEM\":[\"Save Changes\"],\"IXxATP\":[\"Custom Exercises\"],\"IbbuFX\":[\"Deleting. Please wait...\"],\"IuXB4Q\":[\"Add a note...\"],\"Izf0kk\":[\"No prior weight data. Hold steady for now.\"],\"JE-yVp\":[\"Manage Metrics\"],\"JR5hAM\":[\"1yr\"],\"JTkSvz\":[\"Are you sure you want to remove this workout?\"],\"JVKmoO\":[\"The update couldn't be downloaded. Check your internet connection and reopen the app to try again.\"],\"JW7_2_\":[\"Download Failed\"],\"JWTR_A\":[\"An error occurred while downloading images.\"],\"JYRqp5\":[\"Sa\"],\"JbvV5d\":[\"During a session, swipe left/right or use the arrow buttons to move between sets. Enter your weight and reps, then tap Complete Set. The total elapsed time is shown in the header throughout. You can drag the handle on any exercise card to reorder exercises while the session is in progress. Time-based exercises have a Start Timer button that opens a count-up timer with a progress ring that shows you when you hit your goal time but you can keep going as long as you like. Notes can be added per-exercise via the notes icon in the exercise header, per workout from the workout overview screen, or per plan from the plan overview screen. If you add, remove, or reorder exercises or sets during a session, you will be prompted at the end to save those changes back to the original workout or plan.\"],\"JfDOWo\":[\"The update is ready but the app couldn't restart automatically. Try tapping the button below, or close and reopen the app manually.\"],\"JkpsKr\":[\"Downloading. Please wait...\"],\"JmZ_-d\":[\"Finish\"],\"JsIy35\":[\"You activated this plan.\"],\"JumwGu\":[\"cardio\"],\"Jv9TrU\":[\"obliques\"],\"KIL-9T\":[\"Next: \"],\"KKalG-\":[\"Pin exercises in the Stats tab to track their strength progression over time. Each tracked exercise shows a chart of your performance over the selected time range, your all-time personal record, your top sets, and a list of recent sessions showing the best set per day. Charts update automatically after each workout that includes that exercise.\"],\"KM1Iw2\":[\"MuscleQuest\"],\"KSqQx0\":[\"Max Reps\"],\"Km7tR4\":[\"Buy Me a Coffee\"],\"KmiPdE\":[\"dumbbell\"],\"KxWSWU\":[\"Keep screen on during workout\"],\"LAC2eo\":[\"Workout Reminders\"],\"LAHzG1\":[\"View/Edit\"],\"LIrnc0\":[\"No exercises added yet\"],\"LZKayn\":[\"Search help…\"],\"LcPJBt\":[\"completed workouts\"],\"LhMjLm\":[\"Time\"],\"LyPttd\":[\"Chest\"],\"M0GVkz\":[\"Select a day to see workouts.\"],\"M1POMr\":[\"Exercise Library\"],\"M4hMaA\":[\"Enter a name for the custom metric.\"],\"M57U8X\":[\"Group two exercises into a superset so they alternate automatically during a session, ideal for pairing antagonist muscles or staying efficient between sets. Tap the three-dot menu on any exercise in the workout editor and choose Create Superset, then select the second exercise. A coloured label identifies which superset each exercise belongs to throughout the app. When you complete a set on one exercise, the app moves you straight to its superset partner.\"],\"MEt7-_\":[\"soleus\"],\"MHk_Wu\":[\"Entry not found.\"],\"MLQOxI\":[\"rear deltoids\"],\"MM-MTF\":[\"Superset \",[\"0\"]],\"MQ9jL7\":[\"One more workout to hit your goal!\"],\"MQA2H9\":[\"Delete Plan\"],\"MTqmCb\":[\"Request or vote for new features\"],\"McFNQO\":[\"Monitor your fitness journey with detailed stats and insights. Keep track of workout history, analyse your body part splits, and visualise improvements over time with exercise progression graphs.\"],\"MmDz7_\":[\"Uploading. Please wait...\"],\"N4e_z1\":[\"Rest Time: \",[\"restMinutes\"],\":\",[\"0\"]],\"N85c_3\":[\"Remove Workout\"],\"NC2AI2\":[\"Length\"],\"NIuBdI\":[\"Premade plans\"],\"NKdWDE\":[\"cardiovascular system\"],\"NLBiJk\":[\"Log Entry\"],\"NPG8SK\":[\"Body weight\"],\"NQJHen\":[\"Are you sure you want to restart this workout?\"],\"NVOqiK\":[\"Log in to secure your data\"],\"NXoGPK\":[\"Edit Exercise\"],\"Ne5n-8\":[\"Add Personal Notes\"],\"NnRCUm\":[[\"0\"],\"s\"],\"Ns5WaC\":[\"No backups found\"],\"Nu4oKW\":[\"Description\"],\"O1GFNQ\":[\"All target muscles\"],\"O2TAe0\":[\"barbell\"],\"O2wCGL\":[\"Play countdown beeps (Exercise Timer)\"],\"Otd3xX\":[\"A deload is a planned recovery week where you train at reduced intensity to let your body fully recover before the next training block. Tap Mark as Deload Week on the plan overview screen to flag the current week as a deload. While the deload is active, the post-exercise feedback sheet does not appear and no new progression states are created or updated, so your suggestion history is not disrupted by the lighter sessions. The deload resets automatically at the start of the following week, and normal feedback and progression tracking resume without any manual action. If you change your mind, tapping the button again while the deload is active will clear it.\"],\"Ov8o8m\":[\"Start Plan\"],\"OwNTSr\":[\"Save to Plan\"],\"Owchfv\":[\"Recently Used\"],\"OzAZw8\":[\"This screen doesn't exist.\"],\"P0mjNu\":[\"Delete Entry\"],\"P0svFp\":[\"Rest\"],\"P1svYv\":[\"abs\"],\"P247ya\":[\"Body Part *\"],\"P3nVsi\":[\"\\n📅 New: Weekly Schedule for Your Plan!\\n\\nYou can now assign workouts to specific days of the week directly in the plan editor. Tap any day to pick a workout or mark it as a rest day. Use the auto-suggest button to instantly generate a balanced schedule based on your weekly goal.\\n\"],\"P3omNB\":[\"Select a workout to view\"],\"PBt59F\":[\"Favourite Exercises\"],\"PFcCy0\":[\"x \",[\"0\"],\" reps \"],\"PHWHEO\":[\"Accept all\"],\"PITZNx\":[\"chest\"],\"PN5Zzf\":[\"Weight unit\"],\"PNapeY\":[\"+ Add\"],\"POx12e\":[\"\\n↕️ New: Reorder Exercises in the Workout Overview!\\n\\nYou can now drag and drop exercises and supersets to reorder them directly from the workout overview screen during a session.\\n\"],\"PSNHRi\":[\"* features in development\"],\"P_0oX-\":[\"Assist\"],\"PiK6Ld\":[\"Sat\"],\"PruBpO\":[\"Are you sure you want to delete this measurement entry?\"],\"Q1Lq8I\":[\"Total Time\"],\"Q2QJ28\":[\"Play goal achieved sound (Exercise Timer)\"],\"Q8bEQa\":[\"An error occurred while deleting images.\"],\"Q9qAkA\":[\"Estimated Duration: \",[\"0\"]],\"QENBWX\":[\"triceps\"],\"Qdwk82\":[\"Dumbbell load increment\"],\"Qjp-BQ\":[\"Add a set\"],\"QlT4B5\":[\"Recent Sessions\"],\"Qmbwcr\":[\"Edit Plan\"],\"QoHy-T\":[[\"weeks\",\"plural\",{\"one\":[\"#\",\" week ago\"],\"other\":[\"#\",\" weeks ago\"]}]],\"QrwEaQ\":[\"pectorals\"],\"QzJCdZ\":[\"lats\"],\"R-ABt9\":[\"Weekly goal\"],\"R0gwbc\":[\"biceps\"],\"RCk1J0\":[\"sled machine\"],\"RGfnXX\":[\"(to Failure)\"],\"RIHmRj\":[\"Good pace. Try adding one rep per set before bumping the load.\"],\"RM5DG6\":[\"Tracked Exercises\"],\"RN4XJV\":[\"Rest Day\"],\"RU6ELr\":[\"Stats & History\"],\"RXkbtG\":[\"Push harder next time?\"],\"RY_JyV\":[\"lower back\"],\"R_h8B2\":[\"Most Used\"],\"Rc-8oy\":[\"Downloading Update\"],\"RmahBs\":[[\"0\"],\": \",[\"best\"],\"s (+\",[\"delta\"],\"s, \",[\"pctStr\"],\")\"],\"Rr5U7J\":[\"Completed sets will appear here\"],\"Rwc-xL\":[\"Time PR\"],\"RxzN1M\":[\"Enabled\"],\"S2uNE5\":[\"Continue Editing?\"],\"SEyweA\":[\"\\n🐛 Fixed: Various Bug Fixes & Improvements!\\n\\nFixed the rest timer notification not triggering correctly, exercise name wrapping in the workout session, the workout completion circle width, notes not updating correctly while typing, and workout details sometimes opening in the wrong tab. Workouts now load faster thanks to internal performance improvements.\\n\"],\"SGISp8\":[\"You finished everything at the limit. Stay here and own it.\"],\"SRhtpX\":[\"forearms\"],\"SUd4dA\":[\"\\n📏 New: Body Measurements!\\n\\nTrack your body composition alongside your training from the new Measurements section in the Stats tab.\\n\\n• Log weight, body fat %, waist, hips, chest, and more\\n• Tap any past entry to edit values or view a chart of that metric over time\\n• Manage which metrics appear and add your own custom metrics\\n• Units follow your weight and size preferences in Settings\\n\"],\"SWtay1\":[\"After completing the last working set of an exercise, a feedback sheet slides up with two questions. The first asks how the effort felt: Easy (you could have done more), About right, Hard (near your limit), or Couldn't finish all sets. The second asks about pain: No pain, Minor discomfort, or Pain or form issues. If you answer Easy, a third question appears asking whether you want to push harder next time. This lets you deliberately hold the current load even when a session felt light, so the engine respects your intent. If you answer Pain, an optional text field lets you note where you felt it for your own reference. The sheet can be dismissed without answering if you prefer not to log feedback for that exercise in that session.\"],\"SZw9tS\":[\"View Details\"],\"SadoC9\":[\"smith machine\"],\"SbGW67\":[\" (to Failure) \"],\"ScJ9fj\":[\"Privacy policy\"],\"SlfejT\":[\"Error\"],\"SmkA26\":[\"1RM \",[\"0\"],\" \",[\"unit\"]],\"SoWD_0\":[\"Save Set\"],\"SrVzRe\":[\"Percent\"],\"St3y2e\":[\"Name required\"],\"SvOMfA\":[[\"0\"],\" workouts\"],\"T0cOwV\":[\"Delete Set\"],\"T7QVyK\":[\"When you open a workout that contains exercises you trained recently, a Recovery Check-in sheet appears if those exercises have a pending progression suggestion and your last session was at least 12 hours ago. For each relevant muscle group, you choose one of three options: Fresh (fully recovered), Mild soreness, or Still very sore. If a muscle is marked as still very sore, any upward progression suggestion for exercises targeting that muscle is paused and held at the current load until you re-evaluate at the start of the following session. Fresh or Mild soreness does not affect suggestions. Tap Skip for now to bypass the check-in entirely; a skipped check-in is treated the same as fresh recovery, so pending suggestions are unaffected.\"],\"TBTwj-\":[\"Follow MuscleQuest on Instagram\"],\"TJLDrx\":[\"Doubling weight for volume calculations\"],\"T_qHwF\":[\"lower legs\"],\"Ta25TG\":[\"No history yet\"],\"TpqeIh\":[\"Error: \",[\"0\"]],\"Tz0i8g\":[\"Settings\"],\"TzLpDD\":[\"\\n🏋️ New: Single Workouts & Quick Workouts!\\n\\nCreate standalone workouts outside of your training plans — perfect for flexible training sessions, mobility work, or anything ad hoc. Find them on the Plans screen.\\n\\nOr start a Quick Workout from the home screen, add exercises on the fly, and optionally save it as a standalone workout when you're done.\\n\"],\"U0HZma\":[\"Tracking\"],\"U4QKsL\":[\"Hide / Show Onboarding\"],\"U8BTVm\":[\"Rest Time Left:\"],\"UCtAiM\":[\"To enable rest timer notifications, grant notification permissions in your device settings.\"],\"UD8kHo\":[\"Next: \",[\"workoutName\"],\" on \",[\"0\"]],\"URmyfc\":[\"Details\"],\"US8F_H\":[\"More reps suggested\"],\"USXXjt\":[\"No results for \\\"\",[\"query\"],\"\\\"\"],\"U_-GrY\":[\"Please wait while we download the latest version...\"],\"UlnAQR\":[\"Failed to delete workout. Please try again.\"],\"UneMBz\":[\"Active Plan\"],\"UnnFak\":[\"Great start to the week!\"],\"Uorrgj\":[\"rhomboids\"],\"Uu14s5\":[[\"0\",\"plural\",{\"one\":[\"#\",\" set\"],\"other\":[\"#\",\" sets\"]}]],\"UyvU3-\":[\"Help & Info\"],\"UzNvmf\":[\"• Backup and restore data\"],\"V6wjuJ\":[\"Tracking type is required.\"],\"V6xf0O\":[\"This exercise is already in your workout. Please choose a different one.\"],\"V8MVAm\":[\"upper chest\"],\"V8dVu4\":[\"\\n🔗 New: Supersets!\\n\\nPair two exercises together as a superset directly in the plan editor. Sets are kept in sync between both exercises, and supersets are clearly grouped with a visual indicator throughout the app.\\n\"],\"V8yTm6\":[\"Clear search\"],\"VAcXNz\":[\"Wednesday\"],\"VCJb5r\":[\"Set \",[\"0\"],\" of \",[\"totalSets\"]],\"VDkJml\":[\"Adaptive Progression analyses your effort feedback over consecutive sessions and suggests when to increase your weight, reps, or sets. Enable it in Settings under Adaptive Progression. Once on, a short feedback prompt appears after each exercise in plan-based workouts. The engine requires two sessions with the same signal before recommending an upward change, filtering out one-off easy days and ensuring consistent performance before suggesting an increase. Pain or failed sets act immediately regardless of your session history. A suggestion is never applied to your workout without your explicit approval. You can also configure your preferred load increment per equipment category in the same section of Settings, for example 2.5 kg for barbell exercises and 2.0 kg for dumbbells.\"],\"VFlRXJ\":[\"Hold steady this session.\"],\"VhVOxx\":[\"Your journey to Swoletown begins today!\"],\"VhfZbD\":[\"Size: ~100MB\"],\"W-pY1H\":[\"Failed to save custom exercise. Please try again.\"],\"W0qDyY\":[\"Home Screen & Weekly Goal\"],\"W3QcBP\":[\"Plan Overview\"],\"W3u9nh\":[\"To failure, \"],\"WDciil\":[\"\\n📋 New: \\\"More\\\" Menu and Help & Info Section!\\n\\nThere's a new \\\"More\\\" tab in the navigation bar. Tap it to open a slide-in panel where you'll find Settings and a brand new Help & Info section.\\n\\nSettings has moved here from the tab bar, and Help & Info covers everything from plans and workouts to stats and your account, with a search bar to find answers quickly.\\n\"],\"WHwUfF\":[\"Error loading exercise details\"],\"WIbOhZ\":[\"Adaptive Progression\"],\"WJp2MH\":[\"Size unit\"],\"WKHqM-\":[\"Weight\"],\"WOi4Vm\":[\"Name *\"],\"WSzg3A\":[\"Distance (\",[\"distanceUnit\"],\")\"],\"WU-3OC\":[\"Single-arm / single-leg\"],\"WaIjmh\":[\"Calf (R)\"],\"WoEX6M\":[\"Suggest load and rep adjustments\"],\"WzcO-J\":[\"Create Plan\"],\"X9kySA\":[\"Favorites\"],\"X9r6cu\":[[\"goal\",\"plural\",{\"one\":[[\"completed\"],\" of \",\"#\",\" workout this week\"],\"other\":[[\"completed\"],\" of \",\"#\",\" workouts this week\"]}]],\"XHHEUg\":[\"Customise Plan\"],\"XJQdl_\":[\"Send notification in background after rest\"],\"XNRDYn\":[\"wrist extensors\"],\"XdavYY\":[\"Workouts\"],\"Xdcdfd\":[\"Sets & Exercises\"],\"XoEooZ\":[\"Time (s)\"],\"Xu14OQ\":[[\"0\",\"plural\",{\"one\":[\"#\",\" Rep\"],\"other\":[\"#\",\" Reps\"]}]],\"Xu2iGM\":[\"Add Weight\"],\"Xv4OIW\":[\"Workout in progress\"],\"Xwd4Hm\":[\"rotator cuff\"],\"Y6QE0T\":[\"Select equipment\"],\"YANNVr\":[\"Workout\"],\"YDnEIW\":[\"Best gain\"],\"YIix5Y\":[\"Search...\"],\"YLIqcF\":[\"Welcome back\",[\"userName\"]],\"YXJbW8\":[\"Standalone workouts live outside of plans and appear alongside your plans on the Plans screen. Create one by tapping New Workout, give it a name, and add exercises; you can run it at any time without needing an active plan. An estimated duration is shown on each standalone workout so you can plan your time before starting. Quick Workouts let you start a session immediately from the home screen: tap Quick Workout, add exercises as you go, and at the end you can save it as a standalone workout for future use or simply discard it. Like plans, the workout editor automatically saves a draft so you can safely leave and return without losing your work.\"],\"YYzBv9\":[\"Mo\"],\"YekWWq\":[[\"0\",\"plural\",{\"one\":[\"#\",\" rep\"],\"other\":[\"#\",\" reps\"]}]],\"YiPU_R\":[\"delts\"],\"YnHdfF\":[\"Set \",[\"0\"]],\"Yr-t8O\":[\"feet\"],\"YuP-pS\":[\"\\\"\",[\"label\"],\"\\\" will be hidden from the entry form. Your historical data is preserved.\"],\"Z3FXyt\":[\"Loading...\"],\"Z8RW4m\":[\"After finishing a workout, the Workout Summary screen shows a Next Session card listing actionable suggestions for your exercises. Each row shows the exercise name, the proposed change (a new target weight, a wider rep range, or a note to reduce load), and a short explanation of why the change is being suggested. Tap Accept to apply the suggestion to that exercise for your next session, or Dismiss to ignore it. Accepted suggestions are pre-filled into the weight and rep fields the next time you open that workout, so you start the session already targeting the right load. The Accept All button at the top applies every suggestion at once. Suggestions that recommend holding the current load do not appear in the card, as no action is needed for those.\"],\"ZAWGCX\":[[\"0\"],\" seconds\"],\"ZAvcCf\":[[\"0\"],[\"weightUnit\"],\" × \",[\"1\"]],\"ZI8idP\":[\"Fresh, fully recovered\"],\"Zm9Eu3\":[\"Button size during workout\"],\"Zvc_N1\":[\"1RM (\",[\"weightUnitLabel\"],\")\"],\"_-nVtu\":[\"Felt easy this time. Hold for now and confirm next session.\"],\"_2fO4v\":[\"Workout Summary\"],\"_D5y8a\":[\"Default sets\"],\"_K9jUO\":[\"upper body ergometer\"],\"_P2B4j\":[[\"biggestGainLabel\"],\" 1RM\"],\"_RhvUo\":[\"settings\"],\"_UGS0C\":[\"Workout name\"],\"_W-KPJ\":[\"No measurements yet. Tap to log your first entry.\"],\"_WRCmH\":[[\"0\"],\" \",[\"1\"],\" | \",[\"2\"],\" Reps\"],\"_XczSN\":[\"Select target muscle\"],\"_Xvx5t\":[\"\\n📈 New: Adaptive Progression!\\n\\nMuscleQuest can now suggest when to increase your weight or reps based on how your sessions feel. After each exercise, answer two quick questions about effort and pain. Once you have reported the same signal for two sessions in a row, the app suggests a change. All suggestions appear in the Workout Summary screen, where you can accept or dismiss each one individually. Accepted suggestions are pre-filled into your next session automatically.\\n\\nA Recovery Check-in at the start of your next workout lets you factor in soreness before any suggestion is applied. You can also mark a full week as a Deload from the plan overview, which pauses feedback and progression tracking for that week.\\n\\nEnable it in Settings under Adaptive Progression, and configure your preferred load increment per equipment category.\\n\"],\"_cF7Rs\":[\"Volume\"],\"_f5DAr\":[\"Completed on: \",[\"formattedDate\"]],\"a2Fu8q\":[\"You can login at any time from the settings screen, if you choose to skip it now.\"],\"a5BPTT\":[\"kettlebell\"],\"a8TA11\":[\"Next Session\"],\"aAIQg2\":[\"Appearance\"],\"aMwZcE\":[\"Upper Arm (L)\"],\"aN_GPe\":[\"Where did you feel it?\"],\"ahW3x6\":[\"\\n📅 New: Workout Calendar!\\n\\nTap the calendar icon in the Workout History section on the Stats tab to browse your training history by date. Days with workouts are highlighted, and tapping any day shows the sessions logged on that date.\\n\"],\"aj6ZJx\":[\"Google sign in\"],\"b3e7Re\":[\"Restart App\"],\"b9OAHS\":[\"Add Warm-up\"],\"bFeIdj\":[\"Drop Set\"],\"bQdjFX\":[[\"0\"],\" Note\"],\"bRAv_4\":[\"Workout \",[\"0\"]],\"bZS72M\":[[\"setsCount\",\"plural\",{\"one\":[\"#\",\" set\"],\"other\":[\"#\",\" sets\"]}]],\"bosqpS\":[\"No workouts completed yet. Start your first workout!\"],\"bqb_ci\":[\"\\n🐛 Fixed: Workout Session Buttons & Edit Set Modal!\\n\\nFixed a bug where all buttons (increment/decrement, next/previous set, complete set) would stop working after completing a set. Also fixed an error in the edit set modal. Set transitions now happen instantly for a smoother workout flow.\\n\"],\"bwd2oE\":[\"Rest Timer Finished!\"],\"bzSI52\":[\"Discard\"],\"c2TGz5\":[[\"completed\"],\" workouts this week. You've smashed your goal!\"],\"cCbON-\":[\"\\n🔥 Improved: Warm-Up Set Management!\\n\\nWarm-up sets are visually grouped and styled separately from working sets, and \\\"Apply to all\\\" lets you bulk-edit warm-up or working sets independently.\\n\"],\"cF5b-5\":[[\"weeklyGoal\",\"plural\",{\"one\":[\"Auto-suggest (\",\"#\",\" day)\"],\"other\":[\"Auto-suggest (\",\"#\",\" days)\"]}]],\"cI6f7l\":[\"30d\"],\"cU45Co\":[\"Add Workout\"],\"cUD6H0\":[\"Get Ready...\"],\"cUY9dI\":[\"Are you sure you want to delete this exercise?\"],\"ckJ-os\":[\"Muscles\"],\"cnGeoo\":[\"Delete\"],\"crwali\":[\"Reminders\"],\"ctrAML\":[\"Make sure to track your progress!\"],\"cyR8-W\":[\"\\n🕐 New: Workout Duration Estimate!\\n\\nEach workout card now shows an estimated duration so you can plan your sessions at a glance before you start.\\n\"],\"d1z1ZY\":[\"The rest timer starts automatically after each set and counts down to zero. Each set remembers its own rest duration, so different sets within the same exercise can have different rest periods. Use the ± buttons to adjust the remaining time on the fly during rest. Configure the default rest duration, the timer increment, and whether a sound, vibration, or background notification fires at the end; each option is independently toggleable in Settings.\"],\"dEgA5A\":[\"Cancel\"],\"dH9Y4t\":[\"No workouts on this day.\"],\"dVK-Er\":[\"A render error has occurred. Press the button to reload.\"],\"dXCD6-\":[\"Download all exercise animations\"],\"dXoieq\":[\"Summary\"],\"dYOPCE\":[\"Assist \",[\"0\"],\" \",[\"1\"],\" | Resist \",[\"2\"],\" \",[\"3\"],\" | \",[\"4\"],\" Reps\"],\"dbWo0h\":[\"Sign in with Google\"],\"deoJBi\":[[\"0\"],\" reps\"],\"dfunKV\":[\"Weight/Reps\"],\"dpOqdQ\":[\"To failure\"],\"dqjuBA\":[\"90d\"],\"dx0cCC\":[\"Keep the momentum going!\"],\"e0dGJ7\":[\"Benefits of logging in:\"],\"e0l-Z0\":[[\"scheduledDays\",\"plural\",{\"one\":[\"#\",\" day/week\"],\"other\":[\"#\",\" days/week\"]}]],\"e5h2IT\":[[\"0\"],\" Notes\"],\"e9qdcV\":[\"Minor discomfort\"],\"eLA0I2\":[\"Download Images\"],\"eQm4BH\":[\"After finishing a workout, a summary screen shows your total duration, sets completed, and total volume. If you have done the same workout before, a comparison row shows how each metric compares to the previous session. A weekly goal banner shows how many sessions you have logged this week against your goal. Tap any exercise in the list to expand it and review every set in detail. When completing a Quick Workout, you will be prompted to save it as a standalone workout for future use or discard it.\"],\"eYbd7b\":[\"Su\"],\"ecUA8p\":[\"Today\"],\"ehOkF-\":[\"Basics\"],\"emOtYn\":[\"Premade Plans\"],\"ez-cQL\":[\"\\n🔔 New: Workout Reminder Notifications!\\n\\nNever miss a session. Set reminder notifications for your workouts directly from the app. Choose which days you want to be reminded, and pick a time to get started.\\n\"],\"f2yjAZ\":[\"No pain\"],\"f7pPKh\":[\"Thigh (L)\"],\"f8Vl8d\":[\"Metric name\"],\"fFHHFp\":[\"Measurements\"],\"fPpo2L\":[\"Superset\"],\"fSu2Jl\":[\"A new version has been downloaded. Tap the button below to restart and apply the update.\"],\"fXVIZq\":[\"Values\"],\"f_bxrN\":[\"Name is required.\"],\"feWdkU\":[\"Restart Workout\"],\"fj5byd\":[\"N/A\"],\"fpMgHS\":[\"Mon\"],\"fqSfXY\":[\"Replace\"],\"fsJAR5\":[\"Barbell load increment\"],\"ftiGCv\":[\"All equipment\"],\"fvyzOr\":[\"upper back\"],\"g36TSx\":[\"Distance unit\"],\"g3UF2V\":[\"Accept\"],\"gCVtjC\":[[\"0\"],\" Sets\"],\"gEOgEq\":[[\"0\"],\" Exercises\",[\"1\"]],\"gQYPDg\":[\"−\",[\"restTimerIncrement\"],\"s\"],\"gTdjGc\":[\"Failed to delete the workout. Please try again.\"],\"giOl9F\":[\"Thigh (R)\"],\"gkn1WJ\":[\"Exercise Already Added\"],\"gzBfh2\":[\"No Sets Available\"],\"h-DKuf\":[\"vs. last \\\"\",[\"0\"],\"\\\"\"],\"h2ALJf\":[\"glutes\"],\"h7CU4q\":[\"How did that feel?\"],\"hBjQ0O\":[[\"0\",\"plural\",{\"one\":[\"#\",\" workout\"],\"other\":[\"#\",\" workouts\"]}]],\"hF_t4W\":[\"Volume (\",[\"volumeUnit\"],\")\"],\"hLONcx\":[\"Backup and restore\"],\"hPXEuO\":[\"Paired with \",[\"0\"]],\"hXzOVo\":[\"Next\"],\"hnJ2UC\":[\"brachialis\"],\"hnlGzG\":[\"Skip for now\"],\"hnrFBk\":[\"Reminder days\"],\"hpsdvR\":[\"\\n📋 New: View Workout Details from the Home Screen!\\n\\nYou can now tap any recent workout on the home screen to view its full details. Each workout and set overview also has a new details button for quick access to exercise information.\\n\"],\"hsoeHo\":[\"Workout Details\"],\"hty0d5\":[\"Monday\"],\"hvfche\":[[\"scheduledCount\",\"plural\",{\"one\":[\"#\",\" day/week\"],\"other\":[\"#\",\" days/week\"]}]],\"i-tNaY\":[\"Assistance/Reps\"],\"i09UfG\":[\"Equipment:\"],\"i0qMbr\":[\"Home\"],\"i4Vk1Q\":[\"Active Plan Exercises\"],\"i6f8rt\":[\"Starting Workout...\"],\"iGokZG\":[\"Cable load increment\"],\"iHmyze\":[\"Exercises\"],\"iQyKX1\":[\"You chose to keep it steady. Hold this load.\"],\"iV1Jat\":[\"Are you sure you want to delete this set?\"],\"iYfCFU\":[\"Show onboarding on home screen\"],\"i_48Se\":[\"Active Plan: \",[\"0\"]],\"i_nB8P\":[\"No schedule set\"],\"ifRQL2\":[\"Drop set, \"],\"ikOJPT\":[\"shins\"],\"irLwtB\":[\"Training Plan\"],\"irrqfe\":[\"Custom Metrics\"],\"iuwbqi\":[\"Failed to save workout. Please try again.\"],\"ivpCYv\":[\"Discard Changes?\"],\"j-MPXl\":[\"Backup & Restore\"],\"jDTG0T\":[\"Progression Suggestions\"],\"jDh_CH\":[\"Plans are structured training programmes made up of workouts. To create one, go to the Plans tab, tap New Plan, give it a name, and pick a cover image. Add workouts to the plan, then add exercises to each workout with target sets and reps. Use the up/down arrow buttons on a workout card to reorder it, or the X button to remove it; both are in the top right of the card. Assign workouts to specific days of the week in the schedule editor: tap any day to pick a workout or leave it as a rest day, and use the auto-suggest button to space them out evenly. Once your plan is ready, open it and tap Activate. You can also add notes to a plan from the plan overview screen. Each workout card shows an estimated duration alongside the exercise count so you can gauge the session length at a glance. Use the view icons next to the \\\"Your Training Plans\\\" heading to switch between Carousel, List, and Grid layouts; your chosen view is saved automatically. Your progress in the plan editor is automatically saved as a draft, so if you leave mid-edit you will be prompted to continue where you left off or discard and start from the last saved state.\"],\"jYjrmQ\":[\"Last backup: \",[\"0\"]],\"jfzZZ0\":[\"Skip login\"],\"jpVuia\":[\"Save Changes to Workout?\"],\"jxTU3u\":[\"stepmill machine\"],\"jzJENZ\":[\"Track Your Progress\"],\"k4kpgL\":[\"Welcome to MuscleQuest, your personal strength training companion. Use this guide to discover the features and get the most from your training.\"],\"k7Oi68\":[\"upper legs\"],\"kDJ_Ja\":[\"Solid session. Keep this load.\"],\"kFoQmI\":[\"abductors\"],\"kILzHz\":[\"Add (\",[\"0\"],\")\"],\"kQe_xM\":[\"Pain reported. Keeping load unchanged until you feel better.\"],\"kSi1ha\":[\"+\",[\"suggestedWeight\"],[\"unit\"],\" suggested\"],\"kdwbaT\":[\"Skip all\"],\"kf4tdd\":[\"Select tracking type\"],\"kfxr8q\":[\"\\n📊 New: Workout Summary!\\n\\nAfter completing a workout, you'll now see a full summary of your session: total duration, sets, and volume, plus a comparison against your previous session. Tap any exercise to expand its individual sets and weights.\\n\"],\"kg0oKA\":[\" (to Failure)\"],\"kkDQ8m\":[\"Thursday\"],\"konUZ1\":[\"Default rest time\"],\"kvpjYu\":[\"Enter exercise name\"],\"l1P93s\":[\"Enter weight per dumbbell/cable, not total\"],\"l75CjT\":[\"Yes\"],\"lWy5a1\":[\"Plans\"],\"lY9GM0\":[\"Target muscle is required.\"],\"lkz6PL\":[\"Duration\"],\"llGZy3\":[\"No exercises tracked yet. Tap + Add to start.\"],\"loRbvf\":[\"Go to home screen!\"],\"m0YANP\":[\"You can hide this onboarding screen at any time from the settings page in the appearance section. If you ever want to revisit the onboarding, you can enable it again from the same settings page.\"],\"m16xKo\":[\"Add\"],\"mAoTHw\":[\"Some images failed to delete. Failed exercise IDs: \",[\"0\"]],\"mDmPnX\":[\"Per week (avg)\"],\"mEQ95z\":[\"Failed to save the image. Please try again.\"],\"mF1US0\":[\"Always use most recent exercise history\"],\"mFQ4KK\":[\"Double the weight for volume when the setting is enabled\"],\"mK5j7_\":[\"\\n🔃 New: Sort the Exercise Library!\\n\\nThe exercise library now has sort chips so you can find exercises faster. Sort by Default, Active Plan, Recent, or Frequent to see the exercises most relevant to you at the top.\\n\"],\"mRTnNi\":[\"Paired implements\"],\"mSit7t\":[\"Failed to fetch data. Please try again.\"],\"mSj_dN\":[[\"0\",\"plural\",{\"one\":[\"+\",\"#\",\" more\"],\"other\":[\"+\",\"#\",\" more\"]}]],\"mT57-Q\":[\"Go to Settings\"],\"mob_am\":[\"Fr\"],\"mwX_w0\":[\"Change Image\"],\"mzI_c-\":[\"Download\"],\"n00ykB\":[\"Your workouts\"],\"n1BXGc\":[\"Training Split (by sets)\"],\"nAEGxm\":[\"Yes, increase the challenge\"],\"nJSX83\":[\"Workout reminders\"],\"nO6sra\":[[\"0\"],\": \",[\"best\"],\" \",[\"best\",\"plural\",{\"one\":[\"rep\"],\"other\":[\"reps\"]}],\" (+\",[\"delta\"],\", \",[\"pctStr\"],\")\"],\"nPGn3W\":[\"Warm-up, \"],\"nkkWxK\":[\"Jumpstart your fitness journey with professionally designed training plans. Choose from a variety of options tailored to different goals and experience levels. \"],\"nmdLhD\":[\"Reps: \",[\"repRange\"]],\"o2XlZw\":[\"Are you sure you want to delete this workout? This action cannot be undone.\"],\"oB9lvM\":[\"Exclude warmup sets from stats\"],\"oOHOWH\":[\"\\n✨ New: Workout Session Animations!\\n\\nNavigating between sets now features smooth slide transitions. Swipe left or right to move between sets, or use the pre-existing arrow buttons for the same effect.\\n\"],\"oOYj_W\":[\"Failed to load workouts\"],\"oRTTfk\":[\"The Stats tab shows total workouts, total volume, total time, and average session duration over a selectable time range, with a period-over-period delta for each metric. Charts display weekly volume and your training split by body part. Browse your full workout history and tap any session to review every set in detail, including weights, reps, time, or distance. You can edit or delete completed workouts from the history details screen. Tap the calendar icon in the Workout History section to open a calendar view: days with workouts are highlighted with a yellow circle, and tapping any day shows the workouts logged on that date.\"],\"oRvy2V\":[\"Exercise Tracking\"],\"oXsjxN\":[\"Calf (L)\"],\"oYZpj8\":[\"• Challenges and badges *\"],\"ocEDZS\":[\"Remove a set\"],\"oeF-HP\":[\"Failed to sign in. Please try again.\"],\"oeeBm6\":[\"\\n🔔 New: In-App Update Notifications!\\n\\nA new update modal now appears when an over-the-air update is available, so you always know when improvements have been downloaded and are ready to apply.\\n\"],\"ofVE0I\":[\"Clears the search field\"],\"oiHVLP\":[\"Remove Superset\"],\"oqKRAn\":[\"Each set can be flagged as a Warm-up, Drop Set, To Failure, or any combination of these. The badge shown next to a set displays its current type. To change the type during a session, tap the menu (⋮) and toggle the relevant option on or off. When building a plan, use the checkboxes in the set editor; tap Add Warm-up to insert a dedicated warm-up set at the top of the list. Warm-up sets are visually grouped and separated from working sets, and the Apply to All option in the edit modal only affects sets of the same type. Warm-up sets can be excluded from volume and stats calculations in Settings.\"],\"oqUOKk\":[\"Drop set\"],\"osILGh\":[\"Target Distance (\",[\"distanceUnit\"],\")\"],\"ovBPCi\":[\"Default\"],\"ovGl86\":[\"(to Failure) \"],\"p5nYkr\":[\"View All\"],\"p72uBF\":[\"No training plans found\"],\"p8F9k_\":[\"Neck\"],\"pBGx0B\":[\"\\n🗂️ New: Plan View Options!\\n\\nThe Plans screen now has three display modes. Use the icons next to the \\\"Your Training Plans\\\" heading to switch between Carousel, List, and Grid view. Your preferred layout is saved automatically.\\n\"],\"pE7tOx\":[\"Active Workout\"],\"pIX6X7\":[\"MuscleQuest's Instagram\"],\"pIuJtP\":[\"Workout not found.\"],\"pY_gY7\":[\"Rep PR\"],\"p_C-3G\":[\"Mild soreness\"],\"pbzA-s\":[\"Optional description\"],\"pfXEaj\":[\"Body Weight\"],\"pkD36F\":[\"Are you sure you want to delete \\\"\",[\"0\"],\"\\\"?\"],\"poLmqL\":[\"Choose from Device\"],\"psxXnW\":[\"Sign in with Google in Settings to enable cloud backups of all your workout data. Tap Backup at any time to save a snapshot; the date of your last backup is shown beneath the button. Tap Restore to download and apply your latest backup; confirm the prompt and the app will reload with your restored data. Your backups are stored securely and are tied to your Google account. If you switch devices or reinstall the app, simply sign in with the same Google account and tap Restore to get your data back.\"],\"pvW0MQ\":[\"Complete Set\"],\"pwfNCc\":[\"+\",[\"restTimerIncrement\"],\"s\"],\"pz0gzh\":[\"Hide metric\"],\"pzA-xG\":[\"Capture important cues, reminders, and personal insights for your exercises, workouts, and training plans. Stay focused and refine your technique with custom notes throughout your fitness journey. Notes save automatically when you're done editing.\"],\"q3pTrs\":[\"All images deleted successfully!\"],\"qIATCE\":[\"\\n📋 Improved: Smarter History Pre-Fill During Workouts!\\n\\nSet fields now pre-fill more intelligently. If an exercise has no history in the current workout, it falls back to the most recent time you performed it in any session, so you always start with a useful reference.\\n\\nA new setting in the Workout section lets you always use the most recent history across all workouts, regardless of which routine it came from.\\n\"],\"qJb6G2\":[\"Try Again\"],\"qQ5ALI\":[\"Save Changes to Plan?\"],\"qQ8Xkc\":[\"Machine load increment\"],\"qQLn75\":[\"Select body part\"],\"qUSLnH\":[\"Enter description\"],\"qZMNNX\":[\"Upper Arm (R)\"],\"qaT7mT\":[\"You'll lose what you've entered so far.\"],\"qdalvN\":[\"Deload week — comparison paused.\"],\"qeygIa\":[\"We\"],\"qlKdB2\":[\"No, keep it the same\"],\"qtNMEu\":[\"quads\"],\"qvcKXF\":[\"Great work today!\"],\"qvolLq\":[\"Mass\"],\"rCROTr\":[\"Buy me a coffee\"],\"rLgPvm\":[\"Backup\"],\"rPj8yN\":[\"Other Exercises\"],\"rZzMre\":[\"upper arms\"],\"rickIy\":[\"Saving Workout...\"],\"rlNJuG\":[\"Entry Detail\"],\"rtypiF\":[\"🎉 What's New\"],\"rzjsxH\":[\"Time (Minutes:Seconds)\"],\"s53UX_\":[\"Volume per Week (\",[\"volumeUnit\"],\")\"],\"s6qW4K\":[\"Tracking type cannot be changed after creation.\"],\"sAkBSh\":[[\"0\",\"plural\",{\"one\":[\"#\",\" exercise\"],\"other\":[\"#\",\" exercises\"]}]],\"sHe-bW\":[\"Give it a name to save it as a reusable workout.\"],\"sRh2_9\":[\"Your training plans\"],\"sey42b\":[\"Workout Complete!\"],\"slcKOz\":[\"To enable workout reminders, grant notification permissions in your device settings.\"],\"spvawa\":[\"Exclude deload workouts from exercise stats\"],\"t-VWgS\":[\"Workouts per Week\"],\"t1WtPm\":[\"vs PR\"],\"t7OD9_\":[\"traps\"],\"t9rBTs\":[[\"0\"],\": \",[\"best\"],[\"unit\"],\" (+\",[\"delta\"],[\"unit\"],\", \",[\"pctStr\"],\")\"],\"tCHU1b\":[\"Body Parts\"],\"tLdxsV\":[\"MuscleQuest.app\"],\"tXkhj_\":[\"Start\"],\"t_YqKh\":[\"Remove\"],\"tcZ16z\":[\"\\n💾 New: Save Workout Changes Back to Your Plan!\\n\\nWhen you finish a session where you added, removed, or reordered exercises, or sets, you'll be prompted to save those changes back to the original plan or standalone workout, keeping your training up to date automatically.\\n\"],\"tfDRzk\":[\"Save\"],\"tj-hng\":[\"wrists\"],\"tlcz2i\":[\"No data for this period.\"],\"twA2hZ\":[\"legs\"],\"tyb5gZ\":[\"Rest Time (Minutes:Seconds)\"],\"u0F1Ey\":[\"Th\"],\"u0Vng2\":[\"Still very sore\"],\"u16ECS\":[\"Download Complete\"],\"uGkCJQ\":[\"ez barbell\"],\"uIVkKI\":[\"Signing In\"],\"uP80lb\":[\"Update Ready\"],\"ue_JxE\":[\"Sets Overview\"],\"ufHAsd\":[\"Training Plan Name\"],\"uyJsf6\":[\"About\"],\"v2e7py\":[\"Create a Plan\"],\"v39wLo\":[\"Resume\"],\"v67n_r\":[\"Enable recurring workout reminders from Settings. Select the days of the week you want to be reminded using the day chips and choose a time. You will receive a notification at that time on each selected day. Notification permission must be granted for reminders to work.\"],\"vCrBBg\":[\"Take full control of your training by designing your own personalised plan. Select exercises, set rep ranges, rest times, and more to create a plan that aligns perfectly with your fitness goals.\"],\"vFte8a\":[\"Create Superset\"],\"vLSd93\":[\"Set Types\"],\"vLyv1R\":[\"Hide\"],\"vPWLpz\":[\"Units of measurement\"],\"vV1rrV\":[[\"suggestedRepsMin\"],\" reps suggested\"],\"vbOlQu\":[\"Failed to pick image. Please try again.\"],\"vbfDgJ\":[\"No workouts yet\"],\"vcpc5o\":[\"Close menu\"],\"vmatEA\":[\"Loading data, please wait...\"],\"vq2WxD\":[\"Tue\"],\"vqV9pV\":[\"New Plan\"],\"vyQFtJ\":[[\"0\"],\" Complete!\"],\"w55mIe\":[\"active plan\"],\"w95UZr\":[\"best \",[\"maxDist\"],[\"distanceUnit\"]],\"wBAK8Q\":[\"Body part is required.\"],\"wL3cK8\":[\"Latest\"],\"wL7wrB\":[\"Weight increment\"],\"wUwyC0\":[\"Streak\"],\"wYwS57\":[\"Customise Your Settings\"],\"wckWOP\":[\"Manage\"],\"wgbq86\":[\"Restart Failed\"],\"wpLp4M\":[\"Assistance\"],\"wvxWx2\":[\"trapezius\"],\"wxKcF0\":[\"About the developer\"],\"x5LlnE\":[\"Stats Options\"],\"xGVfLh\":[\"Continue\"],\"xM_hqb\":[\"assistance \"],\"xMidTh\":[\"All body parts\"],\"xRGBk4\":[\"Explore Ready-Made Plans\"],\"xVhQZV\":[\"Fri\"],\"xYxQCZ\":[[\"0\"],\" \",[\"1\"]],\"xx7Wjz\":[\"Failed to load exercise details.\"],\"y04OSh\":[\"Workout History\"],\"y3CwcG\":[\"best \",[\"maxTime\"],\"s\"],\"y8le-Z\":[\"Training\"],\"yAeHP4\":[\"No data available.\"],\"yBSiRY\":[\"Deload Week\"],\"yKu_3Y\":[\"Restore\"],\"yUWaVv\":[\"elliptical machine\"],\"yWCES-\":[\"Secondary muscles:\"],\"y_0uwd\":[\"Yesterday\"],\"y_f0Ik\":[\"Opens in your browser\"],\"yf16RU\":[\"Warm-up\"],\"ygCKqB\":[\"Stop\"],\"yhrNcC\":[\"Image Save Error\"],\"ykve2U\":[\"Add Set\"],\"yu1K_Z\":[\"No Sets\"],\"z1-0FW\":[\"Track your workouts, monitor progress, and achieve your fitness goals. MuscleQuest makes your fitness journey simple and effective.\\n\\nSwipe through the introduction cards to learn more about the app.\"],\"z44QLk\":[\"Restore Backup\"],\"z5uobd\":[\"Tap the star icon in the top-right corner of any exercise info screen to mark it as a favourite. Favourited exercises appear at the top of the exercise picker when building or editing workouts, so the exercises you use most are always within quick reach.\"],\"zAhZMD\":[\"• Share your training plans with others *\"],\"zAt78k\":[\"Rest Timer\"],\"zDq2cZ\":[\"Waist\"],\"zEHmq8\":[\"The Plans tab includes a library of ready-made training programmes you can start immediately. Scroll past Your Training Plans to find the Premade Plans section. Tap any programme to preview its workouts and schedule, then tap Activate to make it your active plan. You can edit a premade plan to adjust exercises, sets, or the weekly schedule. This will create a copy of the premade plan that you can modify without affecting the original, so you can always return to the default version if needed.\"],\"zIFP3N\":[\"Set your weekly workout goal and enter your body weight to get accurate stats and recommendations. You can also adjust your weight increment preferences, choose your preferred units, and much more.\"],\"zNnnyF\":[\"calves\"],\"zOwYV3\":[\"You modified this workout. Save those changes for future sessions?\"],\"zga9sT\":[\"OK\"],\"zhIkkH\":[\"Goal: \",[\"goalLabel\"],[\"0\"]],\"zsaR7t\":[\"Equipment & Tracking\"],\"zt6jiv\":[\"No progression tracking for this exercise type.\"],\"zuwyEJ\":[\"Add exercises to get started\"],\"zzDlyQ\":[\"Success\"]}")}; \ No newline at end of file +/*eslint-disable*/module.exports={messages:JSON.parse("{\"-2Ut5a\":[\"The Insights strip at the top of the Stats tab gives four at-a-glance highlights for the selected time range: your average workouts per week, your biggest strength gain across tracked exercises, the body part you have trained most, and your current weekly streak. These update automatically after each workout.\"],\"-5kO8P\":[\"Saturday\"],\"-BjMj_\":[\"Create Workout\"],\"-FjWgX\":[\"Thu\"],\"-Tpjjs\":[[\"0\"],\" sets\"],\"-WSEJS\":[\"Delete Workout\"],\"-Xejuf\":[\"Hips\"],\"-XvJee\":[\"best \",[\"0\"],[\"weightUnit\"],\" × \",[\"1\"]],\"-rhD7g\":[\"No pending friend requests.\"],\"-svcUj\":[\"Save this workout?\"],\"03mQOq\":[\"Failed to activate this plan: \",[\"0\"]],\"06EUQy\":[\"All-time PR\"],\"0EHHPz\":[\"adductors\"],\"0EPpEZ\":[\"Add custom metric\"],\"0EcUWz\":[\"Discard changes?\"],\"0OeId4\":[\"Create a Custom Plan\"],\"0P1btN\":[\"\\n🔔 New: Exercise Timer Sounds!\\n\\nThe exercise timer now plays audio cues to keep you on track. A countdown beep as the timer nears zero and a sound when you hit your goal. Toggle each sound independently in Settings.\\n\"],\"0SaB4K\":[\"Warm-up set\"],\"0U938S\":[\"Select at least one day\"],\"0V9gKq\":[\"\\n🔵 New: Exercise Timer Modal!\\n\\nTime-based exercises now show a dedicated countdown modal with a progress ring, making it easy to track your effort and stay on pace during timed sets.\\n\"],\"0caMy7\":[\"History\"],\"0dHvKo\":[\"Target muscle:\"],\"0eRpDV\":[\"Hard, near limit\"],\"0f7U0k\":[\"Wed\"],\"0tJJBW\":[\"Prev: \"],\"0vGEy2\":[\"\\n📊 New: Improved Stats Screen!\\n\\nThe stats screen has been redesigned with a fresh new look and improved insights. Explore your training history with better charts, clearer summaries, and more detailed breakdowns of your progress over time.\\n\"],\"14ytif\":[\"Start Workout\"],\"1DF4Ah\":[\"Delete all shared data\"],\"1DPB1m\":[\"\\n🗂️ New: Five New Premade Training Plans!\\n\\nFive new ready-to-use plans are now available: 5-Day Bro Split, 5-Day Push/Pull/Legs, 6-Day Split, Bodyweight, and Dumbbell Only. Whether you're training at home or in the gym, there's a plan to get you started straight away.\\n\"],\"1FnEj9\":[\"Body Measurements\"],\"1Kx4Hp\":[\"Error fetching \",[\"0\"],\": \",[\"1\"]],\"1Mx10o\":[\"View Stats\"],\"1QfxQT\":[\"Dismiss\"],\"1Se9J7\":[\"stationary bike\"],\"1UzENP\":[\"No\"],\"1gbc4_\":[\"New Workout\"],\"1hW6-f\":[\"Some images failed to download after retries. Failed exercise IDs: \",[\"0\"]],\"1j3Ob3\":[\"Workout Calendar\"],\"1mm2JF\":[\"deltoids\"],\"296mtr\":[\"trap bar\"],\"29Hx9U\":[\"Stats\"],\"2FYpfJ\":[\"More\"],\"2ZZM6V\":[\"core\"],\"2bnWaQ\":[[\"completedCount\"],\"/\",[\"0\"],\" sets completed\"],\"2cupe5\":[\"Apply to all \",[\"0\"],\" sets\"],\"2dPYb7\":[\"No measurements yet. Log your first entry above.\"],\"2dX9Kv\":[\"back\"],\"2eB2c7\":[\"Train without a plan! Create standalone workouts that live outside your training plans — perfect for mobility sessions, warm-ups, or anything ad hoc.\\n\\nOr jump straight into a Quick Workout from the home screen, add exercises on the fly, and optionally save it as a standalone workout when you're done.\"],\"2gSypt\":[\"Equipment *\"],\"2j0v05\":[\"All images downloaded successfully!\"],\"2lfUf3\":[[\"streak\",\"plural\",{\"one\":[\"#\",\" week in a row\"],\"other\":[\"#\",\" weeks in a row\"]}]],\"2saL1j\":[\"1RM\"],\"2vS4Oc\":[\"Easy, could do more\"],\"2wR0QE\":[\"Add Exercise\"],\"30xwUM\":[\"Are you sure you want to delete all animated images? Single images will be automatically re-downloaded when viewed.\"],\"39y5bn\":[\"Friday\"],\"3A79ox\":[\"Reduce load\"],\"3L-1Z1\":[\"Error loading exercises: \",[\"0\"]],\"3RoflF\":[\"\\n📈 New: Exercise History in the Info Screen!\\n\\nThe exercise info screen now includes a full history of every time you've performed that exercise, showing weights, reps, time, and distance for each set from past sessions. Access it during a workout, from your plan, or anywhere else exercise info is available.\\n\"],\"3ezHPX\":[\"Play sound after rest\"],\"3hJ166\":[\"\\n🔍 Improved: Smarter Exercise Search & Easy Access to the Exercise Library!\\n\\nExercise search now understands common abbreviations like RDL, OHP, DB, and KB, corrects minor typos, and ranks results by relevance so the best match always comes first.\\n\\nYou can also browse the full exercise library any time from the menu, without needing to be in a workout or plan.\\n\"],\"3hJypY\":[\"Insights\"],\"43lYJ-\":[\"Welcome\",[\"userName\"]],\"4BgR4M\":[\"You've hit your weekly goal. Incredible work!\"],\"4GTHgi\":[\"Exercise timer countdown\"],\"4M4P8M\":[\"No values entered\"],\"4OjqAQ\":[\"Keep editing\"],\"4Y9aig\":[\"Updated \",[\"0\"]],\"4_WLmI\":[\"body weight\"],\"4j0zbV\":[\"Saving Plan...\"],\"4jkyRj\":[\"warmup\"],\"4mrNi3\":[[\"suggestedRepsMin\"],\"-\",[\"suggestedRepsMax\"],\" reps suggested\"],\"4oRoD4\":[\"Configure weight, size, and distance units, default sets per exercise, default rest time, and the weight increment used by the ± buttons during a session. Adjust workout button size (Standard, Large, or XLarge) and toggle Keep Screen On to prevent the display sleeping mid-workout. Under Stats, you can exclude warmup sets from volume, double reps for unilateral exercises, or double the weight for paired implements, useful if you prefer logging per-dumbbell weight rather than the total. Set your body weight here; it is used to calculate effective load for assisted exercises.\"],\"4sGdeG\":[\"Body Fat\"],\"5-5naM\":[\"Friends & Social\"],\"50_FGa\":[\"Exercise\"],\"538Jsv\":[\"Cancel Workout\"],\"58iwz8\":[\"Error loading plans\"],\"5Hrw0r\":[\"Add to my workouts\"],\"5SgD0L\":[\"You have unsaved changes. Are you sure you want to discard them?\"],\"5Z05pb\":[\"Type to filter help topics\"],\"5aB9II\":[\"Time to do your next set!\"],\"5b4J4v\":[\"All Time\"],\"5lWFkC\":[\"Sign in\"],\"5w2VTM\":[\"Are you sure you want to download all animated images? This may take a while.\"],\"5yIPLp\":[\"Oops!\"],\"66llpx\":[\"Add Image\"],\"699xiu\":[\"Are you sure you want to restore the backup?\"],\"6Bqki7\":[\"Weekly Goal Complete!\"],\"6Hcqaf\":[\"\\n↕️ New: Reorder Workouts in Your Plan!\\n\\nYou can now reorder workouts directly in the plan creation screen and workout cards, giving you full control over your training schedule layout.\\n\"],\"6MR2yM\":[\"Browse almost 1,000 exercises and filter by body part, target muscle, or equipment. Use the sort chips at the top to order exercises by Default, Active Plan, Recent, or Frequent, so the exercises most relevant to you appear first. When replacing an exercise, the filter automatically preselects the matching target muscle to help you find alternatives faster. Tap any exercise to view its animated demonstration, the muscles targeted, and a full history of every time you have performed it, including weights, reps, time, or distance per set. Download all exercise animations (~100 MB) in Settings for offline access.\"],\"6XIVae\":[\"Load up\"],\"6_dCYd\":[\"Overview\"],\"6g63at\":[\"Explore Plans\"],\"6glEtt\":[\"Still recovering. Hold this load for now.\"],\"6igHT6\":[\"Edit Workout\"],\"6lAGPA\":[\"Add a workout to get started\"],\"6lv7us\":[\"Weight (\",[\"weightUnitLabel\"],\")\"],\"6q7I63\":[\"waist\"],\"6u9LvN\":[[\"days\",\"plural\",{\"one\":[\"#\",\" day ago\"],\"other\":[\"#\",\" days ago\"]}]],\"6uHnph\":[\"Time (Hour:Min)\"],\"6vinCF\":[\"Tracking Type *\"],\"6z9W13\":[\"Restart\"],\"716aO7\":[\"Most trained\"],\"75Qc-e\":[\"Count reps ×2 for volume when the setting is enabled\"],\"77kllS\":[\"best \",[\"0\"],\" reps\"],\"7F8buC\":[\"lower arms\"],\"7FYy4K\":[\"Error saving workout\"],\"7LBKtm\":[\"No workout available\"],\"7LLkrj\":[\"grip muscles\"],\"7MuXko\":[\"Personal\"],\"7P_9OY\":[\"Tu\"],\"7YT_7y\":[\"Reps\"],\"7Z9Tzs\":[\"spine\"],\"7eMo-U\":[\"Go Home\"],\"7hAJKI\":[[\"0\",\"plural\",{\"one\":[\"set\"],\"other\":[\"sets\"]}]],\"7iTVa8\":[\"Secondary Muscles\"],\"7p3sn_\":[\"Time: \",[\"0\"]],\"7x42zy\":[\"No data for this period\"],\"7xB0qQ\":[\"Target Muscle *\"],\"87VAxI\":[\"Exercise Info\"],\"8BG66J\":[\"No completed workouts shared yet\"],\"8JaOZF\":[\"Friend Profile\"],\"8Mlj-A\":[\"Rep target not met. Hold steady for now.\"],\"8Rd3od\":[\"Are you sure you want to cancel and delete this workout?\"],\"8V8f_Q\":[\"Latest \",[\"metricLabel\"],\": \",[\"0\"]],\"8YBh-G\":[\"Counting reps ×2 for these exercises\"],\"8ZJ9dh\":[\"Weight Tracking for Bodyweight Exercises\"],\"8ZU8FI\":[\"Error loading stats. Please try again.\"],\"8_MCsG\":[\"\\n💾 New: Save & Resume Plan and Workout Drafts!\\n\\nYour work in the plan and standalone workout editors is now automatically saved as a draft. If you leave mid-edit, you'll be prompted to continue where you left off or discard the draft, so you never lose progress by accident.\\n\"],\"8aTiea\":[\"Customisation\"],\"8cA6YX\":[\"Track your body composition over time from the Measurements section in the Stats tab. Use the Log Entry form to record values for any active metric, then tap a past entry in the History list to review or edit it. On the entry detail screen, tap a metric chip to switch the chart between different measurements and use the time range selector to zoom in or out. Metrics are split into three types: mass (weight, in kg or lbs), length (circumferences like waist and hips, in cm or in), and percentage (body fat). Units follow your weight and size preferences in Settings. To control which metrics appear in the entry form, tap Manage Metrics at the top of the Log Entry section. Built-in metrics can be toggled on or off; you can also create your own custom metrics and choose their type. Custom metrics can be hidden from the form at any time, and your historical data for them is always preserved.\"],\"8jcZyX\":[\"Built-in Metrics\"],\"8mjpCE\":[\"MuscleQuest Introduction\"],\"8uqQSD\":[\"Couldn't finish all sets\"],\"8wbSm2\":[\"No strength data shared yet\"],\"8yLreB\":[\"for \",[\"0\"],\"s \"],\"8yw7nc\":[\"Recovery Check-in\"],\"91hJvI\":[\"Target: \",[\"distanceMin\"],\" \",[\"distanceUnit\"]],\"94FTWy\":[\"Delete Complete\"],\"95IyBI\":[\"Bodyweight exercises like pull-ups or dips track reps only by default. If you want to log added weight, such as a weight belt or vest, open the sets overview for that exercise in the workout or plan editor and toggle Track Weight on. The toggle is saved per workout, so you can have some workouts use bodyweight-only and others track the additional load. Progression charts and history will reflect the logged weight once the toggle is on.\"],\"97-TIS\":[\"You couldn't complete all sets. Reducing load slightly for next time.\"],\"9Anet0\":[\"Equipment\"],\"9C6X7Q\":[\"Discard Changes\"],\"9EGOsa\":[\"cable\"],\"9H3-WL\":[\"\\n⚙️ New: Three New Stats Settings!\\n\\nCustomise how your volume and stats are calculated with three new options in Settings:\\n\\n• Exclude warm-up sets from stats so they don't skew your numbers.\\n• Double dumbbell weight automatically, so you can log the weight of one dumbbell and have the total counted for you.\\n• Double reps for single arm/leg exercises, so unilateral movements are counted correctly in your volume totals.\\n\"],\"9HyV9h\":[\"Enable to add a publish toggle to each standalone workout.\"],\"9LmK3L\":[\"Images by Unsplash\"],\"9XoWik\":[\"serratus anterior\"],\"9eQmcp\":[[\"0\"],\" days per week\"],\"A-gAFO\":[\"Create your own exercises from the exercise picker. Give it a name, an optional image, body part, target muscles, secondary muscles, and equipment. Choose a tracking type: weight + reps, time, distance, reps only, or assisted (which factors in your body weight for movements like assisted pull-ups). Toggle Unilateral for single-arm or single-leg exercises; reps can be automatically doubled in your stats. Toggle Paired Implements if you track the weight of one implement rather than the total: for example, if you log 20 kg for one dumbbell, the app counts 40 kg toward your volume.\"],\"A1-VaP\":[\"latissimus dorsi\"],\"A1_kH4\":[\"Exercise Timer\"],\"A1taO8\":[\"Search\"],\"ATGYL1\":[\"Email address\"],\"AWokve\":[\"Using history from same workout\"],\"AeXO77\":[\"Account\"],\"AqyJQg\":[\"Post-Exercise Feedback\"],\"Ayx1au\":[\"Are you sure you want to delete this plan?\"],\"B8ZQ8n\":[\"Min Reps\"],\"B9LtU1\":[\"You have unsaved changes from your last session. Would you like to continue?\"],\"BEVzjL\":[\"Import failed\"],\"BGO6Rp\":[\"How are these muscles feeling since your last session?\"],\"BTqs-Z\":[[\"0\",\"plural\",{\"one\":[\"#\",\" Set\"],\"other\":[\"#\",\" Sets\"]}]],\"BZDlVl\":[\"hip flexors\"],\"BaG4Vp\":[\"Frequent\"],\"BdnYlL\":[\"Avg Duration\"],\"BpTc_M\":[\"Search help\"],\"Bqo02Q\":[\"Start Timer\"],\"BrHgnn\":[\"\\n⏱️ New: Adjustable Rest Timer!\\n\\nA new slide-in panel lets you fine-tune your rest duration on the fly during a workout. Your custom rest time is saved per set, so each set remembers exactly how long you like to rest.\\n\"],\"BwTx3c\":[\"Are you sure you want to remove \",[\"0\"],\"?\"],\"C4GKOD\":[[\"repRange\"],\" Reps, \"],\"CCTop_\":[\"Recent\"],\"CE-M2e\":[\"Info\"],\"CFL873\":[\"Enable to automatically share each workout you complete.\"],\"CV6Ez2\":[\"Tap Sign In With Google in Settings to connect your account. Signing in enables cloud backups so your data is safe if you switch devices or reinstall the app, and your name is shown in the home screen greeting. The app works fully offline without signing in, but cloud backups are unavailable. Your data is stored locally on your device and is not shared with anyone unless you choose to share it yourself.\"],\"CZKXmk\":[\"ankles\"],\"CaKjcv\":[\"Quick Workout\"],\"CghlOu\":[\"lower abs\"],\"CiUwqB\":[\"Go to Workouts\"],\"CxQnhY\":[\"\\n👥 New: Friends & Social Sharing!\\n\\nAdd friends by searching for their username from the Friends tab in the menu. Send a request, and once accepted you can browse each other's shared content. A badge on the Friends menu item shows pending incoming requests.\\n\\nShare your plans, standalone workouts, custom exercises, body measurements, and strength PRs by toggling Share in the relevant screen or from Privacy Settings in the Account section of Settings. Shared content syncs automatically whenever it changes, and a cloud icon on plan and workout cards shows what is currently published. You can delete all shared data for any category from Privacy Settings at any time.\\n\\nTap any accepted friend's name to open their profile and import their plans, standalone workouts, or custom exercises directly into your own library.\\n\"],\"D-GweR\":[\"Sign in to use the Friends feature.\"],\"D0GOrZ\":[\"You need to sign in to use this feature\"],\"D3h1sn\":[\"working\"],\"D45Cr4\":[\"Select secondary muscles\"],\"D89zck\":[\"Sun\"],\"DBC3t5\":[\"Sunday\"],\"DIS-zd\":[\"Failed to delete plan: \",[\"0\"]],\"DJMHhb\":[\"Last session was a deload — comparison skipped.\"],\"DNhKLr\":[\"\\n🎯 Improved: Smarter Exercise Filters!\\n\\nWhen replacing an exercise, the filter now automatically preselects the target muscle to match what you're replacing. Only relevant filters are shown based on your current selection, making it much faster to find the right alternative.\\n\"],\"DPfwMq\":[\"Done\"],\"DTtUaj\":[\"Enter at least one measurement to log.\"],\"DWFuyG\":[\"Remove Exercise\"],\"DYOFso\":[\"ankle stabilizers\"],\"DdBQBl\":[\"Weekly Schedule\"],\"Dh5Ge5\":[\"Any pain or form breakdown?\"],\"Di-cgt\":[\"Welcome to MuscleQuest!\"],\"DqgDEk\":[\"Using most recent from any workout\"],\"Dvc8Qg\":[\"Description:\"],\"Dy8Cvh\":[\"quadriceps\"],\"Dy_8Fq\":[\"DISMISS\"],\"E3kRqj\":[[\"uniqueWorkoutDaysCount\"],\" / \",[\"0\"],\" days worked out\"],\"EANWES\":[\"Failed to load history\"],\"EHgz6Q\":[\"Failed to update sharing. Please try again.\"],\"EMyNOr\":[[\"0\"],\" \",[\"1\"],\" (used for assisted exercises)\"],\"E_QGRL\":[\"Disabled\"],\"Ed3YeG\":[\"Each workout you complete is shared automatically.\"],\"Ef7StM\":[\"Unknown\"],\"EfdYnO\":[[\"0\"],[\"distanceUnit\"]],\"EjAXiq\":[\"Adaptive Progression (beta)\"],\"EkVHAp\":[\"Rest timer increment\"],\"EoQHhQ\":[\"treadmill\"],\"Euo2Um\":[\"Time (Min:Sec)\"],\"F37c1s\":[\"Open Settings\"],\"F6pfE9\":[\"Active\"],\"FCGpHg\":[\"No exercises in this workout yet.\"],\"FHIDZO\":[\"Save and select\"],\"FPsvA8\":[\"Got it!\"],\"FXHR4B\":[\"Body Part\"],\"Fb5zs_\":[\"\\n⚖️ New: Track Weight for Bodyweight Exercises!\\n\\nFor bodyweight exercises like pull-ups or dips, you can now toggle on weight tracking per workout. Perfect for weighted variations, so you can log the added weight and track progression over time.\\n\"],\"Fe0wLe\":[\"Supersets\"],\"FnTClW\":[\"You've been hitting targets easily. Time to add a little more weight.\"],\"Fp1hl-\":[\"Loading Plan...\"],\"FwCUad\":[\"Equipment is required.\"],\"G-iXUH\":[\"shoulders\"],\"G1onOm\":[\"Delete all shared data?\"],\"G2R9Qq\":[\"wrist flexors\"],\"G2nnKc\":[\"Add to my plans\"],\"G3myU-\":[\"Tuesday\"],\"G49bAb\":[\"leverage machine\"],\"G4JNdR\":[\"Exercise not found.\"],\"G6rTvo\":[\"Track (\",[\"0\"],\")\"],\"GB-X8R\":[\"Importing from Friends\"],\"GCV1HM\":[\"Signed in as \",[\"0\"]],\"GCqPY4\":[\"The home screen shows your progress toward your weekly training goal, which is the number of days you want to work out each week, set in Settings. A strip at the top tracks how many days you have completed and highlights each completed day. Below it, your active plan's workouts are listed with their completion status for the week; tap Start on any workout to begin. The card displayed beneath changes with your status: a Resume card appears if a session is in progress, a Rest Day card shows on days with no scheduled workout, and a Workout Done card confirms today's session is complete. When you hit your weekly goal, a Weekly Summary card appears showing total workouts, sets, and volume for the week, plus your streak, which counts the number of consecutive weeks you have met your goal.\"],\"GGqR7k\":[\"Single & Quick Workouts\"],\"GLJjec\":[\"To Failure\"],\"GLm0-9\":[\"Pain or form issues\"],\"GNurdZ\":[\"Delete Exercise\"],\"GPeIuw\":[\"Distance\"],\"GS7yxz\":[\"Permission Required\"],\"GSOeV2\":[\"hamstrings\"],\"GVN2lL\":[\"Create Exercise\"],\"GWvJTL\":[\"About right\"],\"GX9tlq\":[\"neck\"],\"Gd-KuS\":[\"Manage metrics\"],\"Gf9sn6\":[\"Checking for backups...\"],\"GhCGeL\":[\"Sets\"],\"GksdwI\":[\"Top PR Sets\"],\"HNWkJr\":[\"\\n📏 New: Distance Tracking for Custom Exercises!\\n\\nCustom exercises can now use a distance tracking type, perfect for cardio and conditioning movements like runs, rows, or sled pushes. Log distance for your sets and get insights on progression just like any other exercise.\\n\"],\"HYL9fJ\":[\"Log one side only for single-arm/leg exercises\"],\"Hp6ceF\":[\"Unable to save your workout. Please try again later.\"],\"HpK_8d\":[\"Reload\"],\"Hplwk7\":[\"Restoring. Please wait...\"],\"I2Hpku\":[\"Track Weight\"],\"ICkQNB\":[\"Reminder time\"],\"IFowGw\":[\"rope\"],\"IHMx9j\":[\"Week streak\"],\"ILE1kp\":[\"arms\"],\"INkdlR\":[\"No friends yet. Search by email to add someone.\"],\"IRiG-a\":[\"Vibrate after rest\"],\"IUwGEM\":[\"Save Changes\"],\"IXxATP\":[\"Custom Exercises\"],\"IbbuFX\":[\"Deleting. Please wait...\"],\"IuXB4Q\":[\"Add a note...\"],\"Izf0kk\":[\"No prior weight data. Hold steady for now.\"],\"JE-yVp\":[\"Manage Metrics\"],\"JR5hAM\":[\"1yr\"],\"JTkSvz\":[\"Are you sure you want to remove this workout?\"],\"JVKmoO\":[\"The update couldn't be downloaded. Check your internet connection and reopen the app to try again.\"],\"JW7_2_\":[\"Download Failed\"],\"JWTR_A\":[\"An error occurred while downloading images.\"],\"JYRqp5\":[\"Sa\"],\"JbvV5d\":[\"During a session, swipe left/right or use the arrow buttons to move between sets. Enter your weight and reps, then tap Complete Set. The total elapsed time is shown in the header throughout. You can drag the handle on any exercise card to reorder exercises while the session is in progress. Time-based exercises have a Start Timer button that opens a count-up timer with a progress ring that shows you when you hit your goal time but you can keep going as long as you like. Notes can be added per-exercise via the notes icon in the exercise header, per workout from the workout overview screen, or per plan from the plan overview screen. If you add, remove, or reorder exercises or sets during a session, you will be prompted at the end to save those changes back to the original workout or plan.\"],\"JfDOWo\":[\"The update is ready but the app couldn't restart automatically. Try tapping the button below, or close and reopen the app manually.\"],\"JkpsKr\":[\"Downloading. Please wait...\"],\"JmZ_-d\":[\"Finish\"],\"JsIy35\":[\"You activated this plan.\"],\"JumwGu\":[\"cardio\"],\"Jv9TrU\":[\"obliques\"],\"KIL-9T\":[\"Next: \"],\"KKalG-\":[\"Pin exercises in the Stats tab to track their strength progression over time. Each tracked exercise shows a chart of your performance over the selected time range, your all-time personal record, your top sets, and a list of recent sessions showing the best set per day. Charts update automatically after each workout that includes that exercise.\"],\"KM1Iw2\":[\"MuscleQuest\"],\"KSqQx0\":[\"Max Reps\"],\"Km7tR4\":[\"Buy Me a Coffee\"],\"KmiPdE\":[\"dumbbell\"],\"KxWSWU\":[\"Keep screen on during workout\"],\"LAC2eo\":[\"Workout Reminders\"],\"LAHzG1\":[\"View/Edit\"],\"LIrnc0\":[\"No exercises added yet\"],\"LLt1-u\":[\"Unilateral\"],\"LZKayn\":[\"Search help…\"],\"LcPJBt\":[\"completed workouts\"],\"LhMjLm\":[\"Time\"],\"LyPttd\":[\"Chest\"],\"M0GVkz\":[\"Select a day to see workouts.\"],\"M1POMr\":[\"Exercise Library\"],\"M4hMaA\":[\"Enter a name for the custom metric.\"],\"M57U8X\":[\"Group two exercises into a superset so they alternate automatically during a session, ideal for pairing antagonist muscles or staying efficient between sets. Tap the three-dot menu on any exercise in the workout editor and choose Create Superset, then select the second exercise. A coloured label identifies which superset each exercise belongs to throughout the app. When you complete a set on one exercise, the app moves you straight to its superset partner.\"],\"MEt7-_\":[\"soleus\"],\"MHk_Wu\":[\"Entry not found.\"],\"MLQOxI\":[\"rear deltoids\"],\"MM-MTF\":[\"Superset \",[\"0\"]],\"MQ9jL7\":[\"One more workout to hit your goal!\"],\"MQA2H9\":[\"Delete Plan\"],\"MTqmCb\":[\"Request or vote for new features\"],\"McFNQO\":[\"Monitor your fitness journey with detailed stats and insights. Keep track of workout history, analyse your body part splits, and visualise improvements over time with exercise progression graphs.\"],\"MmDz7_\":[\"Uploading. Please wait...\"],\"N4e_z1\":[\"Rest Time: \",[\"restMinutes\"],\":\",[\"0\"]],\"N5Cyfw\":[\"Friends since \",[\"0\"]],\"N85c_3\":[\"Remove Workout\"],\"NC2AI2\":[\"Length\"],\"NIuBdI\":[\"Premade plans\"],\"NKdWDE\":[\"cardiovascular system\"],\"NLBiJk\":[\"Log Entry\"],\"NLYLjM\":[\"sets\"],\"NPG8SK\":[\"Body weight\"],\"NQJHen\":[\"Are you sure you want to restart this workout?\"],\"NVOqiK\":[\"Log in to secure your data\"],\"NXoGPK\":[\"Edit Exercise\"],\"Ne5n-8\":[\"Add Personal Notes\"],\"NnRCUm\":[[\"0\"],\"s\"],\"Ns5WaC\":[\"No backups found\"],\"Nu4oKW\":[\"Description\"],\"O1GFNQ\":[\"All target muscles\"],\"O1xiRM\":[\"reps\"],\"O2TAe0\":[\"barbell\"],\"O2wCGL\":[\"Play countdown beeps (Exercise Timer)\"],\"ODbgw_\":[\"This removes all content you have shared with friends. Your friends and friend list are not affected.\"],\"OdFJle\":[\"Enable to automatically share custom exercises you create or edit.\"],\"Otd3xX\":[\"A deload is a planned recovery week where you train at reduced intensity to let your body fully recover before the next training block. Tap Mark as Deload Week on the plan overview screen to flag the current week as a deload. While the deload is active, the post-exercise feedback sheet does not appear and no new progression states are created or updated, so your suggestion history is not disrupted by the lighter sessions. The deload resets automatically at the start of the following week, and normal feedback and progression tracking resume without any manual action. If you change your mind, tapping the button again while the deload is active will clear it.\"],\"Ov8o8m\":[\"Start Plan\"],\"OwNTSr\":[\"Save to Plan\"],\"Owchfv\":[\"Recently Used\"],\"OzAZw8\":[\"This screen doesn't exist.\"],\"P0mjNu\":[\"Delete Entry\"],\"P0svFp\":[\"Rest\"],\"P1svYv\":[\"abs\"],\"P247ya\":[\"Body Part *\"],\"P3NwXY\":[\"Share Workout\"],\"P3nVsi\":[\"\\n📅 New: Weekly Schedule for Your Plan!\\n\\nYou can now assign workouts to specific days of the week directly in the plan editor. Tap any day to pick a workout or mark it as a rest day. Use the auto-suggest button to instantly generate a balanced schedule based on your weekly goal.\\n\"],\"P3omNB\":[\"Select a workout to view\"],\"PBt59F\":[\"Favourite Exercises\"],\"PFcCy0\":[\"x \",[\"0\"],\" reps \"],\"PHWHEO\":[\"Accept all\"],\"PITZNx\":[\"chest\"],\"PN5Zzf\":[\"Weight unit\"],\"PNapeY\":[\"+ Add\"],\"POx12e\":[\"\\n↕️ New: Reorder Exercises in the Workout Overview!\\n\\nYou can now drag and drop exercises and supersets to reorder them directly from the workout overview screen during a session.\\n\"],\"PSNHRi\":[\"* features in development\"],\"PWfg7v\":[\"Requests\"],\"P_0oX-\":[\"Assist\"],\"PeTE4m\":[\"Plan not found.\"],\"PiK6Ld\":[\"Sat\"],\"PruBpO\":[\"Are you sure you want to delete this measurement entry?\"],\"Q1Lq8I\":[\"Total Time\"],\"Q2QJ28\":[\"Play goal achieved sound (Exercise Timer)\"],\"Q8bEQa\":[\"An error occurred while deleting images.\"],\"Q9qAkA\":[\"Estimated Duration: \",[\"0\"]],\"QENBWX\":[\"triceps\"],\"QOTvot\":[\"Sharing Your Content\"],\"Qdwk82\":[\"Dumbbell load increment\"],\"Qjp-BQ\":[\"Add a set\"],\"QlT4B5\":[\"Recent Sessions\"],\"Qmbwcr\":[\"Edit Plan\"],\"QoHy-T\":[[\"weeks\",\"plural\",{\"one\":[\"#\",\" week ago\"],\"other\":[\"#\",\" weeks ago\"]}]],\"QrwEaQ\":[\"pectorals\"],\"QzJCdZ\":[\"lats\"],\"R-ABt9\":[\"Weekly goal\"],\"R0gwbc\":[\"biceps\"],\"RAMaAx\":[\"Incoming\"],\"RCk1J0\":[\"sled machine\"],\"RGfnXX\":[\"(to Failure)\"],\"RIHmRj\":[\"Good pace. Try adding one rep per set before bumping the load.\"],\"RM5DG6\":[\"Tracked Exercises\"],\"RN4XJV\":[\"Rest Day\"],\"RU6ELr\":[\"Stats & History\"],\"RXkbtG\":[\"Push harder next time?\"],\"RY_JyV\":[\"lower back\"],\"R_h8B2\":[\"Most Used\"],\"Rc-8oy\":[\"Downloading Update\"],\"RmahBs\":[[\"0\"],\": \",[\"best\"],\"s (+\",[\"delta\"],\"s, \",[\"pctStr\"],\")\"],\"Rr5U7J\":[\"Completed sets will appear here\"],\"Rwc-xL\":[\"Time PR\"],\"RxzN1M\":[\"Enabled\"],\"S2uNE5\":[\"Continue Editing?\"],\"SEyweA\":[\"\\n🐛 Fixed: Various Bug Fixes & Improvements!\\n\\nFixed the rest timer notification not triggering correctly, exercise name wrapping in the workout session, the workout completion circle width, notes not updating correctly while typing, and workout details sometimes opening in the wrong tab. Workouts now load faster thanks to internal performance improvements.\\n\"],\"SGISp8\":[\"You finished everything at the limit. Stay here and own it.\"],\"SRhtpX\":[\"forearms\"],\"SUd4dA\":[\"\\n📏 New: Body Measurements!\\n\\nTrack your body composition alongside your training from the new Measurements section in the Stats tab.\\n\\n• Log weight, body fat %, waist, hips, chest, and more\\n• Tap any past entry to edit values or view a chart of that metric over time\\n• Manage which metrics appear and add your own custom metrics\\n• Units follow your weight and size preferences in Settings\\n\"],\"SWtay1\":[\"After completing the last working set of an exercise, a feedback sheet slides up with two questions. The first asks how the effort felt: Easy (you could have done more), About right, Hard (near your limit), or Couldn't finish all sets. The second asks about pain: No pain, Minor discomfort, or Pain or form issues. If you answer Easy, a third question appears asking whether you want to push harder next time. This lets you deliberately hold the current load even when a session felt light, so the engine respects your intent. If you answer Pain, an optional text field lets you note where you felt it for your own reference. The sheet can be dismissed without answering if you prefer not to log feedback for that exercise in that session.\"],\"SZw9tS\":[\"View Details\"],\"SadoC9\":[\"smith machine\"],\"SbGW67\":[\" (to Failure) \"],\"ScJ9fj\":[\"Privacy policy\"],\"SdpDoo\":[\"Share completed workouts with friends\"],\"SlfejT\":[\"Error\"],\"SmkA26\":[\"1RM \",[\"0\"],\" \",[\"unit\"]],\"SoWD_0\":[\"Save Set\"],\"SrVzRe\":[\"Percent\"],\"St3y2e\":[\"Name required\"],\"SvOMfA\":[[\"0\"],\" workouts\"],\"SzQe8k\":[\"Add to my exercises\"],\"T0cOwV\":[\"Delete Set\"],\"T7QVyK\":[\"When you open a workout that contains exercises you trained recently, a Recovery Check-in sheet appears if those exercises have a pending progression suggestion and your last session was at least 12 hours ago. For each relevant muscle group, you choose one of three options: Fresh (fully recovered), Mild soreness, or Still very sore. If a muscle is marked as still very sore, any upward progression suggestion for exercises targeting that muscle is paused and held at the current load until you re-evaluate at the start of the following session. Fresh or Mild soreness does not affect suggestions. Tap Skip for now to bypass the check-in entirely; a skipped check-in is treated the same as fresh recovery, so pending suggestions are unaffected.\"],\"TBTwj-\":[\"Follow MuscleQuest on Instagram\"],\"TJLDrx\":[\"Doubling weight for volume calculations\"],\"T_qHwF\":[\"lower legs\"],\"Ta25TG\":[\"No history yet\"],\"Tfzp6S\":[\"Share strength PRs with friends\"],\"TpqeIh\":[\"Error: \",[\"0\"]],\"Tz0i8g\":[\"Settings\"],\"TzLpDD\":[\"\\n🏋️ New: Single Workouts & Quick Workouts!\\n\\nCreate standalone workouts outside of your training plans — perfect for flexible training sessions, mobility work, or anything ad hoc. Find them on the Plans screen.\\n\\nOr start a Quick Workout from the home screen, add exercises on the fly, and optionally save it as a standalone workout when you're done.\\n\"],\"U0HZma\":[\"Tracking\"],\"U4QKsL\":[\"Hide / Show Onboarding\"],\"U8BTVm\":[\"Rest Time Left:\"],\"UCtAiM\":[\"To enable rest timer notifications, grant notification permissions in your device settings.\"],\"UD8kHo\":[\"Next: \",[\"workoutName\"],\" on \",[\"0\"]],\"URmyfc\":[\"Details\"],\"US8F_H\":[\"More reps suggested\"],\"USXXjt\":[\"No results for \\\"\",[\"query\"],\"\\\"\"],\"U_-GrY\":[\"Please wait while we download the latest version...\"],\"UbRKMZ\":[\"Pending\"],\"UlnAQR\":[\"Failed to delete workout. Please try again.\"],\"UneMBz\":[\"Active Plan\"],\"UnnFak\":[\"Great start to the week!\"],\"Uorrgj\":[\"rhomboids\"],\"Uu14s5\":[[\"0\",\"plural\",{\"one\":[\"#\",\" set\"],\"other\":[\"#\",\" sets\"]}]],\"UyvU3-\":[\"Help & Info\"],\"UzNvmf\":[\"• Backup and restore data\"],\"V6wjuJ\":[\"Tracking type is required.\"],\"V6xf0O\":[\"This exercise is already in your workout. Please choose a different one.\"],\"V8MVAm\":[\"upper chest\"],\"V8dVu4\":[\"\\n🔗 New: Supersets!\\n\\nPair two exercises together as a superset directly in the plan editor. Sets are kept in sync between both exercises, and supersets are clearly grouped with a visual indicator throughout the app.\\n\"],\"V8yTm6\":[\"Clear search\"],\"VAcXNz\":[\"Wednesday\"],\"VCJb5r\":[\"Set \",[\"0\"],\" of \",[\"totalSets\"]],\"VDkJml\":[\"Adaptive Progression analyses your effort feedback over consecutive sessions and suggests when to increase your weight, reps, or sets. Enable it in Settings under Adaptive Progression. Once on, a short feedback prompt appears after each exercise in plan-based workouts. The engine requires two sessions with the same signal before recommending an upward change, filtering out one-off easy days and ensuring consistent performance before suggesting an increase. Pain or failed sets act immediately regardless of your session history. A suggestion is never applied to your workout without your explicit approval. You can also configure your preferred load increment per equipment category in the same section of Settings, for example 2.5 kg for barbell exercises and 2.0 kg for dumbbells.\"],\"VFlRXJ\":[\"Hold steady this session.\"],\"VJVR1o\":[\"Share Plan\"],\"VcD4kW\":[\"This friend hasn't shared any content yet.\"],\"VhVOxx\":[\"Your journey to Swoletown begins today!\"],\"VhfZbD\":[\"Size: ~100MB\"],\"W-pY1H\":[\"Failed to save custom exercise. Please try again.\"],\"W0qDyY\":[\"Home Screen & Weekly Goal\"],\"W3QcBP\":[\"Plan Overview\"],\"W3u9nh\":[\"To failure, \"],\"WDciil\":[\"\\n📋 New: \\\"More\\\" Menu and Help & Info Section!\\n\\nThere's a new \\\"More\\\" tab in the navigation bar. Tap it to open a slide-in panel where you'll find Settings and a brand new Help & Info section.\\n\\nSettings has moved here from the tab bar, and Help & Info covers everything from plans and workouts to stats and your account, with a search bar to find answers quickly.\\n\"],\"WHwUfF\":[\"Error loading exercise details\"],\"WIbOhZ\":[\"Adaptive Progression\"],\"WJp2MH\":[\"Size unit\"],\"WKHqM-\":[\"Weight\"],\"WMvAhQ\":[\"Custom exercises you create or edit are shared automatically.\"],\"WOi4Vm\":[\"Name *\"],\"WSzg3A\":[\"Distance (\",[\"distanceUnit\"],\")\"],\"WU-3OC\":[\"Single-arm / single-leg\"],\"WaIjmh\":[\"Calf (R)\"],\"Wjxizh\":[\"All shared data has been removed.\"],\"WoEX6M\":[\"Suggest load and rep adjustments\"],\"WzcO-J\":[\"Create Plan\"],\"X9kySA\":[\"Favorites\"],\"X9r6cu\":[[\"goal\",\"plural\",{\"one\":[[\"completed\"],\" of \",\"#\",\" workout this week\"],\"other\":[[\"completed\"],\" of \",\"#\",\" workouts this week\"]}]],\"XBUsEY\":[\"Target Muscle\"],\"XHHEUg\":[\"Customise Plan\"],\"XJQdl_\":[\"Send notification in background after rest\"],\"XNRDYn\":[\"wrist extensors\"],\"XdavYY\":[\"Workouts\"],\"Xdcdfd\":[\"Sets & Exercises\"],\"XoEooZ\":[\"Time (s)\"],\"Xu14OQ\":[[\"0\",\"plural\",{\"one\":[\"#\",\" Rep\"],\"other\":[\"#\",\" Reps\"]}]],\"Xu2iGM\":[\"Add Weight\"],\"Xv4OIW\":[\"Workout in progress\"],\"Xwd4Hm\":[\"rotator cuff\"],\"Y35ibG\":[\"Strength PRs are shared automatically after each workout.\"],\"Y6QE0T\":[\"Select equipment\"],\"YANNVr\":[\"Workout\"],\"YDnEIW\":[\"Best gain\"],\"YIix5Y\":[\"Search...\"],\"YLIqcF\":[\"Welcome back\",[\"userName\"]],\"YXJbW8\":[\"Standalone workouts live outside of plans and appear alongside your plans on the Plans screen. Create one by tapping New Workout, give it a name, and add exercises; you can run it at any time without needing an active plan. An estimated duration is shown on each standalone workout so you can plan your time before starting. Quick Workouts let you start a session immediately from the home screen: tap Quick Workout, add exercises as you go, and at the end you can save it as a standalone workout for future use or simply discard it. Like plans, the workout editor automatically saves a draft so you can safely leave and return without losing your work.\"],\"YYzBv9\":[\"Mo\"],\"YekWWq\":[[\"0\",\"plural\",{\"one\":[\"#\",\" rep\"],\"other\":[\"#\",\" reps\"]}]],\"YiPU_R\":[\"delts\"],\"YnHdfF\":[\"Set \",[\"0\"]],\"Yr-t8O\":[\"feet\"],\"YuP-pS\":[\"\\\"\",[\"label\"],\"\\\" will be hidden from the entry form. Your historical data is preserved.\"],\"Z3FXyt\":[\"Loading...\"],\"Z8RW4m\":[\"After finishing a workout, the Workout Summary screen shows a Next Session card listing actionable suggestions for your exercises. Each row shows the exercise name, the proposed change (a new target weight, a wider rep range, or a note to reduce load), and a short explanation of why the change is being suggested. Tap Accept to apply the suggestion to that exercise for your next session, or Dismiss to ignore it. Accepted suggestions are pre-filled into the weight and rep fields the next time you open that workout, so you start the session already targeting the right load. The Accept All button at the top applies every suggestion at once. Suggestions that recommend holding the current load do not appear in the card, as no action is needed for those.\"],\"ZARyDw\":[\"Adding Friends\"],\"ZAWGCX\":[[\"0\"],\" seconds\"],\"ZAvcCf\":[[\"0\"],[\"weightUnit\"],\" × \",[\"1\"]],\"ZI8idP\":[\"Fresh, fully recovered\"],\"Zm9Eu3\":[\"Button size during workout\"],\"Zv7vjq\":[\"Share plans with friends\"],\"Zvc_N1\":[\"1RM (\",[\"weightUnitLabel\"],\")\"],\"_-nVtu\":[\"Felt easy this time. Hold for now and confirm next session.\"],\"_2fO4v\":[\"Workout Summary\"],\"_D5y8a\":[\"Default sets\"],\"_K9jUO\":[\"upper body ergometer\"],\"_P2B4j\":[[\"biggestGainLabel\"],\" 1RM\"],\"_RhvUo\":[\"settings\"],\"_UGS0C\":[\"Workout name\"],\"_W-KPJ\":[\"No measurements yet. Tap to log your first entry.\"],\"_WRCmH\":[[\"0\"],\" \",[\"1\"],\" | \",[\"2\"],\" Reps\"],\"_XczSN\":[\"Select target muscle\"],\"_cF7Rs\":[\"Volume\"],\"_f5DAr\":[\"Completed on: \",[\"formattedDate\"]],\"a2Fu8q\":[\"You can login at any time from the settings screen, if you choose to skip it now.\"],\"a5BPTT\":[\"kettlebell\"],\"a8SF50\":[\"Enables a per-workout publish toggle.\"],\"a8TA11\":[\"Next Session\"],\"a99tuk\":[\"Enable to add a publish toggle to each plan.\"],\"aAIQg2\":[\"Appearance\"],\"aMwZcE\":[\"Upper Arm (L)\"],\"aN_GPe\":[\"Where did you feel it?\"],\"aRwEh5\":[\"Share custom exercises with friends\"],\"ahW3x6\":[\"\\n📅 New: Workout Calendar!\\n\\nTap the calendar icon in the Workout History section on the Stats tab to browse your training history by date. Days with workouts are highlighted, and tapping any day shows the sessions logged on that date.\\n\"],\"aj6ZJx\":[\"Google sign in\"],\"b3e7Re\":[\"Restart App\"],\"b63Dw_\":[\"No user found with that email address.\"],\"b9OAHS\":[\"Add Warm-up\"],\"bFeIdj\":[\"Drop Set\"],\"bQdjFX\":[[\"0\"],\" Note\"],\"bRAv_4\":[\"Workout \",[\"0\"]],\"bZS72M\":[[\"setsCount\",\"plural\",{\"one\":[\"#\",\" set\"],\"other\":[\"#\",\" sets\"]}]],\"bosqpS\":[\"No workouts completed yet. Start your first workout!\"],\"bqb_ci\":[\"\\n🐛 Fixed: Workout Session Buttons & Edit Set Modal!\\n\\nFixed a bug where all buttons (increment/decrement, next/previous set, complete set) would stop working after completing a set. Also fixed an error in the edit set modal. Set transitions now happen instantly for a smoother workout flow.\\n\"],\"bwd2oE\":[\"Rest Timer Finished!\"],\"bzSI52\":[\"Discard\"],\"c2TGz5\":[[\"completed\"],\" workouts this week. You've smashed your goal!\"],\"c7AAAa\":[\"\\n📈 Beta: Adaptive Progression!\\n\\nMuscleQuest can now suggest when to increase your weight or reps based on how your sessions feel. After each exercise, answer two quick questions about effort and pain. Once you have reported the same signal for two sessions in a row, the app suggests a change. All suggestions appear in the Workout Summary screen, where you can accept or dismiss each one individually. Accepted suggestions are pre-filled into your next session automatically.\\n\\nA Recovery Check-in at the start of your next workout lets you factor in soreness before any suggestion is applied. You can also mark a full week as a Deload from the plan overview, which pauses feedback and progression tracking for that week.\\n\\nEnable it in Settings under Adaptive Progression, and configure your preferred load increment per equipment category.\\n\"],\"cCbON-\":[\"\\n🔥 Improved: Warm-Up Set Management!\\n\\nWarm-up sets are visually grouped and styled separately from working sets, and \\\"Apply to all\\\" lets you bulk-edit warm-up or working sets independently.\\n\"],\"cF5b-5\":[[\"weeklyGoal\",\"plural\",{\"one\":[\"Auto-suggest (\",\"#\",\" day)\"],\"other\":[\"Auto-suggest (\",\"#\",\" days)\"]}]],\"cI6f7l\":[\"30d\"],\"cU45Co\":[\"Add Workout\"],\"cUD6H0\":[\"Get Ready...\"],\"cUY9dI\":[\"Are you sure you want to delete this exercise?\"],\"ckJ-os\":[\"Muscles\"],\"cnGeoo\":[\"Delete\"],\"crwali\":[\"Reminders\"],\"ctrAML\":[\"Make sure to track your progress!\"],\"cyR8-W\":[\"\\n🕐 New: Workout Duration Estimate!\\n\\nEach workout card now shows an estimated duration so you can plan your sessions at a glance before you start.\\n\"],\"d1z1ZY\":[\"The rest timer starts automatically after each set and counts down to zero. Each set remembers its own rest duration, so different sets within the same exercise can have different rest periods. Use the ± buttons to adjust the remaining time on the fly during rest. Configure the default rest duration, the timer increment, and whether a sound, vibration, or background notification fires at the end; each option is independently toggleable in Settings.\"],\"dEgA5A\":[\"Cancel\"],\"dH9Y4t\":[\"No workouts on this day.\"],\"dVK-Er\":[\"A render error has occurred. Press the button to reload.\"],\"dXCD6-\":[\"Download all exercise animations\"],\"dXoieq\":[\"Summary\"],\"dYOPCE\":[\"Assist \",[\"0\"],\" \",[\"1\"],\" | Resist \",[\"2\"],\" \",[\"3\"],\" | \",[\"4\"],\" Reps\"],\"dbWo0h\":[\"Sign in with Google\"],\"deoJBi\":[[\"0\"],\" reps\"],\"dfunKV\":[\"Weight/Reps\"],\"dpOqdQ\":[\"To failure\"],\"dqjuBA\":[\"90d\"],\"dx0cCC\":[\"Keep the momentum going!\"],\"e0dGJ7\":[\"Benefits of logging in:\"],\"e0l-Z0\":[[\"scheduledDays\",\"plural\",{\"one\":[\"#\",\" day/week\"],\"other\":[\"#\",\" days/week\"]}]],\"e52k4Y\":[\"Open the Friends tab from the menu to manage your connections. Use the search bar to find other users by username and send them a friend request. Incoming requests appear in the Requests tab; tap Accept to confirm or Decline to ignore. A badge on the Friends menu item shows how many pending requests are waiting. Once a request is accepted, both users appear in each other's Friends list and can view each other's shared content.\"],\"e5h2IT\":[[\"0\"],\" Notes\"],\"e9qdcV\":[\"Minor discomfort\"],\"eLA0I2\":[\"Download Images\"],\"eQm4BH\":[\"After finishing a workout, a summary screen shows your total duration, sets completed, and total volume. If you have done the same workout before, a comparison row shows how each metric compares to the previous session. A weekly goal banner shows how many sessions you have logged this week against your goal. Tap any exercise in the list to expand it and review every set in detail. When completing a Quick Workout, you will be prompted to save it as a standalone workout for future use or discard it.\"],\"eYbd7b\":[\"Su\"],\"ecUA8p\":[\"Today\"],\"ehOkF-\":[\"Basics\"],\"emOtYn\":[\"Premade Plans\"],\"enD4RG\":[\"Could not add this exercise. Please try again.\"],\"ez-cQL\":[\"\\n🔔 New: Workout Reminder Notifications!\\n\\nNever miss a session. Set reminder notifications for your workouts directly from the app. Choose which days you want to be reminded, and pick a time to get started.\\n\"],\"f2yjAZ\":[\"No pain\"],\"f7pPKh\":[\"Thigh (L)\"],\"f8Vl8d\":[\"Metric name\"],\"fFHHFp\":[\"Measurements\"],\"fPpo2L\":[\"Superset\"],\"fQWEzC\":[\"No plans shared yet\"],\"fSu2Jl\":[\"A new version has been downloaded. Tap the button below to restart and apply the update.\"],\"fWsBTs\":[\"Something went wrong. Please try again.\"],\"fXVIZq\":[\"Values\"],\"f_bxrN\":[\"Name is required.\"],\"feWdkU\":[\"Restart Workout\"],\"fj5byd\":[\"N/A\"],\"fpMgHS\":[\"Mon\"],\"fqSfXY\":[\"Replace\"],\"fsJAR5\":[\"Barbell load increment\"],\"ftiGCv\":[\"All equipment\"],\"fvyzOr\":[\"upper back\"],\"g36TSx\":[\"Distance unit\"],\"g3UF2V\":[\"Accept\"],\"g3cPNV\":[\"Enable to automatically share each body measurement you record.\"],\"gCVtjC\":[[\"0\"],\" Sets\"],\"gEOgEq\":[[\"0\"],\" Exercises\",[\"1\"]],\"gQYPDg\":[\"−\",[\"restTimerIncrement\"],\"s\"],\"gTdjGc\":[\"Failed to delete the workout. Please try again.\"],\"giOl9F\":[\"Thigh (R)\"],\"gkn1WJ\":[\"Exercise Already Added\"],\"gloTI5\":[\"Tap any accepted friend in your Friends list to open their profile. Their profile shows the plans, standalone workouts, and custom exercises they have chosen to share. Tap Import on any item to add it directly to your own library. Imported plans and workouts are saved as new copies that you can edit freely without affecting the original. Imported custom exercises are added to your exercise library and available immediately when building workouts.\"],\"gzBfh2\":[\"No Sets Available\"],\"h-DKuf\":[\"vs. last \\\"\",[\"0\"],\"\\\"\"],\"h2ALJf\":[\"glutes\"],\"h69WC6\":[\"Sent\"],\"h7CU4q\":[\"How did that feel?\"],\"hBjQ0O\":[[\"0\",\"plural\",{\"one\":[\"#\",\" workout\"],\"other\":[\"#\",\" workouts\"]}]],\"hF_t4W\":[\"Volume (\",[\"volumeUnit\"],\")\"],\"hLONcx\":[\"Backup and restore\"],\"hPXEuO\":[\"Paired with \",[\"0\"]],\"hXzOVo\":[\"Next\"],\"hnJ2UC\":[\"brachialis\"],\"hnlGzG\":[\"Skip for now\"],\"hnrFBk\":[\"Reminder days\"],\"hp8OtS\":[\"Added\"],\"hpsdvR\":[\"\\n📋 New: View Workout Details from the Home Screen!\\n\\nYou can now tap any recent workout on the home screen to view its full details. Each workout and set overview also has a new details button for quick access to exercise information.\\n\"],\"hsoeHo\":[\"Workout Details\"],\"hty0d5\":[\"Monday\"],\"hupMcg\":[\"Remove this friend? They will no longer be able to see your shared content.\"],\"hvfche\":[[\"scheduledCount\",\"plural\",{\"one\":[\"#\",\" day/week\"],\"other\":[\"#\",\" days/week\"]}]],\"i-mS1s\":[\"Previously shared data always remains visible to your friends until you delete it below.\"],\"i-tNaY\":[\"Assistance/Reps\"],\"i09UfG\":[\"Equipment:\"],\"i0qMbr\":[\"Home\"],\"i4Vk1Q\":[\"Active Plan Exercises\"],\"i6f8rt\":[\"Starting Workout...\"],\"iGokZG\":[\"Cable load increment\"],\"iHjmbB\":[\"Added to my plans\"],\"iHmyze\":[\"Exercises\"],\"iO73Kk\":[\"You can share plans, standalone workouts, custom exercises, body measurements, and strength PRs with your friends. All five categories have a global toggle in Privacy Settings, found in the Account section of Settings. Enabling the global toggle for a category shares all items in that category and syncs new data automatically whenever it changes. Plans and standalone workouts also have an individual Share toggle on each item's overview screen, so you can publish specific plans or workouts without sharing everything. A cloud icon on the plan or workout card confirms it is currently published. To remove shared data, disable the toggle in Privacy Settings and tap Delete Shared Data for that category. You can also delete all shared data for every category from the same screen.\"],\"iQyKX1\":[\"You chose to keep it steady. Hold this load.\"],\"iV1Jat\":[\"Are you sure you want to delete this set?\"],\"iYfCFU\":[\"Show onboarding on home screen\"],\"i_48Se\":[\"Active Plan: \",[\"0\"]],\"i_nB8P\":[\"No schedule set\"],\"ifRQL2\":[\"Drop set, \"],\"ikOJPT\":[\"shins\"],\"irLwtB\":[\"Training Plan\"],\"irrqfe\":[\"Custom Metrics\"],\"iuwbqi\":[\"Failed to save workout. Please try again.\"],\"ivpCYv\":[\"Discard Changes?\"],\"j-MPXl\":[\"Backup & Restore\"],\"jDTG0T\":[\"Progression Suggestions\"],\"jDh_CH\":[\"Plans are structured training programmes made up of workouts. To create one, go to the Plans tab, tap New Plan, give it a name, and pick a cover image. Add workouts to the plan, then add exercises to each workout with target sets and reps. Use the up/down arrow buttons on a workout card to reorder it, or the X button to remove it; both are in the top right of the card. Assign workouts to specific days of the week in the schedule editor: tap any day to pick a workout or leave it as a rest day, and use the auto-suggest button to space them out evenly. Once your plan is ready, open it and tap Activate. You can also add notes to a plan from the plan overview screen. Each workout card shows an estimated duration alongside the exercise count so you can gauge the session length at a glance. Use the view icons next to the \\\"Your Training Plans\\\" heading to switch between Carousel, List, and Grid layouts; your chosen view is saved automatically. Your progress in the plan editor is automatically saved as a draft, so if you leave mid-edit you will be prompted to continue where you left off or discard and start from the last saved state.\"],\"jYjrmQ\":[\"Last backup: \",[\"0\"]],\"jbq7j2\":[\"Decline\"],\"jfzZZ0\":[\"Skip login\"],\"jpVuia\":[\"Save Changes to Workout?\"],\"jxTU3u\":[\"stepmill machine\"],\"jzJENZ\":[\"Track Your Progress\"],\"k4kpgL\":[\"Welcome to MuscleQuest, your personal strength training companion. Use this guide to discover the features and get the most from your training.\"],\"k5alGf\":[\"No workouts shared yet\"],\"k7Oi68\":[\"upper legs\"],\"kDJ_Ja\":[\"Solid session. Keep this load.\"],\"kFoQmI\":[\"abductors\"],\"kILzHz\":[\"Add (\",[\"0\"],\")\"],\"kQe_xM\":[\"Pain reported. Keeping load unchanged until you feel better.\"],\"kSi1ha\":[\"+\",[\"suggestedWeight\"],[\"unit\"],\" suggested\"],\"kdwbaT\":[\"Skip all\"],\"kf4tdd\":[\"Select tracking type\"],\"kfxr8q\":[\"\\n📊 New: Workout Summary!\\n\\nAfter completing a workout, you'll now see a full summary of your session: total duration, sets, and volume, plus a comparison against your previous session. Tap any exercise to expand its individual sets and weights.\\n\"],\"kg0oKA\":[\" (to Failure)\"],\"kkDQ8m\":[\"Thursday\"],\"konUZ1\":[\"Default rest time\"],\"kvpjYu\":[\"Enter exercise name\"],\"l1P93s\":[\"Enter weight per dumbbell/cable, not total\"],\"l75CjT\":[\"Yes\"],\"lWy5a1\":[\"Plans\"],\"lY9GM0\":[\"Target muscle is required.\"],\"lkz6PL\":[\"Duration\"],\"llGZy3\":[\"No exercises tracked yet. Tap + Add to start.\"],\"loRbvf\":[\"Go to home screen!\"],\"m0YANP\":[\"You can hide this onboarding screen at any time from the settings page in the appearance section. If you ever want to revisit the onboarding, you can enable it again from the same settings page.\"],\"m16xKo\":[\"Add\"],\"m2QQkt\":[\"Added to my workouts\"],\"m66_4D\":[\"Tracking Type\"],\"mAoTHw\":[\"Some images failed to delete. Failed exercise IDs: \",[\"0\"]],\"mDmPnX\":[\"Per week (avg)\"],\"mEQ95z\":[\"Failed to save the image. Please try again.\"],\"mF1US0\":[\"Always use most recent exercise history\"],\"mFQ4KK\":[\"Double the weight for volume when the setting is enabled\"],\"mK5j7_\":[\"\\n🔃 New: Sort the Exercise Library!\\n\\nThe exercise library now has sort chips so you can find exercises faster. Sort by Default, Active Plan, Recent, or Frequent to see the exercises most relevant to you at the top.\\n\"],\"mRTnNi\":[\"Paired implements\"],\"mSit7t\":[\"Failed to fetch data. Please try again.\"],\"mSj_dN\":[[\"0\",\"plural\",{\"one\":[\"+\",\"#\",\" more\"],\"other\":[\"+\",\"#\",\" more\"]}]],\"mT57-Q\":[\"Go to Settings\"],\"mob_am\":[\"Fr\"],\"mwX_w0\":[\"Change Image\"],\"mzI_c-\":[\"Download\"],\"n00ykB\":[\"Your workouts\"],\"n1BXGc\":[\"Training Split (by sets)\"],\"n1ekoW\":[\"Sign In\"],\"nAEGxm\":[\"Yes, increase the challenge\"],\"nJSX83\":[\"Workout reminders\"],\"nO6sra\":[[\"0\"],\": \",[\"best\"],\" \",[\"best\",\"plural\",{\"one\":[\"rep\"],\"other\":[\"reps\"]}],\" (+\",[\"delta\"],\", \",[\"pctStr\"],\")\"],\"nPGn3W\":[\"Warm-up, \"],\"nkkWxK\":[\"Jumpstart your fitness journey with professionally designed training plans. Choose from a variety of options tailored to different goals and experience levels. \"],\"nmdLhD\":[\"Reps: \",[\"repRange\"]],\"nmvpnF\":[\"No custom exercises shared yet\"],\"o2XlZw\":[\"Are you sure you want to delete this workout? This action cannot be undone.\"],\"oB9lvM\":[\"Exclude warmup sets from stats\"],\"oOHOWH\":[\"\\n✨ New: Workout Session Animations!\\n\\nNavigating between sets now features smooth slide transitions. Swipe left or right to move between sets, or use the pre-existing arrow buttons for the same effect.\\n\"],\"oOYj_W\":[\"Failed to load workouts\"],\"oRTTfk\":[\"The Stats tab shows total workouts, total volume, total time, and average session duration over a selectable time range, with a period-over-period delta for each metric. Charts display weekly volume and your training split by body part. Browse your full workout history and tap any session to review every set in detail, including weights, reps, time, or distance. You can edit or delete completed workouts from the history details screen. Tap the calendar icon in the Workout History section to open a calendar view: days with workouts are highlighted with a yellow circle, and tapping any day shows the workouts logged on that date.\"],\"oRvy2V\":[\"Exercise Tracking\"],\"oXsjxN\":[\"Calf (L)\"],\"oYZpj8\":[\"• Challenges and badges *\"],\"ocEDZS\":[\"Remove a set\"],\"oeF-HP\":[\"Failed to sign in. Please try again.\"],\"oeeBm6\":[\"\\n🔔 New: In-App Update Notifications!\\n\\nA new update modal now appears when an over-the-air update is available, so you always know when improvements have been downloaded and are ready to apply.\\n\"],\"ofVE0I\":[\"Clears the search field\"],\"oiHVLP\":[\"Remove Superset\"],\"oqKRAn\":[\"Each set can be flagged as a Warm-up, Drop Set, To Failure, or any combination of these. The badge shown next to a set displays its current type. To change the type during a session, tap the menu (⋮) and toggle the relevant option on or off. When building a plan, use the checkboxes in the set editor; tap Add Warm-up to insert a dedicated warm-up set at the top of the list. Warm-up sets are visually grouped and separated from working sets, and the Apply to All option in the edit modal only affects sets of the same type. Warm-up sets can be excluded from volume and stats calculations in Settings.\"],\"oqUOKk\":[\"Drop set\"],\"osILGh\":[\"Target Distance (\",[\"distanceUnit\"],\")\"],\"os_BJP\":[\"No measurements shared yet\"],\"ovBPCi\":[\"Default\"],\"ovGl86\":[\"(to Failure) \"],\"p5nYkr\":[\"View All\"],\"p72uBF\":[\"No training plans found\"],\"p8F9k_\":[\"Neck\"],\"pB7xVW\":[\"Strength PRs\"],\"pBGx0B\":[\"\\n🗂️ New: Plan View Options!\\n\\nThe Plans screen now has three display modes. Use the icons next to the \\\"Your Training Plans\\\" heading to switch between Carousel, List, and Grid view. Your preferred layout is saved automatically.\\n\"],\"pE7tOx\":[\"Active Workout\"],\"pIX6X7\":[\"MuscleQuest's Instagram\"],\"pIuJtP\":[\"Workout not found.\"],\"pY_gY7\":[\"Rep PR\"],\"p_C-3G\":[\"Mild soreness\"],\"pbzA-s\":[\"Optional description\"],\"pfXEaj\":[\"Body Weight\"],\"pkD36F\":[\"Are you sure you want to delete \\\"\",[\"0\"],\"\\\"?\"],\"poLmqL\":[\"Choose from Device\"],\"psxXnW\":[\"Sign in with Google in Settings to enable cloud backups of all your workout data. Tap Backup at any time to save a snapshot; the date of your last backup is shown beneath the button. Tap Restore to download and apply your latest backup; confirm the prompt and the app will reload with your restored data. Your backups are stored securely and are tied to your Google account. If you switch devices or reinstall the app, simply sign in with the same Google account and tap Restore to get your data back.\"],\"pvW0MQ\":[\"Complete Set\"],\"pwfNCc\":[\"+\",[\"restTimerIncrement\"],\"s\"],\"pz0gzh\":[\"Hide metric\"],\"pzA-xG\":[\"Capture important cues, reminders, and personal insights for your exercises, workouts, and training plans. Stay focused and refine your technique with custom notes throughout your fitness journey. Notes save automatically when you're done editing.\"],\"q3pTrs\":[\"All images deleted successfully!\"],\"qIATCE\":[\"\\n📋 Improved: Smarter History Pre-Fill During Workouts!\\n\\nSet fields now pre-fill more intelligently. If an exercise has no history in the current workout, it falls back to the most recent time you performed it in any session, so you always start with a useful reference.\\n\\nA new setting in the Workout section lets you always use the most recent history across all workouts, regardless of which routine it came from.\\n\"],\"qJb6G2\":[\"Try Again\"],\"qP4pOu\":[\"Share body measurements with friends\"],\"qQ5ALI\":[\"Save Changes to Plan?\"],\"qQ8Xkc\":[\"Machine load increment\"],\"qQLn75\":[\"Select body part\"],\"qUSLnH\":[\"Enter description\"],\"qZMNNX\":[\"Upper Arm (R)\"],\"qaT7mT\":[\"You'll lose what you've entered so far.\"],\"qdLLeB\":[\"Recent Workouts\"],\"qdalvN\":[\"Deload week — comparison paused.\"],\"qeygIa\":[\"We\"],\"qlKdB2\":[\"No, keep it the same\"],\"qtNMEu\":[\"quads\"],\"qvcKXF\":[\"Great work today!\"],\"qvolLq\":[\"Mass\"],\"rCROTr\":[\"Buy me a coffee\"],\"rLgPvm\":[\"Backup\"],\"rPj8yN\":[\"Other Exercises\"],\"rXJFNV\":[\"Share standalone workouts with friends\"],\"rZzMre\":[\"upper arms\"],\"rickIy\":[\"Saving Workout...\"],\"rjGI_Q\":[\"Privacy\"],\"rlNJuG\":[\"Entry Detail\"],\"rtypiF\":[\"🎉 What's New\"],\"rzjsxH\":[\"Time (Minutes:Seconds)\"],\"s53UX_\":[\"Volume per Week (\",[\"volumeUnit\"],\")\"],\"s6qW4K\":[\"Tracking type cannot be changed after creation.\"],\"sAkBSh\":[[\"0\",\"plural\",{\"one\":[\"#\",\" exercise\"],\"other\":[\"#\",\" exercises\"]}]],\"sHe-bW\":[\"Give it a name to save it as a reusable workout.\"],\"sOXSnZ\":[\"Exercise Details\"],\"sRh2_9\":[\"Your training plans\"],\"scHKm4\":[\"Standalone Workouts\"],\"sey42b\":[\"Workout Complete!\"],\"slcKOz\":[\"To enable workout reminders, grant notification permissions in your device settings.\"],\"spvawa\":[\"Exclude deload workouts from exercise stats\"],\"t-VWgS\":[\"Workouts per Week\"],\"t1WtPm\":[\"vs PR\"],\"t5tvzw\":[\"Enables a per-plan publish toggle.\"],\"t7OD9_\":[\"traps\"],\"t9rBTs\":[[\"0\"],\": \",[\"best\"],[\"unit\"],\" (+\",[\"delta\"],[\"unit\"],\", \",[\"pctStr\"],\")\"],\"tBmnPU\":[\"Friends\"],\"tCHU1b\":[\"Body Parts\"],\"tLdxsV\":[\"MuscleQuest.app\"],\"tXYsgg\":[\"Each measurement entry you record is shared automatically.\"],\"tXkhj_\":[\"Start\"],\"t_YqKh\":[\"Remove\"],\"tcZ16z\":[\"\\n💾 New: Save Workout Changes Back to Your Plan!\\n\\nWhen you finish a session where you added, removed, or reordered exercises, or sets, you'll be prompted to save those changes back to the original plan or standalone workout, keeping your training up to date automatically.\\n\"],\"tfDRzk\":[\"Save\"],\"tj-hng\":[\"wrists\"],\"tlcz2i\":[\"No data for this period.\"],\"twA2hZ\":[\"legs\"],\"tyb5gZ\":[\"Rest Time (Minutes:Seconds)\"],\"u0F1Ey\":[\"Th\"],\"u0Vng2\":[\"Still very sore\"],\"u16ECS\":[\"Download Complete\"],\"uGkCJQ\":[\"ez barbell\"],\"uIVkKI\":[\"Signing In\"],\"uP80lb\":[\"Update Ready\"],\"ue_JxE\":[\"Sets Overview\"],\"ufHAsd\":[\"Training Plan Name\"],\"uyJsf6\":[\"About\"],\"v2e7py\":[\"Create a Plan\"],\"v39wLo\":[\"Resume\"],\"v67n_r\":[\"Enable recurring workout reminders from Settings. Select the days of the week you want to be reminded using the day chips and choose a time. You will receive a notification at that time on each selected day. Notification permission must be granted for reminders to work.\"],\"vCrBBg\":[\"Take full control of your training by designing your own personalised plan. Select exercises, set rep ranges, rest times, and more to create a plan that aligns perfectly with your fitness goals.\"],\"vFte8a\":[\"Create Superset\"],\"vLSd93\":[\"Set Types\"],\"vLyv1R\":[\"Hide\"],\"vPWLpz\":[\"Units of measurement\"],\"vV1rrV\":[[\"suggestedRepsMin\"],\" reps suggested\"],\"vbOlQu\":[\"Failed to pick image. Please try again.\"],\"vbfDgJ\":[\"No workouts yet\"],\"vcpc5o\":[\"Close menu\"],\"vmatEA\":[\"Loading data, please wait...\"],\"vq2WxD\":[\"Tue\"],\"vqV9pV\":[\"New Plan\"],\"vyQFtJ\":[[\"0\"],\" Complete!\"],\"w55mIe\":[\"active plan\"],\"w95UZr\":[\"best \",[\"maxDist\"],[\"distanceUnit\"]],\"wBAK8Q\":[\"Body part is required.\"],\"wL3cK8\":[\"Latest\"],\"wL7wrB\":[\"Weight increment\"],\"wUwyC0\":[\"Streak\"],\"wYwS57\":[\"Customise Your Settings\"],\"wckWOP\":[\"Manage\"],\"wgbq86\":[\"Restart Failed\"],\"wiIJoN\":[\"Plan Details\"],\"wpLp4M\":[\"Assistance\"],\"wvxWx2\":[\"trapezius\"],\"wxKcF0\":[\"About the developer\"],\"x5LlnE\":[\"Stats Options\"],\"xGVfLh\":[\"Continue\"],\"xM_hqb\":[\"assistance \"],\"xMidTh\":[\"All body parts\"],\"xRGBk4\":[\"Explore Ready-Made Plans\"],\"xVhQZV\":[\"Fri\"],\"xYxQCZ\":[[\"0\"],\" \",[\"1\"]],\"xx7Wjz\":[\"Failed to load exercise details.\"],\"y04OSh\":[\"Workout History\"],\"y3CwcG\":[\"best \",[\"maxTime\"],\"s\"],\"y8le-Z\":[\"Training\"],\"yAeHP4\":[\"No data available.\"],\"yBSiRY\":[\"Deload Week\"],\"yKu_3Y\":[\"Restore\"],\"yUWaVv\":[\"elliptical machine\"],\"yWCES-\":[\"Secondary muscles:\"],\"y_0uwd\":[\"Yesterday\"],\"y_f0Ik\":[\"Opens in your browser\"],\"yf16RU\":[\"Warm-up\"],\"ygCKqB\":[\"Stop\"],\"yhrNcC\":[\"Image Save Error\"],\"ykve2U\":[\"Add Set\"],\"ysv0WA\":[\"Added to my exercises\"],\"yu1K_Z\":[\"No Sets\"],\"z1-0FW\":[\"Track your workouts, monitor progress, and achieve your fitness goals. MuscleQuest makes your fitness journey simple and effective.\\n\\nSwipe through the introduction cards to learn more about the app.\"],\"z44QLk\":[\"Restore Backup\"],\"z5uobd\":[\"Tap the star icon in the top-right corner of any exercise info screen to mark it as a favourite. Favourited exercises appear at the top of the exercise picker when building or editing workouts, so the exercises you use most are always within quick reach.\"],\"zAhZMD\":[\"• Share your training plans with others *\"],\"zAt78k\":[\"Rest Timer\"],\"zDq2cZ\":[\"Waist\"],\"zEHmq8\":[\"The Plans tab includes a library of ready-made training programmes you can start immediately. Scroll past Your Training Plans to find the Premade Plans section. Tap any programme to preview its workouts and schedule, then tap Activate to make it your active plan. You can edit a premade plan to adjust exercises, sets, or the weekly schedule. This will create a copy of the premade plan that you can modify without affecting the original, so you can always return to the default version if needed.\"],\"zIFP3N\":[\"Set your weekly workout goal and enter your body weight to get accurate stats and recommendations. You can also adjust your weight increment preferences, choose your preferred units, and much more.\"],\"zNnnyF\":[\"calves\"],\"zOwYV3\":[\"You modified this workout. Save those changes for future sessions?\"],\"zeFzVj\":[\"Enable to automatically share strength PRs after each workout.\"],\"zga9sT\":[\"OK\"],\"zhIkkH\":[\"Goal: \",[\"goalLabel\"],[\"0\"]],\"zsaR7t\":[\"Equipment & Tracking\"],\"zt6jiv\":[\"No progression tracking for this exercise type.\"],\"zuwyEJ\":[\"Add exercises to get started\"],\"zzDlyQ\":[\"Success\"]}")}; \ No newline at end of file diff --git a/locales/en/messages.po b/locales/en/messages.po index afef3052..d809e862 100644 --- a/locales/en/messages.po +++ b/locales/en/messages.po @@ -164,6 +164,28 @@ msgstr "" "Fixed a bug where all buttons (increment/decrement, next/previous set, complete set) would stop working after completing a set. Also fixed an error in the edit set modal. Set transitions now happen instantly for a smoother workout flow.\n" "" +#: constants/WhatsNew.ts:305 +msgid "" +"\n" +"👥 New: Friends & Social Sharing!\n" +"\n" +"Add friends by searching for their username from the Friends tab in the menu. Send a request, and once accepted you can browse each other's shared content. A badge on the Friends menu item shows pending incoming requests.\n" +"\n" +"Share your plans, standalone workouts, custom exercises, body measurements, and strength PRs by toggling Share in the relevant screen or from Privacy Settings in the Account section of Settings. Shared content syncs automatically whenever it changes, and a cloud icon on plan and workout cards shows what is currently published. You can delete all shared data for any category from Privacy Settings at any time.\n" +"\n" +"Tap any accepted friend's name to open their profile and import their plans, standalone workouts, or custom exercises directly into your own library.\n" +"" +msgstr "" +"\n" +"👥 New: Friends & Social Sharing!\n" +"\n" +"Add friends by searching for their username from the Friends tab in the menu. Send a request, and once accepted you can browse each other's shared content. A badge on the Friends menu item shows pending incoming requests.\n" +"\n" +"Share your plans, standalone workouts, custom exercises, body measurements, and strength PRs by toggling Share in the relevant screen or from Privacy Settings in the Account section of Settings. Shared content syncs automatically whenever it changes, and a cloud icon on plan and workout cards shows what is currently published. You can delete all shared data for any category from Privacy Settings at any time.\n" +"\n" +"Tap any accepted friend's name to open their profile and import their plans, standalone workouts, or custom exercises directly into your own library.\n" +"" + #: constants/WhatsNew.ts:204 msgid "" "\n" @@ -223,7 +245,7 @@ msgstr "" #: constants/WhatsNew.ts:293 msgid "" "\n" -"📈 New: Adaptive Progression!\n" +"📈 Beta: Adaptive Progression!\n" "\n" "MuscleQuest can now suggest when to increase your weight or reps based on how your sessions feel. After each exercise, answer two quick questions about effort and pain. Once you have reported the same signal for two sessions in a row, the app suggests a change. All suggestions appear in the Workout Summary screen, where you can accept or dismiss each one individually. Accepted suggestions are pre-filled into your next session automatically.\n" "\n" @@ -233,7 +255,7 @@ msgid "" "" msgstr "" "\n" -"📈 New: Adaptive Progression!\n" +"📈 Beta: Adaptive Progression!\n" "\n" "MuscleQuest can now suggest when to increase your weight or reps based on how your sessions feel. After each exercise, answer two quick questions about effort and pain. Once you have reported the same signal for two sessions in a row, the app suggests a change. All suggestions appear in the Workout Summary screen, where you can accept or dismiss each one individually. Accepted suggestions are pre-filled into your next session automatically.\n" "\n" @@ -530,11 +552,11 @@ msgstr "" "The Plans screen now has three display modes. Use the icons next to the \"Your Training Plans\" heading to switch between Carousel, List, and Grid view. Your preferred layout is saved automatically.\n" "" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:179 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:191 msgid " (to Failure)" msgstr " (to Failure)" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:186 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:198 msgid " (to Failure) " msgstr " (to Failure) " @@ -580,7 +602,7 @@ msgid "{0, plural, one {# Set} other {# Sets}}" msgstr "{0, plural, one {# Set} other {# Sets}}" #. placeholder {0}: plan.workouts.length -#: components/TrainingPlanListItem.tsx:60 +#: components/TrainingPlanListItem.tsx:71 msgid "{0, plural, one {# workout} other {# workouts}}" msgstr "{0, plural, one {# workout} other {# workouts}}" @@ -596,13 +618,13 @@ msgstr "{0, plural, one {set} other {sets}}" #. placeholder {0}: settings?.weightIncrement #. placeholder {1}: settings?.weightUnit -#: app/(app)/settings.tsx:758 +#: app/(app)/settings.tsx:794 msgid "{0} {1}" msgstr "{0} {1}" #. placeholder {0}: settings?.bodyWeight #. placeholder {1}: settings?.weightUnit -#: app/(app)/settings.tsx:583 +#: app/(app)/settings.tsx:619 msgid "{0} {1} (used for assisted exercises)" msgstr "{0} {1} (used for assisted exercises)" @@ -619,7 +641,7 @@ msgid "{0} Complete!" msgstr "{0} Complete!" #. placeholder {0}: settings?.weeklyGoal -#: app/(app)/settings.tsx:561 +#: app/(app)/settings.tsx:597 msgid "{0} days per week" msgstr "{0} days per week" @@ -627,7 +649,7 @@ msgstr "{0} days per week" #. placeholder {0}: workout.exercises.length #. placeholder {1}: estimate ? ` · ~${formatDurationEstimate(estimate)}` : "" #. placeholder {1}: estimate ? ` · ~${formatDurationEstimateCompact(estimate)}` : "" -#: app/(app)/(tabs)/(plans)/overview.tsx:78 +#: app/(app)/(tabs)/(plans)/overview.tsx:82 #: app/(app)/(tabs)/index.tsx:57 msgid "{0} Exercises{1}" msgstr "{0} Exercises{1}" @@ -649,18 +671,18 @@ msgstr "{0} reps" #. placeholder {0}: settings?.restTimerIncrement #. placeholder {0}: settings?.timerCountdown || "5" -#: app/(app)/settings.tsx:786 -#: app/(app)/settings.tsx:812 +#: app/(app)/settings.tsx:822 +#: app/(app)/settings.tsx:848 msgid "{0} seconds" msgstr "{0} seconds" #. placeholder {0}: settings?.defaultSets -#: app/(app)/settings.tsx:1369 +#: app/(app)/settings.tsx:1408 msgid "{0} sets" msgstr "{0} sets" #. placeholder {0}: item.sets.length -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:176 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:188 #: components/WorkoutDetailsScreen.tsx:141 msgid "{0} Sets" msgstr "{0} Sets" @@ -785,7 +807,7 @@ msgid "+ Add" msgstr "+ Add" #: app/(app)/(workout)/index.tsx:1153 -#: app/(app)/(workout)/workout-session.tsx:1559 +#: app/(app)/(workout)/workout-session.tsx:1591 msgid "+{restTimerIncrement}s" msgstr "+{restTimerIncrement}s" @@ -794,7 +816,7 @@ msgid "+{suggestedWeight}{unit} suggested" msgstr "+{suggestedWeight}{unit} suggested" #: app/(app)/(workout)/index.tsx:1142 -#: app/(app)/(workout)/workout-session.tsx:1548 +#: app/(app)/(workout)/workout-session.tsx:1580 msgid "−{restTimerIncrement}s" msgstr "−{restTimerIncrement}s" @@ -835,7 +857,7 @@ msgstr "A deload is a planned recovery week where you train at reduced intensity msgid "A new version has been downloaded. Tap the button below to restart and apply the update." msgstr "A new version has been downloaded. Tap the button below to restart and apply the update." -#: app/_layout.tsx:91 +#: app/_layout.tsx:97 msgid "A render error has occurred. Press the button to reload." msgstr "A render error has occurred. Press the button to reload." @@ -843,15 +865,15 @@ msgstr "A render error has occurred. Press the button to reload." msgid "abductors" msgstr "abductors" -#: app/(app)/settings.tsx:1560 +#: app/(app)/settings.tsx:1873 msgid "About" msgstr "About" -#: components/ExerciseFeedbackSheet.tsx:37 +#: components/ExerciseFeedbackSheet.tsx:38 msgid "About right" msgstr "About right" -#: app/(app)/settings.tsx:1649 +#: app/(app)/settings.tsx:1962 msgid "About the developer" msgstr "About the developer" @@ -859,6 +881,7 @@ msgstr "About the developer" msgid "abs" msgstr "abs" +#: components/friends/FriendRequestItem.tsx:47 #: components/ProgressionSummaryCard.tsx:145 msgid "Accept" msgstr "Accept" @@ -867,13 +890,13 @@ msgstr "Accept" msgid "Accept all" msgstr "Accept all" -#: constants/HelpData.ts:164 +#: constants/HelpData.ts:184 msgid "Account" msgstr "Account" -#: app/(app)/(tabs)/(plans)/overview.tsx:222 -#: components/TrainingPlanCard.tsx:80 -#: components/TrainingPlanListItem.tsx:54 +#: app/(app)/(tabs)/(plans)/overview.tsx:233 +#: components/TrainingPlanCard.tsx:83 +#: components/TrainingPlanListItem.tsx:56 msgid "Active" msgstr "Active" @@ -898,16 +921,23 @@ msgstr "Active Plan: {0}" msgid "Active Workout" msgstr "Active Workout" -#: app/(app)/settings.tsx:1076 #: constants/HelpData.ts:64 msgid "Adaptive Progression" msgstr "Adaptive Progression" +#: app/(app)/settings.tsx:1112 +msgid "Adaptive Progression (beta)" +msgstr "Adaptive Progression (beta)" + #: constants/HelpData.ts:69 msgid "Adaptive Progression analyses your effort feedback over consecutive sessions and suggests when to increase your weight, reps, or sets. Enable it in Settings under Adaptive Progression. Once on, a short feedback prompt appears after each exercise in plan-based workouts. The engine requires two sessions with the same signal before recommending an upward change, filtering out one-off easy days and ensuring consistent performance before suggesting an increase. Pain or failed sets act immediately regardless of your session history. A suggestion is never applied to your workout without your explicit approval. You can also configure your preferred load increment per equipment category in the same section of Settings, for example 2.5 kg for barbell exercises and 2.0 kg for dumbbells." msgstr "Adaptive Progression analyses your effort feedback over consecutive sessions and suggests when to increase your weight, reps, or sets. Enable it in Settings under Adaptive Progression. Once on, a short feedback prompt appears after each exercise in plan-based workouts. The engine requires two sessions with the same signal before recommending an upward change, filtering out one-off easy days and ensuring consistent performance before suggesting an increase. Pain or failed sets act immediately regardless of your session history. A suggestion is never applied to your workout without your explicit approval. You can also configure your preferred load increment per equipment category in the same section of Settings, for example 2.5 kg for barbell exercises and 2.0 kg for dumbbells." #: app/(app)/(tabs)/(stats)/measurements-manage.tsx:167 +#: app/(app)/friend-profile.tsx:218 +#: app/(app)/friend-profile.tsx:310 +#: app/(app)/friend-profile.tsx:397 +#: app/(app)/friends.tsx:291 #: components/Notes.tsx:87 msgid "Add" msgstr "Add" @@ -943,7 +973,7 @@ msgstr "Add Exercise" msgid "Add exercises to get started" msgstr "Add exercises to get started" -#: app/(app)/custom-exercise.tsx:324 +#: app/(app)/custom-exercise.tsx:350 msgid "Add Image" msgstr "Add Image" @@ -956,6 +986,18 @@ msgstr "Add Personal Notes" msgid "Add Set" msgstr "Add Set" +#: app/(app)/friend-exercise.tsx:161 +msgid "Add to my exercises" +msgstr "Add to my exercises" + +#: app/(app)/friend-plan.tsx:177 +msgid "Add to my plans" +msgstr "Add to my plans" + +#: app/(app)/friend-workout.tsx:136 +msgid "Add to my workouts" +msgstr "Add to my workouts" + #: app/(app)/(create-plan)/sets-overview.tsx:257 msgid "Add Warm-up" msgstr "Add Warm-up" @@ -968,6 +1010,28 @@ msgstr "Add Weight" msgid "Add Workout" msgstr "Add Workout" +#: app/(app)/friend-profile.tsx:216 +#: app/(app)/friend-profile.tsx:308 +#: app/(app)/friend-profile.tsx:395 +msgid "Added" +msgstr "Added" + +#: app/(app)/friend-exercise.tsx:159 +msgid "Added to my exercises" +msgstr "Added to my exercises" + +#: app/(app)/friend-plan.tsx:175 +msgid "Added to my plans" +msgstr "Added to my plans" + +#: app/(app)/friend-workout.tsx:134 +msgid "Added to my workouts" +msgstr "Added to my workouts" + +#: constants/HelpData.ts:168 +msgid "Adding Friends" +msgstr "Adding Friends" + #: constants/dbTranslations.ts:22 msgid "adductors" msgstr "adductors" @@ -1002,6 +1066,10 @@ msgstr "All images deleted successfully!" msgid "All images downloaded successfully!" msgstr "All images downloaded successfully!" +#: app/(app)/settings.tsx:98 +msgid "All shared data has been removed." +msgstr "All shared data has been removed." + #: components/FilterRow.tsx:62 #: components/FilterRow.tsx:114 #: components/FilterRow.tsx:204 @@ -1016,7 +1084,7 @@ msgstr "All Time" msgid "All-time PR" msgstr "All-time PR" -#: app/(app)/settings.tsx:974 +#: app/(app)/settings.tsx:1010 msgid "Always use most recent exercise history" msgstr "Always use most recent exercise history" @@ -1036,11 +1104,11 @@ msgstr "ankle stabilizers" msgid "ankles" msgstr "ankles" -#: components/ExerciseFeedbackSheet.tsx:191 +#: components/ExerciseFeedbackSheet.tsx:205 msgid "Any pain or form breakdown?" msgstr "Any pain or form breakdown?" -#: app/(app)/settings.tsx:1440 +#: app/(app)/settings.tsx:1479 msgid "Appearance" msgstr "Appearance" @@ -1054,7 +1122,7 @@ msgid "Are you sure you want to cancel and delete this workout?" msgstr "Are you sure you want to cancel and delete this workout?" #. placeholder {0}: workout?.name ?? "" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:81 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:93 msgid "Are you sure you want to delete \"{0}\"?" msgstr "Are you sure you want to delete \"{0}\"?" @@ -1070,11 +1138,11 @@ msgstr "Are you sure you want to delete this exercise?" msgid "Are you sure you want to delete this measurement entry?" msgstr "Are you sure you want to delete this measurement entry?" -#: app/(app)/(tabs)/(plans)/overview.tsx:118 +#: app/(app)/(tabs)/(plans)/overview.tsx:129 msgid "Are you sure you want to delete this plan?" msgstr "Are you sure you want to delete this plan?" -#: app/(app)/(workout)/workout-session.tsx:710 +#: app/(app)/(workout)/workout-session.tsx:717 msgid "Are you sure you want to delete this set?" msgstr "Are you sure you want to delete this set?" @@ -1099,7 +1167,7 @@ msgstr "Are you sure you want to remove this workout?" msgid "Are you sure you want to restart this workout?" msgstr "Are you sure you want to restart this workout?" -#: app/(app)/settings.tsx:460 +#: app/(app)/settings.tsx:496 msgid "Are you sure you want to restore the backup?" msgstr "Are you sure you want to restore the backup?" @@ -1128,7 +1196,7 @@ msgstr "Assistance" msgid "assistance " msgstr "assistance " -#: app/(app)/custom-exercise.tsx:63 +#: app/(app)/custom-exercise.tsx:68 msgid "Assistance/Reps" msgstr "Assistance/Reps" @@ -1141,15 +1209,15 @@ msgstr "Avg Duration" msgid "back" msgstr "back" -#: app/(app)/settings.tsx:622 +#: app/(app)/settings.tsx:658 msgid "Backup" msgstr "Backup" -#: constants/HelpData.ts:173 +#: constants/HelpData.ts:193 msgid "Backup & Restore" msgstr "Backup & Restore" -#: app/(app)/settings.tsx:600 +#: app/(app)/settings.tsx:636 msgid "Backup and restore" msgstr "Backup and restore" @@ -1157,11 +1225,11 @@ msgstr "Backup and restore" msgid "barbell" msgstr "barbell" -#: app/(app)/settings.tsx:1122 +#: app/(app)/settings.tsx:1160 msgid "Barbell load increment" msgstr "Barbell load increment" -#: app/(app)/custom-exercise.tsx:309 +#: app/(app)/custom-exercise.tsx:335 msgid "Basics" msgstr "Basics" @@ -1201,15 +1269,20 @@ msgid "Body Fat" msgstr "Body Fat" #: app/(app)/(tabs)/(stats)/index.tsx:553 +#: app/(app)/friend-profile.tsx:458 #: constants/HelpData.ts:143 msgid "Body Measurements" msgstr "Body Measurements" -#: app/(app)/custom-exercise.tsx:372 +#: app/(app)/friend-exercise.tsx:70 +msgid "Body Part" +msgstr "Body Part" + +#: app/(app)/custom-exercise.tsx:398 msgid "Body Part *" msgstr "Body Part *" -#: app/(app)/custom-exercise.tsx:201 +#: app/(app)/custom-exercise.tsx:206 msgid "Body part is required." msgstr "Body part is required." @@ -1221,7 +1294,7 @@ msgstr "Body Parts" msgid "body weight" msgstr "body weight" -#: app/(app)/settings.tsx:580 +#: app/(app)/settings.tsx:616 msgid "Body weight" msgstr "Body weight" @@ -1245,15 +1318,15 @@ msgstr "Browse almost 1,000 exercises and filter by body part, target muscle, or msgid "Built-in Metrics" msgstr "Built-in Metrics" -#: app/(app)/settings.tsx:1484 +#: app/(app)/settings.tsx:1523 msgid "Button size during workout" msgstr "Button size during workout" -#: app/(app)/settings.tsx:1596 +#: app/(app)/settings.tsx:1909 msgid "Buy me a coffee" msgstr "Buy me a coffee" -#: components/AppMenu.tsx:202 +#: components/AppMenu.tsx:220 msgid "Buy Me a Coffee" msgstr "Buy Me a Coffee" @@ -1261,7 +1334,7 @@ msgstr "Buy Me a Coffee" msgid "cable" msgstr "cable" -#: app/(app)/settings.tsx:1176 +#: app/(app)/settings.tsx:1214 msgid "Cable load increment" msgstr "Cable load increment" @@ -1280,17 +1353,19 @@ msgstr "calves" #: app/(app)/(create-plan)/create-workout.tsx:174 #: app/(app)/(create-plan)/create.tsx:234 #: app/(app)/(create-plan)/create.tsx:279 -#: app/(app)/(tabs)/(plans)/overview.tsx:121 -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:83 +#: app/(app)/(tabs)/(plans)/overview.tsx:132 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:95 #: app/(app)/(tabs)/(stats)/history-details.tsx:173 #: app/(app)/(tabs)/(stats)/measurements-detail.tsx:118 #: app/(app)/(tabs)/(stats)/measurements-manage.tsx:85 #: app/(app)/(workout)/index.tsx:405 #: app/(app)/(workout)/index.tsx:1007 -#: app/(app)/(workout)/workout-session.tsx:711 -#: app/(app)/settings.tsx:387 -#: app/(app)/settings.tsx:462 +#: app/(app)/(workout)/workout-session.tsx:718 +#: app/(app)/settings.tsx:90 +#: app/(app)/settings.tsx:423 +#: app/(app)/settings.tsx:498 #: components/EditSetModal.tsx:454 +#: components/friends/FriendListItem.tsx:24 #: components/SettingsModal.tsx:282 #: components/WorkoutCard.tsx:87 #: hooks/useImageManagement.ts:25 @@ -1314,11 +1389,11 @@ msgstr "cardio" msgid "cardiovascular system" msgstr "cardiovascular system" -#: app/(app)/custom-exercise.tsx:324 +#: app/(app)/custom-exercise.tsx:350 msgid "Change Image" msgstr "Change Image" -#: app/(app)/settings.tsx:606 +#: app/(app)/settings.tsx:642 msgid "Checking for backups..." msgstr "Checking for backups..." @@ -1343,8 +1418,8 @@ msgstr "Clear search" msgid "Clears the search field" msgstr "Clears the search field" -#: components/AppMenu.tsx:146 -#: components/AppMenu.tsx:168 +#: components/AppMenu.tsx:156 +#: components/AppMenu.tsx:178 msgid "Close menu" msgstr "Close menu" @@ -1382,15 +1457,19 @@ msgstr "Continue Editing?" msgid "core" msgstr "core" -#: components/ExerciseFeedbackSheet.tsx:39 +#: app/(app)/friend-exercise.tsx:143 +msgid "Could not add this exercise. Please try again." +msgstr "Could not add this exercise. Please try again." + +#: components/ExerciseFeedbackSheet.tsx:40 msgid "Couldn't finish all sets" msgstr "Couldn't finish all sets" -#: app/(app)/custom-exercise.tsx:508 +#: app/(app)/custom-exercise.tsx:534 msgid "Count reps ×2 for volume when the setting is enabled" msgstr "Count reps ×2 for volume when the setting is enabled" -#: app/(app)/settings.tsx:1035 +#: app/(app)/settings.tsx:1071 msgid "Counting reps ×2 for these exercises" msgstr "Counting reps ×2 for these exercises" @@ -1403,7 +1482,7 @@ msgid "Create a Plan" msgstr "Create a Plan" #: app/(app)/(create-plan)/exercises.tsx:360 -#: app/(app)/custom-exercise.tsx:71 +#: app/(app)/custom-exercise.tsx:76 msgid "Create Exercise" msgstr "Create Exercise" @@ -1425,10 +1504,15 @@ msgstr "Create Workout" msgid "Create your own exercises from the exercise picker. Give it a name, an optional image, body part, target muscles, secondary muscles, and equipment. Choose a tracking type: weight + reps, time, distance, reps only, or assisted (which factors in your body weight for movements like assisted pull-ups). Toggle Unilateral for single-arm or single-leg exercises; reps can be automatically doubled in your stats. Toggle Paired Implements if you track the weight of one implement rather than the total: for example, if you log 20 kg for one dumbbell, the app counts 40 kg toward your volume." msgstr "Create your own exercises from the exercise picker. Give it a name, an optional image, body part, target muscles, secondary muscles, and equipment. Choose a tracking type: weight + reps, time, distance, reps only, or assisted (which factors in your body weight for movements like assisted pull-ups). Toggle Unilateral for single-arm or single-leg exercises; reps can be automatically doubled in your stats. Toggle Paired Implements if you track the weight of one implement rather than the total: for example, if you log 20 kg for one dumbbell, the app counts 40 kg toward your volume." +#: app/(app)/friend-profile.tsx:326 #: constants/HelpData.ts:113 msgid "Custom Exercises" msgstr "Custom Exercises" +#: app/(app)/settings.tsx:1701 +msgid "Custom exercises you create or edit are shared automatically." +msgstr "Custom exercises you create or edit are shared automatically." + #: app/(app)/(tabs)/(stats)/measurements-manage.tsx:204 msgid "Custom Metrics" msgstr "Custom Metrics" @@ -1437,7 +1521,7 @@ msgstr "Custom Metrics" msgid "Customisation" msgstr "Customisation" -#: app/(app)/(tabs)/(plans)/overview.tsx:306 +#: app/(app)/(tabs)/(plans)/overview.tsx:351 msgid "Customise Plan" msgstr "Customise Plan" @@ -1445,30 +1529,43 @@ msgstr "Customise Plan" msgid "Customise Your Settings" msgstr "Customise Your Settings" +#: components/friends/FriendRequestItem.tsx:56 +msgid "Decline" +msgstr "Decline" + #: components/ExerciseSortChips.tsx:27 msgid "Default" msgstr "Default" -#: app/(app)/settings.tsx:1392 +#: app/(app)/settings.tsx:1431 msgid "Default rest time" msgstr "Default rest time" -#: app/(app)/settings.tsx:1366 +#: app/(app)/settings.tsx:1405 msgid "Default sets" msgstr "Default sets" -#: app/(app)/(tabs)/(plans)/overview.tsx:125 -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:85 +#: app/(app)/(tabs)/(plans)/overview.tsx:136 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:97 #: app/(app)/(tabs)/(stats)/history-details.tsx:175 #: app/(app)/(tabs)/(stats)/measurements-detail.tsx:120 #: app/(app)/(workout)/index.tsx:407 #: app/(app)/(workout)/index.tsx:629 -#: app/(app)/(workout)/workout-session.tsx:713 +#: app/(app)/(workout)/workout-session.tsx:720 +#: app/(app)/settings.tsx:92 #: components/WorkoutCard.tsx:298 #: hooks/useImageManagement.ts:46 msgid "Delete" msgstr "Delete" +#: app/(app)/settings.tsx:1862 +msgid "Delete all shared data" +msgstr "Delete all shared data" + +#: app/(app)/settings.tsx:87 +msgid "Delete all shared data?" +msgstr "Delete all shared data?" + #: hooks/useImageManagement.ts:103 msgid "Delete Complete" msgstr "Delete Complete" @@ -1482,25 +1579,25 @@ msgstr "Delete Entry" msgid "Delete Exercise" msgstr "Delete Exercise" -#: app/(app)/(tabs)/(plans)/overview.tsx:117 +#: app/(app)/(tabs)/(plans)/overview.tsx:128 msgid "Delete Plan" msgstr "Delete Plan" -#: app/(app)/(workout)/workout-session.tsx:710 +#: app/(app)/(workout)/workout-session.tsx:717 #: components/SessionSetInfo.tsx:251 msgid "Delete Set" msgstr "Delete Set" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:80 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:92 #: app/(app)/(tabs)/(stats)/history-details.tsx:170 msgid "Delete Workout" msgstr "Delete Workout" -#: app/(app)/settings.tsx:1427 +#: app/(app)/settings.tsx:1466 msgid "Deleting. Please wait..." msgstr "Deleting. Please wait..." -#: app/(app)/(tabs)/(plans)/overview.tsx:265 +#: app/(app)/(tabs)/(plans)/overview.tsx:276 #: app/(app)/(tabs)/index.tsx:472 #: constants/HelpData.ts:88 msgid "Deload Week" @@ -1518,7 +1615,8 @@ msgstr "deltoids" msgid "delts" msgstr "delts" -#: app/(app)/custom-exercise.tsx:347 +#: app/(app)/custom-exercise.tsx:373 +#: app/(app)/friend-exercise.tsx:109 msgid "Description" msgstr "Description" @@ -1530,19 +1628,19 @@ msgstr "Description:" msgid "Details" msgstr "Details" -#: app/(app)/settings.tsx:831 -#: app/(app)/settings.tsx:856 -#: app/(app)/settings.tsx:881 -#: app/(app)/settings.tsx:904 -#: app/(app)/settings.tsx:929 -#: app/(app)/settings.tsx:954 -#: app/(app)/settings.tsx:1011 -#: app/(app)/settings.tsx:1036 -#: app/(app)/settings.tsx:1061 -#: app/(app)/settings.tsx:1093 -#: app/(app)/settings.tsx:1227 -#: app/(app)/settings.tsx:1258 -#: app/(app)/settings.tsx:1455 +#: app/(app)/settings.tsx:867 +#: app/(app)/settings.tsx:892 +#: app/(app)/settings.tsx:917 +#: app/(app)/settings.tsx:940 +#: app/(app)/settings.tsx:965 +#: app/(app)/settings.tsx:990 +#: app/(app)/settings.tsx:1047 +#: app/(app)/settings.tsx:1072 +#: app/(app)/settings.tsx:1097 +#: app/(app)/settings.tsx:1129 +#: app/(app)/settings.tsx:1265 +#: app/(app)/settings.tsx:1297 +#: app/(app)/settings.tsx:1494 msgid "Disabled" msgstr "Disabled" @@ -1551,7 +1649,7 @@ msgstr "Disabled" #: app/(app)/(workout)/index.tsx:808 #: app/(app)/(workout)/index.tsx:841 #: app/(app)/(workout)/index.tsx:1037 -#: app/(app)/custom-exercise.tsx:85 +#: app/(app)/custom-exercise.tsx:90 msgid "Discard" msgstr "Discard" @@ -1560,7 +1658,7 @@ msgstr "Discard" msgid "Discard Changes" msgstr "Discard Changes" -#: app/(app)/custom-exercise.tsx:80 +#: app/(app)/custom-exercise.tsx:85 msgid "Discard changes?" msgstr "Discard changes?" @@ -1575,12 +1673,12 @@ msgstr "Discard Changes?" msgid "Dismiss" msgstr "Dismiss" -#: app/(app)/(tabs)/(plans)/overview.tsx:320 +#: app/(app)/(tabs)/(plans)/overview.tsx:365 msgid "DISMISS" msgstr "DISMISS" #: app/(app)/(tabs)/(stats)/edit-history.tsx:268 -#: app/(app)/custom-exercise.tsx:66 +#: app/(app)/custom-exercise.tsx:71 msgid "Distance" msgstr "Distance" @@ -1590,21 +1688,22 @@ msgstr "Distance" msgid "Distance ({distanceUnit})" msgstr "Distance ({distanceUnit})" -#: app/(app)/settings.tsx:697 +#: app/(app)/settings.tsx:733 msgid "Distance unit" msgstr "Distance unit" #: app/(app)/(workout)/workout-summary.tsx:656 -#: components/ExerciseFeedbackSheet.tsx:261 +#: app/(app)/settings.tsx:98 +#: components/ExerciseFeedbackSheet.tsx:275 #: components/RecoveryCheckInSheet.tsx:191 msgid "Done" msgstr "Done" -#: app/(app)/custom-exercise.tsx:528 +#: app/(app)/custom-exercise.tsx:554 msgid "Double the weight for volume when the setting is enabled" msgstr "Double the weight for volume when the setting is enabled" -#: app/(app)/settings.tsx:1060 +#: app/(app)/settings.tsx:1096 msgid "Doubling weight for volume calculations" msgstr "Doubling weight for volume calculations" @@ -1612,7 +1711,7 @@ msgstr "Doubling weight for volume calculations" msgid "Download" msgstr "Download" -#: app/(app)/settings.tsx:1409 +#: app/(app)/settings.tsx:1448 msgid "Download all exercise animations" msgstr "Download all exercise animations" @@ -1634,7 +1733,7 @@ msgstr "Download Images" msgid "Downloading Update" msgstr "Downloading Update" -#: app/(app)/settings.tsx:1426 +#: app/(app)/settings.tsx:1465 msgid "Downloading. Please wait..." msgstr "Downloading. Please wait..." @@ -1656,7 +1755,7 @@ msgstr "Drop set, " msgid "dumbbell" msgstr "dumbbell" -#: app/(app)/settings.tsx:1149 +#: app/(app)/settings.tsx:1187 msgid "Dumbbell load increment" msgstr "Dumbbell load increment" @@ -1669,25 +1768,33 @@ msgstr "Duration" msgid "During a session, swipe left/right or use the arrow buttons to move between sets. Enter your weight and reps, then tap Complete Set. The total elapsed time is shown in the header throughout. You can drag the handle on any exercise card to reorder exercises while the session is in progress. Time-based exercises have a Start Timer button that opens a count-up timer with a progress ring that shows you when you hit your goal time but you can keep going as long as you like. Notes can be added per-exercise via the notes icon in the exercise header, per workout from the workout overview screen, or per plan from the plan overview screen. If you add, remove, or reorder exercises or sets during a session, you will be prompted at the end to save those changes back to the original workout or plan." msgstr "During a session, swipe left/right or use the arrow buttons to move between sets. Enter your weight and reps, then tap Complete Set. The total elapsed time is shown in the header throughout. You can drag the handle on any exercise card to reorder exercises while the session is in progress. Time-based exercises have a Start Timer button that opens a count-up timer with a progress ring that shows you when you hit your goal time but you can keep going as long as you like. Notes can be added per-exercise via the notes icon in the exercise header, per workout from the workout overview screen, or per plan from the plan overview screen. If you add, remove, or reorder exercises or sets during a session, you will be prompted at the end to save those changes back to the original workout or plan." +#: app/(app)/settings.tsx:1783 +msgid "Each measurement entry you record is shared automatically." +msgstr "Each measurement entry you record is shared automatically." + #: constants/HelpData.ts:99 msgid "Each set can be flagged as a Warm-up, Drop Set, To Failure, or any combination of these. The badge shown next to a set displays its current type. To change the type during a session, tap the menu (⋮) and toggle the relevant option on or off. When building a plan, use the checkboxes in the set editor; tap Add Warm-up to insert a dedicated warm-up set at the top of the list. Warm-up sets are visually grouped and separated from working sets, and the Apply to All option in the edit modal only affects sets of the same type. Warm-up sets can be excluded from volume and stats calculations in Settings." msgstr "Each set can be flagged as a Warm-up, Drop Set, To Failure, or any combination of these. The badge shown next to a set displays its current type. To change the type during a session, tap the menu (⋮) and toggle the relevant option on or off. When building a plan, use the checkboxes in the set editor; tap Add Warm-up to insert a dedicated warm-up set at the top of the list. Warm-up sets are visually grouped and separated from working sets, and the Apply to All option in the edit modal only affects sets of the same type. Warm-up sets can be excluded from volume and stats calculations in Settings." -#: components/ExerciseFeedbackSheet.tsx:36 +#: app/(app)/settings.tsx:1743 +msgid "Each workout you complete is shared automatically." +msgstr "Each workout you complete is shared automatically." + +#: components/ExerciseFeedbackSheet.tsx:37 msgid "Easy, could do more" msgstr "Easy, could do more" -#: app/(app)/custom-exercise.tsx:71 +#: app/(app)/custom-exercise.tsx:76 #: app/(app)/exercise-info.tsx:307 msgid "Edit Exercise" msgstr "Edit Exercise" -#: app/(app)/(tabs)/(plans)/overview.tsx:308 +#: app/(app)/(tabs)/(plans)/overview.tsx:353 msgid "Edit Plan" msgstr "Edit Plan" #: app/(app)/(create-plan)/create-workout.tsx:247 -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:276 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:328 #: app/(app)/(tabs)/(stats)/_layout.tsx:22 msgid "Edit Workout" msgstr "Edit Workout" @@ -1696,24 +1803,60 @@ msgstr "Edit Workout" msgid "elliptical machine" msgstr "elliptical machine" +#: app/(app)/friends.tsx:209 +msgid "Email address" +msgstr "Email address" + #: constants/HelpData.ts:159 msgid "Enable recurring workout reminders from Settings. Select the days of the week you want to be reminded using the day chips and choose a time. You will receive a notification at that time on each selected day. Notification permission must be granted for reminders to work." msgstr "Enable recurring workout reminders from Settings. Select the days of the week you want to be reminded using the day chips and choose a time. You will receive a notification at that time on each selected day. Notification permission must be granted for reminders to work." -#: app/(app)/settings.tsx:830 -#: app/(app)/settings.tsx:855 -#: app/(app)/settings.tsx:880 -#: app/(app)/settings.tsx:904 -#: app/(app)/settings.tsx:928 -#: app/(app)/settings.tsx:953 -#: app/(app)/settings.tsx:1010 -#: app/(app)/settings.tsx:1092 -#: app/(app)/settings.tsx:1226 -#: app/(app)/settings.tsx:1258 -#: app/(app)/settings.tsx:1455 +#: app/(app)/settings.tsx:1628 +msgid "Enable to add a publish toggle to each plan." +msgstr "Enable to add a publish toggle to each plan." + +#: app/(app)/settings.tsx:1666 +msgid "Enable to add a publish toggle to each standalone workout." +msgstr "Enable to add a publish toggle to each standalone workout." + +#: app/(app)/settings.tsx:1708 +msgid "Enable to automatically share custom exercises you create or edit." +msgstr "Enable to automatically share custom exercises you create or edit." + +#: app/(app)/settings.tsx:1790 +msgid "Enable to automatically share each body measurement you record." +msgstr "Enable to automatically share each body measurement you record." + +#: app/(app)/settings.tsx:1749 +msgid "Enable to automatically share each workout you complete." +msgstr "Enable to automatically share each workout you complete." + +#: app/(app)/settings.tsx:1832 +msgid "Enable to automatically share strength PRs after each workout." +msgstr "Enable to automatically share strength PRs after each workout." + +#: app/(app)/settings.tsx:866 +#: app/(app)/settings.tsx:891 +#: app/(app)/settings.tsx:916 +#: app/(app)/settings.tsx:940 +#: app/(app)/settings.tsx:964 +#: app/(app)/settings.tsx:989 +#: app/(app)/settings.tsx:1046 +#: app/(app)/settings.tsx:1128 +#: app/(app)/settings.tsx:1264 +#: app/(app)/settings.tsx:1297 +#: app/(app)/settings.tsx:1494 msgid "Enabled" msgstr "Enabled" +#: app/(app)/settings.tsx:1624 +msgid "Enables a per-plan publish toggle." +msgstr "Enables a per-plan publish toggle." + +#: app/(app)/settings.tsx:1662 +msgid "Enables a per-workout publish toggle." +msgstr "Enables a per-workout publish toggle." + #: app/(app)/(tabs)/(stats)/measurements-manage.tsx:65 msgid "Enter a name for the custom metric." msgstr "Enter a name for the custom metric." @@ -1722,15 +1865,15 @@ msgstr "Enter a name for the custom metric." msgid "Enter at least one measurement to log." msgstr "Enter at least one measurement to log." -#: app/(app)/custom-exercise.tsx:350 +#: app/(app)/custom-exercise.tsx:376 msgid "Enter description" msgstr "Enter description" -#: app/(app)/custom-exercise.tsx:331 +#: app/(app)/custom-exercise.tsx:357 msgid "Enter exercise name" msgstr "Enter exercise name" -#: app/(app)/settings.tsx:1056 +#: app/(app)/settings.tsx:1092 msgid "Enter weight per dumbbell/cable, not total" msgstr "Enter weight per dumbbell/cable, not total" @@ -1742,15 +1885,19 @@ msgstr "Entry Detail" msgid "Entry not found." msgstr "Entry not found." -#: app/(app)/custom-exercise.tsx:442 +#: app/(app)/friend-exercise.tsx:64 +msgid "Equipment" +msgstr "Equipment" + +#: app/(app)/custom-exercise.tsx:468 msgid "Equipment *" msgstr "Equipment *" -#: app/(app)/custom-exercise.tsx:438 +#: app/(app)/custom-exercise.tsx:464 msgid "Equipment & Tracking" msgstr "Equipment & Tracking" -#: app/(app)/custom-exercise.tsx:203 +#: app/(app)/custom-exercise.tsx:208 msgid "Equipment is required." msgstr "Equipment is required." @@ -1759,13 +1906,13 @@ msgid "Equipment:" msgstr "Equipment:" #: app/(app)/(create-plan)/image-search.tsx:43 -#: app/(app)/(tabs)/(plans)/overview.tsx:134 -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:94 +#: app/(app)/(tabs)/(plans)/overview.tsx:145 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:106 #: app/(app)/(workout)/index.tsx:871 #: app/(app)/(workout)/index.tsx:1065 -#: app/(app)/custom-exercise.tsx:129 -#: app/(app)/custom-exercise.tsx:178 -#: app/(app)/custom-exercise.tsx:286 +#: app/(app)/custom-exercise.tsx:134 +#: app/(app)/custom-exercise.tsx:183 +#: app/(app)/custom-exercise.tsx:312 #: app/login.tsx:69 #: components/FilterRow.tsx:86 #: components/FilterRow.tsx:132 @@ -1794,7 +1941,7 @@ msgstr "Error loading exercise details" msgid "Error loading exercises: {0}" msgstr "Error loading exercises: {0}" -#: app/(app)/(tabs)/(plans)/index.tsx:93 +#: app/(app)/(tabs)/(plans)/index.tsx:97 msgid "Error loading plans" msgstr "Error loading plans" @@ -1808,8 +1955,8 @@ msgstr "Error saving workout" #. placeholder {0}: error.message #. placeholder {0}: settingsError.message -#: app/(app)/(tabs)/(plans)/overview.tsx:174 -#: app/(app)/(workout)/workout-session.tsx:1355 +#: app/(app)/(tabs)/(plans)/overview.tsx:185 +#: app/(app)/(workout)/workout-session.tsx:1386 #: components/WorkoutDetailsScreen.tsx:175 msgid "Error: {0}" msgstr "Error: {0}" @@ -1819,15 +1966,15 @@ msgstr "Error: {0}" msgid "Estimated Duration: {0}" msgstr "Estimated Duration: {0}" -#: app/(app)/settings.tsx:1222 +#: app/(app)/settings.tsx:1260 msgid "Exclude deload workouts from exercise stats" msgstr "Exclude deload workouts from exercise stats" -#: app/(app)/settings.tsx:1006 +#: app/(app)/settings.tsx:1042 msgid "Exclude warmup sets from stats" msgstr "Exclude warmup sets from stats" -#: app/(app)/settings.tsx:1349 +#: app/(app)/settings.tsx:1388 msgid "Exercise" msgstr "Exercise" @@ -1838,21 +1985,29 @@ msgstr "Exercise" msgid "Exercise Already Added" msgstr "Exercise Already Added" -#: app/(app)/_layout.tsx:37 +#: app/(app)/_layout.tsx:59 +msgid "Exercise Details" +msgstr "Exercise Details" + +#: app/(app)/_layout.tsx:39 msgid "Exercise Info" msgstr "Exercise Info" -#: app/(app)/_layout.tsx:44 -#: components/AppMenu.tsx:184 +#: app/(app)/_layout.tsx:46 +#: components/AppMenu.tsx:202 #: constants/HelpData.ts:103 msgid "Exercise Library" msgstr "Exercise Library" +#: app/(app)/friend-exercise.tsx:47 +msgid "Exercise not found." +msgstr "Exercise not found." + #: components/ExerciseTimerModal.tsx:159 msgid "Exercise Timer" msgstr "Exercise Timer" -#: app/(app)/settings.tsx:809 +#: app/(app)/settings.tsx:845 msgid "Exercise timer countdown" msgstr "Exercise timer countdown" @@ -1880,12 +2035,12 @@ msgid "ez barbell" msgstr "ez barbell" #. placeholder {0}: error.message -#: app/(app)/(tabs)/(plans)/overview.tsx:155 +#: app/(app)/(tabs)/(plans)/overview.tsx:166 msgid "Failed to activate this plan: {0}" msgstr "Failed to activate this plan: {0}" #. placeholder {0}: error.message -#: app/(app)/(tabs)/(plans)/overview.tsx:135 +#: app/(app)/(tabs)/(plans)/overview.tsx:146 msgid "Failed to delete plan: {0}" msgstr "Failed to delete plan: {0}" @@ -1893,17 +2048,17 @@ msgstr "Failed to delete plan: {0}" msgid "Failed to delete the workout. Please try again." msgstr "Failed to delete the workout. Please try again." -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:95 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:107 msgid "Failed to delete workout. Please try again." msgstr "Failed to delete workout. Please try again." -#: app/(app)/custom-exercise.tsx:129 +#: app/(app)/custom-exercise.tsx:134 #: components/FilterRow.tsx:86 #: components/FilterRow.tsx:132 msgid "Failed to fetch data. Please try again." msgstr "Failed to fetch data. Please try again." -#: app/(app)/custom-exercise.tsx:178 +#: app/(app)/custom-exercise.tsx:183 msgid "Failed to load exercise details." msgstr "Failed to load exercise details." @@ -1911,7 +2066,7 @@ msgstr "Failed to load exercise details." msgid "Failed to load history" msgstr "Failed to load history" -#: app/(app)/(tabs)/(plans)/index.tsx:147 +#: app/(app)/(tabs)/(plans)/index.tsx:153 msgid "Failed to load workouts" msgstr "Failed to load workouts" @@ -1919,11 +2074,11 @@ msgstr "Failed to load workouts" msgid "Failed to pick image. Please try again." msgstr "Failed to pick image. Please try again." -#: app/(app)/custom-exercise.tsx:287 +#: app/(app)/custom-exercise.tsx:313 msgid "Failed to save custom exercise. Please try again." msgstr "Failed to save custom exercise. Please try again." -#: app/(app)/custom-exercise.tsx:226 +#: app/(app)/custom-exercise.tsx:231 msgid "Failed to save the image. Please try again." msgstr "Failed to save the image. Please try again." @@ -1936,6 +2091,10 @@ msgstr "Failed to save workout. Please try again." msgid "Failed to sign in. Please try again." msgstr "Failed to sign in. Please try again." +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:304 +msgid "Failed to update sharing. Please try again." +msgstr "Failed to update sharing. Please try again." + #: components/ExerciseList.tsx:41 msgid "Favorites" msgstr "Favorites" @@ -1956,7 +2115,7 @@ msgstr "Felt easy this time. Hold for now and confirm next session." msgid "Finish" msgstr "Finish" -#: app/(app)/settings.tsx:1632 +#: app/(app)/settings.tsx:1945 msgid "Follow MuscleQuest on Instagram" msgstr "Follow MuscleQuest on Instagram" @@ -1969,7 +2128,7 @@ msgstr "for {0}s " msgid "forearms" msgstr "forearms" -#: app/(app)/settings.tsx:53 +#: app/(app)/settings.tsx:56 msgid "Fr" msgstr "Fr" @@ -1992,6 +2151,27 @@ msgstr "Fri" msgid "Friday" msgstr "Friday" +#: app/(app)/_layout.tsx:50 +msgid "Friend Profile" +msgstr "Friend Profile" + +#: app/(app)/friends.tsx:39 +#: app/(app)/friends.tsx:58 +#: app/(app)/friends.tsx:69 +#: app/(app)/friends.tsx:264 +#: components/AppMenu.tsx:194 +msgid "Friends" +msgstr "Friends" + +#: constants/HelpData.ts:164 +msgid "Friends & Social" +msgstr "Friends & Social" + +#. placeholder {0}: formatDistanceToNow(friend.since.toDate(), { addSuffix: true }) +#: app/(app)/friend-profile.tsx:121 +msgid "Friends since {0}" +msgstr "Friends since {0}" + #: components/ExerciseTimerModal.tsx:165 msgid "Get Ready..." msgstr "Get Ready..." @@ -2059,12 +2239,12 @@ msgstr "Group two exercises into a superset so they alternate automatically duri msgid "hamstrings" msgstr "hamstrings" -#: components/ExerciseFeedbackSheet.tsx:38 +#: components/ExerciseFeedbackSheet.tsx:39 msgid "Hard, near limit" msgstr "Hard, near limit" -#: app/(app)/_layout.tsx:41 -#: components/AppMenu.tsx:194 +#: app/(app)/_layout.tsx:43 +#: components/AppMenu.tsx:212 msgid "Help & Info" msgstr "Help & Info" @@ -2111,11 +2291,11 @@ msgstr "Home Screen & Weekly Goal" msgid "How are these muscles feeling since your last session?" msgstr "How are these muscles feeling since your last session?" -#: components/ExerciseFeedbackSheet.tsx:173 +#: components/ExerciseFeedbackSheet.tsx:187 msgid "How did that feel?" msgstr "How did that feel?" -#: app/(app)/custom-exercise.tsx:225 +#: app/(app)/custom-exercise.tsx:230 msgid "Image Save Error" msgstr "Image Save Error" @@ -2123,6 +2303,19 @@ msgstr "Image Save Error" msgid "Images by Unsplash" msgstr "Images by Unsplash" +#: app/(app)/friend-exercise.tsx:142 +msgid "Import failed" +msgstr "Import failed" + +#: constants/HelpData.ts:178 +msgid "Importing from Friends" +msgstr "Importing from Friends" + +#: app/(app)/friends.tsx:278 +#: app/(app)/friends.tsx:331 +msgid "Incoming" +msgstr "Incoming" + #: app/(app)/exercise-info.tsx:202 msgid "Info" msgstr "Info" @@ -2136,11 +2329,11 @@ msgstr "Insights" msgid "Jumpstart your fitness journey with professionally designed training plans. Choose from a variety of options tailored to different goals and experience levels. " msgstr "Jumpstart your fitness journey with professionally designed training plans. Choose from a variety of options tailored to different goals and experience levels. " -#: app/(app)/custom-exercise.tsx:83 +#: app/(app)/custom-exercise.tsx:88 msgid "Keep editing" msgstr "Keep editing" -#: app/(app)/settings.tsx:949 +#: app/(app)/settings.tsx:985 msgid "Keep screen on during workout" msgstr "Keep screen on during workout" @@ -2153,7 +2346,7 @@ msgid "kettlebell" msgstr "kettlebell" #. placeholder {0}: lastBackupDate.toLocaleDateString() -#: app/(app)/settings.tsx:608 +#: app/(app)/settings.tsx:644 msgid "Last backup: {0}" msgstr "Last backup: {0}" @@ -2194,15 +2387,15 @@ msgstr "leverage machine" msgid "Load up" msgstr "Load up" -#: app/_layout.tsx:199 +#: app/_layout.tsx:213 msgid "Loading data, please wait..." msgstr "Loading data, please wait..." -#: app/(app)/(tabs)/(plans)/overview.tsx:187 +#: app/(app)/(tabs)/(plans)/overview.tsx:198 msgid "Loading Plan..." msgstr "Loading Plan..." -#: app/(app)/(tabs)/(plans)/overview.tsx:166 +#: app/(app)/(tabs)/(plans)/overview.tsx:177 #: components/WorkoutDetailsScreen.tsx:166 msgid "Loading..." msgstr "Loading..." @@ -2212,11 +2405,11 @@ msgstr "Loading..." msgid "Log Entry" msgstr "Log Entry" -#: app/(app)/settings.tsx:528 +#: app/(app)/settings.tsx:564 msgid "Log in to secure your data" msgstr "Log in to secure your data" -#: app/(app)/settings.tsx:1031 +#: app/(app)/settings.tsx:1067 msgid "Log one side only for single-arm/leg exercises" msgstr "Log one side only for single-arm/leg exercises" @@ -2236,7 +2429,7 @@ msgstr "lower back" msgid "lower legs" msgstr "lower legs" -#: app/(app)/settings.tsx:1203 +#: app/(app)/settings.tsx:1241 msgid "Machine load increment" msgstr "Machine load increment" @@ -2280,11 +2473,11 @@ msgstr "Mild soreness" msgid "Min Reps" msgstr "Min Reps" -#: components/ExerciseFeedbackSheet.tsx:46 +#: components/ExerciseFeedbackSheet.tsx:47 msgid "Minor discomfort" msgstr "Minor discomfort" -#: app/(app)/settings.tsx:49 +#: app/(app)/settings.tsx:52 msgid "Mo" msgstr "Mo" @@ -2327,15 +2520,15 @@ msgstr "MuscleQuest" msgid "MuscleQuest Introduction" msgstr "MuscleQuest Introduction" -#: app/(app)/settings.tsx:1613 +#: app/(app)/settings.tsx:1926 msgid "MuscleQuest.app" msgstr "MuscleQuest.app" -#: components/AppMenu.tsx:208 +#: components/AppMenu.tsx:226 msgid "MuscleQuest's Instagram" msgstr "MuscleQuest's Instagram" -#: app/(app)/custom-exercise.tsx:368 +#: app/(app)/custom-exercise.tsx:394 msgid "Muscles" msgstr "Muscles" @@ -2343,11 +2536,11 @@ msgstr "Muscles" msgid "N/A" msgstr "N/A" -#: app/(app)/custom-exercise.tsx:328 +#: app/(app)/custom-exercise.tsx:354 msgid "Name *" msgstr "Name *" -#: app/(app)/custom-exercise.tsx:200 +#: app/(app)/custom-exercise.tsx:205 msgid "Name is required." msgstr "Name is required." @@ -2363,11 +2556,11 @@ msgstr "neck" msgid "Neck" msgstr "Neck" -#: app/(app)/(tabs)/(plans)/index.tsx:118 +#: app/(app)/(tabs)/(plans)/index.tsx:122 msgid "New Plan" msgstr "New Plan" -#: app/(app)/(tabs)/(plans)/index.tsx:110 +#: app/(app)/(tabs)/(plans)/index.tsx:114 msgid "New Workout" msgstr "New Workout" @@ -2379,8 +2572,8 @@ msgstr "Next" msgid "Next Session" msgstr "Next Session" -#: app/(app)/(workout)/workout-session.tsx:1415 -#: app/(app)/(workout)/workout-session.tsx:1502 +#: app/(app)/(workout)/workout-session.tsx:1446 +#: app/(app)/(workout)/workout-session.tsx:1533 msgid "Next: " msgstr "Next: " @@ -2395,10 +2588,18 @@ msgstr "Next: {workoutName} on {0}" msgid "No" msgstr "No" -#: app/(app)/settings.tsx:609 +#: app/(app)/settings.tsx:645 msgid "No backups found" msgstr "No backups found" +#: app/(app)/friend-profile.tsx:423 +msgid "No completed workouts shared yet" +msgstr "No completed workouts shared yet" + +#: app/(app)/friend-profile.tsx:336 +msgid "No custom exercises shared yet" +msgstr "No custom exercises shared yet" + #: components/charts/BodyPartChart.tsx:198 msgid "No data available." msgstr "No data available." @@ -2415,7 +2616,7 @@ msgstr "No data for this period." msgid "No exercises added yet" msgstr "No exercises added yet" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:252 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:264 msgid "No exercises in this workout yet." msgstr "No exercises in this workout yet." @@ -2423,10 +2624,18 @@ msgstr "No exercises in this workout yet." msgid "No exercises tracked yet. Tap + Add to start." msgstr "No exercises tracked yet. Tap + Add to start." +#: app/(app)/friends.tsx:141 +msgid "No friends yet. Search by email to add someone." +msgstr "No friends yet. Search by email to add someone." + #: app/(app)/exercise-info.tsx:407 msgid "No history yet" msgstr "No history yet" +#: app/(app)/friend-profile.tsx:468 +msgid "No measurements shared yet" +msgstr "No measurements shared yet" + #: app/(app)/(tabs)/(stats)/measurements.tsx:265 msgid "No measurements yet. Log your first entry above." msgstr "No measurements yet. Log your first entry above." @@ -2435,10 +2644,18 @@ msgstr "No measurements yet. Log your first entry above." msgid "No measurements yet. Tap to log your first entry." msgstr "No measurements yet. Tap to log your first entry." -#: components/ExerciseFeedbackSheet.tsx:45 +#: components/ExerciseFeedbackSheet.tsx:46 msgid "No pain" msgstr "No pain" +#: app/(app)/friends.tsx:317 +msgid "No pending friend requests." +msgstr "No pending friend requests." + +#: app/(app)/friend-profile.tsx:156 +msgid "No plans shared yet" +msgstr "No plans shared yet" + #: components/ProgressionSummaryCard.tsx:26 msgid "No prior weight data. Hold steady for now." msgstr "No prior weight data. Hold steady for now." @@ -2455,7 +2672,7 @@ msgstr "No results for \"{query}\"" msgid "No schedule set" msgstr "No schedule set" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:176 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:188 msgid "No Sets" msgstr "No Sets" @@ -2464,10 +2681,18 @@ msgstr "No Sets" msgid "No Sets Available" msgstr "No Sets Available" -#: components/PlanList.tsx:46 +#: app/(app)/friend-profile.tsx:501 +msgid "No strength data shared yet" +msgstr "No strength data shared yet" + +#: components/PlanList.tsx:50 msgid "No training plans found" msgstr "No training plans found" +#: app/(app)/friends.tsx:228 +msgid "No user found with that email address." +msgstr "No user found with that email address." + #: app/(app)/(tabs)/(stats)/measurements.tsx:131 msgid "No values entered" msgstr "No values entered" @@ -2484,11 +2709,15 @@ msgstr "No workouts completed yet. Start your first workout!" msgid "No workouts on this day." msgstr "No workouts on this day." -#: app/(app)/(tabs)/(plans)/index.tsx:160 +#: app/(app)/friend-profile.tsx:244 +msgid "No workouts shared yet" +msgstr "No workouts shared yet" + +#: app/(app)/(tabs)/(plans)/index.tsx:166 msgid "No workouts yet" msgstr "No workouts yet" -#: components/ExerciseFeedbackSheet.tsx:221 +#: components/ExerciseFeedbackSheet.tsx:235 msgid "No, keep it the same" msgstr "No, keep it the same" @@ -2502,10 +2731,10 @@ msgstr "obliques" #: app/(app)/(workout)/exercises.tsx:109 #: app/(app)/(workout)/exercises.tsx:130 #: app/(app)/(workout)/index.tsx:873 -#: app/(app)/custom-exercise.tsx:130 -#: app/(app)/custom-exercise.tsx:179 -#: app/(app)/custom-exercise.tsx:227 -#: app/(app)/custom-exercise.tsx:288 +#: app/(app)/custom-exercise.tsx:135 +#: app/(app)/custom-exercise.tsx:184 +#: app/(app)/custom-exercise.tsx:232 +#: app/(app)/custom-exercise.tsx:314 #: app/login.tsx:70 #: components/FilterRow.tsx:87 #: components/FilterRow.tsx:133 @@ -2520,16 +2749,20 @@ msgstr "One more workout to hit your goal!" msgid "Oops!" msgstr "Oops!" -#: app/(app)/settings.tsx:386 +#: app/(app)/settings.tsx:422 msgid "Open Settings" msgstr "Open Settings" -#: components/AppMenu.tsx:204 -#: components/AppMenu.tsx:210 +#: constants/HelpData.ts:169 +msgid "Open the Friends tab from the menu to manage your connections. Use the search bar to find other users by username and send them a friend request. Incoming requests appear in the Requests tab; tap Accept to confirm or Decline to ignore. A badge on the Friends menu item shows how many pending requests are waiting. Once a request is accepted, both users appear in each other's Friends list and can view each other's shared content." +msgstr "Open the Friends tab from the menu to manage your connections. Use the search bar to find other users by username and send them a friend request. Incoming requests appear in the Requests tab; tap Accept to confirm or Decline to ignore. A badge on the Friends menu item shows how many pending requests are waiting. Once a request is accepted, both users appear in each other's Friends list and can view each other's shared content." + +#: components/AppMenu.tsx:222 +#: components/AppMenu.tsx:228 msgid "Opens in your browser" msgstr "Opens in your browser" -#: components/ExerciseFeedbackSheet.tsx:243 +#: components/ExerciseFeedbackSheet.tsx:257 msgid "Optional description" msgstr "Optional description" @@ -2542,7 +2775,7 @@ msgstr "Other Exercises" msgid "Overview" msgstr "Overview" -#: components/ExerciseFeedbackSheet.tsx:47 +#: components/ExerciseFeedbackSheet.tsx:48 msgid "Pain or form issues" msgstr "Pain or form issues" @@ -2550,7 +2783,7 @@ msgstr "Pain or form issues" msgid "Pain reported. Keeping load unchanged until you feel better." msgstr "Pain reported. Keeping load unchanged until you feel better." -#: app/(app)/custom-exercise.tsx:525 +#: app/(app)/custom-exercise.tsx:551 #: app/(app)/exercise-info.tsx:277 msgid "Paired implements" msgstr "Paired implements" @@ -2564,6 +2797,10 @@ msgstr "Paired with {0}" msgid "pectorals" msgstr "pectorals" +#: app/(app)/friends.tsx:377 +msgid "Pending" +msgstr "Pending" + #: components/stats/InsightsStrip.tsx:74 msgid "Per week (avg)" msgstr "Per week (avg)" @@ -2572,12 +2809,12 @@ msgstr "Per week (avg)" msgid "Percent" msgstr "Percent" -#: app/(app)/settings.tsx:364 -#: app/(app)/settings.tsx:383 +#: app/(app)/settings.tsx:400 +#: app/(app)/settings.tsx:419 msgid "Permission Required" msgstr "Permission Required" -#: app/(app)/settings.tsx:511 +#: app/(app)/settings.tsx:547 msgid "Personal" msgstr "Personal" @@ -2585,12 +2822,21 @@ msgstr "Personal" msgid "Pin exercises in the Stats tab to track their strength progression over time. Each tracked exercise shows a chart of your performance over the selected time range, your all-time personal record, your top sets, and a list of recent sessions showing the best set per day. Charts update automatically after each workout that includes that exercise." msgstr "Pin exercises in the Stats tab to track their strength progression over time. Each tracked exercise shows a chart of your performance over the selected time range, your all-time personal record, your top sets, and a list of recent sessions showing the best set per day. Charts update automatically after each workout that includes that exercise." +#: app/(app)/_layout.tsx:52 +msgid "Plan Details" +msgstr "Plan Details" + +#: app/(app)/friend-plan.tsx:56 +msgid "Plan not found." +msgstr "Plan not found." + #: app/(app)/(tabs)/(plans)/_layout.tsx:17 msgid "Plan Overview" msgstr "Plan Overview" #: app/(app)/(tabs)/_layout.tsx:49 #: app/(app)/(tabs)/(plans)/_layout.tsx:16 +#: app/(app)/friend-profile.tsx:146 #: constants/HelpData.ts:28 msgid "Plans" msgstr "Plans" @@ -2599,15 +2845,15 @@ msgstr "Plans" msgid "Plans are structured training programmes made up of workouts. To create one, go to the Plans tab, tap New Plan, give it a name, and pick a cover image. Add workouts to the plan, then add exercises to each workout with target sets and reps. Use the up/down arrow buttons on a workout card to reorder it, or the X button to remove it; both are in the top right of the card. Assign workouts to specific days of the week in the schedule editor: tap any day to pick a workout or leave it as a rest day, and use the auto-suggest button to space them out evenly. Once your plan is ready, open it and tap Activate. You can also add notes to a plan from the plan overview screen. Each workout card shows an estimated duration alongside the exercise count so you can gauge the session length at a glance. Use the view icons next to the \"Your Training Plans\" heading to switch between Carousel, List, and Grid layouts; your chosen view is saved automatically. Your progress in the plan editor is automatically saved as a draft, so if you leave mid-edit you will be prompted to continue where you left off or discard and start from the last saved state." msgstr "Plans are structured training programmes made up of workouts. To create one, go to the Plans tab, tap New Plan, give it a name, and pick a cover image. Add workouts to the plan, then add exercises to each workout with target sets and reps. Use the up/down arrow buttons on a workout card to reorder it, or the X button to remove it; both are in the top right of the card. Assign workouts to specific days of the week in the schedule editor: tap any day to pick a workout or leave it as a rest day, and use the auto-suggest button to space them out evenly. Once your plan is ready, open it and tap Activate. You can also add notes to a plan from the plan overview screen. Each workout card shows an estimated duration alongside the exercise count so you can gauge the session length at a glance. Use the view icons next to the \"Your Training Plans\" heading to switch between Carousel, List, and Grid layouts; your chosen view is saved automatically. Your progress in the plan editor is automatically saved as a draft, so if you leave mid-edit you will be prompted to continue where you left off or discard and start from the last saved state." -#: app/(app)/settings.tsx:826 +#: app/(app)/settings.tsx:862 msgid "Play countdown beeps (Exercise Timer)" msgstr "Play countdown beeps (Exercise Timer)" -#: app/(app)/settings.tsx:851 +#: app/(app)/settings.tsx:887 msgid "Play goal achieved sound (Exercise Timer)" msgstr "Play goal achieved sound (Exercise Timer)" -#: app/(app)/settings.tsx:901 +#: app/(app)/settings.tsx:937 msgid "Play sound after rest" msgstr "Play sound after rest" @@ -2619,7 +2865,7 @@ msgstr "Please wait while we download the latest version..." msgid "Post-Exercise Feedback" msgstr "Post-Exercise Feedback" -#: app/(app)/(tabs)/(plans)/index.tsx:134 +#: app/(app)/(tabs)/(plans)/index.tsx:140 msgid "Premade plans" msgstr "Premade plans" @@ -2627,12 +2873,20 @@ msgstr "Premade plans" msgid "Premade Plans" msgstr "Premade Plans" -#: app/(app)/(workout)/workout-session.tsx:1417 -#: app/(app)/(workout)/workout-session.tsx:1504 +#: app/(app)/(workout)/workout-session.tsx:1448 +#: app/(app)/(workout)/workout-session.tsx:1535 msgid "Prev: " msgstr "Prev: " -#: app/(app)/settings.tsx:1668 +#: app/(app)/settings.tsx:1604 +msgid "Previously shared data always remains visible to your friends until you delete it below." +msgstr "Previously shared data always remains visible to your friends until you delete it below." + +#: app/(app)/settings.tsx:1601 +msgid "Privacy" +msgstr "Privacy" + +#: app/(app)/settings.tsx:1981 msgid "Privacy policy" msgstr "Privacy policy" @@ -2640,7 +2894,7 @@ msgstr "Privacy policy" msgid "Progression Suggestions" msgstr "Progression Suggestions" -#: components/ExerciseFeedbackSheet.tsx:211 +#: components/ExerciseFeedbackSheet.tsx:225 msgid "Push harder next time?" msgstr "Push harder next time?" @@ -2669,6 +2923,10 @@ msgstr "Recent" msgid "Recent Sessions" msgstr "Recent Sessions" +#: app/(app)/friend-profile.tsx:413 +msgid "Recent Workouts" +msgstr "Recent Workouts" + #: hooks/useExerciseSort.ts:57 msgid "Recently Used" msgstr "Recently Used" @@ -2682,23 +2940,24 @@ msgstr "Recovery Check-in" msgid "Reduce load" msgstr "Reduce load" -#: app/_layout.tsx:94 +#: app/_layout.tsx:100 msgid "Reload" msgstr "Reload" -#: app/(app)/settings.tsx:1280 +#: app/(app)/settings.tsx:1319 msgid "Reminder days" msgstr "Reminder days" -#: app/(app)/settings.tsx:1335 +#: app/(app)/settings.tsx:1374 msgid "Reminder time" msgstr "Reminder time" -#: app/(app)/settings.tsx:1243 +#: app/(app)/settings.tsx:1282 msgid "Reminders" msgstr "Reminders" #: app/(app)/(create-plan)/create.tsx:283 +#: components/friends/FriendListItem.tsx:26 #: components/WorkoutCard.tsx:89 msgid "Remove" msgstr "Remove" @@ -2716,6 +2975,10 @@ msgstr "Remove Exercise" msgid "Remove Superset" msgstr "Remove Superset" +#: components/friends/FriendListItem.tsx:22 +msgid "Remove this friend? They will no longer be able to see your shared content." +msgstr "Remove this friend? They will no longer be able to see your shared content." + #: app/(app)/(create-plan)/create.tsx:275 msgid "Remove Workout" msgstr "Remove Workout" @@ -2733,12 +2996,17 @@ msgstr "Rep target not met. Hold steady for now." msgid "Replace" msgstr "Replace" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:186 +#: app/(app)/friend-plan.tsx:130 +#: app/(app)/friend-workout.tsx:89 +msgid "reps" +msgstr "reps" + +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:198 #: app/(app)/(tabs)/(stats)/edit-history.tsx:201 #: app/(app)/(tabs)/(stats)/edit-history.tsx:205 #: app/(app)/(tabs)/(stats)/edit-history.tsx:242 #: app/(app)/(tabs)/(stats)/edit-history.tsx:246 -#: app/(app)/custom-exercise.tsx:64 +#: app/(app)/custom-exercise.tsx:69 #: components/charts/ExerciseProgressionChart.tsx:377 #: components/SessionSetInfo.tsx:435 #: components/WorkoutCard.tsx:276 @@ -2750,10 +3018,14 @@ msgstr "Reps" msgid "Reps: {repRange}" msgstr "Reps: {repRange}" -#: app/(app)/settings.tsx:1577 +#: app/(app)/settings.tsx:1890 msgid "Request or vote for new features" msgstr "Request or vote for new features" +#: app/(app)/friends.tsx:62 +msgid "Requests" +msgstr "Requests" + #: app/(app)/(create-plan)/sets-overview.tsx:173 #: components/PlanScheduleEditor.tsx:94 #: components/PlanScheduleEditor.tsx:189 @@ -2770,7 +3042,7 @@ msgid "Rest Time (Minutes:Seconds)" msgstr "Rest Time (Minutes:Seconds)" #: app/(app)/(workout)/index.tsx:1134 -#: app/(app)/(workout)/workout-session.tsx:1540 +#: app/(app)/(workout)/workout-session.tsx:1572 msgid "Rest Time Left:" msgstr "Rest Time Left:" @@ -2783,11 +3055,11 @@ msgstr "Rest Time: {restMinutes}:{0}" msgid "Rest Timer" msgstr "Rest Timer" -#: app/(app)/(workout)/workout-session.tsx:551 +#: app/(app)/(workout)/workout-session.tsx:558 msgid "Rest Timer Finished!" msgstr "Rest Timer Finished!" -#: app/(app)/settings.tsx:783 +#: app/(app)/settings.tsx:819 msgid "Rest timer increment" msgstr "Rest timer increment" @@ -2807,16 +3079,16 @@ msgstr "Restart Failed" msgid "Restart Workout" msgstr "Restart Workout" -#: app/(app)/settings.tsx:464 -#: app/(app)/settings.tsx:625 +#: app/(app)/settings.tsx:500 +#: app/(app)/settings.tsx:661 msgid "Restore" msgstr "Restore" -#: app/(app)/settings.tsx:459 +#: app/(app)/settings.tsx:495 msgid "Restore Backup" msgstr "Restore Backup" -#: app/(app)/settings.tsx:635 +#: app/(app)/settings.tsx:671 msgid "Restoring. Please wait..." msgstr "Restoring. Please wait..." @@ -2836,7 +3108,7 @@ msgstr "rope" msgid "rotator cuff" msgstr "rotator cuff" -#: app/(app)/settings.tsx:54 +#: app/(app)/settings.tsx:57 msgid "Sa" msgstr "Sa" @@ -2855,12 +3127,12 @@ msgstr "Saturday" #: app/(app)/(create-plan)/create.tsx:363 #: app/(app)/(workout)/index.tsx:843 #: app/(app)/(workout)/index.tsx:1071 -#: app/(app)/custom-exercise.tsx:549 +#: app/(app)/custom-exercise.tsx:575 #: components/SettingsModal.tsx:296 msgid "Save" msgstr "Save" -#: app/(app)/custom-exercise.tsx:549 +#: app/(app)/custom-exercise.tsx:575 msgid "Save and select" msgstr "Save and select" @@ -2900,6 +3172,8 @@ msgstr "Saving Workout..." #: app/(app)/(tabs)/(stats)/exercises.tsx:166 #: app/(app)/(workout)/exercises.tsx:233 #: app/(app)/exercise-library.tsx:91 +#: app/(app)/friends.tsx:59 +#: app/(app)/friends.tsx:219 msgid "Search" msgstr "Search" @@ -2911,13 +3185,14 @@ msgstr "Search help" msgid "Search help…" msgstr "Search help…" -#: app/(app)/custom-exercise.tsx:404 -#: app/(app)/custom-exercise.tsx:427 +#: app/(app)/custom-exercise.tsx:430 #: app/(app)/custom-exercise.tsx:453 +#: app/(app)/custom-exercise.tsx:479 msgid "Search..." msgstr "Search..." -#: app/(app)/custom-exercise.tsx:416 +#: app/(app)/custom-exercise.tsx:442 +#: app/(app)/friend-exercise.tsx:83 msgid "Secondary Muscles" msgstr "Secondary Muscles" @@ -2933,34 +3208,39 @@ msgstr "Select a day to see workouts." msgid "Select a workout to view" msgstr "Select a workout to view" -#: app/(app)/settings.tsx:1311 +#: app/(app)/settings.tsx:1350 msgid "Select at least one day" msgstr "Select at least one day" -#: app/(app)/custom-exercise.tsx:382 +#: app/(app)/custom-exercise.tsx:408 msgid "Select body part" msgstr "Select body part" -#: app/(app)/custom-exercise.tsx:454 +#: app/(app)/custom-exercise.tsx:480 msgid "Select equipment" msgstr "Select equipment" -#: app/(app)/custom-exercise.tsx:428 +#: app/(app)/custom-exercise.tsx:454 msgid "Select secondary muscles" msgstr "Select secondary muscles" -#: app/(app)/custom-exercise.tsx:405 +#: app/(app)/custom-exercise.tsx:431 msgid "Select target muscle" msgstr "Select target muscle" -#: app/(app)/custom-exercise.tsx:475 +#: app/(app)/custom-exercise.tsx:501 msgid "Select tracking type" msgstr "Select tracking type" -#: app/(app)/settings.tsx:924 +#: app/(app)/settings.tsx:960 msgid "Send notification in background after rest" msgstr "Send notification in background after rest" +#: app/(app)/friends.tsx:271 +#: app/(app)/friends.tsx:344 +msgid "Sent" +msgstr "Sent" + #: constants/dbTranslations.ts:33 msgid "serratus anterior" msgstr "serratus anterior" @@ -2989,6 +3269,11 @@ msgstr "Set Types" msgid "Set your weekly workout goal and enter your body weight to get accurate stats and recommendations. You can also adjust your weight increment preferences, choose your preferred units, and much more." msgstr "Set your weekly workout goal and enter your body weight to get accurate stats and recommendations. You can also adjust your weight increment preferences, choose your preferred units, and much more." +#: app/(app)/friend-plan.tsx:124 +#: app/(app)/friend-workout.tsx:83 +msgid "sets" +msgstr "sets" + #: app/(app)/(workout)/workout-summary.tsx:574 #: app/(app)/(workout)/workout-summary.tsx:597 msgid "Sets" @@ -3006,12 +3291,48 @@ msgstr "Sets Overview" msgid "settings" msgstr "settings" -#: app/(app)/_layout.tsx:40 -#: components/AppMenu.tsx:189 +#: app/(app)/_layout.tsx:42 +#: components/AppMenu.tsx:207 #: constants/HelpData.ts:153 msgid "Settings" msgstr "Settings" +#: app/(app)/settings.tsx:1779 +msgid "Share body measurements with friends" +msgstr "Share body measurements with friends" + +#: app/(app)/settings.tsx:1739 +msgid "Share completed workouts with friends" +msgstr "Share completed workouts with friends" + +#: app/(app)/settings.tsx:1697 +msgid "Share custom exercises with friends" +msgstr "Share custom exercises with friends" + +#: app/(app)/(tabs)/(plans)/overview.tsx:306 +msgid "Share Plan" +msgstr "Share Plan" + +#: app/(app)/settings.tsx:1620 +msgid "Share plans with friends" +msgstr "Share plans with friends" + +#: app/(app)/settings.tsx:1658 +msgid "Share standalone workouts with friends" +msgstr "Share standalone workouts with friends" + +#: app/(app)/settings.tsx:1821 +msgid "Share strength PRs with friends" +msgstr "Share strength PRs with friends" + +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:291 +msgid "Share Workout" +msgstr "Share Workout" + +#: constants/HelpData.ts:173 +msgid "Sharing Your Content" +msgstr "Sharing Your Content" + #: constants/dbTranslations.ts:57 msgid "shins" msgstr "shins" @@ -3021,28 +3342,36 @@ msgstr "shins" msgid "shoulders" msgstr "shoulders" -#: app/(app)/settings.tsx:1452 +#: app/(app)/settings.tsx:1491 msgid "Show onboarding on home screen" msgstr "Show onboarding on home screen" -#: app/(app)/settings.tsx:532 +#: app/(app)/settings.tsx:568 msgid "Sign in" msgstr "Sign in" -#: app/(app)/settings.tsx:525 +#: app/(app)/friends.tsx:51 +msgid "Sign In" +msgstr "Sign In" + +#: app/(app)/friends.tsx:48 +msgid "Sign in to use the Friends feature." +msgstr "Sign in to use the Friends feature." + +#: app/(app)/settings.tsx:561 msgid "Sign in with Google" msgstr "Sign in with Google" -#: constants/HelpData.ts:174 +#: constants/HelpData.ts:194 msgid "Sign in with Google in Settings to enable cloud backups of all your workout data. Tap Backup at any time to save a snapshot; the date of your last backup is shown beneath the button. Tap Restore to download and apply your latest backup; confirm the prompt and the app will reload with your restored data. Your backups are stored securely and are tied to your Google account. If you switch devices or reinstall the app, simply sign in with the same Google account and tap Restore to get your data back." msgstr "Sign in with Google in Settings to enable cloud backups of all your workout data. Tap Backup at any time to save a snapshot; the date of your last backup is shown beneath the button. Tap Restore to download and apply your latest backup; confirm the prompt and the app will reload with your restored data. Your backups are stored securely and are tied to your Google account. If you switch devices or reinstall the app, simply sign in with the same Google account and tap Restore to get your data back." #. placeholder {0}: user.displayName || user.email -#: app/(app)/settings.tsx:538 +#: app/(app)/settings.tsx:574 msgid "Signed in as {0}" msgstr "Signed in as {0}" -#: constants/HelpData.ts:168 +#: constants/HelpData.ts:188 msgid "Signing In" msgstr "Signing In" @@ -3050,16 +3379,16 @@ msgstr "Signing In" msgid "Single & Quick Workouts" msgstr "Single & Quick Workouts" -#: app/(app)/custom-exercise.tsx:505 +#: app/(app)/custom-exercise.tsx:531 #: app/(app)/exercise-info.tsx:263 msgid "Single-arm / single-leg" msgstr "Single-arm / single-leg" -#: app/(app)/settings.tsx:722 +#: app/(app)/settings.tsx:758 msgid "Size unit" msgstr "Size unit" -#: app/(app)/settings.tsx:1412 +#: app/(app)/settings.tsx:1451 msgid "Size: ~100MB" msgstr "Size: ~100MB" @@ -3101,10 +3430,18 @@ msgstr "Some images failed to delete. Failed exercise IDs: {0}" msgid "Some images failed to download after retries. Failed exercise IDs: {0}" msgstr "Some images failed to download after retries. Failed exercise IDs: {0}" +#: app/(app)/friends.tsx:237 +msgid "Something went wrong. Please try again." +msgstr "Something went wrong. Please try again." + #: constants/dbTranslations.ts:34 msgid "spine" msgstr "spine" +#: app/(app)/friend-profile.tsx:234 +msgid "Standalone Workouts" +msgstr "Standalone Workouts" + #: constants/HelpData.ts:39 msgid "Standalone workouts live outside of plans and appear alongside your plans on the Plans screen. Create one by tapping New Workout, give it a name, and add exercises; you can run it at any time without needing an active plan. An estimated duration is shown on each standalone workout so you can plan your time before starting. Quick Workouts let you start a session immediately from the home screen: tap Quick Workout, add exercises as you go, and at the end you can save it as a standalone workout for future use or simply discard it. Like plans, the workout editor automatically saves a draft so you can safely leave and return without losing your work." msgstr "Standalone workouts live outside of plans and appear alongside your plans on the Plans screen. Create one by tapping New Workout, give it a name, and add exercises; you can run it at any time without needing an active plan. An estimated duration is shown on each standalone workout so you can plan your time before starting. Quick Workouts let you start a session immediately from the home screen: tap Quick Workout, add exercises as you go, and at the end you can save it as a standalone workout for future use or simply discard it. Like plans, the workout editor automatically saves a draft so you can safely leave and return without losing your work." @@ -3113,7 +3450,7 @@ msgstr "Standalone workouts live outside of plans and appear alongside your plan msgid "Start" msgstr "Start" -#: app/(app)/(tabs)/(plans)/overview.tsx:282 +#: app/(app)/(tabs)/(plans)/overview.tsx:327 msgid "Start Plan" msgstr "Start Plan" @@ -3121,11 +3458,11 @@ msgstr "Start Plan" msgid "Start Timer" msgstr "Start Timer" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:267 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:319 msgid "Start Workout" msgstr "Start Workout" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:223 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:235 #: app/(app)/(tabs)/index.tsx:306 msgid "Starting Workout..." msgstr "Starting Workout..." @@ -3136,7 +3473,7 @@ msgstr "stationary bike" #: app/(app)/(tabs)/_layout.tsx:74 #: app/(app)/(tabs)/(stats)/_layout.tsx:16 -#: app/(app)/settings.tsx:994 +#: app/(app)/settings.tsx:1030 msgid "Stats" msgstr "Stats" @@ -3144,7 +3481,7 @@ msgstr "Stats" msgid "Stats & History" msgstr "Stats & History" -#: app/(app)/custom-exercise.tsx:499 +#: app/(app)/custom-exercise.tsx:525 msgid "Stats Options" msgstr "Stats Options" @@ -3168,7 +3505,15 @@ msgstr "Stop" msgid "Streak" msgstr "Streak" -#: app/(app)/settings.tsx:55 +#: app/(app)/friend-profile.tsx:491 +msgid "Strength PRs" +msgstr "Strength PRs" + +#: app/(app)/settings.tsx:1825 +msgid "Strength PRs are shared automatically after each workout." +msgstr "Strength PRs are shared automatically after each workout." + +#: app/(app)/settings.tsx:58 msgid "Su" msgstr "Su" @@ -3177,7 +3522,7 @@ msgstr "Su" msgid "Success" msgstr "Success" -#: app/(app)/settings.tsx:1088 +#: app/(app)/settings.tsx:1124 msgid "Suggest load and rep adjustments" msgstr "Suggest load and rep adjustments" @@ -3204,8 +3549,8 @@ msgstr "Superset" #. placeholder {0}: outgoingSnapshot.isFirstInSuperset ? "A" : "B" #. placeholder {0}: ss.isFirstInSuperset ? "A" : "B" -#: app/(app)/(workout)/workout-session.tsx:1405 -#: app/(app)/(workout)/workout-session.tsx:1491 +#: app/(app)/(workout)/workout-session.tsx:1436 +#: app/(app)/(workout)/workout-session.tsx:1522 msgid "Superset {0}" msgstr "Superset {0}" @@ -3217,7 +3562,11 @@ msgstr "Supersets" msgid "Take full control of your training by designing your own personalised plan. Select exercises, set rep ranges, rest times, and more to create a plan that aligns perfectly with your fitness goals." msgstr "Take full control of your training by designing your own personalised plan. Select exercises, set rep ranges, rest times, and more to create a plan that aligns perfectly with your fitness goals." -#: constants/HelpData.ts:169 +#: constants/HelpData.ts:179 +msgid "Tap any accepted friend in your Friends list to open their profile. Their profile shows the plans, standalone workouts, and custom exercises they have chosen to share. Tap Import on any item to add it directly to your own library. Imported plans and workouts are saved as new copies that you can edit freely without affecting the original. Imported custom exercises are added to your exercise library and available immediately when building workouts." +msgstr "Tap any accepted friend in your Friends list to open their profile. Their profile shows the plans, standalone workouts, and custom exercises they have chosen to share. Tap Import on any item to add it directly to your own library. Imported plans and workouts are saved as new copies that you can edit freely without affecting the original. Imported custom exercises are added to your exercise library and available immediately when building workouts." + +#: constants/HelpData.ts:189 msgid "Tap Sign In With Google in Settings to connect your account. Signing in enables cloud backups so your data is safe if you switch devices or reinstall the app, and your name is shown in the home screen greeting. The app works fully offline without signing in, but cloud backups are unavailable. Your data is stored locally on your device and is not shared with anyone unless you choose to share it yourself." msgstr "Tap Sign In With Google in Settings to connect your account. Signing in enables cloud backups so your data is safe if you switch devices or reinstall the app, and your name is shown in the home screen greeting. The app works fully offline without signing in, but cloud backups are unavailable. Your data is stored locally on your device and is not shared with anyone unless you choose to share it yourself." @@ -3229,11 +3578,15 @@ msgstr "Tap the star icon in the top-right corner of any exercise info screen to msgid "Target Distance ({distanceUnit})" msgstr "Target Distance ({distanceUnit})" -#: app/(app)/custom-exercise.tsx:393 +#: app/(app)/friend-exercise.tsx:76 +msgid "Target Muscle" +msgstr "Target Muscle" + +#: app/(app)/custom-exercise.tsx:419 msgid "Target Muscle *" msgstr "Target Muscle *" -#: app/(app)/custom-exercise.tsx:202 +#: app/(app)/custom-exercise.tsx:207 msgid "Target muscle is required." msgstr "Target muscle is required." @@ -3245,7 +3598,7 @@ msgstr "Target muscle:" msgid "Target: {distanceMin} {distanceUnit}" msgstr "Target: {distanceMin} {distanceUnit}" -#: app/(app)/settings.tsx:52 +#: app/(app)/settings.tsx:55 msgid "Th" msgstr "Th" @@ -3293,6 +3646,14 @@ msgstr "Thigh (R)" msgid "This exercise is already in your workout. Please choose a different one." msgstr "This exercise is already in your workout. Please choose a different one." +#: app/(app)/friend-profile.tsx:140 +msgid "This friend hasn't shared any content yet." +msgstr "This friend hasn't shared any content yet." + +#: app/(app)/settings.tsx:88 +msgid "This removes all content you have shared with friends. Your friends and friend list are not affected." +msgstr "This removes all content you have shared with friends. Your friends and friend list are not affected." + #: app/(app)/+not-found.tsx:18 msgid "This screen doesn't exist." msgstr "This screen doesn't exist." @@ -3308,7 +3669,7 @@ msgstr "Thu" msgid "Thursday" msgstr "Thursday" -#: app/(app)/custom-exercise.tsx:65 +#: app/(app)/custom-exercise.tsx:70 #: components/WeeklySummaryCard.tsx:299 msgid "Time" msgstr "Time" @@ -3335,7 +3696,7 @@ msgstr "Time (s)" msgid "Time PR" msgstr "Time PR" -#: app/(app)/(workout)/workout-session.tsx:552 +#: app/(app)/(workout)/workout-session.tsx:559 msgid "Time to do your next set!" msgstr "Time to do your next set!" @@ -3344,11 +3705,11 @@ msgstr "Time to do your next set!" msgid "Time: {0}" msgstr "Time: {0}" -#: app/(app)/settings.tsx:365 +#: app/(app)/settings.tsx:401 msgid "To enable rest timer notifications, grant notification permissions in your device settings." msgstr "To enable rest timer notifications, grant notification permissions in your device settings." -#: app/(app)/settings.tsx:384 +#: app/(app)/settings.tsx:420 msgid "To enable workout reminders, grant notification permissions in your device settings." msgstr "To enable workout reminders, grant notification permissions in your device settings." @@ -3413,15 +3774,19 @@ msgstr "Tracked Exercises" msgid "Tracking" msgstr "Tracking" -#: app/(app)/custom-exercise.tsx:465 +#: app/(app)/friend-exercise.tsx:90 +msgid "Tracking Type" +msgstr "Tracking Type" + +#: app/(app)/custom-exercise.tsx:491 msgid "Tracking Type *" msgstr "Tracking Type *" -#: app/(app)/custom-exercise.tsx:485 +#: app/(app)/custom-exercise.tsx:511 msgid "Tracking type cannot be changed after creation." msgstr "Tracking type cannot be changed after creation." -#: app/(app)/custom-exercise.tsx:205 +#: app/(app)/custom-exercise.tsx:210 msgid "Tracking type is required." msgstr "Tracking type is required." @@ -3439,7 +3804,7 @@ msgstr "" msgid "Training" msgstr "Training" -#: components/TrainingPlanCard.tsx:74 +#: components/TrainingPlanCard.tsx:77 msgid "Training Plan" msgstr "Training Plan" @@ -3475,7 +3840,7 @@ msgstr "triceps" msgid "Try Again" msgstr "Try Again" -#: app/(app)/settings.tsx:50 +#: app/(app)/settings.tsx:53 msgid "Tu" msgstr "Tu" @@ -3498,7 +3863,11 @@ msgstr "Type to filter help topics" msgid "Unable to save your workout. Please try again later." msgstr "Unable to save your workout. Please try again later." -#: app/(app)/settings.tsx:650 +#: app/(app)/friend-exercise.tsx:97 +msgid "Unilateral" +msgstr "Unilateral" + +#: app/(app)/settings.tsx:686 msgid "Units of measurement" msgstr "Units of measurement" @@ -3510,7 +3879,17 @@ msgstr "Unknown" msgid "Update Ready" msgstr "Update Ready" -#: app/(app)/settings.tsx:634 +#. placeholder {0}: formatDistanceToNow(plan.updatedAt.toDate(), { addSuffix: true, }) +#. placeholder {0}: formatDistanceToNow(plan.updatedAt.toDate(), { addSuffix: true }) +#. placeholder {0}: formatDistanceToNow(workout.updatedAt.toDate(), { addSuffix: true, }) +#: app/(app)/friend-plan.tsx:75 +#: app/(app)/friend-profile.tsx:185 +#: app/(app)/friend-profile.tsx:276 +#: app/(app)/friend-workout.tsx:62 +msgid "Updated {0}" +msgstr "Updated {0}" + +#: app/(app)/settings.tsx:670 msgid "Uploading. Please wait..." msgstr "Uploading. Please wait..." @@ -3542,11 +3921,11 @@ msgstr "upper chest" msgid "upper legs" msgstr "upper legs" -#: app/(app)/settings.tsx:979 +#: app/(app)/settings.tsx:1015 msgid "Using history from same workout" msgstr "Using history from same workout" -#: app/(app)/settings.tsx:978 +#: app/(app)/settings.tsx:1014 msgid "Using most recent from any workout" msgstr "Using most recent from any workout" @@ -3554,7 +3933,7 @@ msgstr "Using most recent from any workout" msgid "Values" msgstr "Values" -#: app/(app)/settings.tsx:876 +#: app/(app)/settings.tsx:912 msgid "Vibrate after rest" msgstr "Vibrate after rest" @@ -3623,7 +4002,7 @@ msgstr "Warm-up, " msgid "warmup" msgstr "warmup" -#: app/(app)/settings.tsx:51 +#: app/(app)/settings.tsx:54 msgid "We" msgstr "We" @@ -3642,7 +4021,7 @@ msgstr "Wednesday" msgid "Week streak" msgstr "Week streak" -#: app/(app)/settings.tsx:558 +#: app/(app)/settings.tsx:594 msgid "Weekly goal" msgstr "Weekly goal" @@ -3666,7 +4045,7 @@ msgstr "Weight" msgid "Weight ({weightUnitLabel})" msgstr "Weight ({weightUnitLabel})" -#: app/(app)/settings.tsx:755 +#: app/(app)/settings.tsx:791 msgid "Weight increment" msgstr "Weight increment" @@ -3674,11 +4053,11 @@ msgstr "Weight increment" msgid "Weight Tracking for Bodyweight Exercises" msgstr "Weight Tracking for Bodyweight Exercises" -#: app/(app)/settings.tsx:670 +#: app/(app)/settings.tsx:706 msgid "Weight unit" msgstr "Weight unit" -#: app/(app)/custom-exercise.tsx:62 +#: app/(app)/custom-exercise.tsx:67 msgid "Weight/Reps" msgstr "Weight/Reps" @@ -3702,7 +4081,7 @@ msgstr "Welcome{userName}" msgid "When you open a workout that contains exercises you trained recently, a Recovery Check-in sheet appears if those exercises have a pending progression suggestion and your last session was at least 12 hours ago. For each relevant muscle group, you choose one of three options: Fresh (fully recovered), Mild soreness, or Still very sore. If a muscle is marked as still very sore, any upward progression suggestion for exercises targeting that muscle is paused and held at the current load until you re-evaluate at the start of the following session. Fresh or Mild soreness does not affect suggestions. Tap Skip for now to bypass the check-in entirely; a skipped check-in is treated the same as fresh recovery, so pending suggestions are unaffected." msgstr "When you open a workout that contains exercises you trained recently, a Recovery Check-in sheet appears if those exercises have a pending progression suggestion and your last session was at least 12 hours ago. For each relevant muscle group, you choose one of three options: Fresh (fully recovered), Mild soreness, or Still very sore. If a muscle is marked as still very sore, any upward progression suggestion for exercises targeting that muscle is paused and held at the current load until you re-evaluate at the start of the following session. Fresh or Mild soreness does not affect suggestions. Tap Skip for now to bypass the check-in entirely; a skipped check-in is treated the same as fresh recovery, so pending suggestions are unaffected." -#: components/ExerciseFeedbackSheet.tsx:233 +#: components/ExerciseFeedbackSheet.tsx:247 msgid "Where did you feel it?" msgstr "Where did you feel it?" @@ -3712,7 +4091,7 @@ msgstr "working" #: app/(app)/(tabs)/(plans)/_layout.tsx:18 #: app/(app)/(workout)/_layout.tsx:17 -#: app/(app)/settings.tsx:734 +#: app/(app)/settings.tsx:770 #: components/RestDayCard.tsx:41 #: components/WeeklyScheduleDisplay.tsx:88 #: components/WorkoutDoneCard.tsx:50 @@ -3735,7 +4114,8 @@ msgstr "Workout Calendar" msgid "Workout Complete!" msgstr "Workout Complete!" -#: app/(app)/_layout.tsx:33 +#: app/(app)/_layout.tsx:35 +#: app/(app)/_layout.tsx:55 #: app/(app)/(tabs)/(stats)/_layout.tsx:19 msgid "Workout Details" msgstr "Workout Details" @@ -3753,13 +4133,14 @@ msgstr "Workout in progress" msgid "Workout name" msgstr "Workout name" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:54 -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:207 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:66 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:219 #: app/(app)/(workout)/workout-summary.tsx:518 +#: app/(app)/friend-workout.tsx:43 msgid "Workout not found." msgstr "Workout not found." -#: app/(app)/settings.tsx:1255 +#: app/(app)/settings.tsx:1294 msgid "Workout reminders" msgstr "Workout reminders" @@ -3803,7 +4184,7 @@ msgstr "x {0} reps " msgid "Yes" msgstr "Yes" -#: components/ExerciseFeedbackSheet.tsx:215 +#: components/ExerciseFeedbackSheet.tsx:229 msgid "Yes, increase the challenge" msgstr "Yes, increase the challenge" @@ -3811,7 +4192,7 @@ msgstr "Yes, increase the challenge" msgid "Yesterday" msgstr "Yesterday" -#: app/(app)/(tabs)/(plans)/overview.tsx:150 +#: app/(app)/(tabs)/(plans)/overview.tsx:161 msgid "You activated this plan." msgstr "You activated this plan." @@ -3823,6 +4204,10 @@ msgstr "You can hide this onboarding screen at any time from the settings page i msgid "You can login at any time from the settings screen, if you choose to skip it now." msgstr "You can login at any time from the settings screen, if you choose to skip it now." +#: constants/HelpData.ts:174 +msgid "You can share plans, standalone workouts, custom exercises, body measurements, and strength PRs with your friends. All five categories have a global toggle in Privacy Settings, found in the Account section of Settings. Enabling the global toggle for a category shares all items in that category and syncs new data automatically whenever it changes. Plans and standalone workouts also have an individual Share toggle on each item's overview screen, so you can publish specific plans or workouts without sharing everything. A cloud icon on the plan or workout card confirms it is currently published. To remove shared data, disable the toggle in Privacy Settings and tap Delete Shared Data for that category. You can also delete all shared data for every category from the same screen." +msgstr "You can share plans, standalone workouts, custom exercises, body measurements, and strength PRs with your friends. All five categories have a global toggle in Privacy Settings, found in the Account section of Settings. Enabling the global toggle for a category shares all items in that category and syncs new data automatically whenever it changes. Plans and standalone workouts also have an individual Share toggle on each item's overview screen, so you can publish specific plans or workouts without sharing everything. A cloud icon on the plan or workout card confirms it is currently published. To remove shared data, disable the toggle in Privacy Settings and tap Delete Shared Data for that category. You can also delete all shared data for every category from the same screen." + #: components/ProgressionSummaryCard.tsx:22 msgid "You chose to keep it steady. Hold this load." msgstr "You chose to keep it steady. Hold this load." @@ -3850,11 +4235,11 @@ msgstr "You have unsaved changes. Are you sure you want to discard them?" msgid "You modified this workout. Save those changes for future sessions?" msgstr "You modified this workout. Save those changes for future sessions?" -#: app/(app)/settings.tsx:604 +#: app/(app)/settings.tsx:640 msgid "You need to sign in to use this feature" msgstr "You need to sign in to use this feature" -#: app/(app)/custom-exercise.tsx:81 +#: app/(app)/custom-exercise.tsx:86 msgid "You'll lose what you've entered so far." msgstr "You'll lose what you've entered so far." @@ -3870,10 +4255,10 @@ msgstr "You've hit your weekly goal. Incredible work!" msgid "Your journey to Swoletown begins today!" msgstr "Your journey to Swoletown begins today!" -#: app/(app)/(tabs)/(plans)/index.tsx:126 +#: app/(app)/(tabs)/(plans)/index.tsx:130 msgid "Your training plans" msgstr "Your training plans" -#: app/(app)/(tabs)/(plans)/index.tsx:141 +#: app/(app)/(tabs)/(plans)/index.tsx:147 msgid "Your workouts" msgstr "Your workouts" diff --git a/locales/es/messages.js b/locales/es/messages.js index ec76d287..c5190b2e 100644 --- a/locales/es/messages.js +++ b/locales/es/messages.js @@ -1 +1 @@ -/*eslint-disable*/module.exports={messages:JSON.parse("{\"-2Ut5a\":[\"La franja de Estadísticas clave en la parte superior de la pestaña Estadísticas ofrece cuatro aspectos destacados de un vistazo para el rango de tiempo seleccionado: tu promedio de entrenamientos por semana, tu mayor ganancia de fuerza entre los ejercicios seguidos, la parte del cuerpo que más has entrenado y tu racha semanal actual. Se actualizan automáticamente tras cada entrenamiento.\"],\"-5kO8P\":[\"Sábado\"],\"-BjMj_\":[\"Crear entrenamiento\"],\"-FjWgX\":[\"Jue\"],\"-Tpjjs\":[[\"0\"],\" series\"],\"-WSEJS\":[\"Eliminar entrenamiento\"],\"-Xejuf\":[\"Caderas\"],\"-XvJee\":[\"mejor \",[\"0\"],[\"weightUnit\"],\" × \",[\"1\"]],\"-svcUj\":[\"¿Guardar este entrenamiento?\"],\"03mQOq\":[\"Error al activar este plan: \",[\"0\"]],\"06EUQy\":[\"PR histórico\"],\"0EHHPz\":[\"aductores\"],\"0EPpEZ\":[\"Añadir métrica personalizada\"],\"0EcUWz\":[\"¿Descartar cambios?\"],\"0OeId4\":[\"Crear un plan personalizado\"],\"0P1btN\":[\"\\n🔔 Nuevo: ¡Sonidos del temporizador de ejercicios!\\n\\nEl temporizador de ejercicios ahora reproduce señales de audio para mantenerte en camino. Un pitido de cuenta atrás cuando el temporizador se acerca a cero y un sonido cuando alcanzas tu objetivo. Activa o desactiva cada sonido de forma independiente en Ajustes.\\n\"],\"0SaB4K\":[\"Serie de calentamiento\"],\"0U938S\":[\"Selecciona al menos un día\"],\"0V9gKq\":[\"\\n🔵 Nuevo: ¡Modal del temporizador de ejercicios!\\n\\nLos ejercicios basados en tiempo ahora muestran un modal de cuenta atrás dedicado con un anillo de progreso, lo que facilita el seguimiento de tu esfuerzo y mantener el ritmo durante las series cronometradas.\\n\"],\"0caMy7\":[\"Historial\"],\"0dHvKo\":[\"Músculo objetivo:\"],\"0eRpDV\":[\"Difícil, cerca del límite\"],\"0f7U0k\":[\"Mié\"],\"0tJJBW\":[\"Anterior: \"],\"0vGEy2\":[\"\\n📊 Nuevo: ¡Pantalla de estadísticas mejorada!\\n\\nLa pantalla de estadísticas ha sido rediseñada con un aspecto renovado y perspectivas mejoradas. Explora tu historial de entrenamiento con mejores gráficos, resúmenes más claros y desgloses más detallados de tu progreso a lo largo del tiempo.\\n\"],\"14ytif\":[\"Iniciar entrenamiento\"],\"1DPB1m\":[\"\\n🗂️ Nuevo: ¡Cinco nuevos planes de entrenamiento prediseñados!\\n\\nCinco nuevos planes listos para usar están ahora disponibles: Split de 5 días Bro, Push/Pull/Piernas de 5 días, Split de 6 días, Peso corporal y Solo mancuernas. Tanto si entrenas en casa como en el gimnasio, hay un plan para que empieces de inmediato.\\n\"],\"1FnEj9\":[\"Medidas corporales\"],\"1Kx4Hp\":[\"Error al obtener \",[\"0\"],\": \",[\"1\"]],\"1Mx10o\":[\"Ver estadísticas\"],\"1QfxQT\":[\"Cerrar\"],\"1Se9J7\":[\"bicicleta estática\"],\"1UzENP\":[\"No\"],\"1gbc4_\":[\"Nuevo entrenamiento\"],\"1hW6-f\":[\"Algunas imágenes no se pudieron descargar tras varios intentos. IDs de ejercicio fallidos: \",[\"0\"]],\"1j3Ob3\":[\"Calendario de entrenamientos\"],\"1mm2JF\":[\"deltoides\"],\"296mtr\":[\"barra trampa\"],\"29Hx9U\":[\"Estadísticas\"],\"2FYpfJ\":[\"Más\"],\"2ZZM6V\":[\"core\"],\"2bnWaQ\":[[\"completedCount\"],\"/\",[\"0\"],\" series completadas\"],\"2cupe5\":[\"Aplicar a todas las series \",[\"0\"]],\"2dPYb7\":[\"Aún no hay medidas. Registra tu primera entrada arriba.\"],\"2dX9Kv\":[\"espalda\"],\"2eB2c7\":[\"¡Entrena sin un plan! Crea entrenamientos independientes que viven fuera de tus planes de entrenamiento, perfectos para sesiones de movilidad, calentamientos o cualquier cosa improvisada.\\n\\nO entra directamente en un Entrenamiento rápido desde la pantalla de inicio, añade ejercicios sobre la marcha y opcionalmente guárdalo como entrenamiento independiente cuando termines.\"],\"2gSypt\":[\"Equipamiento *\"],\"2j0v05\":[\"¡Todas las imágenes se han descargado correctamente!\"],\"2lfUf3\":[[\"streak\",\"plural\",{\"one\":[\"#\",\" semana consecutiva\"],\"other\":[\"#\",\" semanas consecutivas\"]}]],\"2saL1j\":[\"1RM\"],\"2vS4Oc\":[\"Fácil, podría haber hecho más\"],\"2wR0QE\":[\"Añadir ejercicio\"],\"30xwUM\":[\"¿Estás seguro de que quieres eliminar todas las imágenes animadas? Las imágenes individuales se volverán a descargar automáticamente cuando se vean.\"],\"39y5bn\":[\"Viernes\"],\"3A79ox\":[\"Reducir peso\"],\"3L-1Z1\":[\"Error al cargar los ejercicios: \",[\"0\"]],\"3RoflF\":[\"\\n📈 Nuevo: ¡Historial de ejercicios en la pantalla de información!\\n\\nLa pantalla de información del ejercicio ahora incluye un historial completo de cada vez que has realizado ese ejercicio, mostrando pesos, reps, tiempo y distancia de cada serie en sesiones anteriores. Accede a él durante un entrenamiento, desde tu plan o desde cualquier lugar donde esté disponible la información del ejercicio.\\n\"],\"3ezHPX\":[\"Reproducir sonido tras el descanso\"],\"3hJ166\":[\"\\n🔍 Mejorado: ¡Búsqueda de ejercicios más inteligente y acceso fácil a la biblioteca de ejercicios!\\n\\nLa búsqueda de ejercicios ahora reconoce abreviaturas comunes como RDL, OHP, DB y KB, corrige pequeños errores tipográficos y clasifica los resultados por relevancia para que la mejor coincidencia aparezca siempre primero.\\n\\nTambién puedes explorar la biblioteca completa de ejercicios en cualquier momento desde el menú, sin necesidad de estar en un entrenamiento o plan.\\n\"],\"3hJypY\":[\"Estadísticas clave\"],\"43lYJ-\":[\"Bienvenido/a\",[\"userName\"]],\"4BgR4M\":[\"Has alcanzado tu objetivo semanal. ¡Increíble trabajo!\"],\"4GTHgi\":[\"Cuenta atrás del temporizador de ejercicio\"],\"4M4P8M\":[\"No se han introducido valores\"],\"4OjqAQ\":[\"Seguir editando\"],\"4_WLmI\":[\"peso corporal\"],\"4j0zbV\":[\"Guardando plan...\"],\"4jkyRj\":[\"calentamiento\"],\"4mrNi3\":[[\"suggestedRepsMin\"],\"-\",[\"suggestedRepsMax\"],\" reps sugeridas\"],\"4oRoD4\":[\"Configura las unidades de peso, tamaño y distancia, las series predeterminadas por ejercicio, el tiempo de descanso predeterminado y el incremento de peso de los botones ± durante la sesión. Ajusta el tamaño de los botones de entrenamiento (Estándar, Grande o Muy grande) y activa Mantener pantalla encendida para que la pantalla no se apague. En Estadísticas, puedes excluir las series de calentamiento del volumen, duplicar las repeticiones en ejercicios unilaterales o doblar el peso para implementos emparejados, útil si registras el peso de una mancuerna en lugar del total. Introduce tu peso corporal aquí; se usa para calcular la carga efectiva en ejercicios asistidos.\"],\"4sGdeG\":[\"Grasa corporal\"],\"50_FGa\":[\"Ejercicio\"],\"538Jsv\":[\"Cancelar entrenamiento\"],\"58iwz8\":[\"Error al cargar los planes\"],\"5SgD0L\":[\"Tienes cambios sin guardar. ¿Seguro que quieres descartarlos?\"],\"5Z05pb\":[\"Escribe para filtrar temas de ayuda\"],\"5aB9II\":[\"¡Es hora de tu próxima serie!\"],\"5b4J4v\":[\"Todo el tiempo\"],\"5lWFkC\":[\"Iniciar sesión\"],\"5w2VTM\":[\"¿Estás seguro de que quieres descargar todas las imágenes animadas? Puede tardar un poco.\"],\"5yIPLp\":[\"¡Vaya!\"],\"66llpx\":[\"Añadir imagen\"],\"699xiu\":[\"¿Estás seguro de que quieres restaurar la copia de seguridad?\"],\"6Bqki7\":[\"¡Objetivo semanal completado!\"],\"6Hcqaf\":[\"\\n↕️ Nuevo: ¡Reordena entrenamientos en tu plan!\\n\\nAhora puedes reordenar los entrenamientos directamente en la pantalla de creación del plan y en las tarjetas de entrenamiento, dándote control total sobre la estructura de tu horario de entrenamiento.\\n\"],\"6MR2yM\":[\"Explora casi 1.000 ejercicios y filtra por parte del cuerpo, músculo objetivo o equipamiento. Usa los chips de ordenación en la parte superior para ordenar los ejercicios por Predeterminado, Plan activo, Reciente o Frecuente, y así los ejercicios más relevantes para ti aparecerán primero. Al reemplazar un ejercicio, el filtro preselecciona automáticamente el músculo objetivo correspondiente para ayudarte a encontrar alternativas más rápido. Toca cualquier ejercicio para ver su demostración animada, los músculos trabajados y un historial completo de cada vez que lo has realizado, incluyendo pesos, reps, tiempo o distancia por serie. Descarga todas las animaciones de ejercicios (~100 MB) en Ajustes para acceso sin conexión.\"],\"6XIVae\":[\"Subir peso\"],\"6_dCYd\":[\"Vista general\"],\"6g63at\":[\"Explorar planes\"],\"6glEtt\":[\"Todavía en recuperación. Mantener este peso por ahora.\"],\"6igHT6\":[\"Editar entrenamiento\"],\"6lAGPA\":[\"Añade un entrenamiento para empezar\"],\"6lv7us\":[\"Peso (\",[\"weightUnitLabel\"],\")\"],\"6q7I63\":[\"cintura\"],\"6u9LvN\":[[\"days\",\"plural\",{\"one\":[\"hace \",\"#\",\" día\"],\"other\":[\"hace \",\"#\",\" días\"]}]],\"6uHnph\":[\"Tiempo (Hora:Min)\"],\"6vinCF\":[\"Tipo de seguimiento *\"],\"6z9W13\":[\"Reiniciar\"],\"716aO7\":[\"Más entrenado\"],\"75Qc-e\":[\"Cuenta reps ×2 para el volumen cuando el ajuste está activado\"],\"77kllS\":[\"mejor \",[\"0\"],\" reps\"],\"7F8buC\":[\"brazos inferiores\"],\"7FYy4K\":[\"Error al guardar el entrenamiento\"],\"7LBKtm\":[\"No hay entrenamiento disponible\"],\"7LLkrj\":[\"músculos de agarre\"],\"7MuXko\":[\"Personal\"],\"7P_9OY\":[\"Ma\"],\"7YT_7y\":[\"Reps\"],\"7Z9Tzs\":[\"columna vertebral\"],\"7eMo-U\":[\"Ir al inicio\"],\"7hAJKI\":[[\"0\",\"plural\",{\"one\":[\"serie\"],\"other\":[\"series\"]}]],\"7iTVa8\":[\"Músculos secundarios\"],\"7p3sn_\":[\"Tiempo: \",[\"0\"]],\"7x42zy\":[\"No hay datos para este período\"],\"7xB0qQ\":[\"Músculo objetivo *\"],\"87VAxI\":[\"Info del ejercicio\"],\"8Mlj-A\":[\"No se alcanzó el objetivo de reps. Mantener por ahora.\"],\"8Rd3od\":[\"¿Estás seguro de que quieres cancelar y eliminar este entrenamiento?\"],\"8V8f_Q\":[\"Último \",[\"metricLabel\"],\": \",[\"0\"]],\"8YBh-G\":[\"Contando reps ×2 para estos ejercicios\"],\"8ZJ9dh\":[\"Registro de peso para ejercicios con peso corporal\"],\"8ZU8FI\":[\"Error al cargar las estadísticas. Por favor, inténtalo de nuevo.\"],\"8_MCsG\":[\"\\n💾 Nuevo: ¡Guarda y reanuda borradores de planes y entrenamientos!\\n\\nTu trabajo en los editores de planes y entrenamientos independientes ahora se guarda automáticamente como borrador. Si sales a mitad de la edición, se te preguntará si quieres continuar donde lo dejaste o descartar el borrador, para que nunca pierdas el progreso por accidente.\\n\"],\"8aTiea\":[\"Personalización\"],\"8cA6YX\":[\"Sigue tu composición corporal a lo largo del tiempo desde la sección Medidas del tab Estadísticas. Usa el formulario Registrar entrada para introducir valores en cualquier métrica activa y toca una entrada anterior en el historial para revisarla o editarla. En la pantalla de detalle de la entrada, toca el chip de una métrica para cambiar el gráfico entre distintas medidas y usa el selector de rango de tiempo para acercar o alejar la vista. Las métricas se dividen en tres tipos: masa (peso, en kg o lbs), longitud (circunferencias como cintura y caderas, en cm o pulgadas) y porcentaje (grasa corporal). Las unidades siguen tus preferencias de peso y tamaño en Ajustes. Para controlar qué métricas aparecen en el formulario, toca Gestionar métricas en la parte superior de la sección Registrar entrada. Las métricas integradas pueden activarse o desactivarse; también puedes crear métricas personalizadas y elegir su tipo. Las métricas personalizadas pueden ocultarse del formulario en cualquier momento y tus datos históricos se conservan siempre.\"],\"8jcZyX\":[\"Métricas integradas\"],\"8mjpCE\":[\"Introducción a MuscleQuest\"],\"8uqQSD\":[\"No pude terminar todas las series\"],\"8yLreB\":[\"durante \",[\"0\"],\"s \"],\"8yw7nc\":[\"Control de recuperación\"],\"91hJvI\":[\"Objetivo: \",[\"distanceMin\"],\" \",[\"distanceUnit\"]],\"94FTWy\":[\"Eliminación completa\"],\"95IyBI\":[\"Los ejercicios con peso corporal como las dominadas o los fondos registran solo repeticiones por defecto. Si quieres anotar peso adicional, como un cinturón de lastre o un chaleco, abre el resumen de series de ese ejercicio en el editor de entrenamiento o plan y activa Registrar peso. La opción se guarda por entrenamiento, así que puedes tener algunos entrenamientos solo con peso corporal y otros que registren la carga adicional. Los gráficos de progresión y el historial reflejarán el peso registrado una vez que la opción esté activada.\"],\"97-TIS\":[\"No pudiste completar todas las series. El peso baja un poco para la próxima.\"],\"9C6X7Q\":[\"Descartar cambios\"],\"9EGOsa\":[\"cable\"],\"9H3-WL\":[\"\\n⚙️ Nuevo: ¡Tres nuevas opciones de estadísticas!\\n\\nPersonaliza cómo se calculan tu volumen y tus estadísticas con tres nuevas opciones en Ajustes:\\n\\n• Excluir las series de calentamiento de las estadísticas para que no distorsionen tus números.\\n• Doblar el peso de las mancuernas automáticamente, para que puedas registrar el peso de una mancuerna y que el total se calcule solo.\\n• Doblar las reps de los ejercicios unilaterales, para que los movimientos unilaterales se cuenten correctamente en tus totales de volumen.\\n\"],\"9LmK3L\":[\"Imágenes de Unsplash\"],\"9XoWik\":[\"serrato anterior\"],\"9eQmcp\":[[\"0\"],\" días por semana\"],\"A-gAFO\":[\"Crea tus propios ejercicios desde el selector de ejercicios. Dale un nombre, una imagen opcional, parte del cuerpo, músculos objetivo, músculos secundarios y equipamiento. Elige un tipo de seguimiento: peso + reps, tiempo, distancia, solo reps o asistido (que tiene en cuenta tu peso corporal para movimientos como dominadas asistidas). Activa Unilateral para ejercicios de un solo brazo o pierna; las reps pueden doblarse automáticamente en tus estadísticas. Activa Implementos pareados si registras el peso de un solo implemento en lugar del total: por ejemplo, si anotas 20 kg para una mancuerna, la app cuenta 40 kg hacia tu volumen.\"],\"A1-VaP\":[\"dorsal ancho\"],\"A1_kH4\":[\"Temporizador de ejercicio\"],\"A1taO8\":[\"Buscar\"],\"AWokve\":[\"Historial del mismo entrenamiento\"],\"AeXO77\":[\"Cuenta\"],\"AqyJQg\":[\"Feedback tras el ejercicio\"],\"Ayx1au\":[\"¿Estás seguro de que quieres eliminar este plan?\"],\"B8ZQ8n\":[\"Reps mín.\"],\"B9LtU1\":[\"Tienes cambios sin guardar de tu última sesión. ¿Quieres continuar?\"],\"BGO6Rp\":[\"¿Cómo se sienten estos músculos desde tu última sesión?\"],\"BTqs-Z\":[[\"0\",\"plural\",{\"one\":[\"#\",\" Serie\"],\"other\":[\"#\",\" Series\"]}]],\"BZDlVl\":[\"flexores de cadera\"],\"BaG4Vp\":[\"Frecuente\"],\"BdnYlL\":[\"Duración media\"],\"BpTc_M\":[\"Buscar en la ayuda\"],\"Bqo02Q\":[\"Iniciar temporizador\"],\"BrHgnn\":[\"\\n⏱️ Nuevo: ¡Temporizador de descanso ajustable!\\n\\nUn nuevo panel deslizante te permite ajustar la duración del descanso en cualquier momento durante un entrenamiento. Tu tiempo de descanso personalizado se guarda por serie, para que cada serie recuerde exactamente cuánto tiempo quieres descansar.\\n\"],\"BwTx3c\":[\"¿Estás seguro de que quieres eliminar \",[\"0\"],\"?\"],\"C4GKOD\":[[\"repRange\"],\" Reps, \"],\"CCTop_\":[\"Reciente\"],\"CE-M2e\":[\"Info\"],\"CV6Ez2\":[\"Toca Iniciar sesión con Google en Ajustes para conectar tu cuenta. Al iniciar sesión se activan las copias de seguridad en la nube para que tus datos estén seguros si cambias de dispositivo o reinstala la app, y tu nombre aparece en el saludo de la pantalla de inicio. La app funciona completamente sin conexión sin iniciar sesión, pero las copias de seguridad en la nube no están disponibles. Tus datos se almacenan localmente en tu dispositivo y no se comparten con nadie a menos que tú decidas hacerlo.\"],\"CZKXmk\":[\"tobillos\"],\"CaKjcv\":[\"Entrenamiento rápido\"],\"CghlOu\":[\"abdominales inferiores\"],\"CiUwqB\":[\"Ir a entrenamientos\"],\"D0GOrZ\":[\"Necesitas iniciar sesión para usar esta función\"],\"D3h1sn\":[\"trabajando\"],\"D45Cr4\":[\"Selecciona los músculos secundarios\"],\"D89zck\":[\"Dom\"],\"DBC3t5\":[\"Domingo\"],\"DIS-zd\":[\"Error al eliminar el plan: \",[\"0\"]],\"DJMHhb\":[\"La última sesión fue una descarga. Comparación omitida.\"],\"DNhKLr\":[\"\\n🎯 Mejorado: ¡Filtros de ejercicios más inteligentes!\\n\\nAl reemplazar un ejercicio, el filtro ahora preselecciona automáticamente el músculo objetivo para que coincida con lo que estás reemplazando. Solo se muestran los filtros relevantes según tu selección actual, lo que hace mucho más rápido encontrar la alternativa adecuada.\\n\"],\"DPfwMq\":[\"Listo\"],\"DTtUaj\":[\"Introduce al menos una medida para registrar.\"],\"DWFuyG\":[\"Eliminar ejercicio\"],\"DYOFso\":[\"estabilizadores del tobillo\"],\"DdBQBl\":[\"Horario semanal\"],\"Dh5Ge5\":[\"¿Algún dolor o problema de técnica?\"],\"Di-cgt\":[\"¡Bienvenido/a a MuscleQuest!\"],\"DqgDEk\":[\"El más reciente de cualquier entrenamiento\"],\"Dvc8Qg\":[\"Descripción:\"],\"Dy8Cvh\":[\"cuádriceps\"],\"Dy_8Fq\":[\"CERRAR\"],\"E3kRqj\":[[\"uniqueWorkoutDaysCount\"],\" / \",[\"0\"],\" días entrenados\"],\"EANWES\":[\"Error al cargar el historial\"],\"EMyNOr\":[[\"0\"],\" \",[\"1\"],\" (usado en ejercicios asistidos)\"],\"E_QGRL\":[\"Desactivado\"],\"Ef7StM\":[\"Desconocido\"],\"EfdYnO\":[[\"0\"],[\"distanceUnit\"]],\"EkVHAp\":[\"Incremento del temporizador de descanso\"],\"EoQHhQ\":[\"cinta de correr\"],\"Euo2Um\":[\"Tiempo (Min:Seg)\"],\"F37c1s\":[\"Abrir Ajustes\"],\"F6pfE9\":[\"Activo\"],\"FCGpHg\":[\"Aún no hay ejercicios en este entrenamiento.\"],\"FHIDZO\":[\"Guardar y seleccionar\"],\"FPsvA8\":[\"¡Entendido!\"],\"Fb5zs_\":[\"\\n⚖️ Nuevo: ¡Registrar peso para ejercicios con peso corporal!\\n\\nPara ejercicios con peso corporal como dominadas o fondos, ahora puedes activar el registro de peso por entrenamiento. Perfecto para variantes con peso adicional, para anotar el peso añadido y seguir la progresión con el tiempo.\\n\"],\"Fe0wLe\":[\"Superseries\"],\"FnTClW\":[\"Estás alcanzando los objetivos con facilidad. Es hora de añadir un poco más de peso.\"],\"Fp1hl-\":[\"Cargando plan...\"],\"FwCUad\":[\"El equipamiento es obligatorio.\"],\"G-iXUH\":[\"hombros\"],\"G2R9Qq\":[\"flexores de muñeca\"],\"G3myU-\":[\"Martes\"],\"G49bAb\":[\"máquina de palanca\"],\"G6rTvo\":[\"Seguir (\",[\"0\"],\")\"],\"GCV1HM\":[\"Sesión iniciada como \",[\"0\"]],\"GCqPY4\":[\"La pantalla de inicio muestra tu progreso hacia tu objetivo semanal de entrenamiento, que es el número de días que quieres entrenar cada semana, establecido en Ajustes. Una franja en la parte superior registra cuántos días has completado y resalta cada día completado. Debajo, los entrenamientos de tu plan activo se listan con su estado de finalización para la semana; toca Iniciar en cualquier entrenamiento para comenzar. La tarjeta que se muestra debajo cambia según tu estado: aparece una tarjeta Reanudar si hay una sesión en curso, una tarjeta Día de descanso en los días sin entrenamiento programado, y una tarjeta Entrenamiento completado que confirma que la sesión de hoy está terminada. Cuando alcanzas tu objetivo semanal, aparece una tarjeta Resumen semanal que muestra el total de entrenamientos, series y volumen de la semana, más tu racha, que cuenta el número de semanas consecutivas en las que has cumplido tu objetivo.\"],\"GGqR7k\":[\"Entrenamientos individuales y rápidos\"],\"GLJjec\":[\"Al fallo\"],\"GLm0-9\":[\"Dolor o problemas de técnica\"],\"GNurdZ\":[\"Eliminar ejercicio\"],\"GPeIuw\":[\"Distancia\"],\"GS7yxz\":[\"Permiso requerido\"],\"GSOeV2\":[\"isquiotibiales\"],\"GVN2lL\":[\"Crear ejercicio\"],\"GWvJTL\":[\"Más o menos bien\"],\"GX9tlq\":[\"cuello\"],\"Gd-KuS\":[\"Gestionar métricas\"],\"Gf9sn6\":[\"Buscando copias de seguridad...\"],\"GhCGeL\":[\"Series\"],\"GksdwI\":[\"Mejores series PR\"],\"HNWkJr\":[\"\\n📏 Nuevo: ¡Seguimiento de distancia para ejercicios personalizados!\\n\\nLos ejercicios personalizados ahora pueden usar un tipo de seguimiento por distancia, perfecto para movimientos de cardio y acondicionamiento como carreras, remadas o empujes de trineo. Registra la distancia de tus series y obtén información sobre tu progresión igual que con cualquier otro ejercicio.\\n\"],\"HYL9fJ\":[\"Registrar solo un lado para ejercicios de un brazo/pierna\"],\"Hp6ceF\":[\"No se puede guardar tu entrenamiento. Por favor, inténtalo de nuevo más tarde.\"],\"HpK_8d\":[\"Recargar\"],\"Hplwk7\":[\"Restaurando. Por favor, espera...\"],\"I2Hpku\":[\"Registrar peso\"],\"ICkQNB\":[\"Hora del recordatorio\"],\"IFowGw\":[\"cuerda\"],\"IHMx9j\":[\"Racha semanal\"],\"ILE1kp\":[\"brazos\"],\"IRiG-a\":[\"Vibrar tras el descanso\"],\"IUwGEM\":[\"Guardar cambios\"],\"IXxATP\":[\"Ejercicios personalizados\"],\"IbbuFX\":[\"Eliminando. Por favor, espera...\"],\"IuXB4Q\":[\"Añade una nota...\"],\"Izf0kk\":[\"Sin datos previos de peso. Mantener por ahora.\"],\"JE-yVp\":[\"Gestionar métricas\"],\"JR5hAM\":[\"1 año\"],\"JTkSvz\":[\"¿Estás seguro de que quieres eliminar este entrenamiento?\"],\"JVKmoO\":[\"La actualización no se pudo descargar. Comprueba tu conexión a internet y vuelve a abrir la app para intentarlo de nuevo.\"],\"JW7_2_\":[\"Descarga fallida\"],\"JWTR_A\":[\"Se ha producido un error al descargar las imágenes.\"],\"JYRqp5\":[\"Sá\"],\"JbvV5d\":[\"Durante una sesión, desliza a izquierda/derecha o usa los botones de flecha para moverte entre series. Introduce tu peso y reps, luego toca Completar serie. El tiempo total transcurrido se muestra en el encabezado durante toda la sesión. Puedes arrastrar el asa de cualquier tarjeta de ejercicio para reordenar ejercicios mientras la sesión está en curso. Los ejercicios basados en tiempo tienen un botón Iniciar temporizador que abre un cronómetro con un anillo de progreso que te indica cuándo alcanzas tu tiempo objetivo, pero puedes continuar todo lo que quieras. Las notas se pueden añadir por ejercicio mediante el icono de notas en el encabezado del ejercicio, por entrenamiento desde la pantalla de vista general del entrenamiento, o por plan desde la pantalla de vista general del plan. Si añades, eliminas o reordenas ejercicios o series durante una sesión, se te pedirá al final si quieres guardar esos cambios en el entrenamiento o plan original.\"],\"JfDOWo\":[\"La actualización está lista pero la app no pudo reiniciarse automáticamente. Intenta tocar el botón de abajo, o cierra y vuelve a abrir la app manualmente.\"],\"JkpsKr\":[\"Descargando. Por favor, espera...\"],\"JmZ_-d\":[\"Finalizar\"],\"JsIy35\":[\"Has activado este plan.\"],\"JumwGu\":[\"cardio\"],\"Jv9TrU\":[\"oblicuos\"],\"KIL-9T\":[\"Siguiente: \"],\"KKalG-\":[\"Fija ejercicios en la pestaña Estadísticas para seguir su progresión de fuerza con el tiempo. Cada ejercicio fijado muestra un gráfico de tu rendimiento en el rango de tiempo seleccionado, tu récord personal histórico, tus mejores series y una lista de sesiones recientes con la mejor serie por día. Los gráficos se actualizan automáticamente tras cada entrenamiento que incluya ese ejercicio.\"],\"KM1Iw2\":[\"MuscleQuest\"],\"KSqQx0\":[\"Reps máx.\"],\"Km7tR4\":[\"Invítame a un café\"],\"KmiPdE\":[\"mancuerna\"],\"KxWSWU\":[\"Mantener pantalla encendida durante el entrenamiento\"],\"LAC2eo\":[\"Recordatorios de entrenamiento\"],\"LAHzG1\":[\"Ver/Editar\"],\"LIrnc0\":[\"Aún no se han añadido ejercicios\"],\"LZKayn\":[\"Buscar en la ayuda…\"],\"LcPJBt\":[\"entrenamientos completados\"],\"LhMjLm\":[\"Tiempo\"],\"LyPttd\":[\"Pecho\"],\"M0GVkz\":[\"Selecciona un día para ver los entrenamientos.\"],\"M1POMr\":[\"Biblioteca de ejercicios\"],\"M4hMaA\":[\"Introduce un nombre para la métrica personalizada.\"],\"M57U8X\":[\"Agrupa dos ejercicios en una superserie para que alternen automáticamente durante una sesión, ideal para combinar músculos antagonistas o mantener la eficiencia entre series. Toca el menú de tres puntos en cualquier ejercicio del editor de entrenamiento y elige Crear superserie, luego selecciona el segundo ejercicio. Una etiqueta de color identifica en toda la app a qué superserie pertenece cada ejercicio. Cuando completas una serie en un ejercicio, la app te lleva directamente a su compañero de superserie.\"],\"MEt7-_\":[\"sóleo\"],\"MHk_Wu\":[\"Registro no encontrado.\"],\"MLQOxI\":[\"deltoides posteriores\"],\"MM-MTF\":[\"Superserie \",[\"0\"]],\"MQ9jL7\":[\"¡Un entrenamiento más para alcanzar tu objetivo!\"],\"MQA2H9\":[\"Eliminar plan\"],\"MTqmCb\":[\"Solicita o vota por nuevas funciones\"],\"McFNQO\":[\"Monitorea tu viaje fitness con estadísticas e información detalladas. Lleva un registro del historial de entrenamientos, analiza tus divisiones por parte del cuerpo y visualiza las mejoras con el tiempo mediante gráficos de progresión de ejercicios.\"],\"MmDz7_\":[\"Subiendo. Por favor, espera...\"],\"N4e_z1\":[\"Tiempo de descanso: \",[\"restMinutes\"],\":\",[\"0\"]],\"N85c_3\":[\"Eliminar entrenamiento\"],\"NC2AI2\":[\"Longitud\"],\"NIuBdI\":[\"Planes prediseñados\"],\"NKdWDE\":[\"sistema cardiovascular\"],\"NLBiJk\":[\"Registrar entrada\"],\"NPG8SK\":[\"Peso corporal\"],\"NQJHen\":[\"¿Estás seguro de que quieres reiniciar este entrenamiento?\"],\"NVOqiK\":[\"Inicia sesión para proteger tus datos\"],\"NXoGPK\":[\"Editar ejercicio\"],\"Ne5n-8\":[\"Añadir notas personales\"],\"NnRCUm\":[[\"0\"],\"s\"],\"Ns5WaC\":[\"No se encontraron copias de seguridad\"],\"Nu4oKW\":[\"Descripción\"],\"O1GFNQ\":[\"Todos los músculos objetivo\"],\"O2TAe0\":[\"barra\"],\"O2wCGL\":[\"Reproducir pitidos de cuenta atrás (Temporizador de ejercicio)\"],\"Otd3xX\":[\"Una semana de descarga es una semana de recuperación planificada en la que entrenas con menor intensidad para que tu cuerpo se recupere completamente antes del siguiente bloque de entrenamiento. Toca Marcar como semana de descarga en la pantalla de vista general del plan para indicar que la semana actual es una descarga. Mientras la descarga está activa, el cuestionario de feedback tras el ejercicio no aparece y no se crean ni actualizan nuevos estados de progresión, por lo que tu historial de sugerencias no se ve afectado por las sesiones más ligeras. La descarga se restablece automáticamente al inicio de la semana siguiente y el feedback normal y el seguimiento de progresión se reanudan sin ninguna acción manual. Si cambias de opinión, vuelve a tocar el botón mientras la descarga está activa para cancelarla.\"],\"Ov8o8m\":[\"Iniciar plan\"],\"OwNTSr\":[\"Guardar en el plan\"],\"Owchfv\":[\"Usado recientemente\"],\"OzAZw8\":[\"Esta pantalla no existe.\"],\"P0mjNu\":[\"Eliminar registro\"],\"P0svFp\":[\"Descanso\"],\"P1svYv\":[\"abdominales\"],\"P247ya\":[\"Parte del cuerpo *\"],\"P3nVsi\":[\"\\n📅 Nuevo: ¡Horario semanal para tu plan!\\n\\nAhora puedes asignar entrenamientos a días específicos de la semana directamente en el editor del plan. Toca cualquier día para elegir un entrenamiento o marcarlo como día de descanso. Usa el botón de sugerencia automática para generar al instante un horario equilibrado basado en tu objetivo semanal.\\n\"],\"P3omNB\":[\"Selecciona un entrenamiento para ver\"],\"PBt59F\":[\"Ejercicios favoritos\"],\"PFcCy0\":[\"x \",[\"0\"],\" reps \"],\"PHWHEO\":[\"Aceptar todo\"],\"PITZNx\":[\"pecho\"],\"PN5Zzf\":[\"Unidad de peso\"],\"PNapeY\":[\"+ Añadir\"],\"POx12e\":[\"\\n↕️ Nuevo: ¡Reordena ejercicios en la vista general del entrenamiento!\\n\\nAhora puedes arrastrar y soltar ejercicios y superseries para reordenarlos directamente desde la pantalla de vista general del entrenamiento durante una sesión.\\n\"],\"PSNHRi\":[\"* funciones en desarrollo\"],\"P_0oX-\":[\"Asistencia\"],\"PiK6Ld\":[\"Sáb\"],\"PruBpO\":[\"¿Estás seguro de que quieres eliminar este registro de medición?\"],\"Q1Lq8I\":[\"Tiempo total\"],\"Q2QJ28\":[\"Reproducir sonido al alcanzar el objetivo (Temporizador de ejercicio)\"],\"Q8bEQa\":[\"Se ha producido un error al eliminar las imágenes.\"],\"Q9qAkA\":[\"Duración estimada: \",[\"0\"]],\"QENBWX\":[\"tríceps\"],\"Qdwk82\":[\"Incremento de carga para mancuerna\"],\"Qjp-BQ\":[\"Añadir una serie\"],\"QlT4B5\":[\"Sesiones recientes\"],\"Qmbwcr\":[\"Editar plan\"],\"QoHy-T\":[[\"weeks\",\"plural\",{\"one\":[\"hace \",\"#\",\" semana\"],\"other\":[\"hace \",\"#\",\" semanas\"]}]],\"QrwEaQ\":[\"pectorales\"],\"QzJCdZ\":[\"dorsales\"],\"R-ABt9\":[\"Objetivo semanal\"],\"R0gwbc\":[\"bíceps\"],\"RCk1J0\":[\"trineo\"],\"RGfnXX\":[\"(al fallo)\"],\"RIHmRj\":[\"Buen ritmo. Intenta añadir una rep por serie antes de subir el peso.\"],\"RM5DG6\":[\"Ejercicios seguidos\"],\"RN4XJV\":[\"Día de descanso\"],\"RU6ELr\":[\"Estadísticas e historial\"],\"RXkbtG\":[\"¿Más intensidad la próxima vez?\"],\"RY_JyV\":[\"lumbar\"],\"R_h8B2\":[\"Más usado\"],\"Rc-8oy\":[\"Descargando actualización\"],\"RmahBs\":[[\"0\"],\": \",[\"best\"],\"s (+\",[\"delta\"],\"s, \",[\"pctStr\"],\")\"],\"Rr5U7J\":[\"Las series completadas aparecerán aquí\"],\"Rwc-xL\":[\"PR de tiempo\"],\"RxzN1M\":[\"Activado\"],\"S2uNE5\":[\"¿Continuar editando?\"],\"SEyweA\":[\"\\n🐛 Solucionado: ¡Varias correcciones y mejoras!\\n\\nSe corrigió que la notificación del temporizador de descanso no se activaba correctamente, el ajuste de texto del nombre del ejercicio en la sesión, el ancho del círculo de finalización del entrenamiento, las notas que no se actualizaban correctamente al escribir, y los detalles del entrenamiento que a veces se abrían en la pestaña incorrecta. Los entrenamientos ahora se cargan más rápido gracias a mejoras internas de rendimiento.\\n\"],\"SGISp8\":[\"Lo terminaste todo al límite. Quédate aquí y consolídalo.\"],\"SRhtpX\":[\"antebrazos\"],\"SUd4dA\":[\"\\n📏 Nuevo: ¡Medidas corporales!\\n\\nSigue tu composición corporal junto a tu entrenamiento desde la nueva sección Medidas en el tab Estadísticas.\\n\\n• Registra peso, % de grasa corporal, cintura, caderas, pecho y más\\n• Toca cualquier entrada anterior para editar valores o ver un gráfico de esa métrica\\n• Gestiona qué métricas se muestran y añade las tuyas personalizadas\\n• Las unidades siguen tus preferencias de peso y tamaño en Ajustes\\n\"],\"SWtay1\":[\"Al completar la última serie de trabajo de un ejercicio, aparece un cuestionario de feedback con dos preguntas. La primera pregunta cómo se sintió el esfuerzo: Fácil (podrías haber hecho más), Más o menos bien, Difícil (cerca de tu límite) o No pude terminar todas las series. La segunda pregunta sobre el dolor: Sin dolor, Molestia leve o Dolor o problemas de técnica. Si respondes Fácil, aparece una tercera pregunta sobre si quieres superarte más la próxima vez. Esto te permite mantener la carga actual deliberadamente aunque la sesión haya parecido fácil, de modo que el sistema respeta tu intención. Si respondes con Dolor, un campo de texto opcional te permite anotar dónde lo sentiste como referencia personal. El cuestionario se puede cerrar sin responder si prefieres no registrar feedback para ese ejercicio en esa sesión.\"],\"SZw9tS\":[\"Ver detalles\"],\"SadoC9\":[\"máquina Smith\"],\"SbGW67\":[\" (al fallo) \"],\"ScJ9fj\":[\"Política de privacidad\"],\"SlfejT\":[\"Error\"],\"SmkA26\":[\"1RM \",[\"0\"],\" \",[\"unit\"]],\"SoWD_0\":[\"Guardar serie\"],\"SrVzRe\":[\"Porcentaje\"],\"St3y2e\":[\"Nombre requerido\"],\"SvOMfA\":[[\"0\"],\" entrenamientos\"],\"T0cOwV\":[\"Eliminar serie\"],\"T7QVyK\":[\"Cuando abres un entrenamiento con ejercicios que entrenaste recientemente, aparece un cuestionario de Control de recuperación si esos ejercicios tienen una sugerencia de progresión pendiente y tu última sesión fue hace al menos 12 horas. Para cada grupo muscular relevante, eliges una de tres opciones: Fresco (completamente recuperado), Dolor muscular leve o Todavía muy dolorido. Si un músculo se marca como todavía muy dolorido, cualquier sugerencia de progresión ascendente para los ejercicios que trabajan ese músculo se pausa y se mantiene en la carga actual hasta que lo reevalúes al inicio de la siguiente sesión. Fresco o Dolor muscular leve no afectan a las sugerencias. Toca Omitir por ahora para saltarte el control completamente; un control omitido se trata igual que la recuperación completa, por lo que las sugerencias pendientes no se ven afectadas.\"],\"TBTwj-\":[\"Síguenos en Instagram\"],\"TJLDrx\":[\"Doblando el peso para los cálculos de volumen\"],\"T_qHwF\":[\"piernas inferiores\"],\"Ta25TG\":[\"Aún no hay historial\"],\"TpqeIh\":[\"Error: \",[\"0\"]],\"Tz0i8g\":[\"Ajustes\"],\"TzLpDD\":[\"\\n🏋️ Nuevo: ¡Entrenamientos individuales y entrenamientos rápidos!\\n\\nCrea entrenamientos independientes fuera de tus planes de entrenamiento, perfectos para sesiones flexibles, trabajo de movilidad o cualquier cosa espontánea. Encuéntralos en la pantalla de Planes.\\n\\nO empieza un Entrenamiento rápido desde la pantalla de inicio, añade ejercicios al vuelo y guárdalo opcionalmente como entrenamiento independiente cuando termines.\\n\"],\"U0HZma\":[\"Seguimiento\"],\"U4QKsL\":[\"Ocultar / Mostrar onboarding\"],\"U8BTVm\":[\"Tiempo de descanso restante:\"],\"UCtAiM\":[\"Para activar las notificaciones del temporizador de descanso, concede permisos de notificación en los ajustes de tu dispositivo.\"],\"UD8kHo\":[\"Siguiente: \",[\"workoutName\"],\" el \",[\"0\"]],\"URmyfc\":[\"Detalles\"],\"US8F_H\":[\"Se sugieren más reps\"],\"USXXjt\":[\"Sin resultados para \\\"\",[\"query\"],\"\\\"\"],\"U_-GrY\":[\"Por favor, espera mientras descargamos la última versión...\"],\"UlnAQR\":[\"Error al eliminar el entrenamiento. Por favor, inténtalo de nuevo.\"],\"UneMBz\":[\"Plan activo\"],\"UnnFak\":[\"¡Gran comienzo de semana!\"],\"Uorrgj\":[\"romboides\"],\"Uu14s5\":[[\"0\",\"plural\",{\"one\":[\"#\",\" serie\"],\"other\":[\"#\",\" series\"]}]],\"UyvU3-\":[\"Ayuda e información\"],\"UzNvmf\":[\"• Copia de seguridad y restauración de datos\"],\"V6wjuJ\":[\"El tipo de seguimiento es obligatorio.\"],\"V6xf0O\":[\"Este ejercicio ya está en tu entrenamiento. Por favor, elige uno diferente.\"],\"V8MVAm\":[\"pecho superior\"],\"V8dVu4\":[\"\\n🔗 Nuevo: ¡Superseries!\\n\\nCombina dos ejercicios como una superserie directamente en el editor de planes. Las series se mantienen sincronizadas entre ambos ejercicios, y las superseries están claramente agrupadas con un indicador visual en toda la app.\\n\"],\"V8yTm6\":[\"Borrar búsqueda\"],\"VAcXNz\":[\"Miércoles\"],\"VCJb5r\":[\"Serie \",[\"0\"],\" de \",[\"totalSets\"]],\"VDkJml\":[\"La Progresión adaptativa analiza tu feedback de esfuerzo a lo largo de sesiones consecutivas y sugiere cuándo aumentar tu peso, reps o series. Actívala en Ajustes, en Progresión adaptativa. Una vez activada, aparece una breve pregunta de feedback tras cada ejercicio en los entrenamientos basados en un plan. El sistema requiere dos sesiones con la misma señal antes de recomendar un aumento, lo que filtra los días puntualmente fáciles y garantiza un rendimiento constante antes de sugerir un aumento. El dolor o las series fallidas actúan de forma inmediata independientemente de tu historial de sesiones. Una sugerencia nunca se aplica a tu entrenamiento sin tu aprobación explícita. También puedes configurar tu incremento de carga preferido por categoría de equipamiento en la misma sección de Ajustes, por ejemplo 2,5 kg para ejercicios con barra y 2,0 kg para mancuernas.\"],\"VFlRXJ\":[\"Mantener igual esta sesión.\"],\"VhVOxx\":[\"¡Tu camino a Swoletown empieza hoy!\"],\"VhfZbD\":[\"Tamaño: ~100 MB\"],\"W-pY1H\":[\"Error al guardar el ejercicio personalizado. Por favor, inténtalo de nuevo.\"],\"W0qDyY\":[\"Pantalla de inicio y objetivo semanal\"],\"W3QcBP\":[\"Vista general del plan\"],\"W3u9nh\":[\"Al fallo, \"],\"WDciil\":[\"\\n📋 Nuevo: ¡Menú \\\"Más\\\" y sección de Ayuda e información!\\n\\nHay una nueva pestaña \\\"Más\\\" en la barra de navegación. Tócala para abrir un panel deslizante donde encontrarás Ajustes y una nueva sección de Ayuda e información.\\n\\nAjustes se ha movido aquí desde la barra de pestañas, y Ayuda e información lo cubre todo, desde planes y entrenamientos hasta estadísticas y tu cuenta, con una barra de búsqueda para encontrar respuestas rápidamente.\\n\"],\"WHwUfF\":[\"Error al cargar los detalles del ejercicio\"],\"WIbOhZ\":[\"Progresión adaptativa\"],\"WJp2MH\":[\"Unidad de tamaño\"],\"WKHqM-\":[\"Peso\"],\"WOi4Vm\":[\"Nombre *\"],\"WSzg3A\":[\"Distancia (\",[\"distanceUnit\"],\")\"],\"WU-3OC\":[\"Un solo brazo / una sola pierna\"],\"WaIjmh\":[\"Pantorrilla (D)\"],\"WoEX6M\":[\"Sugerir ajustes de carga y reps\"],\"WzcO-J\":[\"Crear plan\"],\"X9kySA\":[\"Favoritos\"],\"X9r6cu\":[[\"goal\",\"plural\",{\"one\":[[\"completed\"],\" de \",\"#\",\" entrenamiento esta semana\"],\"other\":[[\"completed\"],\" de \",\"#\",\" entrenamientos esta semana\"]}]],\"XHHEUg\":[\"Personalizar plan\"],\"XJQdl_\":[\"Enviar notificación en segundo plano tras el descanso\"],\"XNRDYn\":[\"extensores de muñeca\"],\"XdavYY\":[\"Entrenamientos\"],\"Xdcdfd\":[\"Series y ejercicios\"],\"XoEooZ\":[\"Tiempo (s)\"],\"Xu14OQ\":[[\"0\",\"plural\",{\"one\":[\"#\",\" Rep\"],\"other\":[\"#\",\" Reps\"]}]],\"Xu2iGM\":[\"Añadir peso\"],\"Xv4OIW\":[\"Entrenamiento en curso\"],\"Xwd4Hm\":[\"manguito rotador\"],\"Y6QE0T\":[\"Selecciona el equipamiento\"],\"YANNVr\":[\"Entrenamiento\"],\"YDnEIW\":[\"Mejor ganancia\"],\"YIix5Y\":[\"Buscar...\"],\"YLIqcF\":[\"Bienvenido/a de nuevo\",[\"userName\"]],\"YXJbW8\":[\"Los entrenamientos independientes están fuera de los planes y aparecen junto a tus planes en la pantalla Planes. Crea uno tocando Nuevo entrenamiento, dale un nombre y añade ejercicios; puedes ejecutarlo en cualquier momento sin necesitar un plan activo. Cada entrenamiento independiente muestra una duración estimada para que puedas planificar tu tiempo antes de empezar. Los entrenamientos rápidos te permiten iniciar una sesión de inmediato desde la pantalla de inicio: toca Entrenamiento rápido, añade ejercicios sobre la marcha y al final puedes guardarlo como entrenamiento independiente para uso futuro o simplemente descartarlo. Al igual que los planes, el editor de entrenamiento guarda automáticamente un borrador para que puedas salir y volver sin perder tu trabajo.\"],\"YYzBv9\":[\"Lu\"],\"YekWWq\":[[\"0\",\"plural\",{\"one\":[\"#\",\" rep\"],\"other\":[\"#\",\" reps\"]}]],\"YiPU_R\":[\"deltoides\"],\"YnHdfF\":[\"Serie \",[\"0\"]],\"Yr-t8O\":[\"pies\"],\"YuP-pS\":[\"\\\"\",[\"label\"],\"\\\" se ocultará del formulario de entrada. Tus datos históricos se conservan.\"],\"Z3FXyt\":[\"Cargando...\"],\"Z8RW4m\":[\"Al terminar un entrenamiento, la pantalla de Resumen del entrenamiento muestra una tarjeta de Próxima sesión con sugerencias prácticas para tus ejercicios. Cada fila muestra el nombre del ejercicio, el cambio propuesto (un nuevo peso objetivo, un rango de reps más amplio o una nota para reducir la carga) y una breve explicación de por qué se sugiere el cambio. Toca Aceptar para aplicar la sugerencia a ese ejercicio en tu próxima sesión, o Descartar para ignorarla. Las sugerencias aceptadas se prerellenan en los campos de peso y reps la próxima vez que abras ese entrenamiento, para que empieces la sesión ya apuntando a la carga correcta. El botón Aceptar todo en la parte superior aplica todas las sugerencias de una vez. Las sugerencias que recomiendan mantener la carga actual no aparecen en la tarjeta, ya que no se necesita ninguna acción para ellas.\"],\"ZAWGCX\":[[\"0\"],\" segundos\"],\"ZAvcCf\":[[\"0\"],[\"weightUnit\"],\" × \",[\"1\"]],\"ZI8idP\":[\"Fresco, completamente recuperado\"],\"Zm9Eu3\":[\"Tamaño de botones durante el entrenamiento\"],\"Zvc_N1\":[\"1RM (\",[\"weightUnitLabel\"],\")\"],\"_-nVtu\":[\"Se sintió fácil. Mantener por ahora y confirmar en la siguiente sesión.\"],\"_2fO4v\":[\"Resumen del entrenamiento\"],\"_D5y8a\":[\"Series predeterminadas\"],\"_K9jUO\":[\"ergómetro de tren superior\"],\"_P2B4j\":[[\"biggestGainLabel\"],\" 1RM\"],\"_RhvUo\":[\"ajustes\"],\"_UGS0C\":[\"Nombre del entrenamiento\"],\"_W-KPJ\":[\"Aún no hay medidas. Toca para registrar tu primera entrada.\"],\"_WRCmH\":[[\"0\"],\" \",[\"1\"],\" | \",[\"2\"],\" Reps\"],\"_XczSN\":[\"Selecciona el músculo objetivo\"],\"_Xvx5t\":[\"\\n📈 Nuevo: ¡Progresión adaptativa!\\n\\nMuscleQuest ahora puede sugerirte cuándo aumentar tu peso o reps según cómo se sienten tus sesiones. Después de cada ejercicio, responde dos preguntas rápidas sobre esfuerzo y dolor. Cuando hayas reportado la misma señal dos sesiones seguidas, la app sugiere un cambio. Todas las sugerencias aparecen en la pantalla de Resumen del entrenamiento, donde puedes aceptar o descartar cada una por separado. Las sugerencias aceptadas se prerellenan en tu próxima sesión automáticamente.\\n\\nUn Control de recuperación al inicio de tu próximo entrenamiento te permite tener en cuenta el dolor muscular antes de aplicar cualquier sugerencia. También puedes marcar una semana entera como semana de descarga desde la vista general del plan, lo que pausa el feedback y el seguimiento de progresión durante esa semana.\\n\\nActívalo en Ajustes, en Progresión adaptativa, y configura tu incremento de carga preferido por categoría de equipamiento.\\n\"],\"_cF7Rs\":[\"Volumen\"],\"_f5DAr\":[\"Completado el: \",[\"formattedDate\"]],\"a2Fu8q\":[\"Puedes iniciar sesión en cualquier momento desde la pantalla de ajustes, si decides saltarte este paso ahora.\"],\"a5BPTT\":[\"kettlebell\"],\"a8TA11\":[\"Próxima sesión\"],\"aAIQg2\":[\"Apariencia\"],\"aMwZcE\":[\"Brazo superior (I)\"],\"aN_GPe\":[\"¿Dónde lo sentiste?\"],\"ahW3x6\":[\"\\n📅 Nuevo: ¡Calendario de entrenamientos!\\n\\nToca el icono del calendario en la sección Historial de entrenamientos de la pestaña Estadísticas para explorar tu historial de entrenamiento por fecha. Los días con entrenamientos están resaltados, y al tocar cualquier día se muestran las sesiones registradas ese día.\\n\"],\"aj6ZJx\":[\"Iniciar sesión con Google\"],\"b3e7Re\":[\"Reiniciar app\"],\"b9OAHS\":[\"Añadir calentamiento\"],\"bFeIdj\":[\"Serie descendente\"],\"bQdjFX\":[[\"0\"],\" nota\"],\"bRAv_4\":[\"Entrenamiento \",[\"0\"]],\"bZS72M\":[[\"setsCount\",\"plural\",{\"one\":[\"#\",\" serie\"],\"other\":[\"#\",\" series\"]}]],\"bosqpS\":[\"Aún no has completado ningún entrenamiento. ¡Empieza tu primer entrenamiento!\"],\"bqb_ci\":[\"\\n🐛 Solucionado: ¡Botones de la sesión y modal de edición de series!\\n\\nSe corrigió un error por el que todos los botones (incrementar/decrementar, serie siguiente/anterior, completar serie) dejaban de funcionar al completar una serie. También se corrigió un error en el modal de edición de series. Las transiciones entre series ahora son instantáneas para un flujo de entrenamiento más fluido.\\n\"],\"bwd2oE\":[\"¡Temporizador de descanso finalizado!\"],\"bzSI52\":[\"Descartar\"],\"c2TGz5\":[\"¡\",[\"completed\"],\" entrenamientos esta semana. Has superado tu objetivo!\"],\"cCbON-\":[\"\\n🔥 Mejorado: ¡Gestión de series de calentamiento!\\n\\nLas series de calentamiento están agrupadas visualmente y con un estilo separado de las series de trabajo, y \\\"Aplicar a todas\\\" te permite editar en bloque las series de calentamiento o de trabajo de forma independiente.\\n\"],\"cF5b-5\":[[\"weeklyGoal\",\"plural\",{\"one\":[\"Sugerencia automática (\",\"#\",\" día)\"],\"other\":[\"Sugerencia automática (\",\"#\",\" días)\"]}]],\"cI6f7l\":[\"30d\"],\"cU45Co\":[\"Añadir entrenamiento\"],\"cUD6H0\":[\"¡Prepárate...!\"],\"cUY9dI\":[\"¿Estás seguro de que quieres eliminar este ejercicio?\"],\"ckJ-os\":[\"Músculos\"],\"cnGeoo\":[\"Eliminar\"],\"crwali\":[\"Recordatorios\"],\"ctrAML\":[\"¡No olvides registrar tu progreso!\"],\"cyR8-W\":[\"\\n🕐 Nuevo: ¡Estimación de duración del entrenamiento!\\n\\nCada tarjeta de entrenamiento ahora muestra una duración estimada para que puedas planificar tus sesiones de un vistazo antes de empezar.\\n\"],\"d1z1ZY\":[\"El temporizador de descanso se inicia automáticamente tras cada serie y cuenta regresiva hasta cero. Cada serie recuerda su propia duración de descanso, por lo que diferentes series dentro del mismo ejercicio pueden tener períodos de descanso distintos. Usa los botones ± para ajustar el tiempo restante sobre la marcha durante el descanso. Configura la duración de descanso predeterminada, el incremento del temporizador y si se activa un sonido, vibración o notificación en segundo plano al finalizar; cada opción es activable de forma independiente en Ajustes.\"],\"dEgA5A\":[\"Cancelar\"],\"dH9Y4t\":[\"No hay entrenamientos este día.\"],\"dVK-Er\":[\"Se ha producido un error de renderizado. Pulsa el botón para recargar.\"],\"dXCD6-\":[\"Descargar todas las animaciones de ejercicios\"],\"dXoieq\":[\"Resumen\"],\"dYOPCE\":[\"Asistencia \",[\"0\"],\" \",[\"1\"],\" | Resistencia \",[\"2\"],\" \",[\"3\"],\" | \",[\"4\"],\" Reps\"],\"dbWo0h\":[\"Iniciar sesión con Google\"],\"deoJBi\":[[\"0\"],\" reps\"],\"dfunKV\":[\"Peso/Reps\"],\"dpOqdQ\":[\"Al fallo\"],\"dqjuBA\":[\"90d\"],\"dx0cCC\":[\"¡Sigue con el ritmo!\"],\"e0dGJ7\":[\"Ventajas de iniciar sesión:\"],\"e0l-Z0\":[[\"scheduledDays\",\"plural\",{\"one\":[\"#\",\" día/semana\"],\"other\":[\"#\",\" días/semana\"]}]],\"e5h2IT\":[[\"0\"],\" notas\"],\"e9qdcV\":[\"Molestia leve\"],\"eLA0I2\":[\"Descargar imágenes\"],\"eQm4BH\":[\"Al terminar un entrenamiento, una pantalla de resumen muestra tu duración total, series completadas y volumen total. Si ya has hecho ese entrenamiento antes, una fila de comparación muestra cómo se compara cada métrica con la sesión anterior. Un banner de objetivo semanal indica cuántas sesiones has registrado esta semana respecto a tu objetivo. Toca cualquier ejercicio de la lista para expandirlo y revisar cada serie en detalle. Al completar un Entrenamiento rápido, se te pedirá que lo guardes como entrenamiento independiente para uso futuro o que lo descartes.\"],\"eYbd7b\":[\"Do\"],\"ecUA8p\":[\"Hoy\"],\"ehOkF-\":[\"Básico\"],\"emOtYn\":[\"Planes prediseñados\"],\"ez-cQL\":[\"\\n🔔 Nuevo: ¡Notificaciones de recordatorio de entrenamiento!\\n\\nNo te pierdas ninguna sesión. Configura notificaciones de recordatorio para tus entrenamientos directamente desde la app. Elige qué días quieres que te recuerden y selecciona una hora para empezar.\\n\"],\"f2yjAZ\":[\"Sin dolor\"],\"f7pPKh\":[\"Muslo (I)\"],\"f8Vl8d\":[\"Nombre de la métrica\"],\"fFHHFp\":[\"Medidas\"],\"fPpo2L\":[\"Superserie\"],\"fSu2Jl\":[\"Se ha descargado una nueva versión. Toca el botón de abajo para reiniciar y aplicar la actualización.\"],\"fXVIZq\":[\"Valores\"],\"f_bxrN\":[\"El nombre es obligatorio.\"],\"feWdkU\":[\"Reiniciar entrenamiento\"],\"fj5byd\":[\"N/D\"],\"fpMgHS\":[\"Lun\"],\"fqSfXY\":[\"Reemplazar\"],\"fsJAR5\":[\"Incremento de carga para barra\"],\"ftiGCv\":[\"Todo el equipamiento\"],\"fvyzOr\":[\"espalda alta\"],\"g36TSx\":[\"Unidad de distancia\"],\"g3UF2V\":[\"Aceptar\"],\"gCVtjC\":[[\"0\"],\" Series\"],\"gEOgEq\":[[\"0\"],\" ejercicios\",[\"1\"]],\"gQYPDg\":[\"−\",[\"restTimerIncrement\"],\"s\"],\"gTdjGc\":[\"Error al eliminar el entrenamiento. Por favor, inténtalo de nuevo.\"],\"giOl9F\":[\"Muslo (D)\"],\"gkn1WJ\":[\"Ejercicio ya añadido\"],\"gzBfh2\":[\"No hay series disponibles\"],\"h-DKuf\":[\"vs. último \\\"\",[\"0\"],\"\\\"\"],\"h2ALJf\":[\"glúteos\"],\"h7CU4q\":[\"¿Cómo te fue?\"],\"hBjQ0O\":[[\"0\",\"plural\",{\"one\":[\"#\",\" entrenamiento\"],\"other\":[\"#\",\" entrenamientos\"]}]],\"hF_t4W\":[\"Volumen (\",[\"volumeUnit\"],\")\"],\"hLONcx\":[\"Copia de seguridad y restauración\"],\"hPXEuO\":[\"Emparejado con \",[\"0\"]],\"hXzOVo\":[\"Siguiente\"],\"hnJ2UC\":[\"braquial\"],\"hnlGzG\":[\"Omitir por ahora\"],\"hnrFBk\":[\"Días de recordatorio\"],\"hpsdvR\":[\"\\n📋 Nuevo: ¡Ver detalles del entrenamiento desde la pantalla de inicio!\\n\\nAhora puedes tocar cualquier entrenamiento reciente en la pantalla de inicio para ver sus detalles completos. Cada resumen de entrenamiento y series también tiene un nuevo botón de detalles para acceder rápidamente a la información del ejercicio.\\n\"],\"hsoeHo\":[\"Detalles del entrenamiento\"],\"hty0d5\":[\"Lunes\"],\"hvfche\":[[\"scheduledCount\",\"plural\",{\"one\":[\"#\",\" día/semana\"],\"other\":[\"#\",\" días/semana\"]}]],\"i-tNaY\":[\"Asistencia/Reps\"],\"i09UfG\":[\"Equipamiento:\"],\"i0qMbr\":[\"Inicio\"],\"i4Vk1Q\":[\"Ejercicios del plan activo\"],\"i6f8rt\":[\"Iniciando entrenamiento...\"],\"iGokZG\":[\"Incremento de carga para cable\"],\"iHmyze\":[\"Ejercicios\"],\"iQyKX1\":[\"Elegiste mantenerlo igual. El peso se queda así.\"],\"iV1Jat\":[\"¿Estás seguro de que quieres eliminar esta serie?\"],\"iYfCFU\":[\"Mostrar onboarding en la pantalla de inicio\"],\"i_48Se\":[\"Plan activo: \",[\"0\"]],\"i_nB8P\":[\"Sin horario establecido\"],\"ifRQL2\":[\"Serie descendente, \"],\"ikOJPT\":[\"espinillas\"],\"irLwtB\":[\"Plan de entrenamiento\"],\"irrqfe\":[\"Métricas personalizadas\"],\"iuwbqi\":[\"Error al guardar el entrenamiento. Por favor, inténtalo de nuevo.\"],\"ivpCYv\":[\"¿Descartar cambios?\"],\"j-MPXl\":[\"Copia de seguridad y restauración\"],\"jDTG0T\":[\"Sugerencias de progresión\"],\"jDh_CH\":[\"Los planes son programas de entrenamiento estructurados compuestos por entrenamientos. Para crear uno, ve a la pestaña Planes, toca Nuevo plan, dale un nombre y elige una imagen de portada. Añade entrenamientos al plan, luego añade ejercicios a cada entrenamiento con series y reps objetivo. Usa los botones de flecha arriba/abajo en una tarjeta de entrenamiento para reordenarlo, o el botón X para eliminarlo; ambos están en la parte superior derecha de la tarjeta. Asigna entrenamientos a días específicos de la semana en el editor de horarios: toca cualquier día para elegir un entrenamiento o déjalo como día de descanso, y usa el botón de sugerencia automática para distribuirlos de manera uniforme. Una vez que tu plan esté listo, ábrelo y toca Activar. También puedes añadir notas a un plan desde la pantalla de vista general del plan. Cada tarjeta de entrenamiento muestra una duración estimada junto al número de ejercicios para que puedas calcular la duración de la sesión de un vistazo. Usa los iconos de vista junto al encabezado \\\"Tus planes de entrenamiento\\\" para cambiar entre los modos Carrusel, Lista y Cuadrícula; tu vista preferida se guarda automáticamente. Tu progreso en el editor de planes se guarda automáticamente como borrador, así que si sales a mitad de la edición, se te pedirá que continúes donde lo dejaste o que descartes y empieces desde el último estado guardado.\"],\"jYjrmQ\":[\"Última copia de seguridad: \",[\"0\"]],\"jfzZZ0\":[\"Omitir inicio de sesión\"],\"jpVuia\":[\"¿Guardar cambios en el entrenamiento?\"],\"jxTU3u\":[\"máquina de escalera\"],\"jzJENZ\":[\"Sigue tu progreso\"],\"k4kpgL\":[\"Bienvenido/a a MuscleQuest, tu acompañante personal de entrenamiento de fuerza. Usa esta guía para descubrir las funciones y sacar el máximo partido a tu entrenamiento.\"],\"k7Oi68\":[\"piernas superiores\"],\"kDJ_Ja\":[\"Sesión sólida. Mantener este peso.\"],\"kFoQmI\":[\"abductores\"],\"kILzHz\":[\"Añadir (\",[\"0\"],\")\"],\"kQe_xM\":[\"Dolor reportado. El peso no cambiará hasta que te sientas mejor.\"],\"kSi1ha\":[\"+\",[\"suggestedWeight\"],[\"unit\"],\" sugerido\"],\"kdwbaT\":[\"Omitir todo\"],\"kf4tdd\":[\"Selecciona el tipo de seguimiento\"],\"kfxr8q\":[\"\\n📊 Nuevo: ¡Resumen del entrenamiento!\\n\\nAl completar un entrenamiento, verás un resumen completo de tu sesión: duración total, series y volumen, además de una comparación con tu sesión anterior. Toca cualquier ejercicio para expandirlo y ver sus series y pesos individuales.\\n\"],\"kg0oKA\":[\" (al fallo)\"],\"kkDQ8m\":[\"Jueves\"],\"konUZ1\":[\"Tiempo de descanso predeterminado\"],\"kvpjYu\":[\"Introduce el nombre del ejercicio\"],\"l1P93s\":[\"Introducir el peso por mancuerna/cable, no el total\"],\"l75CjT\":[\"Sí\"],\"lWy5a1\":[\"Planes\"],\"lY9GM0\":[\"El músculo objetivo es obligatorio.\"],\"lkz6PL\":[\"Duración\"],\"llGZy3\":[\"Aún no se han registrado ejercicios. Toca + Añadir para empezar.\"],\"loRbvf\":[\"¡Ir a la pantalla de inicio!\"],\"m0YANP\":[\"Puedes ocultar esta pantalla de introducción en cualquier momento desde la página de ajustes, en la sección de apariencia. Si quieres volver a verla, puedes activarla de nuevo desde la misma página de ajustes.\"],\"m16xKo\":[\"Añadir\"],\"mAoTHw\":[\"Algunas imágenes no se pudieron eliminar. IDs de ejercicio fallidos: \",[\"0\"]],\"mDmPnX\":[\"Por semana (prom.)\"],\"mEQ95z\":[\"Error al guardar la imagen. Por favor, inténtalo de nuevo.\"],\"mF1US0\":[\"Usar siempre el historial más reciente del ejercicio\"],\"mFQ4KK\":[\"Dobla el peso para el volumen cuando el ajuste está activado\"],\"mK5j7_\":[\"\\n🔃 Nuevo: ¡Ordena la biblioteca de ejercicios!\\n\\nLa biblioteca de ejercicios ahora tiene chips de ordenación para encontrar ejercicios más rápido. Ordena por Predeterminado, Plan activo, Reciente o Frecuente para ver los ejercicios más relevantes para ti arriba.\\n\"],\"mRTnNi\":[\"Implementos pareados\"],\"mSit7t\":[\"Error al obtener los datos. Por favor, inténtalo de nuevo.\"],\"mSj_dN\":[[\"0\",\"plural\",{\"one\":[\"+\",\"#\",\" más\"],\"other\":[\"+\",\"#\",\" más\"]}]],\"mT57-Q\":[\"Ir a Ajustes\"],\"mob_am\":[\"Vi\"],\"mwX_w0\":[\"Cambiar imagen\"],\"mzI_c-\":[\"Descargar\"],\"n00ykB\":[\"Tus entrenamientos\"],\"n1BXGc\":[\"División de entrenamiento (por series)\"],\"nAEGxm\":[\"Sí, aumentar el reto\"],\"nJSX83\":[\"Recordatorios de entrenamiento\"],\"nO6sra\":[[\"0\"],\": \",[\"best\"],\" \",[\"best\",\"plural\",{\"one\":[\"rep\"],\"other\":[\"reps\"]}],\" (+\",[\"delta\"],\", \",[\"pctStr\"],\")\"],\"nPGn3W\":[\"Calentamiento, \"],\"nkkWxK\":[\"Arranca tu viaje fitness con planes de entrenamiento diseñados profesionalmente. Elige entre una variedad de opciones adaptadas a diferentes objetivos y niveles de experiencia. \"],\"nmdLhD\":[\"Reps: \",[\"repRange\"]],\"o2XlZw\":[\"¿Estás seguro de que quieres eliminar este entrenamiento? Esta acción no se puede deshacer.\"],\"oB9lvM\":[\"Excluir series de calentamiento de las estadísticas\"],\"oOHOWH\":[\"\\n✨ Nuevo: ¡Animaciones en la sesión de entrenamiento!\\n\\nNavegar entre series ahora incluye transiciones deslizantes suaves. Desliza hacia la izquierda o la derecha para moverte entre series, o usa los botones de flecha para el mismo efecto.\\n\"],\"oOYj_W\":[\"Error al cargar los entrenamientos\"],\"oRTTfk\":[\"La pestaña Estadísticas muestra el total de entrenamientos, volumen total, tiempo total y duración media de sesión en un rango de tiempo seleccionable, con una variación período a período para cada métrica. Los gráficos muestran el volumen semanal y tu división de entrenamiento por parte del cuerpo. Navega por tu historial completo de entrenamientos y toca cualquier sesión para revisar cada serie en detalle, incluyendo pesos, reps, tiempo o distancia. Puedes editar o eliminar entrenamientos completados desde la pantalla de detalles del historial. Toca el icono de calendario en la sección Historial de entrenamientos para abrir una vista de calendario: los días con entrenamientos se resaltan con un círculo amarillo, y al tocar cualquier día se muestran los entrenamientos registrados en esa fecha.\"],\"oRvy2V\":[\"Seguimiento de ejercicio\"],\"oXsjxN\":[\"Pantorrilla (I)\"],\"oYZpj8\":[\"• Desafíos y medallas *\"],\"ocEDZS\":[\"Quitar una serie\"],\"oeF-HP\":[\"Error al iniciar sesión. Por favor, inténtalo de nuevo.\"],\"oeeBm6\":[\"\\n🔔 Nuevo: ¡Notificaciones de actualizaciones en la app!\\n\\nAhora aparece un modal de actualización cuando hay una actualización disponible, para que siempre sepas cuándo se han descargado mejoras y están listas para aplicarse.\\n\"],\"ofVE0I\":[\"Borra el campo de búsqueda\"],\"oiHVLP\":[\"Eliminar superserie\"],\"oqKRAn\":[\"Cada serie puede marcarse como Calentamiento, Serie descendente, Al fallo o cualquier combinación de estas. La insignia junto a una serie muestra su tipo actual. Para cambiar el tipo durante una sesión, toca el menú (⋮) y activa o desactiva la opción correspondiente. Al crear un plan, usa las casillas en el editor de series; toca Añadir calentamiento para insertar una serie de calentamiento al principio de la lista. Las series de calentamiento se agrupan y separan visualmente de las series de trabajo, y la opción Aplicar a todas en el modal de edición solo afecta a series del mismo tipo. Las series de calentamiento se pueden excluir de los cálculos de volumen y estadísticas en Ajustes.\"],\"oqUOKk\":[\"Serie descendente\"],\"osILGh\":[\"Distancia objetivo (\",[\"distanceUnit\"],\")\"],\"ovBPCi\":[\"Predeterminado\"],\"ovGl86\":[\"(al fallo) \"],\"p5nYkr\":[\"Ver todo\"],\"p72uBF\":[\"No se encontraron planes de entrenamiento\"],\"p8F9k_\":[\"Cuello\"],\"pBGx0B\":[\"\\n🗂️ Nuevo: ¡Opciones de vista de planes!\\n\\nLa pantalla de Planes ahora tiene tres modos de visualización. Usa los iconos junto al encabezado \\\"Tus planes de entrenamiento\\\" para cambiar entre las vistas Carrusel, Lista y Cuadrícula. Tu disposición preferida se guarda automáticamente.\\n\"],\"pE7tOx\":[\"Entrenamiento activo\"],\"pIX6X7\":[\"Instagram de MuscleQuest\"],\"pIuJtP\":[\"Entrenamiento no encontrado.\"],\"pY_gY7\":[\"PR de reps\"],\"p_C-3G\":[\"Dolor muscular leve\"],\"pbzA-s\":[\"Descripción opcional\"],\"pfXEaj\":[\"Peso corporal\"],\"pkD36F\":[\"¿Estás seguro de que quieres eliminar \\\"\",[\"0\"],\"\\\"?\"],\"poLmqL\":[\"Elegir del dispositivo\"],\"psxXnW\":[\"Inicia sesión con Google en Ajustes para activar las copias de seguridad en la nube de todos tus datos de entrenamiento. Toca Copia de seguridad en cualquier momento para guardar una instantánea; la fecha de tu última copia se muestra bajo el botón. Toca Restaurar para descargar y aplicar tu última copia; confirma el aviso y la app se recargará con tus datos restaurados. Tus copias se almacenan de forma segura y están vinculadas a tu cuenta de Google. Si cambias de dispositivo o reinstalas la app, simplemente inicia sesión con la misma cuenta de Google y toca Restaurar para recuperar tus datos.\"],\"pvW0MQ\":[\"Completar serie\"],\"pwfNCc\":[\"+\",[\"restTimerIncrement\"],\"s\"],\"pz0gzh\":[\"Ocultar métrica\"],\"pzA-xG\":[\"Captura indicaciones importantes, recordatorios e ideas personales sobre tus ejercicios, entrenamientos y planes de entrenamiento. Mantente enfocado y perfecciona tu técnica con notas personalizadas a lo largo de tu viaje fitness. Las notas se guardan automáticamente cuando terminas de editar.\"],\"q3pTrs\":[\"¡Todas las imágenes se han eliminado correctamente!\"],\"qIATCE\":[\"\\n📋 Mejorado: ¡Prerelleno más inteligente del historial durante los entrenamientos!\\n\\nLos campos de series ahora se prerellenan de forma más inteligente. Si un ejercicio no tiene historial en el entrenamiento actual, se usa automáticamente la última vez que lo realizaste en cualquier sesión, para que siempre tengas una referencia útil.\\n\\nUn nuevo ajuste en la sección Entrenamiento te permite usar siempre el historial más reciente de todos los entrenamientos, independientemente de la rutina de la que provenga.\\n\"],\"qJb6G2\":[\"Intentar de nuevo\"],\"qQ5ALI\":[\"¿Guardar cambios en el plan?\"],\"qQ8Xkc\":[\"Incremento de carga para máquina\"],\"qQLn75\":[\"Selecciona la parte del cuerpo\"],\"qUSLnH\":[\"Introduce una descripción\"],\"qZMNNX\":[\"Brazo superior (D)\"],\"qaT7mT\":[\"Perderás lo que has introducido hasta ahora.\"],\"qdalvN\":[\"Semana de descarga activa. Comparación pausada.\"],\"qeygIa\":[\"Mi\"],\"qlKdB2\":[\"No, dejarlo igual\"],\"qtNMEu\":[\"cuádriceps\"],\"qvcKXF\":[\"¡Buen trabajo hoy!\"],\"qvolLq\":[\"Masa\"],\"rCROTr\":[\"Invítame a un café\"],\"rLgPvm\":[\"Copia de seguridad\"],\"rPj8yN\":[\"Otros ejercicios\"],\"rZzMre\":[\"brazos superiores\"],\"rickIy\":[\"Guardando entrenamiento...\"],\"rlNJuG\":[\"Detalle del registro\"],\"rtypiF\":[\"🎉 Novedades\"],\"rzjsxH\":[\"Tiempo (Minutos:Segundos)\"],\"s53UX_\":[\"Volumen por semana (\",[\"volumeUnit\"],\")\"],\"s6qW4K\":[\"El tipo de seguimiento no se puede cambiar después de la creación.\"],\"sAkBSh\":[[\"0\",\"plural\",{\"one\":[\"#\",\" ejercicio\"],\"other\":[\"#\",\" ejercicios\"]}]],\"sHe-bW\":[\"Dale un nombre para guardarlo como entrenamiento reutilizable.\"],\"sRh2_9\":[\"Tus planes de entrenamiento\"],\"sey42b\":[\"¡Entrenamiento completado!\"],\"slcKOz\":[\"Para activar los recordatorios de entrenamiento, concede permisos de notificación en los ajustes de tu dispositivo.\"],\"spvawa\":[\"Excluir entrenamientos de descarga de las estadísticas de ejercicios\"],\"t-VWgS\":[\"Entrenamientos por semana\"],\"t1WtPm\":[\"vs PR\"],\"t7OD9_\":[\"trapecios\"],\"t9rBTs\":[[\"0\"],\": \",[\"best\"],[\"unit\"],\" (+\",[\"delta\"],[\"unit\"],\", \",[\"pctStr\"],\")\"],\"tCHU1b\":[\"Partes del cuerpo\"],\"tLdxsV\":[\"MuscleQuest.app\"],\"tXkhj_\":[\"Iniciar\"],\"t_YqKh\":[\"Eliminar\"],\"tcZ16z\":[\"\\n💾 Nuevo: ¡Guarda los cambios del entrenamiento en tu plan!\\n\\nCuando termines una sesión en la que hayas añadido, eliminado o reordenado ejercicios o series, se te pedirá que guardes esos cambios en el plan original o en el entrenamiento independiente, manteniendo tu entrenamiento actualizado automáticamente.\\n\"],\"tfDRzk\":[\"Guardar\"],\"tj-hng\":[\"muñecas\"],\"tlcz2i\":[\"No hay datos para este período.\"],\"twA2hZ\":[\"piernas\"],\"tyb5gZ\":[\"Tiempo de descanso (Minutos:Segundos)\"],\"u0F1Ey\":[\"Ju\"],\"u0Vng2\":[\"Todavía muy dolorido\"],\"u16ECS\":[\"Descarga completa\"],\"uGkCJQ\":[\"barra EZ\"],\"uIVkKI\":[\"Inicio de sesión\"],\"uP80lb\":[\"Actualización lista\"],\"ue_JxE\":[\"Vista general de series\"],\"ufHAsd\":[\"Nombre del plan de entrenamiento\"],\"uyJsf6\":[\"Acerca de\"],\"v2e7py\":[\"Crear un plan\"],\"v39wLo\":[\"Reanudar\"],\"v67n_r\":[\"Activa los recordatorios de entrenamiento recurrentes desde Ajustes. Selecciona los días de la semana en los que quieres recibir el recordatorio usando los chips de día y elige una hora. Recibirás una notificación a esa hora en cada día seleccionado. Se debe conceder el permiso de notificaciones para que los recordatorios funcionen.\"],\"vCrBBg\":[\"Toma el control total de tu entrenamiento diseñando tu propio plan personalizado. Selecciona ejercicios, establece rangos de reps, tiempos de descanso y más para crear un plan que se ajuste perfectamente a tus objetivos de fitness.\"],\"vFte8a\":[\"Crear superserie\"],\"vLSd93\":[\"Tipos de serie\"],\"vLyv1R\":[\"Ocultar\"],\"vPWLpz\":[\"Unidades de medida\"],\"vV1rrV\":[[\"suggestedRepsMin\"],\" reps sugeridas\"],\"vbOlQu\":[\"Error al seleccionar la imagen. Por favor, inténtalo de nuevo.\"],\"vbfDgJ\":[\"Aún no hay entrenamientos\"],\"vcpc5o\":[\"Cerrar menú\"],\"vmatEA\":[\"Cargando datos, por favor espera...\"],\"vq2WxD\":[\"Mar\"],\"vqV9pV\":[\"Nuevo plan\"],\"vyQFtJ\":[\"¡\",[\"0\"],\" completado!\"],\"w55mIe\":[\"plan activo\"],\"w95UZr\":[\"mejor \",[\"maxDist\"],[\"distanceUnit\"]],\"wBAK8Q\":[\"La parte del cuerpo es obligatoria.\"],\"wL3cK8\":[\"Último\"],\"wL7wrB\":[\"Incremento de peso\"],\"wUwyC0\":[\"Racha\"],\"wYwS57\":[\"Personaliza tus ajustes\"],\"wckWOP\":[\"Gestionar\"],\"wgbq86\":[\"Reinicio fallido\"],\"wpLp4M\":[\"Asistencia\"],\"wvxWx2\":[\"trapecio\"],\"wxKcF0\":[\"Acerca del desarrollador\"],\"x5LlnE\":[\"Opciones de estadísticas\"],\"xGVfLh\":[\"Continuar\"],\"xM_hqb\":[\"asistencia \"],\"xMidTh\":[\"Todas las partes del cuerpo\"],\"xRGBk4\":[\"Explorar planes prediseñados\"],\"xVhQZV\":[\"Vie\"],\"xYxQCZ\":[[\"0\"],\" \",[\"1\"]],\"xx7Wjz\":[\"Error al cargar los detalles del ejercicio.\"],\"y04OSh\":[\"Historial de entrenamientos\"],\"y3CwcG\":[\"mejor \",[\"maxTime\"],\"s\"],\"y8le-Z\":[\"Entrenamiento\"],\"yAeHP4\":[\"No hay datos disponibles.\"],\"yBSiRY\":[\"Semana de descarga\"],\"yKu_3Y\":[\"Restaurar\"],\"yUWaVv\":[\"máquina elíptica\"],\"yWCES-\":[\"Músculos secundarios:\"],\"y_0uwd\":[\"Ayer\"],\"y_f0Ik\":[\"Se abre en tu navegador\"],\"yf16RU\":[\"Calentamiento\"],\"ygCKqB\":[\"Detener\"],\"yhrNcC\":[\"Error al guardar la imagen\"],\"ykve2U\":[\"Añadir serie\"],\"yu1K_Z\":[\"Sin series\"],\"z1-0FW\":[\"Registra tus entrenamientos, monitorea tu progreso y alcanza tus objetivos de fitness. MuscleQuest hace que tu viaje fitness sea simple y efectivo.\\n\\nDesliza las tarjetas de introducción para saber más sobre la app.\"],\"z44QLk\":[\"Restaurar copia de seguridad\"],\"z5uobd\":[\"Toca el icono de estrella en la esquina superior derecha de cualquier pantalla de información de ejercicio para marcarlo como favorito. Los ejercicios favoritos aparecen en la parte superior del selector de ejercicios al crear o editar entrenamientos, para que los ejercicios que más usas siempre estén a mano.\"],\"zAhZMD\":[\"• Comparte tus planes de entrenamiento con otros *\"],\"zAt78k\":[\"Temporizador de descanso\"],\"zDq2cZ\":[\"Cintura\"],\"zEHmq8\":[\"La pestaña Planes incluye una biblioteca de programas de entrenamiento prediseñados que puedes empezar de inmediato. Desplázate más allá de Tus planes de entrenamiento para encontrar la sección Planes prediseñados. Toca cualquier programa para previsualizar sus entrenamientos y horario, luego toca Activar para convertirlo en tu plan activo. Puedes editar un plan prediseñado para ajustar ejercicios, series o el horario semanal. Esto creará una copia del plan prediseñado que puedes modificar sin afectar al original, para que siempre puedas volver a la versión predeterminada si es necesario.\"],\"zIFP3N\":[\"Establece tu objetivo semanal de entrenamientos e introduce tu peso corporal para obtener estadísticas y recomendaciones precisas. También puedes ajustar tus preferencias de incremento de peso, elegir tus unidades preferidas y mucho más.\"],\"zNnnyF\":[\"gemelos\"],\"zOwYV3\":[\"Has modificado este entrenamiento. ¿Guardar los cambios para sesiones futuras?\"],\"zga9sT\":[\"Aceptar\"],\"zhIkkH\":[\"Objetivo: \",[\"goalLabel\"],[\"0\"]],\"zsaR7t\":[\"Equipamiento y seguimiento\"],\"zt6jiv\":[\"No hay seguimiento de progresión para este tipo de ejercicio.\"],\"zuwyEJ\":[\"Añade ejercicios para empezar\"],\"zzDlyQ\":[\"Éxito\"]}")}; \ No newline at end of file +/*eslint-disable*/module.exports={messages:JSON.parse("{\"-2Ut5a\":[\"La franja de Estadísticas clave en la parte superior de la pestaña Estadísticas ofrece cuatro aspectos destacados de un vistazo para el rango de tiempo seleccionado: tu promedio de entrenamientos por semana, tu mayor ganancia de fuerza entre los ejercicios seguidos, la parte del cuerpo que más has entrenado y tu racha semanal actual. Se actualizan automáticamente tras cada entrenamiento.\"],\"-5kO8P\":[\"Sábado\"],\"-BjMj_\":[\"Crear entrenamiento\"],\"-FjWgX\":[\"Jue\"],\"-Tpjjs\":[[\"0\"],\" series\"],\"-WSEJS\":[\"Eliminar entrenamiento\"],\"-Xejuf\":[\"Caderas\"],\"-XvJee\":[\"mejor \",[\"0\"],[\"weightUnit\"],\" × \",[\"1\"]],\"-rhD7g\":[\"No hay solicitudes de amistad pendientes.\"],\"-svcUj\":[\"¿Guardar este entrenamiento?\"],\"03mQOq\":[\"Error al activar este plan: \",[\"0\"]],\"06EUQy\":[\"PR histórico\"],\"0EHHPz\":[\"aductores\"],\"0EPpEZ\":[\"Añadir métrica personalizada\"],\"0EcUWz\":[\"¿Descartar cambios?\"],\"0OeId4\":[\"Crear un plan personalizado\"],\"0P1btN\":[\"\\n🔔 Nuevo: ¡Sonidos del temporizador de ejercicios!\\n\\nEl temporizador de ejercicios ahora reproduce señales de audio para mantenerte en camino. Un pitido de cuenta atrás cuando el temporizador se acerca a cero y un sonido cuando alcanzas tu objetivo. Activa o desactiva cada sonido de forma independiente en Ajustes.\\n\"],\"0SaB4K\":[\"Serie de calentamiento\"],\"0U938S\":[\"Selecciona al menos un día\"],\"0V9gKq\":[\"\\n🔵 Nuevo: ¡Modal del temporizador de ejercicios!\\n\\nLos ejercicios basados en tiempo ahora muestran un modal de cuenta atrás dedicado con un anillo de progreso, lo que facilita el seguimiento de tu esfuerzo y mantener el ritmo durante las series cronometradas.\\n\"],\"0caMy7\":[\"Historial\"],\"0dHvKo\":[\"Músculo objetivo:\"],\"0eRpDV\":[\"Difícil, cerca del límite\"],\"0f7U0k\":[\"Mié\"],\"0tJJBW\":[\"Anterior: \"],\"0vGEy2\":[\"\\n📊 Nuevo: ¡Pantalla de estadísticas mejorada!\\n\\nLa pantalla de estadísticas ha sido rediseñada con un aspecto renovado y perspectivas mejoradas. Explora tu historial de entrenamiento con mejores gráficos, resúmenes más claros y desgloses más detallados de tu progreso a lo largo del tiempo.\\n\"],\"14ytif\":[\"Iniciar entrenamiento\"],\"1DF4Ah\":[\"Eliminar todos los datos compartidos\"],\"1DPB1m\":[\"\\n🗂️ Nuevo: ¡Cinco nuevos planes de entrenamiento prediseñados!\\n\\nCinco nuevos planes listos para usar están ahora disponibles: Split de 5 días Bro, Push/Pull/Piernas de 5 días, Split de 6 días, Peso corporal y Solo mancuernas. Tanto si entrenas en casa como en el gimnasio, hay un plan para que empieces de inmediato.\\n\"],\"1FnEj9\":[\"Medidas corporales\"],\"1Kx4Hp\":[\"Error al obtener \",[\"0\"],\": \",[\"1\"]],\"1Mx10o\":[\"Ver estadísticas\"],\"1QfxQT\":[\"Cerrar\"],\"1Se9J7\":[\"bicicleta estática\"],\"1UzENP\":[\"No\"],\"1gbc4_\":[\"Nuevo entrenamiento\"],\"1hW6-f\":[\"Algunas imágenes no se pudieron descargar tras varios intentos. IDs de ejercicio fallidos: \",[\"0\"]],\"1j3Ob3\":[\"Calendario de entrenamientos\"],\"1mm2JF\":[\"deltoides\"],\"296mtr\":[\"barra trampa\"],\"29Hx9U\":[\"Estadísticas\"],\"2FYpfJ\":[\"Más\"],\"2ZZM6V\":[\"core\"],\"2bnWaQ\":[[\"completedCount\"],\"/\",[\"0\"],\" series completadas\"],\"2cupe5\":[\"Aplicar a todas las series \",[\"0\"]],\"2dPYb7\":[\"Aún no hay medidas. Registra tu primera entrada arriba.\"],\"2dX9Kv\":[\"espalda\"],\"2eB2c7\":[\"¡Entrena sin un plan! Crea entrenamientos independientes que viven fuera de tus planes de entrenamiento, perfectos para sesiones de movilidad, calentamientos o cualquier cosa improvisada.\\n\\nO entra directamente en un Entrenamiento rápido desde la pantalla de inicio, añade ejercicios sobre la marcha y opcionalmente guárdalo como entrenamiento independiente cuando termines.\"],\"2gSypt\":[\"Equipamiento *\"],\"2j0v05\":[\"¡Todas las imágenes se han descargado correctamente!\"],\"2lfUf3\":[[\"streak\",\"plural\",{\"one\":[\"#\",\" semana consecutiva\"],\"other\":[\"#\",\" semanas consecutivas\"]}]],\"2saL1j\":[\"1RM\"],\"2vS4Oc\":[\"Fácil, podría haber hecho más\"],\"2wR0QE\":[\"Añadir ejercicio\"],\"30xwUM\":[\"¿Estás seguro de que quieres eliminar todas las imágenes animadas? Las imágenes individuales se volverán a descargar automáticamente cuando se vean.\"],\"39y5bn\":[\"Viernes\"],\"3A79ox\":[\"Reducir peso\"],\"3L-1Z1\":[\"Error al cargar los ejercicios: \",[\"0\"]],\"3RoflF\":[\"\\n📈 Nuevo: ¡Historial de ejercicios en la pantalla de información!\\n\\nLa pantalla de información del ejercicio ahora incluye un historial completo de cada vez que has realizado ese ejercicio, mostrando pesos, reps, tiempo y distancia de cada serie en sesiones anteriores. Accede a él durante un entrenamiento, desde tu plan o desde cualquier lugar donde esté disponible la información del ejercicio.\\n\"],\"3ezHPX\":[\"Reproducir sonido tras el descanso\"],\"3hJ166\":[\"\\n🔍 Mejorado: ¡Búsqueda de ejercicios más inteligente y acceso fácil a la biblioteca de ejercicios!\\n\\nLa búsqueda de ejercicios ahora reconoce abreviaturas comunes como RDL, OHP, DB y KB, corrige pequeños errores tipográficos y clasifica los resultados por relevancia para que la mejor coincidencia aparezca siempre primero.\\n\\nTambién puedes explorar la biblioteca completa de ejercicios en cualquier momento desde el menú, sin necesidad de estar en un entrenamiento o plan.\\n\"],\"3hJypY\":[\"Estadísticas clave\"],\"43lYJ-\":[\"Bienvenido/a\",[\"userName\"]],\"4BgR4M\":[\"Has alcanzado tu objetivo semanal. ¡Increíble trabajo!\"],\"4GTHgi\":[\"Cuenta atrás del temporizador de ejercicio\"],\"4M4P8M\":[\"No se han introducido valores\"],\"4OjqAQ\":[\"Seguir editando\"],\"4Y9aig\":[\"Actualizado \",[\"0\"]],\"4_WLmI\":[\"peso corporal\"],\"4j0zbV\":[\"Guardando plan...\"],\"4jkyRj\":[\"calentamiento\"],\"4mrNi3\":[[\"suggestedRepsMin\"],\"-\",[\"suggestedRepsMax\"],\" reps sugeridas\"],\"4oRoD4\":[\"Configura las unidades de peso, tamaño y distancia, las series predeterminadas por ejercicio, el tiempo de descanso predeterminado y el incremento de peso de los botones ± durante la sesión. Ajusta el tamaño de los botones de entrenamiento (Estándar, Grande o Muy grande) y activa Mantener pantalla encendida para que la pantalla no se apague. En Estadísticas, puedes excluir las series de calentamiento del volumen, duplicar las repeticiones en ejercicios unilaterales o doblar el peso para implementos emparejados, útil si registras el peso de una mancuerna en lugar del total. Introduce tu peso corporal aquí; se usa para calcular la carga efectiva en ejercicios asistidos.\"],\"4sGdeG\":[\"Grasa corporal\"],\"5-5naM\":[\"Amigos y social\"],\"50_FGa\":[\"Ejercicio\"],\"538Jsv\":[\"Cancelar entrenamiento\"],\"58iwz8\":[\"Error al cargar los planes\"],\"5Hrw0r\":[\"Añadir a mis entrenamientos\"],\"5SgD0L\":[\"Tienes cambios sin guardar. ¿Seguro que quieres descartarlos?\"],\"5Z05pb\":[\"Escribe para filtrar temas de ayuda\"],\"5aB9II\":[\"¡Es hora de tu próxima serie!\"],\"5b4J4v\":[\"Todo el tiempo\"],\"5lWFkC\":[\"Iniciar sesión\"],\"5w2VTM\":[\"¿Estás seguro de que quieres descargar todas las imágenes animadas? Puede tardar un poco.\"],\"5yIPLp\":[\"¡Vaya!\"],\"66llpx\":[\"Añadir imagen\"],\"699xiu\":[\"¿Estás seguro de que quieres restaurar la copia de seguridad?\"],\"6Bqki7\":[\"¡Objetivo semanal completado!\"],\"6Hcqaf\":[\"\\n↕️ Nuevo: ¡Reordena entrenamientos en tu plan!\\n\\nAhora puedes reordenar los entrenamientos directamente en la pantalla de creación del plan y en las tarjetas de entrenamiento, dándote control total sobre la estructura de tu horario de entrenamiento.\\n\"],\"6MR2yM\":[\"Explora casi 1.000 ejercicios y filtra por parte del cuerpo, músculo objetivo o equipamiento. Usa los chips de ordenación en la parte superior para ordenar los ejercicios por Predeterminado, Plan activo, Reciente o Frecuente, y así los ejercicios más relevantes para ti aparecerán primero. Al reemplazar un ejercicio, el filtro preselecciona automáticamente el músculo objetivo correspondiente para ayudarte a encontrar alternativas más rápido. Toca cualquier ejercicio para ver su demostración animada, los músculos trabajados y un historial completo de cada vez que lo has realizado, incluyendo pesos, reps, tiempo o distancia por serie. Descarga todas las animaciones de ejercicios (~100 MB) en Ajustes para acceso sin conexión.\"],\"6XIVae\":[\"Subir peso\"],\"6_dCYd\":[\"Vista general\"],\"6g63at\":[\"Explorar planes\"],\"6glEtt\":[\"Todavía en recuperación. Mantener este peso por ahora.\"],\"6igHT6\":[\"Editar entrenamiento\"],\"6lAGPA\":[\"Añade un entrenamiento para empezar\"],\"6lv7us\":[\"Peso (\",[\"weightUnitLabel\"],\")\"],\"6q7I63\":[\"cintura\"],\"6u9LvN\":[[\"days\",\"plural\",{\"one\":[\"hace \",\"#\",\" día\"],\"other\":[\"hace \",\"#\",\" días\"]}]],\"6uHnph\":[\"Tiempo (Hora:Min)\"],\"6vinCF\":[\"Tipo de seguimiento *\"],\"6z9W13\":[\"Reiniciar\"],\"716aO7\":[\"Más entrenado\"],\"75Qc-e\":[\"Cuenta reps ×2 para el volumen cuando el ajuste está activado\"],\"77kllS\":[\"mejor \",[\"0\"],\" reps\"],\"7F8buC\":[\"brazos inferiores\"],\"7FYy4K\":[\"Error al guardar el entrenamiento\"],\"7LBKtm\":[\"No hay entrenamiento disponible\"],\"7LLkrj\":[\"músculos de agarre\"],\"7MuXko\":[\"Personal\"],\"7P_9OY\":[\"Ma\"],\"7YT_7y\":[\"Reps\"],\"7Z9Tzs\":[\"columna vertebral\"],\"7eMo-U\":[\"Ir al inicio\"],\"7hAJKI\":[[\"0\",\"plural\",{\"one\":[\"serie\"],\"other\":[\"series\"]}]],\"7iTVa8\":[\"Músculos secundarios\"],\"7p3sn_\":[\"Tiempo: \",[\"0\"]],\"7x42zy\":[\"No hay datos para este período\"],\"7xB0qQ\":[\"Músculo objetivo *\"],\"87VAxI\":[\"Info del ejercicio\"],\"8BG66J\":[\"Aún no hay entrenamientos completados compartidos\"],\"8JaOZF\":[\"Perfil de amigo\"],\"8Mlj-A\":[\"No se alcanzó el objetivo de reps. Mantener por ahora.\"],\"8Rd3od\":[\"¿Estás seguro de que quieres cancelar y eliminar este entrenamiento?\"],\"8V8f_Q\":[\"Último \",[\"metricLabel\"],\": \",[\"0\"]],\"8YBh-G\":[\"Contando reps ×2 para estos ejercicios\"],\"8ZJ9dh\":[\"Registro de peso para ejercicios con peso corporal\"],\"8ZU8FI\":[\"Error al cargar las estadísticas. Por favor, inténtalo de nuevo.\"],\"8_MCsG\":[\"\\n💾 Nuevo: ¡Guarda y reanuda borradores de planes y entrenamientos!\\n\\nTu trabajo en los editores de planes y entrenamientos independientes ahora se guarda automáticamente como borrador. Si sales a mitad de la edición, se te preguntará si quieres continuar donde lo dejaste o descartar el borrador, para que nunca pierdas el progreso por accidente.\\n\"],\"8aTiea\":[\"Personalización\"],\"8cA6YX\":[\"Sigue tu composición corporal a lo largo del tiempo desde la sección Medidas del tab Estadísticas. Usa el formulario Registrar entrada para introducir valores en cualquier métrica activa y toca una entrada anterior en el historial para revisarla o editarla. En la pantalla de detalle de la entrada, toca el chip de una métrica para cambiar el gráfico entre distintas medidas y usa el selector de rango de tiempo para acercar o alejar la vista. Las métricas se dividen en tres tipos: masa (peso, en kg o lbs), longitud (circunferencias como cintura y caderas, en cm o pulgadas) y porcentaje (grasa corporal). Las unidades siguen tus preferencias de peso y tamaño en Ajustes. Para controlar qué métricas aparecen en el formulario, toca Gestionar métricas en la parte superior de la sección Registrar entrada. Las métricas integradas pueden activarse o desactivarse; también puedes crear métricas personalizadas y elegir su tipo. Las métricas personalizadas pueden ocultarse del formulario en cualquier momento y tus datos históricos se conservan siempre.\"],\"8jcZyX\":[\"Métricas integradas\"],\"8mjpCE\":[\"Introducción a MuscleQuest\"],\"8uqQSD\":[\"No pude terminar todas las series\"],\"8wbSm2\":[\"Aún no hay datos de fuerza compartidos\"],\"8yLreB\":[\"durante \",[\"0\"],\"s \"],\"8yw7nc\":[\"Control de recuperación\"],\"91hJvI\":[\"Objetivo: \",[\"distanceMin\"],\" \",[\"distanceUnit\"]],\"94FTWy\":[\"Eliminación completa\"],\"95IyBI\":[\"Los ejercicios con peso corporal como las dominadas o los fondos registran solo repeticiones por defecto. Si quieres anotar peso adicional, como un cinturón de lastre o un chaleco, abre el resumen de series de ese ejercicio en el editor de entrenamiento o plan y activa Registrar peso. La opción se guarda por entrenamiento, así que puedes tener algunos entrenamientos solo con peso corporal y otros que registren la carga adicional. Los gráficos de progresión y el historial reflejarán el peso registrado una vez que la opción esté activada.\"],\"97-TIS\":[\"No pudiste completar todas las series. El peso baja un poco para la próxima.\"],\"9Anet0\":[\"Equipamiento\"],\"9C6X7Q\":[\"Descartar cambios\"],\"9EGOsa\":[\"cable\"],\"9H3-WL\":[\"\\n⚙️ Nuevo: ¡Tres nuevas opciones de estadísticas!\\n\\nPersonaliza cómo se calculan tu volumen y tus estadísticas con tres nuevas opciones en Ajustes:\\n\\n• Excluir las series de calentamiento de las estadísticas para que no distorsionen tus números.\\n• Doblar el peso de las mancuernas automáticamente, para que puedas registrar el peso de una mancuerna y que el total se calcule solo.\\n• Doblar las reps de los ejercicios unilaterales, para que los movimientos unilaterales se cuenten correctamente en tus totales de volumen.\\n\"],\"9HyV9h\":[\"Activa para añadir un control de publicación a cada entrenamiento individual.\"],\"9LmK3L\":[\"Imágenes de Unsplash\"],\"9XoWik\":[\"serrato anterior\"],\"9eQmcp\":[[\"0\"],\" días por semana\"],\"A-gAFO\":[\"Crea tus propios ejercicios desde el selector de ejercicios. Dale un nombre, una imagen opcional, parte del cuerpo, músculos objetivo, músculos secundarios y equipamiento. Elige un tipo de seguimiento: peso + reps, tiempo, distancia, solo reps o asistido (que tiene en cuenta tu peso corporal para movimientos como dominadas asistidas). Activa Unilateral para ejercicios de un solo brazo o pierna; las reps pueden doblarse automáticamente en tus estadísticas. Activa Implementos pareados si registras el peso de un solo implemento en lugar del total: por ejemplo, si anotas 20 kg para una mancuerna, la app cuenta 40 kg hacia tu volumen.\"],\"A1-VaP\":[\"dorsal ancho\"],\"A1_kH4\":[\"Temporizador de ejercicio\"],\"A1taO8\":[\"Buscar\"],\"ATGYL1\":[\"Correo electrónico\"],\"AWokve\":[\"Historial del mismo entrenamiento\"],\"AeXO77\":[\"Cuenta\"],\"AqyJQg\":[\"Feedback tras el ejercicio\"],\"Ayx1au\":[\"¿Estás seguro de que quieres eliminar este plan?\"],\"B8ZQ8n\":[\"Reps mín.\"],\"B9LtU1\":[\"Tienes cambios sin guardar de tu última sesión. ¿Quieres continuar?\"],\"BEVzjL\":[\"Importación fallida\"],\"BGO6Rp\":[\"¿Cómo se sienten estos músculos desde tu última sesión?\"],\"BTqs-Z\":[[\"0\",\"plural\",{\"one\":[\"#\",\" Serie\"],\"other\":[\"#\",\" Series\"]}]],\"BZDlVl\":[\"flexores de cadera\"],\"BaG4Vp\":[\"Frecuente\"],\"BdnYlL\":[\"Duración media\"],\"BpTc_M\":[\"Buscar en la ayuda\"],\"Bqo02Q\":[\"Iniciar temporizador\"],\"BrHgnn\":[\"\\n⏱️ Nuevo: ¡Temporizador de descanso ajustable!\\n\\nUn nuevo panel deslizante te permite ajustar la duración del descanso en cualquier momento durante un entrenamiento. Tu tiempo de descanso personalizado se guarda por serie, para que cada serie recuerde exactamente cuánto tiempo quieres descansar.\\n\"],\"BwTx3c\":[\"¿Estás seguro de que quieres eliminar \",[\"0\"],\"?\"],\"C4GKOD\":[[\"repRange\"],\" Reps, \"],\"CCTop_\":[\"Reciente\"],\"CE-M2e\":[\"Info\"],\"CFL873\":[\"Activa para compartir automáticamente cada entrenamiento que completes.\"],\"CV6Ez2\":[\"Toca Iniciar sesión con Google en Ajustes para conectar tu cuenta. Al iniciar sesión se activan las copias de seguridad en la nube para que tus datos estén seguros si cambias de dispositivo o reinstala la app, y tu nombre aparece en el saludo de la pantalla de inicio. La app funciona completamente sin conexión sin iniciar sesión, pero las copias de seguridad en la nube no están disponibles. Tus datos se almacenan localmente en tu dispositivo y no se comparten con nadie a menos que tú decidas hacerlo.\"],\"CZKXmk\":[\"tobillos\"],\"CaKjcv\":[\"Entrenamiento rápido\"],\"CghlOu\":[\"abdominales inferiores\"],\"CiUwqB\":[\"Ir a entrenamientos\"],\"CxQnhY\":[\"\\n👥 Nuevo: ¡Amigos y uso compartido!\\n\\nAñade amigos buscando su nombre de usuario en la pestaña Amigos del menú. Envía una solicitud y, una vez aceptada, podréis explorar el contenido compartido del otro. Un badge en el elemento del menú Amigos muestra las solicitudes entrantes pendientes.\\n\\nComparte tus planes, entrenamientos individuales, ejercicios personalizados, medidas corporales y récords de fuerza activando Compartir en la pantalla correspondiente o desde la Configuración de privacidad en la sección Cuenta de Ajustes. El contenido compartido se sincroniza automáticamente cada vez que cambia, y un icono de nube en las tarjetas de plan y entrenamiento muestra lo que está publicado. Puedes eliminar todos los datos compartidos de cualquier categoría desde la Configuración de privacidad en cualquier momento.\\n\\nToca el nombre de cualquier amigo aceptado para abrir su perfil e importar sus planes, entrenamientos individuales o ejercicios personalizados directamente a tu propia biblioteca.\\n\"],\"D-GweR\":[\"Inicia sesión para usar la función de Amigos.\"],\"D0GOrZ\":[\"Necesitas iniciar sesión para usar esta función\"],\"D3h1sn\":[\"trabajando\"],\"D45Cr4\":[\"Selecciona los músculos secundarios\"],\"D89zck\":[\"Dom\"],\"DBC3t5\":[\"Domingo\"],\"DIS-zd\":[\"Error al eliminar el plan: \",[\"0\"]],\"DJMHhb\":[\"La última sesión fue una descarga. Comparación omitida.\"],\"DNhKLr\":[\"\\n🎯 Mejorado: ¡Filtros de ejercicios más inteligentes!\\n\\nAl reemplazar un ejercicio, el filtro ahora preselecciona automáticamente el músculo objetivo para que coincida con lo que estás reemplazando. Solo se muestran los filtros relevantes según tu selección actual, lo que hace mucho más rápido encontrar la alternativa adecuada.\\n\"],\"DPfwMq\":[\"Listo\"],\"DTtUaj\":[\"Introduce al menos una medida para registrar.\"],\"DWFuyG\":[\"Eliminar ejercicio\"],\"DYOFso\":[\"estabilizadores del tobillo\"],\"DdBQBl\":[\"Horario semanal\"],\"Dh5Ge5\":[\"¿Algún dolor o problema de técnica?\"],\"Di-cgt\":[\"¡Bienvenido/a a MuscleQuest!\"],\"DqgDEk\":[\"El más reciente de cualquier entrenamiento\"],\"Dvc8Qg\":[\"Descripción:\"],\"Dy8Cvh\":[\"cuádriceps\"],\"Dy_8Fq\":[\"CERRAR\"],\"E3kRqj\":[[\"uniqueWorkoutDaysCount\"],\" / \",[\"0\"],\" días entrenados\"],\"EANWES\":[\"Error al cargar el historial\"],\"EHgz6Q\":[\"No se pudo actualizar el uso compartido. Inténtalo de nuevo.\"],\"EMyNOr\":[[\"0\"],\" \",[\"1\"],\" (usado en ejercicios asistidos)\"],\"E_QGRL\":[\"Desactivado\"],\"Ed3YeG\":[\"Cada entrenamiento que completes se comparte automáticamente.\"],\"Ef7StM\":[\"Desconocido\"],\"EfdYnO\":[[\"0\"],[\"distanceUnit\"]],\"EjAXiq\":[\"Progresión adaptativa (beta)\"],\"EkVHAp\":[\"Incremento del temporizador de descanso\"],\"EoQHhQ\":[\"cinta de correr\"],\"Euo2Um\":[\"Tiempo (Min:Seg)\"],\"F37c1s\":[\"Abrir Ajustes\"],\"F6pfE9\":[\"Activo\"],\"FCGpHg\":[\"Aún no hay ejercicios en este entrenamiento.\"],\"FHIDZO\":[\"Guardar y seleccionar\"],\"FPsvA8\":[\"¡Entendido!\"],\"FXHR4B\":[\"Parte del cuerpo\"],\"Fb5zs_\":[\"\\n⚖️ Nuevo: ¡Registrar peso para ejercicios con peso corporal!\\n\\nPara ejercicios con peso corporal como dominadas o fondos, ahora puedes activar el registro de peso por entrenamiento. Perfecto para variantes con peso adicional, para anotar el peso añadido y seguir la progresión con el tiempo.\\n\"],\"Fe0wLe\":[\"Superseries\"],\"FnTClW\":[\"Estás alcanzando los objetivos con facilidad. Es hora de añadir un poco más de peso.\"],\"Fp1hl-\":[\"Cargando plan...\"],\"FwCUad\":[\"El equipamiento es obligatorio.\"],\"G-iXUH\":[\"hombros\"],\"G1onOm\":[\"¿Eliminar todos los datos compartidos?\"],\"G2R9Qq\":[\"flexores de muñeca\"],\"G2nnKc\":[\"Añadir a mis planes\"],\"G3myU-\":[\"Martes\"],\"G49bAb\":[\"máquina de palanca\"],\"G4JNdR\":[\"Ejercicio no encontrado.\"],\"G6rTvo\":[\"Seguir (\",[\"0\"],\")\"],\"GB-X8R\":[\"Importar de amigos\"],\"GCV1HM\":[\"Sesión iniciada como \",[\"0\"]],\"GCqPY4\":[\"La pantalla de inicio muestra tu progreso hacia tu objetivo semanal de entrenamiento, que es el número de días que quieres entrenar cada semana, establecido en Ajustes. Una franja en la parte superior registra cuántos días has completado y resalta cada día completado. Debajo, los entrenamientos de tu plan activo se listan con su estado de finalización para la semana; toca Iniciar en cualquier entrenamiento para comenzar. La tarjeta que se muestra debajo cambia según tu estado: aparece una tarjeta Reanudar si hay una sesión en curso, una tarjeta Día de descanso en los días sin entrenamiento programado, y una tarjeta Entrenamiento completado que confirma que la sesión de hoy está terminada. Cuando alcanzas tu objetivo semanal, aparece una tarjeta Resumen semanal que muestra el total de entrenamientos, series y volumen de la semana, más tu racha, que cuenta el número de semanas consecutivas en las que has cumplido tu objetivo.\"],\"GGqR7k\":[\"Entrenamientos individuales y rápidos\"],\"GLJjec\":[\"Al fallo\"],\"GLm0-9\":[\"Dolor o problemas de técnica\"],\"GNurdZ\":[\"Eliminar ejercicio\"],\"GPeIuw\":[\"Distancia\"],\"GS7yxz\":[\"Permiso requerido\"],\"GSOeV2\":[\"isquiotibiales\"],\"GVN2lL\":[\"Crear ejercicio\"],\"GWvJTL\":[\"Más o menos bien\"],\"GX9tlq\":[\"cuello\"],\"Gd-KuS\":[\"Gestionar métricas\"],\"Gf9sn6\":[\"Buscando copias de seguridad...\"],\"GhCGeL\":[\"Series\"],\"GksdwI\":[\"Mejores series PR\"],\"HNWkJr\":[\"\\n📏 Nuevo: ¡Seguimiento de distancia para ejercicios personalizados!\\n\\nLos ejercicios personalizados ahora pueden usar un tipo de seguimiento por distancia, perfecto para movimientos de cardio y acondicionamiento como carreras, remadas o empujes de trineo. Registra la distancia de tus series y obtén información sobre tu progresión igual que con cualquier otro ejercicio.\\n\"],\"HYL9fJ\":[\"Registrar solo un lado para ejercicios de un brazo/pierna\"],\"Hp6ceF\":[\"No se puede guardar tu entrenamiento. Por favor, inténtalo de nuevo más tarde.\"],\"HpK_8d\":[\"Recargar\"],\"Hplwk7\":[\"Restaurando. Por favor, espera...\"],\"I2Hpku\":[\"Registrar peso\"],\"ICkQNB\":[\"Hora del recordatorio\"],\"IFowGw\":[\"cuerda\"],\"IHMx9j\":[\"Racha semanal\"],\"ILE1kp\":[\"brazos\"],\"INkdlR\":[\"Aún no tienes amigos. Busca por correo para añadir a alguien.\"],\"IRiG-a\":[\"Vibrar tras el descanso\"],\"IUwGEM\":[\"Guardar cambios\"],\"IXxATP\":[\"Ejercicios personalizados\"],\"IbbuFX\":[\"Eliminando. Por favor, espera...\"],\"IuXB4Q\":[\"Añade una nota...\"],\"Izf0kk\":[\"Sin datos previos de peso. Mantener por ahora.\"],\"JE-yVp\":[\"Gestionar métricas\"],\"JR5hAM\":[\"1 año\"],\"JTkSvz\":[\"¿Estás seguro de que quieres eliminar este entrenamiento?\"],\"JVKmoO\":[\"La actualización no se pudo descargar. Comprueba tu conexión a internet y vuelve a abrir la app para intentarlo de nuevo.\"],\"JW7_2_\":[\"Descarga fallida\"],\"JWTR_A\":[\"Se ha producido un error al descargar las imágenes.\"],\"JYRqp5\":[\"Sá\"],\"JbvV5d\":[\"Durante una sesión, desliza a izquierda/derecha o usa los botones de flecha para moverte entre series. Introduce tu peso y reps, luego toca Completar serie. El tiempo total transcurrido se muestra en el encabezado durante toda la sesión. Puedes arrastrar el asa de cualquier tarjeta de ejercicio para reordenar ejercicios mientras la sesión está en curso. Los ejercicios basados en tiempo tienen un botón Iniciar temporizador que abre un cronómetro con un anillo de progreso que te indica cuándo alcanzas tu tiempo objetivo, pero puedes continuar todo lo que quieras. Las notas se pueden añadir por ejercicio mediante el icono de notas en el encabezado del ejercicio, por entrenamiento desde la pantalla de vista general del entrenamiento, o por plan desde la pantalla de vista general del plan. Si añades, eliminas o reordenas ejercicios o series durante una sesión, se te pedirá al final si quieres guardar esos cambios en el entrenamiento o plan original.\"],\"JfDOWo\":[\"La actualización está lista pero la app no pudo reiniciarse automáticamente. Intenta tocar el botón de abajo, o cierra y vuelve a abrir la app manualmente.\"],\"JkpsKr\":[\"Descargando. Por favor, espera...\"],\"JmZ_-d\":[\"Finalizar\"],\"JsIy35\":[\"Has activado este plan.\"],\"JumwGu\":[\"cardio\"],\"Jv9TrU\":[\"oblicuos\"],\"KIL-9T\":[\"Siguiente: \"],\"KKalG-\":[\"Fija ejercicios en la pestaña Estadísticas para seguir su progresión de fuerza con el tiempo. Cada ejercicio fijado muestra un gráfico de tu rendimiento en el rango de tiempo seleccionado, tu récord personal histórico, tus mejores series y una lista de sesiones recientes con la mejor serie por día. Los gráficos se actualizan automáticamente tras cada entrenamiento que incluya ese ejercicio.\"],\"KM1Iw2\":[\"MuscleQuest\"],\"KSqQx0\":[\"Reps máx.\"],\"Km7tR4\":[\"Invítame a un café\"],\"KmiPdE\":[\"mancuerna\"],\"KxWSWU\":[\"Mantener pantalla encendida durante el entrenamiento\"],\"LAC2eo\":[\"Recordatorios de entrenamiento\"],\"LAHzG1\":[\"Ver/Editar\"],\"LIrnc0\":[\"Aún no se han añadido ejercicios\"],\"LLt1-u\":[\"Unilateral\"],\"LZKayn\":[\"Buscar en la ayuda…\"],\"LcPJBt\":[\"entrenamientos completados\"],\"LhMjLm\":[\"Tiempo\"],\"LyPttd\":[\"Pecho\"],\"M0GVkz\":[\"Selecciona un día para ver los entrenamientos.\"],\"M1POMr\":[\"Biblioteca de ejercicios\"],\"M4hMaA\":[\"Introduce un nombre para la métrica personalizada.\"],\"M57U8X\":[\"Agrupa dos ejercicios en una superserie para que alternen automáticamente durante una sesión, ideal para combinar músculos antagonistas o mantener la eficiencia entre series. Toca el menú de tres puntos en cualquier ejercicio del editor de entrenamiento y elige Crear superserie, luego selecciona el segundo ejercicio. Una etiqueta de color identifica en toda la app a qué superserie pertenece cada ejercicio. Cuando completas una serie en un ejercicio, la app te lleva directamente a su compañero de superserie.\"],\"MEt7-_\":[\"sóleo\"],\"MHk_Wu\":[\"Registro no encontrado.\"],\"MLQOxI\":[\"deltoides posteriores\"],\"MM-MTF\":[\"Superserie \",[\"0\"]],\"MQ9jL7\":[\"¡Un entrenamiento más para alcanzar tu objetivo!\"],\"MQA2H9\":[\"Eliminar plan\"],\"MTqmCb\":[\"Solicita o vota por nuevas funciones\"],\"McFNQO\":[\"Monitorea tu viaje fitness con estadísticas e información detalladas. Lleva un registro del historial de entrenamientos, analiza tus divisiones por parte del cuerpo y visualiza las mejoras con el tiempo mediante gráficos de progresión de ejercicios.\"],\"MmDz7_\":[\"Subiendo. Por favor, espera...\"],\"N4e_z1\":[\"Tiempo de descanso: \",[\"restMinutes\"],\":\",[\"0\"]],\"N5Cyfw\":[\"Amigos desde \",[\"0\"]],\"N85c_3\":[\"Eliminar entrenamiento\"],\"NC2AI2\":[\"Longitud\"],\"NIuBdI\":[\"Planes prediseñados\"],\"NKdWDE\":[\"sistema cardiovascular\"],\"NLBiJk\":[\"Registrar entrada\"],\"NLYLjM\":[\"series\"],\"NPG8SK\":[\"Peso corporal\"],\"NQJHen\":[\"¿Estás seguro de que quieres reiniciar este entrenamiento?\"],\"NVOqiK\":[\"Inicia sesión para proteger tus datos\"],\"NXoGPK\":[\"Editar ejercicio\"],\"Ne5n-8\":[\"Añadir notas personales\"],\"NnRCUm\":[[\"0\"],\"s\"],\"Ns5WaC\":[\"No se encontraron copias de seguridad\"],\"Nu4oKW\":[\"Descripción\"],\"O1GFNQ\":[\"Todos los músculos objetivo\"],\"O1xiRM\":[\"reps\"],\"O2TAe0\":[\"barra\"],\"O2wCGL\":[\"Reproducir pitidos de cuenta atrás (Temporizador de ejercicio)\"],\"ODbgw_\":[\"Esto elimina todo el contenido que has compartido con amigos. Tus amigos y lista de amigos no se ven afectados.\"],\"OdFJle\":[\"Activa para compartir automáticamente los ejercicios personalizados que crees o edites.\"],\"Otd3xX\":[\"Una semana de descarga es una semana de recuperación planificada en la que entrenas con menor intensidad para que tu cuerpo se recupere completamente antes del siguiente bloque de entrenamiento. Toca Marcar como semana de descarga en la pantalla de vista general del plan para indicar que la semana actual es una descarga. Mientras la descarga está activa, el cuestionario de feedback tras el ejercicio no aparece y no se crean ni actualizan nuevos estados de progresión, por lo que tu historial de sugerencias no se ve afectado por las sesiones más ligeras. La descarga se restablece automáticamente al inicio de la semana siguiente y el feedback normal y el seguimiento de progresión se reanudan sin ninguna acción manual. Si cambias de opinión, vuelve a tocar el botón mientras la descarga está activa para cancelarla.\"],\"Ov8o8m\":[\"Iniciar plan\"],\"OwNTSr\":[\"Guardar en el plan\"],\"Owchfv\":[\"Usado recientemente\"],\"OzAZw8\":[\"Esta pantalla no existe.\"],\"P0mjNu\":[\"Eliminar registro\"],\"P0svFp\":[\"Descanso\"],\"P1svYv\":[\"abdominales\"],\"P247ya\":[\"Parte del cuerpo *\"],\"P3NwXY\":[\"Compartir entrenamiento\"],\"P3nVsi\":[\"\\n📅 Nuevo: ¡Horario semanal para tu plan!\\n\\nAhora puedes asignar entrenamientos a días específicos de la semana directamente en el editor del plan. Toca cualquier día para elegir un entrenamiento o marcarlo como día de descanso. Usa el botón de sugerencia automática para generar al instante un horario equilibrado basado en tu objetivo semanal.\\n\"],\"P3omNB\":[\"Selecciona un entrenamiento para ver\"],\"PBt59F\":[\"Ejercicios favoritos\"],\"PFcCy0\":[\"x \",[\"0\"],\" reps \"],\"PHWHEO\":[\"Aceptar todo\"],\"PITZNx\":[\"pecho\"],\"PN5Zzf\":[\"Unidad de peso\"],\"PNapeY\":[\"+ Añadir\"],\"POx12e\":[\"\\n↕️ Nuevo: ¡Reordena ejercicios en la vista general del entrenamiento!\\n\\nAhora puedes arrastrar y soltar ejercicios y superseries para reordenarlos directamente desde la pantalla de vista general del entrenamiento durante una sesión.\\n\"],\"PSNHRi\":[\"* funciones en desarrollo\"],\"PWfg7v\":[\"Solicitudes\"],\"P_0oX-\":[\"Asistencia\"],\"PeTE4m\":[\"Plan no encontrado.\"],\"PiK6Ld\":[\"Sáb\"],\"PruBpO\":[\"¿Estás seguro de que quieres eliminar este registro de medición?\"],\"Q1Lq8I\":[\"Tiempo total\"],\"Q2QJ28\":[\"Reproducir sonido al alcanzar el objetivo (Temporizador de ejercicio)\"],\"Q8bEQa\":[\"Se ha producido un error al eliminar las imágenes.\"],\"Q9qAkA\":[\"Duración estimada: \",[\"0\"]],\"QENBWX\":[\"tríceps\"],\"QOTvot\":[\"Compartir tu contenido\"],\"Qdwk82\":[\"Incremento de carga para mancuerna\"],\"Qjp-BQ\":[\"Añadir una serie\"],\"QlT4B5\":[\"Sesiones recientes\"],\"Qmbwcr\":[\"Editar plan\"],\"QoHy-T\":[[\"weeks\",\"plural\",{\"one\":[\"hace \",\"#\",\" semana\"],\"other\":[\"hace \",\"#\",\" semanas\"]}]],\"QrwEaQ\":[\"pectorales\"],\"QzJCdZ\":[\"dorsales\"],\"R-ABt9\":[\"Objetivo semanal\"],\"R0gwbc\":[\"bíceps\"],\"RAMaAx\":[\"Recibidas\"],\"RCk1J0\":[\"trineo\"],\"RGfnXX\":[\"(al fallo)\"],\"RIHmRj\":[\"Buen ritmo. Intenta añadir una rep por serie antes de subir el peso.\"],\"RM5DG6\":[\"Ejercicios seguidos\"],\"RN4XJV\":[\"Día de descanso\"],\"RU6ELr\":[\"Estadísticas e historial\"],\"RXkbtG\":[\"¿Más intensidad la próxima vez?\"],\"RY_JyV\":[\"lumbar\"],\"R_h8B2\":[\"Más usado\"],\"Rc-8oy\":[\"Descargando actualización\"],\"RmahBs\":[[\"0\"],\": \",[\"best\"],\"s (+\",[\"delta\"],\"s, \",[\"pctStr\"],\")\"],\"Rr5U7J\":[\"Las series completadas aparecerán aquí\"],\"Rwc-xL\":[\"PR de tiempo\"],\"RxzN1M\":[\"Activado\"],\"S2uNE5\":[\"¿Continuar editando?\"],\"SEyweA\":[\"\\n🐛 Solucionado: ¡Varias correcciones y mejoras!\\n\\nSe corrigió que la notificación del temporizador de descanso no se activaba correctamente, el ajuste de texto del nombre del ejercicio en la sesión, el ancho del círculo de finalización del entrenamiento, las notas que no se actualizaban correctamente al escribir, y los detalles del entrenamiento que a veces se abrían en la pestaña incorrecta. Los entrenamientos ahora se cargan más rápido gracias a mejoras internas de rendimiento.\\n\"],\"SGISp8\":[\"Lo terminaste todo al límite. Quédate aquí y consolídalo.\"],\"SRhtpX\":[\"antebrazos\"],\"SUd4dA\":[\"\\n📏 Nuevo: ¡Medidas corporales!\\n\\nSigue tu composición corporal junto a tu entrenamiento desde la nueva sección Medidas en el tab Estadísticas.\\n\\n• Registra peso, % de grasa corporal, cintura, caderas, pecho y más\\n• Toca cualquier entrada anterior para editar valores o ver un gráfico de esa métrica\\n• Gestiona qué métricas se muestran y añade las tuyas personalizadas\\n• Las unidades siguen tus preferencias de peso y tamaño en Ajustes\\n\"],\"SWtay1\":[\"Al completar la última serie de trabajo de un ejercicio, aparece un cuestionario de feedback con dos preguntas. La primera pregunta cómo se sintió el esfuerzo: Fácil (podrías haber hecho más), Más o menos bien, Difícil (cerca de tu límite) o No pude terminar todas las series. La segunda pregunta sobre el dolor: Sin dolor, Molestia leve o Dolor o problemas de técnica. Si respondes Fácil, aparece una tercera pregunta sobre si quieres superarte más la próxima vez. Esto te permite mantener la carga actual deliberadamente aunque la sesión haya parecido fácil, de modo que el sistema respeta tu intención. Si respondes con Dolor, un campo de texto opcional te permite anotar dónde lo sentiste como referencia personal. El cuestionario se puede cerrar sin responder si prefieres no registrar feedback para ese ejercicio en esa sesión.\"],\"SZw9tS\":[\"Ver detalles\"],\"SadoC9\":[\"máquina Smith\"],\"SbGW67\":[\" (al fallo) \"],\"ScJ9fj\":[\"Política de privacidad\"],\"SdpDoo\":[\"Compartir entrenamientos con amigos\"],\"SlfejT\":[\"Error\"],\"SmkA26\":[\"1RM \",[\"0\"],\" \",[\"unit\"]],\"SoWD_0\":[\"Guardar serie\"],\"SrVzRe\":[\"Porcentaje\"],\"St3y2e\":[\"Nombre requerido\"],\"SvOMfA\":[[\"0\"],\" entrenamientos\"],\"SzQe8k\":[\"Añadir a mis ejercicios\"],\"T0cOwV\":[\"Eliminar serie\"],\"T7QVyK\":[\"Cuando abres un entrenamiento con ejercicios que entrenaste recientemente, aparece un cuestionario de Control de recuperación si esos ejercicios tienen una sugerencia de progresión pendiente y tu última sesión fue hace al menos 12 horas. Para cada grupo muscular relevante, eliges una de tres opciones: Fresco (completamente recuperado), Dolor muscular leve o Todavía muy dolorido. Si un músculo se marca como todavía muy dolorido, cualquier sugerencia de progresión ascendente para los ejercicios que trabajan ese músculo se pausa y se mantiene en la carga actual hasta que lo reevalúes al inicio de la siguiente sesión. Fresco o Dolor muscular leve no afectan a las sugerencias. Toca Omitir por ahora para saltarte el control completamente; un control omitido se trata igual que la recuperación completa, por lo que las sugerencias pendientes no se ven afectadas.\"],\"TBTwj-\":[\"Síguenos en Instagram\"],\"TJLDrx\":[\"Doblando el peso para los cálculos de volumen\"],\"T_qHwF\":[\"piernas inferiores\"],\"Ta25TG\":[\"Aún no hay historial\"],\"Tfzp6S\":[\"Compartir récords de fuerza con amigos\"],\"TpqeIh\":[\"Error: \",[\"0\"]],\"Tz0i8g\":[\"Ajustes\"],\"TzLpDD\":[\"\\n🏋️ Nuevo: ¡Entrenamientos individuales y entrenamientos rápidos!\\n\\nCrea entrenamientos independientes fuera de tus planes de entrenamiento, perfectos para sesiones flexibles, trabajo de movilidad o cualquier cosa espontánea. Encuéntralos en la pantalla de Planes.\\n\\nO empieza un Entrenamiento rápido desde la pantalla de inicio, añade ejercicios al vuelo y guárdalo opcionalmente como entrenamiento independiente cuando termines.\\n\"],\"U0HZma\":[\"Seguimiento\"],\"U4QKsL\":[\"Ocultar / Mostrar onboarding\"],\"U8BTVm\":[\"Tiempo de descanso restante:\"],\"UCtAiM\":[\"Para activar las notificaciones del temporizador de descanso, concede permisos de notificación en los ajustes de tu dispositivo.\"],\"UD8kHo\":[\"Siguiente: \",[\"workoutName\"],\" el \",[\"0\"]],\"URmyfc\":[\"Detalles\"],\"US8F_H\":[\"Se sugieren más reps\"],\"USXXjt\":[\"Sin resultados para \\\"\",[\"query\"],\"\\\"\"],\"U_-GrY\":[\"Por favor, espera mientras descargamos la última versión...\"],\"UbRKMZ\":[\"Pendiente\"],\"UlnAQR\":[\"Error al eliminar el entrenamiento. Por favor, inténtalo de nuevo.\"],\"UneMBz\":[\"Plan activo\"],\"UnnFak\":[\"¡Gran comienzo de semana!\"],\"Uorrgj\":[\"romboides\"],\"Uu14s5\":[[\"0\",\"plural\",{\"one\":[\"#\",\" serie\"],\"other\":[\"#\",\" series\"]}]],\"UyvU3-\":[\"Ayuda e información\"],\"UzNvmf\":[\"• Copia de seguridad y restauración de datos\"],\"V6wjuJ\":[\"El tipo de seguimiento es obligatorio.\"],\"V6xf0O\":[\"Este ejercicio ya está en tu entrenamiento. Por favor, elige uno diferente.\"],\"V8MVAm\":[\"pecho superior\"],\"V8dVu4\":[\"\\n🔗 Nuevo: ¡Superseries!\\n\\nCombina dos ejercicios como una superserie directamente en el editor de planes. Las series se mantienen sincronizadas entre ambos ejercicios, y las superseries están claramente agrupadas con un indicador visual en toda la app.\\n\"],\"V8yTm6\":[\"Borrar búsqueda\"],\"VAcXNz\":[\"Miércoles\"],\"VCJb5r\":[\"Serie \",[\"0\"],\" de \",[\"totalSets\"]],\"VDkJml\":[\"La Progresión adaptativa analiza tu feedback de esfuerzo a lo largo de sesiones consecutivas y sugiere cuándo aumentar tu peso, reps o series. Actívala en Ajustes, en Progresión adaptativa. Una vez activada, aparece una breve pregunta de feedback tras cada ejercicio en los entrenamientos basados en un plan. El sistema requiere dos sesiones con la misma señal antes de recomendar un aumento, lo que filtra los días puntualmente fáciles y garantiza un rendimiento constante antes de sugerir un aumento. El dolor o las series fallidas actúan de forma inmediata independientemente de tu historial de sesiones. Una sugerencia nunca se aplica a tu entrenamiento sin tu aprobación explícita. También puedes configurar tu incremento de carga preferido por categoría de equipamiento en la misma sección de Ajustes, por ejemplo 2,5 kg para ejercicios con barra y 2,0 kg para mancuernas.\"],\"VFlRXJ\":[\"Mantener igual esta sesión.\"],\"VJVR1o\":[\"Compartir plan\"],\"VcD4kW\":[\"Este amigo aún no ha compartido ningún contenido.\"],\"VhVOxx\":[\"¡Tu camino a Swoletown empieza hoy!\"],\"VhfZbD\":[\"Tamaño: ~100 MB\"],\"W-pY1H\":[\"Error al guardar el ejercicio personalizado. Por favor, inténtalo de nuevo.\"],\"W0qDyY\":[\"Pantalla de inicio y objetivo semanal\"],\"W3QcBP\":[\"Vista general del plan\"],\"W3u9nh\":[\"Al fallo, \"],\"WDciil\":[\"\\n📋 Nuevo: ¡Menú \\\"Más\\\" y sección de Ayuda e información!\\n\\nHay una nueva pestaña \\\"Más\\\" en la barra de navegación. Tócala para abrir un panel deslizante donde encontrarás Ajustes y una nueva sección de Ayuda e información.\\n\\nAjustes se ha movido aquí desde la barra de pestañas, y Ayuda e información lo cubre todo, desde planes y entrenamientos hasta estadísticas y tu cuenta, con una barra de búsqueda para encontrar respuestas rápidamente.\\n\"],\"WHwUfF\":[\"Error al cargar los detalles del ejercicio\"],\"WIbOhZ\":[\"Progresión adaptativa\"],\"WJp2MH\":[\"Unidad de tamaño\"],\"WKHqM-\":[\"Peso\"],\"WMvAhQ\":[\"Los ejercicios personalizados que crees o edites se comparten automáticamente.\"],\"WOi4Vm\":[\"Nombre *\"],\"WSzg3A\":[\"Distancia (\",[\"distanceUnit\"],\")\"],\"WU-3OC\":[\"Un solo brazo / una sola pierna\"],\"WaIjmh\":[\"Pantorrilla (D)\"],\"Wjxizh\":[\"Se han eliminado todos los datos compartidos.\"],\"WoEX6M\":[\"Sugerir ajustes de carga y reps\"],\"WzcO-J\":[\"Crear plan\"],\"X9kySA\":[\"Favoritos\"],\"X9r6cu\":[[\"goal\",\"plural\",{\"one\":[[\"completed\"],\" de \",\"#\",\" entrenamiento esta semana\"],\"other\":[[\"completed\"],\" de \",\"#\",\" entrenamientos esta semana\"]}]],\"XBUsEY\":[\"Músculo objetivo\"],\"XHHEUg\":[\"Personalizar plan\"],\"XJQdl_\":[\"Enviar notificación en segundo plano tras el descanso\"],\"XNRDYn\":[\"extensores de muñeca\"],\"XdavYY\":[\"Entrenamientos\"],\"Xdcdfd\":[\"Series y ejercicios\"],\"XoEooZ\":[\"Tiempo (s)\"],\"Xu14OQ\":[[\"0\",\"plural\",{\"one\":[\"#\",\" Rep\"],\"other\":[\"#\",\" Reps\"]}]],\"Xu2iGM\":[\"Añadir peso\"],\"Xv4OIW\":[\"Entrenamiento en curso\"],\"Xwd4Hm\":[\"manguito rotador\"],\"Y35ibG\":[\"Los récords de fuerza se comparten automáticamente tras cada entrenamiento.\"],\"Y6QE0T\":[\"Selecciona el equipamiento\"],\"YANNVr\":[\"Entrenamiento\"],\"YDnEIW\":[\"Mejor ganancia\"],\"YIix5Y\":[\"Buscar...\"],\"YLIqcF\":[\"Bienvenido/a de nuevo\",[\"userName\"]],\"YXJbW8\":[\"Los entrenamientos independientes están fuera de los planes y aparecen junto a tus planes en la pantalla Planes. Crea uno tocando Nuevo entrenamiento, dale un nombre y añade ejercicios; puedes ejecutarlo en cualquier momento sin necesitar un plan activo. Cada entrenamiento independiente muestra una duración estimada para que puedas planificar tu tiempo antes de empezar. Los entrenamientos rápidos te permiten iniciar una sesión de inmediato desde la pantalla de inicio: toca Entrenamiento rápido, añade ejercicios sobre la marcha y al final puedes guardarlo como entrenamiento independiente para uso futuro o simplemente descartarlo. Al igual que los planes, el editor de entrenamiento guarda automáticamente un borrador para que puedas salir y volver sin perder tu trabajo.\"],\"YYzBv9\":[\"Lu\"],\"YekWWq\":[[\"0\",\"plural\",{\"one\":[\"#\",\" rep\"],\"other\":[\"#\",\" reps\"]}]],\"YiPU_R\":[\"deltoides\"],\"YnHdfF\":[\"Serie \",[\"0\"]],\"Yr-t8O\":[\"pies\"],\"YuP-pS\":[\"\\\"\",[\"label\"],\"\\\" se ocultará del formulario de entrada. Tus datos históricos se conservan.\"],\"Z3FXyt\":[\"Cargando...\"],\"Z8RW4m\":[\"Al terminar un entrenamiento, la pantalla de Resumen del entrenamiento muestra una tarjeta de Próxima sesión con sugerencias prácticas para tus ejercicios. Cada fila muestra el nombre del ejercicio, el cambio propuesto (un nuevo peso objetivo, un rango de reps más amplio o una nota para reducir la carga) y una breve explicación de por qué se sugiere el cambio. Toca Aceptar para aplicar la sugerencia a ese ejercicio en tu próxima sesión, o Descartar para ignorarla. Las sugerencias aceptadas se prerellenan en los campos de peso y reps la próxima vez que abras ese entrenamiento, para que empieces la sesión ya apuntando a la carga correcta. El botón Aceptar todo en la parte superior aplica todas las sugerencias de una vez. Las sugerencias que recomiendan mantener la carga actual no aparecen en la tarjeta, ya que no se necesita ninguna acción para ellas.\"],\"ZARyDw\":[\"Añadir amigos\"],\"ZAWGCX\":[[\"0\"],\" segundos\"],\"ZAvcCf\":[[\"0\"],[\"weightUnit\"],\" × \",[\"1\"]],\"ZI8idP\":[\"Fresco, completamente recuperado\"],\"Zm9Eu3\":[\"Tamaño de botones durante el entrenamiento\"],\"Zv7vjq\":[\"Compartir planes con amigos\"],\"Zvc_N1\":[\"1RM (\",[\"weightUnitLabel\"],\")\"],\"_-nVtu\":[\"Se sintió fácil. Mantener por ahora y confirmar en la siguiente sesión.\"],\"_2fO4v\":[\"Resumen del entrenamiento\"],\"_D5y8a\":[\"Series predeterminadas\"],\"_K9jUO\":[\"ergómetro de tren superior\"],\"_P2B4j\":[[\"biggestGainLabel\"],\" 1RM\"],\"_RhvUo\":[\"ajustes\"],\"_UGS0C\":[\"Nombre del entrenamiento\"],\"_W-KPJ\":[\"Aún no hay medidas. Toca para registrar tu primera entrada.\"],\"_WRCmH\":[[\"0\"],\" \",[\"1\"],\" | \",[\"2\"],\" Reps\"],\"_XczSN\":[\"Selecciona el músculo objetivo\"],\"_cF7Rs\":[\"Volumen\"],\"_f5DAr\":[\"Completado el: \",[\"formattedDate\"]],\"a2Fu8q\":[\"Puedes iniciar sesión en cualquier momento desde la pantalla de ajustes, si decides saltarte este paso ahora.\"],\"a5BPTT\":[\"kettlebell\"],\"a8SF50\":[\"Añade un control de publicación por entrenamiento.\"],\"a8TA11\":[\"Próxima sesión\"],\"a99tuk\":[\"Activa para añadir un control de publicación a cada plan.\"],\"aAIQg2\":[\"Apariencia\"],\"aMwZcE\":[\"Brazo superior (I)\"],\"aN_GPe\":[\"¿Dónde lo sentiste?\"],\"aRwEh5\":[\"Compartir ejercicios personalizados con amigos\"],\"ahW3x6\":[\"\\n📅 Nuevo: ¡Calendario de entrenamientos!\\n\\nToca el icono del calendario en la sección Historial de entrenamientos de la pestaña Estadísticas para explorar tu historial de entrenamiento por fecha. Los días con entrenamientos están resaltados, y al tocar cualquier día se muestran las sesiones registradas ese día.\\n\"],\"aj6ZJx\":[\"Iniciar sesión con Google\"],\"b3e7Re\":[\"Reiniciar app\"],\"b63Dw_\":[\"No se encontró ningún usuario con ese correo electrónico.\"],\"b9OAHS\":[\"Añadir calentamiento\"],\"bFeIdj\":[\"Serie descendente\"],\"bQdjFX\":[[\"0\"],\" nota\"],\"bRAv_4\":[\"Entrenamiento \",[\"0\"]],\"bZS72M\":[[\"setsCount\",\"plural\",{\"one\":[\"#\",\" serie\"],\"other\":[\"#\",\" series\"]}]],\"bosqpS\":[\"Aún no has completado ningún entrenamiento. ¡Empieza tu primer entrenamiento!\"],\"bqb_ci\":[\"\\n🐛 Solucionado: ¡Botones de la sesión y modal de edición de series!\\n\\nSe corrigió un error por el que todos los botones (incrementar/decrementar, serie siguiente/anterior, completar serie) dejaban de funcionar al completar una serie. También se corrigió un error en el modal de edición de series. Las transiciones entre series ahora son instantáneas para un flujo de entrenamiento más fluido.\\n\"],\"bwd2oE\":[\"¡Temporizador de descanso finalizado!\"],\"bzSI52\":[\"Descartar\"],\"c2TGz5\":[\"¡\",[\"completed\"],\" entrenamientos esta semana. Has superado tu objetivo!\"],\"c7AAAa\":[\"\\n📈 Beta: ¡Progresión adaptativa!\\n\\nMuscleQuest ahora puede sugerirte cuándo aumentar tu peso o reps según cómo se sienten tus sesiones. Después de cada ejercicio, responde dos preguntas rápidas sobre esfuerzo y dolor. Cuando hayas reportado la misma señal dos sesiones seguidas, la app sugiere un cambio. Todas las sugerencias aparecen en la pantalla de Resumen del entrenamiento, donde puedes aceptar o descartar cada una por separado. Las sugerencias aceptadas se prerellenan en tu próxima sesión automáticamente.\\n\\nUn Control de recuperación al inicio de tu próximo entrenamiento te permite tener en cuenta el dolor muscular antes de aplicar cualquier sugerencia. También puedes marcar una semana entera como semana de descarga desde la vista general del plan, lo que pausa el feedback y el seguimiento de progresión durante esa semana.\\n\\nActívalo en Ajustes, en Progresión adaptativa, y configura tu incremento de carga preferido por categoría de equipamiento.\\n\"],\"cCbON-\":[\"\\n🔥 Mejorado: ¡Gestión de series de calentamiento!\\n\\nLas series de calentamiento están agrupadas visualmente y con un estilo separado de las series de trabajo, y \\\"Aplicar a todas\\\" te permite editar en bloque las series de calentamiento o de trabajo de forma independiente.\\n\"],\"cF5b-5\":[[\"weeklyGoal\",\"plural\",{\"one\":[\"Sugerencia automática (\",\"#\",\" día)\"],\"other\":[\"Sugerencia automática (\",\"#\",\" días)\"]}]],\"cI6f7l\":[\"30d\"],\"cU45Co\":[\"Añadir entrenamiento\"],\"cUD6H0\":[\"¡Prepárate...!\"],\"cUY9dI\":[\"¿Estás seguro de que quieres eliminar este ejercicio?\"],\"ckJ-os\":[\"Músculos\"],\"cnGeoo\":[\"Eliminar\"],\"crwali\":[\"Recordatorios\"],\"ctrAML\":[\"¡No olvides registrar tu progreso!\"],\"cyR8-W\":[\"\\n🕐 Nuevo: ¡Estimación de duración del entrenamiento!\\n\\nCada tarjeta de entrenamiento ahora muestra una duración estimada para que puedas planificar tus sesiones de un vistazo antes de empezar.\\n\"],\"d1z1ZY\":[\"El temporizador de descanso se inicia automáticamente tras cada serie y cuenta regresiva hasta cero. Cada serie recuerda su propia duración de descanso, por lo que diferentes series dentro del mismo ejercicio pueden tener períodos de descanso distintos. Usa los botones ± para ajustar el tiempo restante sobre la marcha durante el descanso. Configura la duración de descanso predeterminada, el incremento del temporizador y si se activa un sonido, vibración o notificación en segundo plano al finalizar; cada opción es activable de forma independiente en Ajustes.\"],\"dEgA5A\":[\"Cancelar\"],\"dH9Y4t\":[\"No hay entrenamientos este día.\"],\"dVK-Er\":[\"Se ha producido un error de renderizado. Pulsa el botón para recargar.\"],\"dXCD6-\":[\"Descargar todas las animaciones de ejercicios\"],\"dXoieq\":[\"Resumen\"],\"dYOPCE\":[\"Asistencia \",[\"0\"],\" \",[\"1\"],\" | Resistencia \",[\"2\"],\" \",[\"3\"],\" | \",[\"4\"],\" Reps\"],\"dbWo0h\":[\"Iniciar sesión con Google\"],\"deoJBi\":[[\"0\"],\" reps\"],\"dfunKV\":[\"Peso/Reps\"],\"dpOqdQ\":[\"Al fallo\"],\"dqjuBA\":[\"90d\"],\"dx0cCC\":[\"¡Sigue con el ritmo!\"],\"e0dGJ7\":[\"Ventajas de iniciar sesión:\"],\"e0l-Z0\":[[\"scheduledDays\",\"plural\",{\"one\":[\"#\",\" día/semana\"],\"other\":[\"#\",\" días/semana\"]}]],\"e52k4Y\":[\"Abre la pestaña Amigos desde el menú para gestionar tus conexiones. Usa la barra de búsqueda para encontrar a otros usuarios por nombre de usuario y enviarles una solicitud de amistad. Las solicitudes entrantes aparecen en la pestaña Solicitudes; toca Aceptar para confirmar o Rechazar para ignorar. Un badge en el elemento Amigos del menú muestra cuántas solicitudes están pendientes. Una vez aceptada una solicitud, ambos usuarios aparecen en la lista de Amigos del otro y pueden ver el contenido compartido del otro.\"],\"e5h2IT\":[[\"0\"],\" notas\"],\"e9qdcV\":[\"Molestia leve\"],\"eLA0I2\":[\"Descargar imágenes\"],\"eQm4BH\":[\"Al terminar un entrenamiento, una pantalla de resumen muestra tu duración total, series completadas y volumen total. Si ya has hecho ese entrenamiento antes, una fila de comparación muestra cómo se compara cada métrica con la sesión anterior. Un banner de objetivo semanal indica cuántas sesiones has registrado esta semana respecto a tu objetivo. Toca cualquier ejercicio de la lista para expandirlo y revisar cada serie en detalle. Al completar un Entrenamiento rápido, se te pedirá que lo guardes como entrenamiento independiente para uso futuro o que lo descartes.\"],\"eYbd7b\":[\"Do\"],\"ecUA8p\":[\"Hoy\"],\"ehOkF-\":[\"Básico\"],\"emOtYn\":[\"Planes prediseñados\"],\"enD4RG\":[\"No se pudo añadir este ejercicio. Inténtalo de nuevo.\"],\"ez-cQL\":[\"\\n🔔 Nuevo: ¡Notificaciones de recordatorio de entrenamiento!\\n\\nNo te pierdas ninguna sesión. Configura notificaciones de recordatorio para tus entrenamientos directamente desde la app. Elige qué días quieres que te recuerden y selecciona una hora para empezar.\\n\"],\"f2yjAZ\":[\"Sin dolor\"],\"f7pPKh\":[\"Muslo (I)\"],\"f8Vl8d\":[\"Nombre de la métrica\"],\"fFHHFp\":[\"Medidas\"],\"fPpo2L\":[\"Superserie\"],\"fQWEzC\":[\"Aún no hay planes compartidos\"],\"fSu2Jl\":[\"Se ha descargado una nueva versión. Toca el botón de abajo para reiniciar y aplicar la actualización.\"],\"fWsBTs\":[\"Algo salió mal. Inténtalo de nuevo.\"],\"fXVIZq\":[\"Valores\"],\"f_bxrN\":[\"El nombre es obligatorio.\"],\"feWdkU\":[\"Reiniciar entrenamiento\"],\"fj5byd\":[\"N/D\"],\"fpMgHS\":[\"Lun\"],\"fqSfXY\":[\"Reemplazar\"],\"fsJAR5\":[\"Incremento de carga para barra\"],\"ftiGCv\":[\"Todo el equipamiento\"],\"fvyzOr\":[\"espalda alta\"],\"g36TSx\":[\"Unidad de distancia\"],\"g3UF2V\":[\"Aceptar\"],\"g3cPNV\":[\"Activa para compartir automáticamente cada medida corporal que registres.\"],\"gCVtjC\":[[\"0\"],\" Series\"],\"gEOgEq\":[[\"0\"],\" ejercicios\",[\"1\"]],\"gQYPDg\":[\"−\",[\"restTimerIncrement\"],\"s\"],\"gTdjGc\":[\"Error al eliminar el entrenamiento. Por favor, inténtalo de nuevo.\"],\"giOl9F\":[\"Muslo (D)\"],\"gkn1WJ\":[\"Ejercicio ya añadido\"],\"gloTI5\":[\"Toca cualquier amigo aceptado en tu lista de Amigos para abrir su perfil. Su perfil muestra los planes, entrenamientos individuales y ejercicios personalizados que ha elegido compartir. Toca Importar en cualquier elemento para añadirlo directamente a tu propia biblioteca. Los planes y entrenamientos importados se guardan como nuevas copias que puedes editar libremente sin afectar al original. Los ejercicios personalizados importados se añaden a tu biblioteca de ejercicios y están disponibles inmediatamente al crear entrenamientos.\"],\"gzBfh2\":[\"No hay series disponibles\"],\"h-DKuf\":[\"vs. último \\\"\",[\"0\"],\"\\\"\"],\"h2ALJf\":[\"glúteos\"],\"h69WC6\":[\"Enviadas\"],\"h7CU4q\":[\"¿Cómo te fue?\"],\"hBjQ0O\":[[\"0\",\"plural\",{\"one\":[\"#\",\" entrenamiento\"],\"other\":[\"#\",\" entrenamientos\"]}]],\"hF_t4W\":[\"Volumen (\",[\"volumeUnit\"],\")\"],\"hLONcx\":[\"Copia de seguridad y restauración\"],\"hPXEuO\":[\"Emparejado con \",[\"0\"]],\"hXzOVo\":[\"Siguiente\"],\"hnJ2UC\":[\"braquial\"],\"hnlGzG\":[\"Omitir por ahora\"],\"hnrFBk\":[\"Días de recordatorio\"],\"hp8OtS\":[\"Añadido\"],\"hpsdvR\":[\"\\n📋 Nuevo: ¡Ver detalles del entrenamiento desde la pantalla de inicio!\\n\\nAhora puedes tocar cualquier entrenamiento reciente en la pantalla de inicio para ver sus detalles completos. Cada resumen de entrenamiento y series también tiene un nuevo botón de detalles para acceder rápidamente a la información del ejercicio.\\n\"],\"hsoeHo\":[\"Detalles del entrenamiento\"],\"hty0d5\":[\"Lunes\"],\"hupMcg\":[\"¿Eliminar este amigo? Ya no podrá ver tu contenido compartido.\"],\"hvfche\":[[\"scheduledCount\",\"plural\",{\"one\":[\"#\",\" día/semana\"],\"other\":[\"#\",\" días/semana\"]}]],\"i-mS1s\":[\"Los datos compartidos anteriormente siguen siendo visibles para tus amigos hasta que los elimines abajo.\"],\"i-tNaY\":[\"Asistencia/Reps\"],\"i09UfG\":[\"Equipamiento:\"],\"i0qMbr\":[\"Inicio\"],\"i4Vk1Q\":[\"Ejercicios del plan activo\"],\"i6f8rt\":[\"Iniciando entrenamiento...\"],\"iGokZG\":[\"Incremento de carga para cable\"],\"iHjmbB\":[\"Añadido a mis planes\"],\"iHmyze\":[\"Ejercicios\"],\"iO73Kk\":[\"Puedes compartir planes, entrenamientos individuales, ejercicios personalizados, medidas corporales y récords de fuerza con tus amigos. Las cinco categorías tienen un interruptor global en la Configuración de privacidad, en la sección Cuenta de Ajustes. Al activar el interruptor global de una categoría se comparten todos los elementos de esa categoría y los nuevos datos se sincronizan automáticamente cada vez que cambian. Los planes y entrenamientos individuales también tienen un interruptor Compartir individual en la pantalla de resumen de cada elemento, para que puedas publicar planes o entrenamientos específicos sin compartir todo. Un icono de nube en la tarjeta del plan o entrenamiento confirma que está publicado actualmente. Para eliminar los datos compartidos, desactiva el interruptor en la Configuración de privacidad y toca Eliminar datos compartidos para esa categoría. También puedes eliminar todos los datos compartidos de cada categoría desde la misma pantalla.\"],\"iQyKX1\":[\"Elegiste mantenerlo igual. El peso se queda así.\"],\"iV1Jat\":[\"¿Estás seguro de que quieres eliminar esta serie?\"],\"iYfCFU\":[\"Mostrar onboarding en la pantalla de inicio\"],\"i_48Se\":[\"Plan activo: \",[\"0\"]],\"i_nB8P\":[\"Sin horario establecido\"],\"ifRQL2\":[\"Serie descendente, \"],\"ikOJPT\":[\"espinillas\"],\"irLwtB\":[\"Plan de entrenamiento\"],\"irrqfe\":[\"Métricas personalizadas\"],\"iuwbqi\":[\"Error al guardar el entrenamiento. Por favor, inténtalo de nuevo.\"],\"ivpCYv\":[\"¿Descartar cambios?\"],\"j-MPXl\":[\"Copia de seguridad y restauración\"],\"jDTG0T\":[\"Sugerencias de progresión\"],\"jDh_CH\":[\"Los planes son programas de entrenamiento estructurados compuestos por entrenamientos. Para crear uno, ve a la pestaña Planes, toca Nuevo plan, dale un nombre y elige una imagen de portada. Añade entrenamientos al plan, luego añade ejercicios a cada entrenamiento con series y reps objetivo. Usa los botones de flecha arriba/abajo en una tarjeta de entrenamiento para reordenarlo, o el botón X para eliminarlo; ambos están en la parte superior derecha de la tarjeta. Asigna entrenamientos a días específicos de la semana en el editor de horarios: toca cualquier día para elegir un entrenamiento o déjalo como día de descanso, y usa el botón de sugerencia automática para distribuirlos de manera uniforme. Una vez que tu plan esté listo, ábrelo y toca Activar. También puedes añadir notas a un plan desde la pantalla de vista general del plan. Cada tarjeta de entrenamiento muestra una duración estimada junto al número de ejercicios para que puedas calcular la duración de la sesión de un vistazo. Usa los iconos de vista junto al encabezado \\\"Tus planes de entrenamiento\\\" para cambiar entre los modos Carrusel, Lista y Cuadrícula; tu vista preferida se guarda automáticamente. Tu progreso en el editor de planes se guarda automáticamente como borrador, así que si sales a mitad de la edición, se te pedirá que continúes donde lo dejaste o que descartes y empieces desde el último estado guardado.\"],\"jYjrmQ\":[\"Última copia de seguridad: \",[\"0\"]],\"jbq7j2\":[\"Rechazar\"],\"jfzZZ0\":[\"Omitir inicio de sesión\"],\"jpVuia\":[\"¿Guardar cambios en el entrenamiento?\"],\"jxTU3u\":[\"máquina de escalera\"],\"jzJENZ\":[\"Sigue tu progreso\"],\"k4kpgL\":[\"Bienvenido/a a MuscleQuest, tu acompañante personal de entrenamiento de fuerza. Usa esta guía para descubrir las funciones y sacar el máximo partido a tu entrenamiento.\"],\"k5alGf\":[\"Aún no hay entrenamientos compartidos\"],\"k7Oi68\":[\"piernas superiores\"],\"kDJ_Ja\":[\"Sesión sólida. Mantener este peso.\"],\"kFoQmI\":[\"abductores\"],\"kILzHz\":[\"Añadir (\",[\"0\"],\")\"],\"kQe_xM\":[\"Dolor reportado. El peso no cambiará hasta que te sientas mejor.\"],\"kSi1ha\":[\"+\",[\"suggestedWeight\"],[\"unit\"],\" sugerido\"],\"kdwbaT\":[\"Omitir todo\"],\"kf4tdd\":[\"Selecciona el tipo de seguimiento\"],\"kfxr8q\":[\"\\n📊 Nuevo: ¡Resumen del entrenamiento!\\n\\nAl completar un entrenamiento, verás un resumen completo de tu sesión: duración total, series y volumen, además de una comparación con tu sesión anterior. Toca cualquier ejercicio para expandirlo y ver sus series y pesos individuales.\\n\"],\"kg0oKA\":[\" (al fallo)\"],\"kkDQ8m\":[\"Jueves\"],\"konUZ1\":[\"Tiempo de descanso predeterminado\"],\"kvpjYu\":[\"Introduce el nombre del ejercicio\"],\"l1P93s\":[\"Introducir el peso por mancuerna/cable, no el total\"],\"l75CjT\":[\"Sí\"],\"lWy5a1\":[\"Planes\"],\"lY9GM0\":[\"El músculo objetivo es obligatorio.\"],\"lkz6PL\":[\"Duración\"],\"llGZy3\":[\"Aún no se han registrado ejercicios. Toca + Añadir para empezar.\"],\"loRbvf\":[\"¡Ir a la pantalla de inicio!\"],\"m0YANP\":[\"Puedes ocultar esta pantalla de introducción en cualquier momento desde la página de ajustes, en la sección de apariencia. Si quieres volver a verla, puedes activarla de nuevo desde la misma página de ajustes.\"],\"m16xKo\":[\"Añadir\"],\"m2QQkt\":[\"Añadido a mis entrenamientos\"],\"m66_4D\":[\"Tipo de seguimiento\"],\"mAoTHw\":[\"Algunas imágenes no se pudieron eliminar. IDs de ejercicio fallidos: \",[\"0\"]],\"mDmPnX\":[\"Por semana (prom.)\"],\"mEQ95z\":[\"Error al guardar la imagen. Por favor, inténtalo de nuevo.\"],\"mF1US0\":[\"Usar siempre el historial más reciente del ejercicio\"],\"mFQ4KK\":[\"Dobla el peso para el volumen cuando el ajuste está activado\"],\"mK5j7_\":[\"\\n🔃 Nuevo: ¡Ordena la biblioteca de ejercicios!\\n\\nLa biblioteca de ejercicios ahora tiene chips de ordenación para encontrar ejercicios más rápido. Ordena por Predeterminado, Plan activo, Reciente o Frecuente para ver los ejercicios más relevantes para ti arriba.\\n\"],\"mRTnNi\":[\"Implementos pareados\"],\"mSit7t\":[\"Error al obtener los datos. Por favor, inténtalo de nuevo.\"],\"mSj_dN\":[[\"0\",\"plural\",{\"one\":[\"+\",\"#\",\" más\"],\"other\":[\"+\",\"#\",\" más\"]}]],\"mT57-Q\":[\"Ir a Ajustes\"],\"mob_am\":[\"Vi\"],\"mwX_w0\":[\"Cambiar imagen\"],\"mzI_c-\":[\"Descargar\"],\"n00ykB\":[\"Tus entrenamientos\"],\"n1BXGc\":[\"División de entrenamiento (por series)\"],\"n1ekoW\":[\"Iniciar sesión\"],\"nAEGxm\":[\"Sí, aumentar el reto\"],\"nJSX83\":[\"Recordatorios de entrenamiento\"],\"nO6sra\":[[\"0\"],\": \",[\"best\"],\" \",[\"best\",\"plural\",{\"one\":[\"rep\"],\"other\":[\"reps\"]}],\" (+\",[\"delta\"],\", \",[\"pctStr\"],\")\"],\"nPGn3W\":[\"Calentamiento, \"],\"nkkWxK\":[\"Arranca tu viaje fitness con planes de entrenamiento diseñados profesionalmente. Elige entre una variedad de opciones adaptadas a diferentes objetivos y niveles de experiencia. \"],\"nmdLhD\":[\"Reps: \",[\"repRange\"]],\"nmvpnF\":[\"Aún no hay ejercicios personalizados compartidos\"],\"o2XlZw\":[\"¿Estás seguro de que quieres eliminar este entrenamiento? Esta acción no se puede deshacer.\"],\"oB9lvM\":[\"Excluir series de calentamiento de las estadísticas\"],\"oOHOWH\":[\"\\n✨ Nuevo: ¡Animaciones en la sesión de entrenamiento!\\n\\nNavegar entre series ahora incluye transiciones deslizantes suaves. Desliza hacia la izquierda o la derecha para moverte entre series, o usa los botones de flecha para el mismo efecto.\\n\"],\"oOYj_W\":[\"Error al cargar los entrenamientos\"],\"oRTTfk\":[\"La pestaña Estadísticas muestra el total de entrenamientos, volumen total, tiempo total y duración media de sesión en un rango de tiempo seleccionable, con una variación período a período para cada métrica. Los gráficos muestran el volumen semanal y tu división de entrenamiento por parte del cuerpo. Navega por tu historial completo de entrenamientos y toca cualquier sesión para revisar cada serie en detalle, incluyendo pesos, reps, tiempo o distancia. Puedes editar o eliminar entrenamientos completados desde la pantalla de detalles del historial. Toca el icono de calendario en la sección Historial de entrenamientos para abrir una vista de calendario: los días con entrenamientos se resaltan con un círculo amarillo, y al tocar cualquier día se muestran los entrenamientos registrados en esa fecha.\"],\"oRvy2V\":[\"Seguimiento de ejercicio\"],\"oXsjxN\":[\"Pantorrilla (I)\"],\"oYZpj8\":[\"• Desafíos y medallas *\"],\"ocEDZS\":[\"Quitar una serie\"],\"oeF-HP\":[\"Error al iniciar sesión. Por favor, inténtalo de nuevo.\"],\"oeeBm6\":[\"\\n🔔 Nuevo: ¡Notificaciones de actualizaciones en la app!\\n\\nAhora aparece un modal de actualización cuando hay una actualización disponible, para que siempre sepas cuándo se han descargado mejoras y están listas para aplicarse.\\n\"],\"ofVE0I\":[\"Borra el campo de búsqueda\"],\"oiHVLP\":[\"Eliminar superserie\"],\"oqKRAn\":[\"Cada serie puede marcarse como Calentamiento, Serie descendente, Al fallo o cualquier combinación de estas. La insignia junto a una serie muestra su tipo actual. Para cambiar el tipo durante una sesión, toca el menú (⋮) y activa o desactiva la opción correspondiente. Al crear un plan, usa las casillas en el editor de series; toca Añadir calentamiento para insertar una serie de calentamiento al principio de la lista. Las series de calentamiento se agrupan y separan visualmente de las series de trabajo, y la opción Aplicar a todas en el modal de edición solo afecta a series del mismo tipo. Las series de calentamiento se pueden excluir de los cálculos de volumen y estadísticas en Ajustes.\"],\"oqUOKk\":[\"Serie descendente\"],\"osILGh\":[\"Distancia objetivo (\",[\"distanceUnit\"],\")\"],\"os_BJP\":[\"Aún no hay medidas compartidas\"],\"ovBPCi\":[\"Predeterminado\"],\"ovGl86\":[\"(al fallo) \"],\"p5nYkr\":[\"Ver todo\"],\"p72uBF\":[\"No se encontraron planes de entrenamiento\"],\"p8F9k_\":[\"Cuello\"],\"pB7xVW\":[\"Récords de fuerza\"],\"pBGx0B\":[\"\\n🗂️ Nuevo: ¡Opciones de vista de planes!\\n\\nLa pantalla de Planes ahora tiene tres modos de visualización. Usa los iconos junto al encabezado \\\"Tus planes de entrenamiento\\\" para cambiar entre las vistas Carrusel, Lista y Cuadrícula. Tu disposición preferida se guarda automáticamente.\\n\"],\"pE7tOx\":[\"Entrenamiento activo\"],\"pIX6X7\":[\"Instagram de MuscleQuest\"],\"pIuJtP\":[\"Entrenamiento no encontrado.\"],\"pY_gY7\":[\"PR de reps\"],\"p_C-3G\":[\"Dolor muscular leve\"],\"pbzA-s\":[\"Descripción opcional\"],\"pfXEaj\":[\"Peso corporal\"],\"pkD36F\":[\"¿Estás seguro de que quieres eliminar \\\"\",[\"0\"],\"\\\"?\"],\"poLmqL\":[\"Elegir del dispositivo\"],\"psxXnW\":[\"Inicia sesión con Google en Ajustes para activar las copias de seguridad en la nube de todos tus datos de entrenamiento. Toca Copia de seguridad en cualquier momento para guardar una instantánea; la fecha de tu última copia se muestra bajo el botón. Toca Restaurar para descargar y aplicar tu última copia; confirma el aviso y la app se recargará con tus datos restaurados. Tus copias se almacenan de forma segura y están vinculadas a tu cuenta de Google. Si cambias de dispositivo o reinstalas la app, simplemente inicia sesión con la misma cuenta de Google y toca Restaurar para recuperar tus datos.\"],\"pvW0MQ\":[\"Completar serie\"],\"pwfNCc\":[\"+\",[\"restTimerIncrement\"],\"s\"],\"pz0gzh\":[\"Ocultar métrica\"],\"pzA-xG\":[\"Captura indicaciones importantes, recordatorios e ideas personales sobre tus ejercicios, entrenamientos y planes de entrenamiento. Mantente enfocado y perfecciona tu técnica con notas personalizadas a lo largo de tu viaje fitness. Las notas se guardan automáticamente cuando terminas de editar.\"],\"q3pTrs\":[\"¡Todas las imágenes se han eliminado correctamente!\"],\"qIATCE\":[\"\\n📋 Mejorado: ¡Prerelleno más inteligente del historial durante los entrenamientos!\\n\\nLos campos de series ahora se prerellenan de forma más inteligente. Si un ejercicio no tiene historial en el entrenamiento actual, se usa automáticamente la última vez que lo realizaste en cualquier sesión, para que siempre tengas una referencia útil.\\n\\nUn nuevo ajuste en la sección Entrenamiento te permite usar siempre el historial más reciente de todos los entrenamientos, independientemente de la rutina de la que provenga.\\n\"],\"qJb6G2\":[\"Intentar de nuevo\"],\"qP4pOu\":[\"Compartir medidas corporales con amigos\"],\"qQ5ALI\":[\"¿Guardar cambios en el plan?\"],\"qQ8Xkc\":[\"Incremento de carga para máquina\"],\"qQLn75\":[\"Selecciona la parte del cuerpo\"],\"qUSLnH\":[\"Introduce una descripción\"],\"qZMNNX\":[\"Brazo superior (D)\"],\"qaT7mT\":[\"Perderás lo que has introducido hasta ahora.\"],\"qdLLeB\":[\"Entrenamientos recientes\"],\"qdalvN\":[\"Semana de descarga activa. Comparación pausada.\"],\"qeygIa\":[\"Mi\"],\"qlKdB2\":[\"No, dejarlo igual\"],\"qtNMEu\":[\"cuádriceps\"],\"qvcKXF\":[\"¡Buen trabajo hoy!\"],\"qvolLq\":[\"Masa\"],\"rCROTr\":[\"Invítame a un café\"],\"rLgPvm\":[\"Copia de seguridad\"],\"rPj8yN\":[\"Otros ejercicios\"],\"rXJFNV\":[\"Compartir entrenamientos individuales con amigos\"],\"rZzMre\":[\"brazos superiores\"],\"rickIy\":[\"Guardando entrenamiento...\"],\"rjGI_Q\":[\"Privacidad\"],\"rlNJuG\":[\"Detalle del registro\"],\"rtypiF\":[\"🎉 Novedades\"],\"rzjsxH\":[\"Tiempo (Minutos:Segundos)\"],\"s53UX_\":[\"Volumen por semana (\",[\"volumeUnit\"],\")\"],\"s6qW4K\":[\"El tipo de seguimiento no se puede cambiar después de la creación.\"],\"sAkBSh\":[[\"0\",\"plural\",{\"one\":[\"#\",\" ejercicio\"],\"other\":[\"#\",\" ejercicios\"]}]],\"sHe-bW\":[\"Dale un nombre para guardarlo como entrenamiento reutilizable.\"],\"sOXSnZ\":[\"Detalles del ejercicio\"],\"sRh2_9\":[\"Tus planes de entrenamiento\"],\"scHKm4\":[\"Entrenamientos individuales\"],\"sey42b\":[\"¡Entrenamiento completado!\"],\"slcKOz\":[\"Para activar los recordatorios de entrenamiento, concede permisos de notificación en los ajustes de tu dispositivo.\"],\"spvawa\":[\"Excluir entrenamientos de descarga de las estadísticas de ejercicios\"],\"t-VWgS\":[\"Entrenamientos por semana\"],\"t1WtPm\":[\"vs PR\"],\"t5tvzw\":[\"Añade un control de publicación por plan.\"],\"t7OD9_\":[\"trapecios\"],\"t9rBTs\":[[\"0\"],\": \",[\"best\"],[\"unit\"],\" (+\",[\"delta\"],[\"unit\"],\", \",[\"pctStr\"],\")\"],\"tBmnPU\":[\"Amigos\"],\"tCHU1b\":[\"Partes del cuerpo\"],\"tLdxsV\":[\"MuscleQuest.app\"],\"tXYsgg\":[\"Cada medida que registres se comparte automáticamente.\"],\"tXkhj_\":[\"Iniciar\"],\"t_YqKh\":[\"Eliminar\"],\"tcZ16z\":[\"\\n💾 Nuevo: ¡Guarda los cambios del entrenamiento en tu plan!\\n\\nCuando termines una sesión en la que hayas añadido, eliminado o reordenado ejercicios o series, se te pedirá que guardes esos cambios en el plan original o en el entrenamiento independiente, manteniendo tu entrenamiento actualizado automáticamente.\\n\"],\"tfDRzk\":[\"Guardar\"],\"tj-hng\":[\"muñecas\"],\"tlcz2i\":[\"No hay datos para este período.\"],\"twA2hZ\":[\"piernas\"],\"tyb5gZ\":[\"Tiempo de descanso (Minutos:Segundos)\"],\"u0F1Ey\":[\"Ju\"],\"u0Vng2\":[\"Todavía muy dolorido\"],\"u16ECS\":[\"Descarga completa\"],\"uGkCJQ\":[\"barra EZ\"],\"uIVkKI\":[\"Inicio de sesión\"],\"uP80lb\":[\"Actualización lista\"],\"ue_JxE\":[\"Vista general de series\"],\"ufHAsd\":[\"Nombre del plan de entrenamiento\"],\"uyJsf6\":[\"Acerca de\"],\"v2e7py\":[\"Crear un plan\"],\"v39wLo\":[\"Reanudar\"],\"v67n_r\":[\"Activa los recordatorios de entrenamiento recurrentes desde Ajustes. Selecciona los días de la semana en los que quieres recibir el recordatorio usando los chips de día y elige una hora. Recibirás una notificación a esa hora en cada día seleccionado. Se debe conceder el permiso de notificaciones para que los recordatorios funcionen.\"],\"vCrBBg\":[\"Toma el control total de tu entrenamiento diseñando tu propio plan personalizado. Selecciona ejercicios, establece rangos de reps, tiempos de descanso y más para crear un plan que se ajuste perfectamente a tus objetivos de fitness.\"],\"vFte8a\":[\"Crear superserie\"],\"vLSd93\":[\"Tipos de serie\"],\"vLyv1R\":[\"Ocultar\"],\"vPWLpz\":[\"Unidades de medida\"],\"vV1rrV\":[[\"suggestedRepsMin\"],\" reps sugeridas\"],\"vbOlQu\":[\"Error al seleccionar la imagen. Por favor, inténtalo de nuevo.\"],\"vbfDgJ\":[\"Aún no hay entrenamientos\"],\"vcpc5o\":[\"Cerrar menú\"],\"vmatEA\":[\"Cargando datos, por favor espera...\"],\"vq2WxD\":[\"Mar\"],\"vqV9pV\":[\"Nuevo plan\"],\"vyQFtJ\":[\"¡\",[\"0\"],\" completado!\"],\"w55mIe\":[\"plan activo\"],\"w95UZr\":[\"mejor \",[\"maxDist\"],[\"distanceUnit\"]],\"wBAK8Q\":[\"La parte del cuerpo es obligatoria.\"],\"wL3cK8\":[\"Último\"],\"wL7wrB\":[\"Incremento de peso\"],\"wUwyC0\":[\"Racha\"],\"wYwS57\":[\"Personaliza tus ajustes\"],\"wckWOP\":[\"Gestionar\"],\"wgbq86\":[\"Reinicio fallido\"],\"wiIJoN\":[\"Detalles del plan\"],\"wpLp4M\":[\"Asistencia\"],\"wvxWx2\":[\"trapecio\"],\"wxKcF0\":[\"Acerca del desarrollador\"],\"x5LlnE\":[\"Opciones de estadísticas\"],\"xGVfLh\":[\"Continuar\"],\"xM_hqb\":[\"asistencia \"],\"xMidTh\":[\"Todas las partes del cuerpo\"],\"xRGBk4\":[\"Explorar planes prediseñados\"],\"xVhQZV\":[\"Vie\"],\"xYxQCZ\":[[\"0\"],\" \",[\"1\"]],\"xx7Wjz\":[\"Error al cargar los detalles del ejercicio.\"],\"y04OSh\":[\"Historial de entrenamientos\"],\"y3CwcG\":[\"mejor \",[\"maxTime\"],\"s\"],\"y8le-Z\":[\"Entrenamiento\"],\"yAeHP4\":[\"No hay datos disponibles.\"],\"yBSiRY\":[\"Semana de descarga\"],\"yKu_3Y\":[\"Restaurar\"],\"yUWaVv\":[\"máquina elíptica\"],\"yWCES-\":[\"Músculos secundarios:\"],\"y_0uwd\":[\"Ayer\"],\"y_f0Ik\":[\"Se abre en tu navegador\"],\"yf16RU\":[\"Calentamiento\"],\"ygCKqB\":[\"Detener\"],\"yhrNcC\":[\"Error al guardar la imagen\"],\"ykve2U\":[\"Añadir serie\"],\"ysv0WA\":[\"Añadido a mis ejercicios\"],\"yu1K_Z\":[\"Sin series\"],\"z1-0FW\":[\"Registra tus entrenamientos, monitorea tu progreso y alcanza tus objetivos de fitness. MuscleQuest hace que tu viaje fitness sea simple y efectivo.\\n\\nDesliza las tarjetas de introducción para saber más sobre la app.\"],\"z44QLk\":[\"Restaurar copia de seguridad\"],\"z5uobd\":[\"Toca el icono de estrella en la esquina superior derecha de cualquier pantalla de información de ejercicio para marcarlo como favorito. Los ejercicios favoritos aparecen en la parte superior del selector de ejercicios al crear o editar entrenamientos, para que los ejercicios que más usas siempre estén a mano.\"],\"zAhZMD\":[\"• Comparte tus planes de entrenamiento con otros *\"],\"zAt78k\":[\"Temporizador de descanso\"],\"zDq2cZ\":[\"Cintura\"],\"zEHmq8\":[\"La pestaña Planes incluye una biblioteca de programas de entrenamiento prediseñados que puedes empezar de inmediato. Desplázate más allá de Tus planes de entrenamiento para encontrar la sección Planes prediseñados. Toca cualquier programa para previsualizar sus entrenamientos y horario, luego toca Activar para convertirlo en tu plan activo. Puedes editar un plan prediseñado para ajustar ejercicios, series o el horario semanal. Esto creará una copia del plan prediseñado que puedes modificar sin afectar al original, para que siempre puedas volver a la versión predeterminada si es necesario.\"],\"zIFP3N\":[\"Establece tu objetivo semanal de entrenamientos e introduce tu peso corporal para obtener estadísticas y recomendaciones precisas. También puedes ajustar tus preferencias de incremento de peso, elegir tus unidades preferidas y mucho más.\"],\"zNnnyF\":[\"gemelos\"],\"zOwYV3\":[\"Has modificado este entrenamiento. ¿Guardar los cambios para sesiones futuras?\"],\"zeFzVj\":[\"Activa para compartir automáticamente tus récords de fuerza tras cada entrenamiento.\"],\"zga9sT\":[\"Aceptar\"],\"zhIkkH\":[\"Objetivo: \",[\"goalLabel\"],[\"0\"]],\"zsaR7t\":[\"Equipamiento y seguimiento\"],\"zt6jiv\":[\"No hay seguimiento de progresión para este tipo de ejercicio.\"],\"zuwyEJ\":[\"Añade ejercicios para empezar\"],\"zzDlyQ\":[\"Éxito\"]}")}; \ No newline at end of file diff --git a/locales/es/messages.po b/locales/es/messages.po index af5be432..a4c5c502 100644 --- a/locales/es/messages.po +++ b/locales/es/messages.po @@ -165,6 +165,28 @@ msgstr "" "Se corrigió un error por el que todos los botones (incrementar/decrementar, serie siguiente/anterior, completar serie) dejaban de funcionar al completar una serie. También se corrigió un error en el modal de edición de series. Las transiciones entre series ahora son instantáneas para un flujo de entrenamiento más fluido.\n" "" +#: constants/WhatsNew.ts:305 +msgid "" +"\n" +"👥 New: Friends & Social Sharing!\n" +"\n" +"Add friends by searching for their username from the Friends tab in the menu. Send a request, and once accepted you can browse each other's shared content. A badge on the Friends menu item shows pending incoming requests.\n" +"\n" +"Share your plans, standalone workouts, custom exercises, body measurements, and strength PRs by toggling Share in the relevant screen or from Privacy Settings in the Account section of Settings. Shared content syncs automatically whenever it changes, and a cloud icon on plan and workout cards shows what is currently published. You can delete all shared data for any category from Privacy Settings at any time.\n" +"\n" +"Tap any accepted friend's name to open their profile and import their plans, standalone workouts, or custom exercises directly into your own library.\n" +"" +msgstr "" +"\n" +"👥 Nuevo: ¡Amigos y uso compartido!\n" +"\n" +"Añade amigos buscando su nombre de usuario en la pestaña Amigos del menú. Envía una solicitud y, una vez aceptada, podréis explorar el contenido compartido del otro. Un badge en el elemento del menú Amigos muestra las solicitudes entrantes pendientes.\n" +"\n" +"Comparte tus planes, entrenamientos individuales, ejercicios personalizados, medidas corporales y récords de fuerza activando Compartir en la pantalla correspondiente o desde la Configuración de privacidad en la sección Cuenta de Ajustes. El contenido compartido se sincroniza automáticamente cada vez que cambia, y un icono de nube en las tarjetas de plan y entrenamiento muestra lo que está publicado. Puedes eliminar todos los datos compartidos de cualquier categoría desde la Configuración de privacidad en cualquier momento.\n" +"\n" +"Toca el nombre de cualquier amigo aceptado para abrir su perfil e importar sus planes, entrenamientos individuales o ejercicios personalizados directamente a tu propia biblioteca.\n" +"" + #: constants/WhatsNew.ts:204 msgid "" "\n" @@ -224,7 +246,7 @@ msgstr "" #: constants/WhatsNew.ts:293 msgid "" "\n" -"📈 New: Adaptive Progression!\n" +"📈 Beta: Adaptive Progression!\n" "\n" "MuscleQuest can now suggest when to increase your weight or reps based on how your sessions feel. After each exercise, answer two quick questions about effort and pain. Once you have reported the same signal for two sessions in a row, the app suggests a change. All suggestions appear in the Workout Summary screen, where you can accept or dismiss each one individually. Accepted suggestions are pre-filled into your next session automatically.\n" "\n" @@ -234,7 +256,7 @@ msgid "" "" msgstr "" "\n" -"📈 Nuevo: ¡Progresión adaptativa!\n" +"📈 Beta: ¡Progresión adaptativa!\n" "\n" "MuscleQuest ahora puede sugerirte cuándo aumentar tu peso o reps según cómo se sienten tus sesiones. Después de cada ejercicio, responde dos preguntas rápidas sobre esfuerzo y dolor. Cuando hayas reportado la misma señal dos sesiones seguidas, la app sugiere un cambio. Todas las sugerencias aparecen en la pantalla de Resumen del entrenamiento, donde puedes aceptar o descartar cada una por separado. Las sugerencias aceptadas se prerellenan en tu próxima sesión automáticamente.\n" "\n" @@ -531,11 +553,11 @@ msgstr "" "La pantalla de Planes ahora tiene tres modos de visualización. Usa los iconos junto al encabezado \"Tus planes de entrenamiento\" para cambiar entre las vistas Carrusel, Lista y Cuadrícula. Tu disposición preferida se guarda automáticamente.\n" "" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:179 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:191 msgid " (to Failure)" msgstr " (al fallo)" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:186 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:198 msgid " (to Failure) " msgstr " (al fallo) " @@ -581,7 +603,7 @@ msgid "{0, plural, one {# Set} other {# Sets}}" msgstr "{0, plural, one {# Serie} other {# Series}}" #. placeholder {0}: plan.workouts.length -#: components/TrainingPlanListItem.tsx:60 +#: components/TrainingPlanListItem.tsx:71 msgid "{0, plural, one {# workout} other {# workouts}}" msgstr "{0, plural, one {# entrenamiento} other {# entrenamientos}}" @@ -597,13 +619,13 @@ msgstr "{0, plural, one {serie} other {series}}" #. placeholder {0}: settings?.weightIncrement #. placeholder {1}: settings?.weightUnit -#: app/(app)/settings.tsx:758 +#: app/(app)/settings.tsx:794 msgid "{0} {1}" msgstr "{0} {1}" #. placeholder {0}: settings?.bodyWeight #. placeholder {1}: settings?.weightUnit -#: app/(app)/settings.tsx:583 +#: app/(app)/settings.tsx:619 msgid "{0} {1} (used for assisted exercises)" msgstr "{0} {1} (usado en ejercicios asistidos)" @@ -620,7 +642,7 @@ msgid "{0} Complete!" msgstr "¡{0} completado!" #. placeholder {0}: settings?.weeklyGoal -#: app/(app)/settings.tsx:561 +#: app/(app)/settings.tsx:597 msgid "{0} days per week" msgstr "{0} días por semana" @@ -628,7 +650,7 @@ msgstr "{0} días por semana" #. placeholder {0}: workout.exercises.length #. placeholder {1}: estimate ? ` · ~${formatDurationEstimate(estimate)}` : "" #. placeholder {1}: estimate ? ` · ~${formatDurationEstimateCompact(estimate)}` : "" -#: app/(app)/(tabs)/(plans)/overview.tsx:78 +#: app/(app)/(tabs)/(plans)/overview.tsx:82 #: app/(app)/(tabs)/index.tsx:57 msgid "{0} Exercises{1}" msgstr "{0} ejercicios{1}" @@ -650,18 +672,18 @@ msgstr "{0} reps" #. placeholder {0}: settings?.restTimerIncrement #. placeholder {0}: settings?.timerCountdown || "5" -#: app/(app)/settings.tsx:786 -#: app/(app)/settings.tsx:812 +#: app/(app)/settings.tsx:822 +#: app/(app)/settings.tsx:848 msgid "{0} seconds" msgstr "{0} segundos" #. placeholder {0}: settings?.defaultSets -#: app/(app)/settings.tsx:1369 +#: app/(app)/settings.tsx:1408 msgid "{0} sets" msgstr "{0} series" #. placeholder {0}: item.sets.length -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:176 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:188 #: components/WorkoutDetailsScreen.tsx:141 msgid "{0} Sets" msgstr "{0} Series" @@ -786,7 +808,7 @@ msgid "+ Add" msgstr "+ Añadir" #: app/(app)/(workout)/index.tsx:1153 -#: app/(app)/(workout)/workout-session.tsx:1559 +#: app/(app)/(workout)/workout-session.tsx:1591 msgid "+{restTimerIncrement}s" msgstr "+{restTimerIncrement}s" @@ -795,7 +817,7 @@ msgid "+{suggestedWeight}{unit} suggested" msgstr "+{suggestedWeight}{unit} sugerido" #: app/(app)/(workout)/index.tsx:1142 -#: app/(app)/(workout)/workout-session.tsx:1548 +#: app/(app)/(workout)/workout-session.tsx:1580 msgid "−{restTimerIncrement}s" msgstr "−{restTimerIncrement}s" @@ -836,7 +858,7 @@ msgstr "Una semana de descarga es una semana de recuperación planificada en la msgid "A new version has been downloaded. Tap the button below to restart and apply the update." msgstr "Se ha descargado una nueva versión. Toca el botón de abajo para reiniciar y aplicar la actualización." -#: app/_layout.tsx:91 +#: app/_layout.tsx:97 msgid "A render error has occurred. Press the button to reload." msgstr "Se ha producido un error de renderizado. Pulsa el botón para recargar." @@ -844,15 +866,15 @@ msgstr "Se ha producido un error de renderizado. Pulsa el botón para recargar." msgid "abductors" msgstr "abductores" -#: app/(app)/settings.tsx:1560 +#: app/(app)/settings.tsx:1873 msgid "About" msgstr "Acerca de" -#: components/ExerciseFeedbackSheet.tsx:37 +#: components/ExerciseFeedbackSheet.tsx:38 msgid "About right" msgstr "Más o menos bien" -#: app/(app)/settings.tsx:1649 +#: app/(app)/settings.tsx:1962 msgid "About the developer" msgstr "Acerca del desarrollador" @@ -860,6 +882,7 @@ msgstr "Acerca del desarrollador" msgid "abs" msgstr "abdominales" +#: components/friends/FriendRequestItem.tsx:47 #: components/ProgressionSummaryCard.tsx:145 msgid "Accept" msgstr "Aceptar" @@ -868,13 +891,13 @@ msgstr "Aceptar" msgid "Accept all" msgstr "Aceptar todo" -#: constants/HelpData.ts:164 +#: constants/HelpData.ts:184 msgid "Account" msgstr "Cuenta" -#: app/(app)/(tabs)/(plans)/overview.tsx:222 -#: components/TrainingPlanCard.tsx:80 -#: components/TrainingPlanListItem.tsx:54 +#: app/(app)/(tabs)/(plans)/overview.tsx:233 +#: components/TrainingPlanCard.tsx:83 +#: components/TrainingPlanListItem.tsx:56 msgid "Active" msgstr "Activo" @@ -899,16 +922,23 @@ msgstr "Plan activo: {0}" msgid "Active Workout" msgstr "Entrenamiento activo" -#: app/(app)/settings.tsx:1076 #: constants/HelpData.ts:64 msgid "Adaptive Progression" msgstr "Progresión adaptativa" +#: app/(app)/settings.tsx:1112 +msgid "Adaptive Progression (beta)" +msgstr "Progresión adaptativa (beta)" + #: constants/HelpData.ts:69 msgid "Adaptive Progression analyses your effort feedback over consecutive sessions and suggests when to increase your weight, reps, or sets. Enable it in Settings under Adaptive Progression. Once on, a short feedback prompt appears after each exercise in plan-based workouts. The engine requires two sessions with the same signal before recommending an upward change, filtering out one-off easy days and ensuring consistent performance before suggesting an increase. Pain or failed sets act immediately regardless of your session history. A suggestion is never applied to your workout without your explicit approval. You can also configure your preferred load increment per equipment category in the same section of Settings, for example 2.5 kg for barbell exercises and 2.0 kg for dumbbells." msgstr "La Progresión adaptativa analiza tu feedback de esfuerzo a lo largo de sesiones consecutivas y sugiere cuándo aumentar tu peso, reps o series. Actívala en Ajustes, en Progresión adaptativa. Una vez activada, aparece una breve pregunta de feedback tras cada ejercicio en los entrenamientos basados en un plan. El sistema requiere dos sesiones con la misma señal antes de recomendar un aumento, lo que filtra los días puntualmente fáciles y garantiza un rendimiento constante antes de sugerir un aumento. El dolor o las series fallidas actúan de forma inmediata independientemente de tu historial de sesiones. Una sugerencia nunca se aplica a tu entrenamiento sin tu aprobación explícita. También puedes configurar tu incremento de carga preferido por categoría de equipamiento en la misma sección de Ajustes, por ejemplo 2,5 kg para ejercicios con barra y 2,0 kg para mancuernas." #: app/(app)/(tabs)/(stats)/measurements-manage.tsx:167 +#: app/(app)/friend-profile.tsx:218 +#: app/(app)/friend-profile.tsx:310 +#: app/(app)/friend-profile.tsx:397 +#: app/(app)/friends.tsx:291 #: components/Notes.tsx:87 msgid "Add" msgstr "Añadir" @@ -944,7 +974,7 @@ msgstr "Añadir ejercicio" msgid "Add exercises to get started" msgstr "Añade ejercicios para empezar" -#: app/(app)/custom-exercise.tsx:324 +#: app/(app)/custom-exercise.tsx:350 msgid "Add Image" msgstr "Añadir imagen" @@ -957,6 +987,18 @@ msgstr "Añadir notas personales" msgid "Add Set" msgstr "Añadir serie" +#: app/(app)/friend-exercise.tsx:161 +msgid "Add to my exercises" +msgstr "Añadir a mis ejercicios" + +#: app/(app)/friend-plan.tsx:177 +msgid "Add to my plans" +msgstr "Añadir a mis planes" + +#: app/(app)/friend-workout.tsx:136 +msgid "Add to my workouts" +msgstr "Añadir a mis entrenamientos" + #: app/(app)/(create-plan)/sets-overview.tsx:257 msgid "Add Warm-up" msgstr "Añadir calentamiento" @@ -969,6 +1011,28 @@ msgstr "Añadir peso" msgid "Add Workout" msgstr "Añadir entrenamiento" +#: app/(app)/friend-profile.tsx:216 +#: app/(app)/friend-profile.tsx:308 +#: app/(app)/friend-profile.tsx:395 +msgid "Added" +msgstr "Añadido" + +#: app/(app)/friend-exercise.tsx:159 +msgid "Added to my exercises" +msgstr "Añadido a mis ejercicios" + +#: app/(app)/friend-plan.tsx:175 +msgid "Added to my plans" +msgstr "Añadido a mis planes" + +#: app/(app)/friend-workout.tsx:134 +msgid "Added to my workouts" +msgstr "Añadido a mis entrenamientos" + +#: constants/HelpData.ts:168 +msgid "Adding Friends" +msgstr "Añadir amigos" + #: constants/dbTranslations.ts:22 msgid "adductors" msgstr "aductores" @@ -1003,6 +1067,10 @@ msgstr "¡Todas las imágenes se han eliminado correctamente!" msgid "All images downloaded successfully!" msgstr "¡Todas las imágenes se han descargado correctamente!" +#: app/(app)/settings.tsx:98 +msgid "All shared data has been removed." +msgstr "Se han eliminado todos los datos compartidos." + #: components/FilterRow.tsx:62 #: components/FilterRow.tsx:114 #: components/FilterRow.tsx:204 @@ -1017,7 +1085,7 @@ msgstr "Todo el tiempo" msgid "All-time PR" msgstr "PR histórico" -#: app/(app)/settings.tsx:974 +#: app/(app)/settings.tsx:1010 msgid "Always use most recent exercise history" msgstr "Usar siempre el historial más reciente del ejercicio" @@ -1037,11 +1105,11 @@ msgstr "estabilizadores del tobillo" msgid "ankles" msgstr "tobillos" -#: components/ExerciseFeedbackSheet.tsx:191 +#: components/ExerciseFeedbackSheet.tsx:205 msgid "Any pain or form breakdown?" msgstr "¿Algún dolor o problema de técnica?" -#: app/(app)/settings.tsx:1440 +#: app/(app)/settings.tsx:1479 msgid "Appearance" msgstr "Apariencia" @@ -1055,7 +1123,7 @@ msgid "Are you sure you want to cancel and delete this workout?" msgstr "¿Estás seguro de que quieres cancelar y eliminar este entrenamiento?" #. placeholder {0}: workout?.name ?? "" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:81 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:93 msgid "Are you sure you want to delete \"{0}\"?" msgstr "¿Estás seguro de que quieres eliminar \"{0}\"?" @@ -1071,11 +1139,11 @@ msgstr "¿Estás seguro de que quieres eliminar este ejercicio?" msgid "Are you sure you want to delete this measurement entry?" msgstr "¿Estás seguro de que quieres eliminar este registro de medición?" -#: app/(app)/(tabs)/(plans)/overview.tsx:118 +#: app/(app)/(tabs)/(plans)/overview.tsx:129 msgid "Are you sure you want to delete this plan?" msgstr "¿Estás seguro de que quieres eliminar este plan?" -#: app/(app)/(workout)/workout-session.tsx:710 +#: app/(app)/(workout)/workout-session.tsx:717 msgid "Are you sure you want to delete this set?" msgstr "¿Estás seguro de que quieres eliminar esta serie?" @@ -1100,7 +1168,7 @@ msgstr "¿Estás seguro de que quieres eliminar este entrenamiento?" msgid "Are you sure you want to restart this workout?" msgstr "¿Estás seguro de que quieres reiniciar este entrenamiento?" -#: app/(app)/settings.tsx:460 +#: app/(app)/settings.tsx:496 msgid "Are you sure you want to restore the backup?" msgstr "¿Estás seguro de que quieres restaurar la copia de seguridad?" @@ -1129,7 +1197,7 @@ msgstr "Asistencia" msgid "assistance " msgstr "asistencia " -#: app/(app)/custom-exercise.tsx:63 +#: app/(app)/custom-exercise.tsx:68 msgid "Assistance/Reps" msgstr "Asistencia/Reps" @@ -1142,15 +1210,15 @@ msgstr "Duración media" msgid "back" msgstr "espalda" -#: app/(app)/settings.tsx:622 +#: app/(app)/settings.tsx:658 msgid "Backup" msgstr "Copia de seguridad" -#: constants/HelpData.ts:173 +#: constants/HelpData.ts:193 msgid "Backup & Restore" msgstr "Copia de seguridad y restauración" -#: app/(app)/settings.tsx:600 +#: app/(app)/settings.tsx:636 msgid "Backup and restore" msgstr "Copia de seguridad y restauración" @@ -1158,11 +1226,11 @@ msgstr "Copia de seguridad y restauración" msgid "barbell" msgstr "barra" -#: app/(app)/settings.tsx:1122 +#: app/(app)/settings.tsx:1160 msgid "Barbell load increment" msgstr "Incremento de carga para barra" -#: app/(app)/custom-exercise.tsx:309 +#: app/(app)/custom-exercise.tsx:335 msgid "Basics" msgstr "Básico" @@ -1202,15 +1270,20 @@ msgid "Body Fat" msgstr "Grasa corporal" #: app/(app)/(tabs)/(stats)/index.tsx:553 +#: app/(app)/friend-profile.tsx:458 #: constants/HelpData.ts:143 msgid "Body Measurements" msgstr "Medidas corporales" -#: app/(app)/custom-exercise.tsx:372 +#: app/(app)/friend-exercise.tsx:70 +msgid "Body Part" +msgstr "Parte del cuerpo" + +#: app/(app)/custom-exercise.tsx:398 msgid "Body Part *" msgstr "Parte del cuerpo *" -#: app/(app)/custom-exercise.tsx:201 +#: app/(app)/custom-exercise.tsx:206 msgid "Body part is required." msgstr "La parte del cuerpo es obligatoria." @@ -1222,7 +1295,7 @@ msgstr "Partes del cuerpo" msgid "body weight" msgstr "peso corporal" -#: app/(app)/settings.tsx:580 +#: app/(app)/settings.tsx:616 msgid "Body weight" msgstr "Peso corporal" @@ -1246,15 +1319,15 @@ msgstr "Explora casi 1.000 ejercicios y filtra por parte del cuerpo, músculo ob msgid "Built-in Metrics" msgstr "Métricas integradas" -#: app/(app)/settings.tsx:1484 +#: app/(app)/settings.tsx:1523 msgid "Button size during workout" msgstr "Tamaño de botones durante el entrenamiento" -#: app/(app)/settings.tsx:1596 +#: app/(app)/settings.tsx:1909 msgid "Buy me a coffee" msgstr "Invítame a un café" -#: components/AppMenu.tsx:202 +#: components/AppMenu.tsx:220 msgid "Buy Me a Coffee" msgstr "Invítame a un café" @@ -1262,7 +1335,7 @@ msgstr "Invítame a un café" msgid "cable" msgstr "cable" -#: app/(app)/settings.tsx:1176 +#: app/(app)/settings.tsx:1214 msgid "Cable load increment" msgstr "Incremento de carga para cable" @@ -1281,17 +1354,19 @@ msgstr "gemelos" #: app/(app)/(create-plan)/create-workout.tsx:174 #: app/(app)/(create-plan)/create.tsx:234 #: app/(app)/(create-plan)/create.tsx:279 -#: app/(app)/(tabs)/(plans)/overview.tsx:121 -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:83 +#: app/(app)/(tabs)/(plans)/overview.tsx:132 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:95 #: app/(app)/(tabs)/(stats)/history-details.tsx:173 #: app/(app)/(tabs)/(stats)/measurements-detail.tsx:118 #: app/(app)/(tabs)/(stats)/measurements-manage.tsx:85 #: app/(app)/(workout)/index.tsx:405 #: app/(app)/(workout)/index.tsx:1007 -#: app/(app)/(workout)/workout-session.tsx:711 -#: app/(app)/settings.tsx:387 -#: app/(app)/settings.tsx:462 +#: app/(app)/(workout)/workout-session.tsx:718 +#: app/(app)/settings.tsx:90 +#: app/(app)/settings.tsx:423 +#: app/(app)/settings.tsx:498 #: components/EditSetModal.tsx:454 +#: components/friends/FriendListItem.tsx:24 #: components/SettingsModal.tsx:282 #: components/WorkoutCard.tsx:87 #: hooks/useImageManagement.ts:25 @@ -1315,11 +1390,11 @@ msgstr "cardio" msgid "cardiovascular system" msgstr "sistema cardiovascular" -#: app/(app)/custom-exercise.tsx:324 +#: app/(app)/custom-exercise.tsx:350 msgid "Change Image" msgstr "Cambiar imagen" -#: app/(app)/settings.tsx:606 +#: app/(app)/settings.tsx:642 msgid "Checking for backups..." msgstr "Buscando copias de seguridad..." @@ -1344,8 +1419,8 @@ msgstr "Borrar búsqueda" msgid "Clears the search field" msgstr "Borra el campo de búsqueda" -#: components/AppMenu.tsx:146 -#: components/AppMenu.tsx:168 +#: components/AppMenu.tsx:156 +#: components/AppMenu.tsx:178 msgid "Close menu" msgstr "Cerrar menú" @@ -1383,15 +1458,19 @@ msgstr "¿Continuar editando?" msgid "core" msgstr "core" -#: components/ExerciseFeedbackSheet.tsx:39 +#: app/(app)/friend-exercise.tsx:143 +msgid "Could not add this exercise. Please try again." +msgstr "No se pudo añadir este ejercicio. Inténtalo de nuevo." + +#: components/ExerciseFeedbackSheet.tsx:40 msgid "Couldn't finish all sets" msgstr "No pude terminar todas las series" -#: app/(app)/custom-exercise.tsx:508 +#: app/(app)/custom-exercise.tsx:534 msgid "Count reps ×2 for volume when the setting is enabled" msgstr "Cuenta reps ×2 para el volumen cuando el ajuste está activado" -#: app/(app)/settings.tsx:1035 +#: app/(app)/settings.tsx:1071 msgid "Counting reps ×2 for these exercises" msgstr "Contando reps ×2 para estos ejercicios" @@ -1404,7 +1483,7 @@ msgid "Create a Plan" msgstr "Crear un plan" #: app/(app)/(create-plan)/exercises.tsx:360 -#: app/(app)/custom-exercise.tsx:71 +#: app/(app)/custom-exercise.tsx:76 msgid "Create Exercise" msgstr "Crear ejercicio" @@ -1426,10 +1505,15 @@ msgstr "Crear entrenamiento" msgid "Create your own exercises from the exercise picker. Give it a name, an optional image, body part, target muscles, secondary muscles, and equipment. Choose a tracking type: weight + reps, time, distance, reps only, or assisted (which factors in your body weight for movements like assisted pull-ups). Toggle Unilateral for single-arm or single-leg exercises; reps can be automatically doubled in your stats. Toggle Paired Implements if you track the weight of one implement rather than the total: for example, if you log 20 kg for one dumbbell, the app counts 40 kg toward your volume." msgstr "Crea tus propios ejercicios desde el selector de ejercicios. Dale un nombre, una imagen opcional, parte del cuerpo, músculos objetivo, músculos secundarios y equipamiento. Elige un tipo de seguimiento: peso + reps, tiempo, distancia, solo reps o asistido (que tiene en cuenta tu peso corporal para movimientos como dominadas asistidas). Activa Unilateral para ejercicios de un solo brazo o pierna; las reps pueden doblarse automáticamente en tus estadísticas. Activa Implementos pareados si registras el peso de un solo implemento en lugar del total: por ejemplo, si anotas 20 kg para una mancuerna, la app cuenta 40 kg hacia tu volumen." +#: app/(app)/friend-profile.tsx:326 #: constants/HelpData.ts:113 msgid "Custom Exercises" msgstr "Ejercicios personalizados" +#: app/(app)/settings.tsx:1701 +msgid "Custom exercises you create or edit are shared automatically." +msgstr "Los ejercicios personalizados que crees o edites se comparten automáticamente." + #: app/(app)/(tabs)/(stats)/measurements-manage.tsx:204 msgid "Custom Metrics" msgstr "Métricas personalizadas" @@ -1438,7 +1522,7 @@ msgstr "Métricas personalizadas" msgid "Customisation" msgstr "Personalización" -#: app/(app)/(tabs)/(plans)/overview.tsx:306 +#: app/(app)/(tabs)/(plans)/overview.tsx:351 msgid "Customise Plan" msgstr "Personalizar plan" @@ -1446,30 +1530,43 @@ msgstr "Personalizar plan" msgid "Customise Your Settings" msgstr "Personaliza tus ajustes" +#: components/friends/FriendRequestItem.tsx:56 +msgid "Decline" +msgstr "Rechazar" + #: components/ExerciseSortChips.tsx:27 msgid "Default" msgstr "Predeterminado" -#: app/(app)/settings.tsx:1392 +#: app/(app)/settings.tsx:1431 msgid "Default rest time" msgstr "Tiempo de descanso predeterminado" -#: app/(app)/settings.tsx:1366 +#: app/(app)/settings.tsx:1405 msgid "Default sets" msgstr "Series predeterminadas" -#: app/(app)/(tabs)/(plans)/overview.tsx:125 -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:85 +#: app/(app)/(tabs)/(plans)/overview.tsx:136 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:97 #: app/(app)/(tabs)/(stats)/history-details.tsx:175 #: app/(app)/(tabs)/(stats)/measurements-detail.tsx:120 #: app/(app)/(workout)/index.tsx:407 #: app/(app)/(workout)/index.tsx:629 -#: app/(app)/(workout)/workout-session.tsx:713 +#: app/(app)/(workout)/workout-session.tsx:720 +#: app/(app)/settings.tsx:92 #: components/WorkoutCard.tsx:298 #: hooks/useImageManagement.ts:46 msgid "Delete" msgstr "Eliminar" +#: app/(app)/settings.tsx:1862 +msgid "Delete all shared data" +msgstr "Eliminar todos los datos compartidos" + +#: app/(app)/settings.tsx:87 +msgid "Delete all shared data?" +msgstr "¿Eliminar todos los datos compartidos?" + #: hooks/useImageManagement.ts:103 msgid "Delete Complete" msgstr "Eliminación completa" @@ -1483,25 +1580,25 @@ msgstr "Eliminar registro" msgid "Delete Exercise" msgstr "Eliminar ejercicio" -#: app/(app)/(tabs)/(plans)/overview.tsx:117 +#: app/(app)/(tabs)/(plans)/overview.tsx:128 msgid "Delete Plan" msgstr "Eliminar plan" -#: app/(app)/(workout)/workout-session.tsx:710 +#: app/(app)/(workout)/workout-session.tsx:717 #: components/SessionSetInfo.tsx:251 msgid "Delete Set" msgstr "Eliminar serie" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:80 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:92 #: app/(app)/(tabs)/(stats)/history-details.tsx:170 msgid "Delete Workout" msgstr "Eliminar entrenamiento" -#: app/(app)/settings.tsx:1427 +#: app/(app)/settings.tsx:1466 msgid "Deleting. Please wait..." msgstr "Eliminando. Por favor, espera..." -#: app/(app)/(tabs)/(plans)/overview.tsx:265 +#: app/(app)/(tabs)/(plans)/overview.tsx:276 #: app/(app)/(tabs)/index.tsx:472 #: constants/HelpData.ts:88 msgid "Deload Week" @@ -1519,7 +1616,8 @@ msgstr "deltoides" msgid "delts" msgstr "deltoides" -#: app/(app)/custom-exercise.tsx:347 +#: app/(app)/custom-exercise.tsx:373 +#: app/(app)/friend-exercise.tsx:109 msgid "Description" msgstr "Descripción" @@ -1531,19 +1629,19 @@ msgstr "Descripción:" msgid "Details" msgstr "Detalles" -#: app/(app)/settings.tsx:831 -#: app/(app)/settings.tsx:856 -#: app/(app)/settings.tsx:881 -#: app/(app)/settings.tsx:904 -#: app/(app)/settings.tsx:929 -#: app/(app)/settings.tsx:954 -#: app/(app)/settings.tsx:1011 -#: app/(app)/settings.tsx:1036 -#: app/(app)/settings.tsx:1061 -#: app/(app)/settings.tsx:1093 -#: app/(app)/settings.tsx:1227 -#: app/(app)/settings.tsx:1258 -#: app/(app)/settings.tsx:1455 +#: app/(app)/settings.tsx:867 +#: app/(app)/settings.tsx:892 +#: app/(app)/settings.tsx:917 +#: app/(app)/settings.tsx:940 +#: app/(app)/settings.tsx:965 +#: app/(app)/settings.tsx:990 +#: app/(app)/settings.tsx:1047 +#: app/(app)/settings.tsx:1072 +#: app/(app)/settings.tsx:1097 +#: app/(app)/settings.tsx:1129 +#: app/(app)/settings.tsx:1265 +#: app/(app)/settings.tsx:1297 +#: app/(app)/settings.tsx:1494 msgid "Disabled" msgstr "Desactivado" @@ -1552,7 +1650,7 @@ msgstr "Desactivado" #: app/(app)/(workout)/index.tsx:808 #: app/(app)/(workout)/index.tsx:841 #: app/(app)/(workout)/index.tsx:1037 -#: app/(app)/custom-exercise.tsx:85 +#: app/(app)/custom-exercise.tsx:90 msgid "Discard" msgstr "Descartar" @@ -1561,7 +1659,7 @@ msgstr "Descartar" msgid "Discard Changes" msgstr "Descartar cambios" -#: app/(app)/custom-exercise.tsx:80 +#: app/(app)/custom-exercise.tsx:85 msgid "Discard changes?" msgstr "¿Descartar cambios?" @@ -1576,12 +1674,12 @@ msgstr "¿Descartar cambios?" msgid "Dismiss" msgstr "Cerrar" -#: app/(app)/(tabs)/(plans)/overview.tsx:320 +#: app/(app)/(tabs)/(plans)/overview.tsx:365 msgid "DISMISS" msgstr "CERRAR" #: app/(app)/(tabs)/(stats)/edit-history.tsx:268 -#: app/(app)/custom-exercise.tsx:66 +#: app/(app)/custom-exercise.tsx:71 msgid "Distance" msgstr "Distancia" @@ -1591,21 +1689,22 @@ msgstr "Distancia" msgid "Distance ({distanceUnit})" msgstr "Distancia ({distanceUnit})" -#: app/(app)/settings.tsx:697 +#: app/(app)/settings.tsx:733 msgid "Distance unit" msgstr "Unidad de distancia" #: app/(app)/(workout)/workout-summary.tsx:656 -#: components/ExerciseFeedbackSheet.tsx:261 +#: app/(app)/settings.tsx:98 +#: components/ExerciseFeedbackSheet.tsx:275 #: components/RecoveryCheckInSheet.tsx:191 msgid "Done" msgstr "Listo" -#: app/(app)/custom-exercise.tsx:528 +#: app/(app)/custom-exercise.tsx:554 msgid "Double the weight for volume when the setting is enabled" msgstr "Dobla el peso para el volumen cuando el ajuste está activado" -#: app/(app)/settings.tsx:1060 +#: app/(app)/settings.tsx:1096 msgid "Doubling weight for volume calculations" msgstr "Doblando el peso para los cálculos de volumen" @@ -1613,7 +1712,7 @@ msgstr "Doblando el peso para los cálculos de volumen" msgid "Download" msgstr "Descargar" -#: app/(app)/settings.tsx:1409 +#: app/(app)/settings.tsx:1448 msgid "Download all exercise animations" msgstr "Descargar todas las animaciones de ejercicios" @@ -1635,7 +1734,7 @@ msgstr "Descargar imágenes" msgid "Downloading Update" msgstr "Descargando actualización" -#: app/(app)/settings.tsx:1426 +#: app/(app)/settings.tsx:1465 msgid "Downloading. Please wait..." msgstr "Descargando. Por favor, espera..." @@ -1657,7 +1756,7 @@ msgstr "Serie descendente, " msgid "dumbbell" msgstr "mancuerna" -#: app/(app)/settings.tsx:1149 +#: app/(app)/settings.tsx:1187 msgid "Dumbbell load increment" msgstr "Incremento de carga para mancuerna" @@ -1670,25 +1769,33 @@ msgstr "Duración" msgid "During a session, swipe left/right or use the arrow buttons to move between sets. Enter your weight and reps, then tap Complete Set. The total elapsed time is shown in the header throughout. You can drag the handle on any exercise card to reorder exercises while the session is in progress. Time-based exercises have a Start Timer button that opens a count-up timer with a progress ring that shows you when you hit your goal time but you can keep going as long as you like. Notes can be added per-exercise via the notes icon in the exercise header, per workout from the workout overview screen, or per plan from the plan overview screen. If you add, remove, or reorder exercises or sets during a session, you will be prompted at the end to save those changes back to the original workout or plan." msgstr "Durante una sesión, desliza a izquierda/derecha o usa los botones de flecha para moverte entre series. Introduce tu peso y reps, luego toca Completar serie. El tiempo total transcurrido se muestra en el encabezado durante toda la sesión. Puedes arrastrar el asa de cualquier tarjeta de ejercicio para reordenar ejercicios mientras la sesión está en curso. Los ejercicios basados en tiempo tienen un botón Iniciar temporizador que abre un cronómetro con un anillo de progreso que te indica cuándo alcanzas tu tiempo objetivo, pero puedes continuar todo lo que quieras. Las notas se pueden añadir por ejercicio mediante el icono de notas en el encabezado del ejercicio, por entrenamiento desde la pantalla de vista general del entrenamiento, o por plan desde la pantalla de vista general del plan. Si añades, eliminas o reordenas ejercicios o series durante una sesión, se te pedirá al final si quieres guardar esos cambios en el entrenamiento o plan original." +#: app/(app)/settings.tsx:1783 +msgid "Each measurement entry you record is shared automatically." +msgstr "Cada medida que registres se comparte automáticamente." + #: constants/HelpData.ts:99 msgid "Each set can be flagged as a Warm-up, Drop Set, To Failure, or any combination of these. The badge shown next to a set displays its current type. To change the type during a session, tap the menu (⋮) and toggle the relevant option on or off. When building a plan, use the checkboxes in the set editor; tap Add Warm-up to insert a dedicated warm-up set at the top of the list. Warm-up sets are visually grouped and separated from working sets, and the Apply to All option in the edit modal only affects sets of the same type. Warm-up sets can be excluded from volume and stats calculations in Settings." msgstr "Cada serie puede marcarse como Calentamiento, Serie descendente, Al fallo o cualquier combinación de estas. La insignia junto a una serie muestra su tipo actual. Para cambiar el tipo durante una sesión, toca el menú (⋮) y activa o desactiva la opción correspondiente. Al crear un plan, usa las casillas en el editor de series; toca Añadir calentamiento para insertar una serie de calentamiento al principio de la lista. Las series de calentamiento se agrupan y separan visualmente de las series de trabajo, y la opción Aplicar a todas en el modal de edición solo afecta a series del mismo tipo. Las series de calentamiento se pueden excluir de los cálculos de volumen y estadísticas en Ajustes." -#: components/ExerciseFeedbackSheet.tsx:36 +#: app/(app)/settings.tsx:1743 +msgid "Each workout you complete is shared automatically." +msgstr "Cada entrenamiento que completes se comparte automáticamente." + +#: components/ExerciseFeedbackSheet.tsx:37 msgid "Easy, could do more" msgstr "Fácil, podría haber hecho más" -#: app/(app)/custom-exercise.tsx:71 +#: app/(app)/custom-exercise.tsx:76 #: app/(app)/exercise-info.tsx:307 msgid "Edit Exercise" msgstr "Editar ejercicio" -#: app/(app)/(tabs)/(plans)/overview.tsx:308 +#: app/(app)/(tabs)/(plans)/overview.tsx:353 msgid "Edit Plan" msgstr "Editar plan" #: app/(app)/(create-plan)/create-workout.tsx:247 -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:276 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:328 #: app/(app)/(tabs)/(stats)/_layout.tsx:22 msgid "Edit Workout" msgstr "Editar entrenamiento" @@ -1697,24 +1804,60 @@ msgstr "Editar entrenamiento" msgid "elliptical machine" msgstr "máquina elíptica" +#: app/(app)/friends.tsx:209 +msgid "Email address" +msgstr "Correo electrónico" + #: constants/HelpData.ts:159 msgid "Enable recurring workout reminders from Settings. Select the days of the week you want to be reminded using the day chips and choose a time. You will receive a notification at that time on each selected day. Notification permission must be granted for reminders to work." msgstr "Activa los recordatorios de entrenamiento recurrentes desde Ajustes. Selecciona los días de la semana en los que quieres recibir el recordatorio usando los chips de día y elige una hora. Recibirás una notificación a esa hora en cada día seleccionado. Se debe conceder el permiso de notificaciones para que los recordatorios funcionen." -#: app/(app)/settings.tsx:830 -#: app/(app)/settings.tsx:855 -#: app/(app)/settings.tsx:880 -#: app/(app)/settings.tsx:904 -#: app/(app)/settings.tsx:928 -#: app/(app)/settings.tsx:953 -#: app/(app)/settings.tsx:1010 -#: app/(app)/settings.tsx:1092 -#: app/(app)/settings.tsx:1226 -#: app/(app)/settings.tsx:1258 -#: app/(app)/settings.tsx:1455 +#: app/(app)/settings.tsx:1628 +msgid "Enable to add a publish toggle to each plan." +msgstr "Activa para añadir un control de publicación a cada plan." + +#: app/(app)/settings.tsx:1666 +msgid "Enable to add a publish toggle to each standalone workout." +msgstr "Activa para añadir un control de publicación a cada entrenamiento individual." + +#: app/(app)/settings.tsx:1708 +msgid "Enable to automatically share custom exercises you create or edit." +msgstr "Activa para compartir automáticamente los ejercicios personalizados que crees o edites." + +#: app/(app)/settings.tsx:1790 +msgid "Enable to automatically share each body measurement you record." +msgstr "Activa para compartir automáticamente cada medida corporal que registres." + +#: app/(app)/settings.tsx:1749 +msgid "Enable to automatically share each workout you complete." +msgstr "Activa para compartir automáticamente cada entrenamiento que completes." + +#: app/(app)/settings.tsx:1832 +msgid "Enable to automatically share strength PRs after each workout." +msgstr "Activa para compartir automáticamente tus récords de fuerza tras cada entrenamiento." + +#: app/(app)/settings.tsx:866 +#: app/(app)/settings.tsx:891 +#: app/(app)/settings.tsx:916 +#: app/(app)/settings.tsx:940 +#: app/(app)/settings.tsx:964 +#: app/(app)/settings.tsx:989 +#: app/(app)/settings.tsx:1046 +#: app/(app)/settings.tsx:1128 +#: app/(app)/settings.tsx:1264 +#: app/(app)/settings.tsx:1297 +#: app/(app)/settings.tsx:1494 msgid "Enabled" msgstr "Activado" +#: app/(app)/settings.tsx:1624 +msgid "Enables a per-plan publish toggle." +msgstr "Añade un control de publicación por plan." + +#: app/(app)/settings.tsx:1662 +msgid "Enables a per-workout publish toggle." +msgstr "Añade un control de publicación por entrenamiento." + #: app/(app)/(tabs)/(stats)/measurements-manage.tsx:65 msgid "Enter a name for the custom metric." msgstr "Introduce un nombre para la métrica personalizada." @@ -1723,15 +1866,15 @@ msgstr "Introduce un nombre para la métrica personalizada." msgid "Enter at least one measurement to log." msgstr "Introduce al menos una medida para registrar." -#: app/(app)/custom-exercise.tsx:350 +#: app/(app)/custom-exercise.tsx:376 msgid "Enter description" msgstr "Introduce una descripción" -#: app/(app)/custom-exercise.tsx:331 +#: app/(app)/custom-exercise.tsx:357 msgid "Enter exercise name" msgstr "Introduce el nombre del ejercicio" -#: app/(app)/settings.tsx:1056 +#: app/(app)/settings.tsx:1092 msgid "Enter weight per dumbbell/cable, not total" msgstr "Introducir el peso por mancuerna/cable, no el total" @@ -1743,15 +1886,19 @@ msgstr "Detalle del registro" msgid "Entry not found." msgstr "Registro no encontrado." -#: app/(app)/custom-exercise.tsx:442 +#: app/(app)/friend-exercise.tsx:64 +msgid "Equipment" +msgstr "Equipamiento" + +#: app/(app)/custom-exercise.tsx:468 msgid "Equipment *" msgstr "Equipamiento *" -#: app/(app)/custom-exercise.tsx:438 +#: app/(app)/custom-exercise.tsx:464 msgid "Equipment & Tracking" msgstr "Equipamiento y seguimiento" -#: app/(app)/custom-exercise.tsx:203 +#: app/(app)/custom-exercise.tsx:208 msgid "Equipment is required." msgstr "El equipamiento es obligatorio." @@ -1760,13 +1907,13 @@ msgid "Equipment:" msgstr "Equipamiento:" #: app/(app)/(create-plan)/image-search.tsx:43 -#: app/(app)/(tabs)/(plans)/overview.tsx:134 -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:94 +#: app/(app)/(tabs)/(plans)/overview.tsx:145 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:106 #: app/(app)/(workout)/index.tsx:871 #: app/(app)/(workout)/index.tsx:1065 -#: app/(app)/custom-exercise.tsx:129 -#: app/(app)/custom-exercise.tsx:178 -#: app/(app)/custom-exercise.tsx:286 +#: app/(app)/custom-exercise.tsx:134 +#: app/(app)/custom-exercise.tsx:183 +#: app/(app)/custom-exercise.tsx:312 #: app/login.tsx:69 #: components/FilterRow.tsx:86 #: components/FilterRow.tsx:132 @@ -1795,7 +1942,7 @@ msgstr "Error al cargar los detalles del ejercicio" msgid "Error loading exercises: {0}" msgstr "Error al cargar los ejercicios: {0}" -#: app/(app)/(tabs)/(plans)/index.tsx:93 +#: app/(app)/(tabs)/(plans)/index.tsx:97 msgid "Error loading plans" msgstr "Error al cargar los planes" @@ -1809,8 +1956,8 @@ msgstr "Error al guardar el entrenamiento" #. placeholder {0}: error.message #. placeholder {0}: settingsError.message -#: app/(app)/(tabs)/(plans)/overview.tsx:174 -#: app/(app)/(workout)/workout-session.tsx:1355 +#: app/(app)/(tabs)/(plans)/overview.tsx:185 +#: app/(app)/(workout)/workout-session.tsx:1386 #: components/WorkoutDetailsScreen.tsx:175 msgid "Error: {0}" msgstr "Error: {0}" @@ -1820,15 +1967,15 @@ msgstr "Error: {0}" msgid "Estimated Duration: {0}" msgstr "Duración estimada: {0}" -#: app/(app)/settings.tsx:1222 +#: app/(app)/settings.tsx:1260 msgid "Exclude deload workouts from exercise stats" msgstr "Excluir entrenamientos de descarga de las estadísticas de ejercicios" -#: app/(app)/settings.tsx:1006 +#: app/(app)/settings.tsx:1042 msgid "Exclude warmup sets from stats" msgstr "Excluir series de calentamiento de las estadísticas" -#: app/(app)/settings.tsx:1349 +#: app/(app)/settings.tsx:1388 msgid "Exercise" msgstr "Ejercicio" @@ -1839,21 +1986,29 @@ msgstr "Ejercicio" msgid "Exercise Already Added" msgstr "Ejercicio ya añadido" -#: app/(app)/_layout.tsx:37 +#: app/(app)/_layout.tsx:59 +msgid "Exercise Details" +msgstr "Detalles del ejercicio" + +#: app/(app)/_layout.tsx:39 msgid "Exercise Info" msgstr "Info del ejercicio" -#: app/(app)/_layout.tsx:44 -#: components/AppMenu.tsx:184 +#: app/(app)/_layout.tsx:46 +#: components/AppMenu.tsx:202 #: constants/HelpData.ts:103 msgid "Exercise Library" msgstr "Biblioteca de ejercicios" +#: app/(app)/friend-exercise.tsx:47 +msgid "Exercise not found." +msgstr "Ejercicio no encontrado." + #: components/ExerciseTimerModal.tsx:159 msgid "Exercise Timer" msgstr "Temporizador de ejercicio" -#: app/(app)/settings.tsx:809 +#: app/(app)/settings.tsx:845 msgid "Exercise timer countdown" msgstr "Cuenta atrás del temporizador de ejercicio" @@ -1881,12 +2036,12 @@ msgid "ez barbell" msgstr "barra EZ" #. placeholder {0}: error.message -#: app/(app)/(tabs)/(plans)/overview.tsx:155 +#: app/(app)/(tabs)/(plans)/overview.tsx:166 msgid "Failed to activate this plan: {0}" msgstr "Error al activar este plan: {0}" #. placeholder {0}: error.message -#: app/(app)/(tabs)/(plans)/overview.tsx:135 +#: app/(app)/(tabs)/(plans)/overview.tsx:146 msgid "Failed to delete plan: {0}" msgstr "Error al eliminar el plan: {0}" @@ -1894,17 +2049,17 @@ msgstr "Error al eliminar el plan: {0}" msgid "Failed to delete the workout. Please try again." msgstr "Error al eliminar el entrenamiento. Por favor, inténtalo de nuevo." -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:95 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:107 msgid "Failed to delete workout. Please try again." msgstr "Error al eliminar el entrenamiento. Por favor, inténtalo de nuevo." -#: app/(app)/custom-exercise.tsx:129 +#: app/(app)/custom-exercise.tsx:134 #: components/FilterRow.tsx:86 #: components/FilterRow.tsx:132 msgid "Failed to fetch data. Please try again." msgstr "Error al obtener los datos. Por favor, inténtalo de nuevo." -#: app/(app)/custom-exercise.tsx:178 +#: app/(app)/custom-exercise.tsx:183 msgid "Failed to load exercise details." msgstr "Error al cargar los detalles del ejercicio." @@ -1912,7 +2067,7 @@ msgstr "Error al cargar los detalles del ejercicio." msgid "Failed to load history" msgstr "Error al cargar el historial" -#: app/(app)/(tabs)/(plans)/index.tsx:147 +#: app/(app)/(tabs)/(plans)/index.tsx:153 msgid "Failed to load workouts" msgstr "Error al cargar los entrenamientos" @@ -1920,11 +2075,11 @@ msgstr "Error al cargar los entrenamientos" msgid "Failed to pick image. Please try again." msgstr "Error al seleccionar la imagen. Por favor, inténtalo de nuevo." -#: app/(app)/custom-exercise.tsx:287 +#: app/(app)/custom-exercise.tsx:313 msgid "Failed to save custom exercise. Please try again." msgstr "Error al guardar el ejercicio personalizado. Por favor, inténtalo de nuevo." -#: app/(app)/custom-exercise.tsx:226 +#: app/(app)/custom-exercise.tsx:231 msgid "Failed to save the image. Please try again." msgstr "Error al guardar la imagen. Por favor, inténtalo de nuevo." @@ -1937,6 +2092,10 @@ msgstr "Error al guardar el entrenamiento. Por favor, inténtalo de nuevo." msgid "Failed to sign in. Please try again." msgstr "Error al iniciar sesión. Por favor, inténtalo de nuevo." +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:304 +msgid "Failed to update sharing. Please try again." +msgstr "No se pudo actualizar el uso compartido. Inténtalo de nuevo." + #: components/ExerciseList.tsx:41 msgid "Favorites" msgstr "Favoritos" @@ -1957,7 +2116,7 @@ msgstr "Se sintió fácil. Mantener por ahora y confirmar en la siguiente sesió msgid "Finish" msgstr "Finalizar" -#: app/(app)/settings.tsx:1632 +#: app/(app)/settings.tsx:1945 msgid "Follow MuscleQuest on Instagram" msgstr "Síguenos en Instagram" @@ -1970,7 +2129,7 @@ msgstr "durante {0}s " msgid "forearms" msgstr "antebrazos" -#: app/(app)/settings.tsx:53 +#: app/(app)/settings.tsx:56 msgid "Fr" msgstr "Vi" @@ -1993,6 +2152,27 @@ msgstr "Vie" msgid "Friday" msgstr "Viernes" +#: app/(app)/_layout.tsx:50 +msgid "Friend Profile" +msgstr "Perfil de amigo" + +#: app/(app)/friends.tsx:39 +#: app/(app)/friends.tsx:58 +#: app/(app)/friends.tsx:69 +#: app/(app)/friends.tsx:264 +#: components/AppMenu.tsx:194 +msgid "Friends" +msgstr "Amigos" + +#: constants/HelpData.ts:164 +msgid "Friends & Social" +msgstr "Amigos y social" + +#. placeholder {0}: formatDistanceToNow(friend.since.toDate(), { addSuffix: true }) +#: app/(app)/friend-profile.tsx:121 +msgid "Friends since {0}" +msgstr "Amigos desde {0}" + #: components/ExerciseTimerModal.tsx:165 msgid "Get Ready..." msgstr "¡Prepárate...!" @@ -2060,12 +2240,12 @@ msgstr "Agrupa dos ejercicios en una superserie para que alternen automáticamen msgid "hamstrings" msgstr "isquiotibiales" -#: components/ExerciseFeedbackSheet.tsx:38 +#: components/ExerciseFeedbackSheet.tsx:39 msgid "Hard, near limit" msgstr "Difícil, cerca del límite" -#: app/(app)/_layout.tsx:41 -#: components/AppMenu.tsx:194 +#: app/(app)/_layout.tsx:43 +#: components/AppMenu.tsx:212 msgid "Help & Info" msgstr "Ayuda e información" @@ -2112,11 +2292,11 @@ msgstr "Pantalla de inicio y objetivo semanal" msgid "How are these muscles feeling since your last session?" msgstr "¿Cómo se sienten estos músculos desde tu última sesión?" -#: components/ExerciseFeedbackSheet.tsx:173 +#: components/ExerciseFeedbackSheet.tsx:187 msgid "How did that feel?" msgstr "¿Cómo te fue?" -#: app/(app)/custom-exercise.tsx:225 +#: app/(app)/custom-exercise.tsx:230 msgid "Image Save Error" msgstr "Error al guardar la imagen" @@ -2124,6 +2304,19 @@ msgstr "Error al guardar la imagen" msgid "Images by Unsplash" msgstr "Imágenes de Unsplash" +#: app/(app)/friend-exercise.tsx:142 +msgid "Import failed" +msgstr "Importación fallida" + +#: constants/HelpData.ts:178 +msgid "Importing from Friends" +msgstr "Importar de amigos" + +#: app/(app)/friends.tsx:278 +#: app/(app)/friends.tsx:331 +msgid "Incoming" +msgstr "Recibidas" + #: app/(app)/exercise-info.tsx:202 msgid "Info" msgstr "Info" @@ -2137,11 +2330,11 @@ msgstr "Estadísticas clave" msgid "Jumpstart your fitness journey with professionally designed training plans. Choose from a variety of options tailored to different goals and experience levels. " msgstr "Arranca tu viaje fitness con planes de entrenamiento diseñados profesionalmente. Elige entre una variedad de opciones adaptadas a diferentes objetivos y niveles de experiencia. " -#: app/(app)/custom-exercise.tsx:83 +#: app/(app)/custom-exercise.tsx:88 msgid "Keep editing" msgstr "Seguir editando" -#: app/(app)/settings.tsx:949 +#: app/(app)/settings.tsx:985 msgid "Keep screen on during workout" msgstr "Mantener pantalla encendida durante el entrenamiento" @@ -2154,7 +2347,7 @@ msgid "kettlebell" msgstr "kettlebell" #. placeholder {0}: lastBackupDate.toLocaleDateString() -#: app/(app)/settings.tsx:608 +#: app/(app)/settings.tsx:644 msgid "Last backup: {0}" msgstr "Última copia de seguridad: {0}" @@ -2195,15 +2388,15 @@ msgstr "máquina de palanca" msgid "Load up" msgstr "Subir peso" -#: app/_layout.tsx:199 +#: app/_layout.tsx:213 msgid "Loading data, please wait..." msgstr "Cargando datos, por favor espera..." -#: app/(app)/(tabs)/(plans)/overview.tsx:187 +#: app/(app)/(tabs)/(plans)/overview.tsx:198 msgid "Loading Plan..." msgstr "Cargando plan..." -#: app/(app)/(tabs)/(plans)/overview.tsx:166 +#: app/(app)/(tabs)/(plans)/overview.tsx:177 #: components/WorkoutDetailsScreen.tsx:166 msgid "Loading..." msgstr "Cargando..." @@ -2213,11 +2406,11 @@ msgstr "Cargando..." msgid "Log Entry" msgstr "Registrar entrada" -#: app/(app)/settings.tsx:528 +#: app/(app)/settings.tsx:564 msgid "Log in to secure your data" msgstr "Inicia sesión para proteger tus datos" -#: app/(app)/settings.tsx:1031 +#: app/(app)/settings.tsx:1067 msgid "Log one side only for single-arm/leg exercises" msgstr "Registrar solo un lado para ejercicios de un brazo/pierna" @@ -2237,7 +2430,7 @@ msgstr "lumbar" msgid "lower legs" msgstr "piernas inferiores" -#: app/(app)/settings.tsx:1203 +#: app/(app)/settings.tsx:1241 msgid "Machine load increment" msgstr "Incremento de carga para máquina" @@ -2281,11 +2474,11 @@ msgstr "Dolor muscular leve" msgid "Min Reps" msgstr "Reps mín." -#: components/ExerciseFeedbackSheet.tsx:46 +#: components/ExerciseFeedbackSheet.tsx:47 msgid "Minor discomfort" msgstr "Molestia leve" -#: app/(app)/settings.tsx:49 +#: app/(app)/settings.tsx:52 msgid "Mo" msgstr "Lu" @@ -2328,15 +2521,15 @@ msgstr "MuscleQuest" msgid "MuscleQuest Introduction" msgstr "Introducción a MuscleQuest" -#: app/(app)/settings.tsx:1613 +#: app/(app)/settings.tsx:1926 msgid "MuscleQuest.app" msgstr "MuscleQuest.app" -#: components/AppMenu.tsx:208 +#: components/AppMenu.tsx:226 msgid "MuscleQuest's Instagram" msgstr "Instagram de MuscleQuest" -#: app/(app)/custom-exercise.tsx:368 +#: app/(app)/custom-exercise.tsx:394 msgid "Muscles" msgstr "Músculos" @@ -2344,11 +2537,11 @@ msgstr "Músculos" msgid "N/A" msgstr "N/D" -#: app/(app)/custom-exercise.tsx:328 +#: app/(app)/custom-exercise.tsx:354 msgid "Name *" msgstr "Nombre *" -#: app/(app)/custom-exercise.tsx:200 +#: app/(app)/custom-exercise.tsx:205 msgid "Name is required." msgstr "El nombre es obligatorio." @@ -2364,11 +2557,11 @@ msgstr "cuello" msgid "Neck" msgstr "Cuello" -#: app/(app)/(tabs)/(plans)/index.tsx:118 +#: app/(app)/(tabs)/(plans)/index.tsx:122 msgid "New Plan" msgstr "Nuevo plan" -#: app/(app)/(tabs)/(plans)/index.tsx:110 +#: app/(app)/(tabs)/(plans)/index.tsx:114 msgid "New Workout" msgstr "Nuevo entrenamiento" @@ -2380,8 +2573,8 @@ msgstr "Siguiente" msgid "Next Session" msgstr "Próxima sesión" -#: app/(app)/(workout)/workout-session.tsx:1415 -#: app/(app)/(workout)/workout-session.tsx:1502 +#: app/(app)/(workout)/workout-session.tsx:1446 +#: app/(app)/(workout)/workout-session.tsx:1533 msgid "Next: " msgstr "Siguiente: " @@ -2396,10 +2589,18 @@ msgstr "Siguiente: {workoutName} el {0}" msgid "No" msgstr "No" -#: app/(app)/settings.tsx:609 +#: app/(app)/settings.tsx:645 msgid "No backups found" msgstr "No se encontraron copias de seguridad" +#: app/(app)/friend-profile.tsx:423 +msgid "No completed workouts shared yet" +msgstr "Aún no hay entrenamientos completados compartidos" + +#: app/(app)/friend-profile.tsx:336 +msgid "No custom exercises shared yet" +msgstr "Aún no hay ejercicios personalizados compartidos" + #: components/charts/BodyPartChart.tsx:198 msgid "No data available." msgstr "No hay datos disponibles." @@ -2416,7 +2617,7 @@ msgstr "No hay datos para este período." msgid "No exercises added yet" msgstr "Aún no se han añadido ejercicios" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:252 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:264 msgid "No exercises in this workout yet." msgstr "Aún no hay ejercicios en este entrenamiento." @@ -2424,10 +2625,18 @@ msgstr "Aún no hay ejercicios en este entrenamiento." msgid "No exercises tracked yet. Tap + Add to start." msgstr "Aún no se han registrado ejercicios. Toca + Añadir para empezar." +#: app/(app)/friends.tsx:141 +msgid "No friends yet. Search by email to add someone." +msgstr "Aún no tienes amigos. Busca por correo para añadir a alguien." + #: app/(app)/exercise-info.tsx:407 msgid "No history yet" msgstr "Aún no hay historial" +#: app/(app)/friend-profile.tsx:468 +msgid "No measurements shared yet" +msgstr "Aún no hay medidas compartidas" + #: app/(app)/(tabs)/(stats)/measurements.tsx:265 msgid "No measurements yet. Log your first entry above." msgstr "Aún no hay medidas. Registra tu primera entrada arriba." @@ -2436,10 +2645,18 @@ msgstr "Aún no hay medidas. Registra tu primera entrada arriba." msgid "No measurements yet. Tap to log your first entry." msgstr "Aún no hay medidas. Toca para registrar tu primera entrada." -#: components/ExerciseFeedbackSheet.tsx:45 +#: components/ExerciseFeedbackSheet.tsx:46 msgid "No pain" msgstr "Sin dolor" +#: app/(app)/friends.tsx:317 +msgid "No pending friend requests." +msgstr "No hay solicitudes de amistad pendientes." + +#: app/(app)/friend-profile.tsx:156 +msgid "No plans shared yet" +msgstr "Aún no hay planes compartidos" + #: components/ProgressionSummaryCard.tsx:26 msgid "No prior weight data. Hold steady for now." msgstr "Sin datos previos de peso. Mantener por ahora." @@ -2456,7 +2673,7 @@ msgstr "Sin resultados para \"{query}\"" msgid "No schedule set" msgstr "Sin horario establecido" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:176 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:188 msgid "No Sets" msgstr "Sin series" @@ -2465,10 +2682,18 @@ msgstr "Sin series" msgid "No Sets Available" msgstr "No hay series disponibles" -#: components/PlanList.tsx:46 +#: app/(app)/friend-profile.tsx:501 +msgid "No strength data shared yet" +msgstr "Aún no hay datos de fuerza compartidos" + +#: components/PlanList.tsx:50 msgid "No training plans found" msgstr "No se encontraron planes de entrenamiento" +#: app/(app)/friends.tsx:228 +msgid "No user found with that email address." +msgstr "No se encontró ningún usuario con ese correo electrónico." + #: app/(app)/(tabs)/(stats)/measurements.tsx:131 msgid "No values entered" msgstr "No se han introducido valores" @@ -2485,11 +2710,15 @@ msgstr "Aún no has completado ningún entrenamiento. ¡Empieza tu primer entren msgid "No workouts on this day." msgstr "No hay entrenamientos este día." -#: app/(app)/(tabs)/(plans)/index.tsx:160 +#: app/(app)/friend-profile.tsx:244 +msgid "No workouts shared yet" +msgstr "Aún no hay entrenamientos compartidos" + +#: app/(app)/(tabs)/(plans)/index.tsx:166 msgid "No workouts yet" msgstr "Aún no hay entrenamientos" -#: components/ExerciseFeedbackSheet.tsx:221 +#: components/ExerciseFeedbackSheet.tsx:235 msgid "No, keep it the same" msgstr "No, dejarlo igual" @@ -2503,10 +2732,10 @@ msgstr "oblicuos" #: app/(app)/(workout)/exercises.tsx:109 #: app/(app)/(workout)/exercises.tsx:130 #: app/(app)/(workout)/index.tsx:873 -#: app/(app)/custom-exercise.tsx:130 -#: app/(app)/custom-exercise.tsx:179 -#: app/(app)/custom-exercise.tsx:227 -#: app/(app)/custom-exercise.tsx:288 +#: app/(app)/custom-exercise.tsx:135 +#: app/(app)/custom-exercise.tsx:184 +#: app/(app)/custom-exercise.tsx:232 +#: app/(app)/custom-exercise.tsx:314 #: app/login.tsx:70 #: components/FilterRow.tsx:87 #: components/FilterRow.tsx:133 @@ -2521,16 +2750,20 @@ msgstr "¡Un entrenamiento más para alcanzar tu objetivo!" msgid "Oops!" msgstr "¡Vaya!" -#: app/(app)/settings.tsx:386 +#: app/(app)/settings.tsx:422 msgid "Open Settings" msgstr "Abrir Ajustes" -#: components/AppMenu.tsx:204 -#: components/AppMenu.tsx:210 +#: constants/HelpData.ts:169 +msgid "Open the Friends tab from the menu to manage your connections. Use the search bar to find other users by username and send them a friend request. Incoming requests appear in the Requests tab; tap Accept to confirm or Decline to ignore. A badge on the Friends menu item shows how many pending requests are waiting. Once a request is accepted, both users appear in each other's Friends list and can view each other's shared content." +msgstr "Abre la pestaña Amigos desde el menú para gestionar tus conexiones. Usa la barra de búsqueda para encontrar a otros usuarios por nombre de usuario y enviarles una solicitud de amistad. Las solicitudes entrantes aparecen en la pestaña Solicitudes; toca Aceptar para confirmar o Rechazar para ignorar. Un badge en el elemento Amigos del menú muestra cuántas solicitudes están pendientes. Una vez aceptada una solicitud, ambos usuarios aparecen en la lista de Amigos del otro y pueden ver el contenido compartido del otro." + +#: components/AppMenu.tsx:222 +#: components/AppMenu.tsx:228 msgid "Opens in your browser" msgstr "Se abre en tu navegador" -#: components/ExerciseFeedbackSheet.tsx:243 +#: components/ExerciseFeedbackSheet.tsx:257 msgid "Optional description" msgstr "Descripción opcional" @@ -2543,7 +2776,7 @@ msgstr "Otros ejercicios" msgid "Overview" msgstr "Vista general" -#: components/ExerciseFeedbackSheet.tsx:47 +#: components/ExerciseFeedbackSheet.tsx:48 msgid "Pain or form issues" msgstr "Dolor o problemas de técnica" @@ -2551,7 +2784,7 @@ msgstr "Dolor o problemas de técnica" msgid "Pain reported. Keeping load unchanged until you feel better." msgstr "Dolor reportado. El peso no cambiará hasta que te sientas mejor." -#: app/(app)/custom-exercise.tsx:525 +#: app/(app)/custom-exercise.tsx:551 #: app/(app)/exercise-info.tsx:277 msgid "Paired implements" msgstr "Implementos pareados" @@ -2565,6 +2798,10 @@ msgstr "Emparejado con {0}" msgid "pectorals" msgstr "pectorales" +#: app/(app)/friends.tsx:377 +msgid "Pending" +msgstr "Pendiente" + #: components/stats/InsightsStrip.tsx:74 msgid "Per week (avg)" msgstr "Por semana (prom.)" @@ -2573,12 +2810,12 @@ msgstr "Por semana (prom.)" msgid "Percent" msgstr "Porcentaje" -#: app/(app)/settings.tsx:364 -#: app/(app)/settings.tsx:383 +#: app/(app)/settings.tsx:400 +#: app/(app)/settings.tsx:419 msgid "Permission Required" msgstr "Permiso requerido" -#: app/(app)/settings.tsx:511 +#: app/(app)/settings.tsx:547 msgid "Personal" msgstr "Personal" @@ -2586,12 +2823,21 @@ msgstr "Personal" msgid "Pin exercises in the Stats tab to track their strength progression over time. Each tracked exercise shows a chart of your performance over the selected time range, your all-time personal record, your top sets, and a list of recent sessions showing the best set per day. Charts update automatically after each workout that includes that exercise." msgstr "Fija ejercicios en la pestaña Estadísticas para seguir su progresión de fuerza con el tiempo. Cada ejercicio fijado muestra un gráfico de tu rendimiento en el rango de tiempo seleccionado, tu récord personal histórico, tus mejores series y una lista de sesiones recientes con la mejor serie por día. Los gráficos se actualizan automáticamente tras cada entrenamiento que incluya ese ejercicio." +#: app/(app)/_layout.tsx:52 +msgid "Plan Details" +msgstr "Detalles del plan" + +#: app/(app)/friend-plan.tsx:56 +msgid "Plan not found." +msgstr "Plan no encontrado." + #: app/(app)/(tabs)/(plans)/_layout.tsx:17 msgid "Plan Overview" msgstr "Vista general del plan" #: app/(app)/(tabs)/_layout.tsx:49 #: app/(app)/(tabs)/(plans)/_layout.tsx:16 +#: app/(app)/friend-profile.tsx:146 #: constants/HelpData.ts:28 msgid "Plans" msgstr "Planes" @@ -2600,15 +2846,15 @@ msgstr "Planes" msgid "Plans are structured training programmes made up of workouts. To create one, go to the Plans tab, tap New Plan, give it a name, and pick a cover image. Add workouts to the plan, then add exercises to each workout with target sets and reps. Use the up/down arrow buttons on a workout card to reorder it, or the X button to remove it; both are in the top right of the card. Assign workouts to specific days of the week in the schedule editor: tap any day to pick a workout or leave it as a rest day, and use the auto-suggest button to space them out evenly. Once your plan is ready, open it and tap Activate. You can also add notes to a plan from the plan overview screen. Each workout card shows an estimated duration alongside the exercise count so you can gauge the session length at a glance. Use the view icons next to the \"Your Training Plans\" heading to switch between Carousel, List, and Grid layouts; your chosen view is saved automatically. Your progress in the plan editor is automatically saved as a draft, so if you leave mid-edit you will be prompted to continue where you left off or discard and start from the last saved state." msgstr "Los planes son programas de entrenamiento estructurados compuestos por entrenamientos. Para crear uno, ve a la pestaña Planes, toca Nuevo plan, dale un nombre y elige una imagen de portada. Añade entrenamientos al plan, luego añade ejercicios a cada entrenamiento con series y reps objetivo. Usa los botones de flecha arriba/abajo en una tarjeta de entrenamiento para reordenarlo, o el botón X para eliminarlo; ambos están en la parte superior derecha de la tarjeta. Asigna entrenamientos a días específicos de la semana en el editor de horarios: toca cualquier día para elegir un entrenamiento o déjalo como día de descanso, y usa el botón de sugerencia automática para distribuirlos de manera uniforme. Una vez que tu plan esté listo, ábrelo y toca Activar. También puedes añadir notas a un plan desde la pantalla de vista general del plan. Cada tarjeta de entrenamiento muestra una duración estimada junto al número de ejercicios para que puedas calcular la duración de la sesión de un vistazo. Usa los iconos de vista junto al encabezado \"Tus planes de entrenamiento\" para cambiar entre los modos Carrusel, Lista y Cuadrícula; tu vista preferida se guarda automáticamente. Tu progreso en el editor de planes se guarda automáticamente como borrador, así que si sales a mitad de la edición, se te pedirá que continúes donde lo dejaste o que descartes y empieces desde el último estado guardado." -#: app/(app)/settings.tsx:826 +#: app/(app)/settings.tsx:862 msgid "Play countdown beeps (Exercise Timer)" msgstr "Reproducir pitidos de cuenta atrás (Temporizador de ejercicio)" -#: app/(app)/settings.tsx:851 +#: app/(app)/settings.tsx:887 msgid "Play goal achieved sound (Exercise Timer)" msgstr "Reproducir sonido al alcanzar el objetivo (Temporizador de ejercicio)" -#: app/(app)/settings.tsx:901 +#: app/(app)/settings.tsx:937 msgid "Play sound after rest" msgstr "Reproducir sonido tras el descanso" @@ -2620,7 +2866,7 @@ msgstr "Por favor, espera mientras descargamos la última versión..." msgid "Post-Exercise Feedback" msgstr "Feedback tras el ejercicio" -#: app/(app)/(tabs)/(plans)/index.tsx:134 +#: app/(app)/(tabs)/(plans)/index.tsx:140 msgid "Premade plans" msgstr "Planes prediseñados" @@ -2628,12 +2874,20 @@ msgstr "Planes prediseñados" msgid "Premade Plans" msgstr "Planes prediseñados" -#: app/(app)/(workout)/workout-session.tsx:1417 -#: app/(app)/(workout)/workout-session.tsx:1504 +#: app/(app)/(workout)/workout-session.tsx:1448 +#: app/(app)/(workout)/workout-session.tsx:1535 msgid "Prev: " msgstr "Anterior: " -#: app/(app)/settings.tsx:1668 +#: app/(app)/settings.tsx:1604 +msgid "Previously shared data always remains visible to your friends until you delete it below." +msgstr "Los datos compartidos anteriormente siguen siendo visibles para tus amigos hasta que los elimines abajo." + +#: app/(app)/settings.tsx:1601 +msgid "Privacy" +msgstr "Privacidad" + +#: app/(app)/settings.tsx:1981 msgid "Privacy policy" msgstr "Política de privacidad" @@ -2641,7 +2895,7 @@ msgstr "Política de privacidad" msgid "Progression Suggestions" msgstr "Sugerencias de progresión" -#: components/ExerciseFeedbackSheet.tsx:211 +#: components/ExerciseFeedbackSheet.tsx:225 msgid "Push harder next time?" msgstr "¿Más intensidad la próxima vez?" @@ -2670,6 +2924,10 @@ msgstr "Reciente" msgid "Recent Sessions" msgstr "Sesiones recientes" +#: app/(app)/friend-profile.tsx:413 +msgid "Recent Workouts" +msgstr "Entrenamientos recientes" + #: hooks/useExerciseSort.ts:57 msgid "Recently Used" msgstr "Usado recientemente" @@ -2683,23 +2941,24 @@ msgstr "Control de recuperación" msgid "Reduce load" msgstr "Reducir peso" -#: app/_layout.tsx:94 +#: app/_layout.tsx:100 msgid "Reload" msgstr "Recargar" -#: app/(app)/settings.tsx:1280 +#: app/(app)/settings.tsx:1319 msgid "Reminder days" msgstr "Días de recordatorio" -#: app/(app)/settings.tsx:1335 +#: app/(app)/settings.tsx:1374 msgid "Reminder time" msgstr "Hora del recordatorio" -#: app/(app)/settings.tsx:1243 +#: app/(app)/settings.tsx:1282 msgid "Reminders" msgstr "Recordatorios" #: app/(app)/(create-plan)/create.tsx:283 +#: components/friends/FriendListItem.tsx:26 #: components/WorkoutCard.tsx:89 msgid "Remove" msgstr "Eliminar" @@ -2717,6 +2976,10 @@ msgstr "Eliminar ejercicio" msgid "Remove Superset" msgstr "Eliminar superserie" +#: components/friends/FriendListItem.tsx:22 +msgid "Remove this friend? They will no longer be able to see your shared content." +msgstr "¿Eliminar este amigo? Ya no podrá ver tu contenido compartido." + #: app/(app)/(create-plan)/create.tsx:275 msgid "Remove Workout" msgstr "Eliminar entrenamiento" @@ -2734,12 +2997,17 @@ msgstr "No se alcanzó el objetivo de reps. Mantener por ahora." msgid "Replace" msgstr "Reemplazar" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:186 +#: app/(app)/friend-plan.tsx:130 +#: app/(app)/friend-workout.tsx:89 +msgid "reps" +msgstr "reps" + +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:198 #: app/(app)/(tabs)/(stats)/edit-history.tsx:201 #: app/(app)/(tabs)/(stats)/edit-history.tsx:205 #: app/(app)/(tabs)/(stats)/edit-history.tsx:242 #: app/(app)/(tabs)/(stats)/edit-history.tsx:246 -#: app/(app)/custom-exercise.tsx:64 +#: app/(app)/custom-exercise.tsx:69 #: components/charts/ExerciseProgressionChart.tsx:377 #: components/SessionSetInfo.tsx:435 #: components/WorkoutCard.tsx:276 @@ -2751,10 +3019,14 @@ msgstr "Reps" msgid "Reps: {repRange}" msgstr "Reps: {repRange}" -#: app/(app)/settings.tsx:1577 +#: app/(app)/settings.tsx:1890 msgid "Request or vote for new features" msgstr "Solicita o vota por nuevas funciones" +#: app/(app)/friends.tsx:62 +msgid "Requests" +msgstr "Solicitudes" + #: app/(app)/(create-plan)/sets-overview.tsx:173 #: components/PlanScheduleEditor.tsx:94 #: components/PlanScheduleEditor.tsx:189 @@ -2771,7 +3043,7 @@ msgid "Rest Time (Minutes:Seconds)" msgstr "Tiempo de descanso (Minutos:Segundos)" #: app/(app)/(workout)/index.tsx:1134 -#: app/(app)/(workout)/workout-session.tsx:1540 +#: app/(app)/(workout)/workout-session.tsx:1572 msgid "Rest Time Left:" msgstr "Tiempo de descanso restante:" @@ -2784,11 +3056,11 @@ msgstr "Tiempo de descanso: {restMinutes}:{0}" msgid "Rest Timer" msgstr "Temporizador de descanso" -#: app/(app)/(workout)/workout-session.tsx:551 +#: app/(app)/(workout)/workout-session.tsx:558 msgid "Rest Timer Finished!" msgstr "¡Temporizador de descanso finalizado!" -#: app/(app)/settings.tsx:783 +#: app/(app)/settings.tsx:819 msgid "Rest timer increment" msgstr "Incremento del temporizador de descanso" @@ -2808,16 +3080,16 @@ msgstr "Reinicio fallido" msgid "Restart Workout" msgstr "Reiniciar entrenamiento" -#: app/(app)/settings.tsx:464 -#: app/(app)/settings.tsx:625 +#: app/(app)/settings.tsx:500 +#: app/(app)/settings.tsx:661 msgid "Restore" msgstr "Restaurar" -#: app/(app)/settings.tsx:459 +#: app/(app)/settings.tsx:495 msgid "Restore Backup" msgstr "Restaurar copia de seguridad" -#: app/(app)/settings.tsx:635 +#: app/(app)/settings.tsx:671 msgid "Restoring. Please wait..." msgstr "Restaurando. Por favor, espera..." @@ -2837,7 +3109,7 @@ msgstr "cuerda" msgid "rotator cuff" msgstr "manguito rotador" -#: app/(app)/settings.tsx:54 +#: app/(app)/settings.tsx:57 msgid "Sa" msgstr "Sá" @@ -2856,12 +3128,12 @@ msgstr "Sábado" #: app/(app)/(create-plan)/create.tsx:363 #: app/(app)/(workout)/index.tsx:843 #: app/(app)/(workout)/index.tsx:1071 -#: app/(app)/custom-exercise.tsx:549 +#: app/(app)/custom-exercise.tsx:575 #: components/SettingsModal.tsx:296 msgid "Save" msgstr "Guardar" -#: app/(app)/custom-exercise.tsx:549 +#: app/(app)/custom-exercise.tsx:575 msgid "Save and select" msgstr "Guardar y seleccionar" @@ -2901,6 +3173,8 @@ msgstr "Guardando entrenamiento..." #: app/(app)/(tabs)/(stats)/exercises.tsx:166 #: app/(app)/(workout)/exercises.tsx:233 #: app/(app)/exercise-library.tsx:91 +#: app/(app)/friends.tsx:59 +#: app/(app)/friends.tsx:219 msgid "Search" msgstr "Buscar" @@ -2912,13 +3186,14 @@ msgstr "Buscar en la ayuda" msgid "Search help…" msgstr "Buscar en la ayuda…" -#: app/(app)/custom-exercise.tsx:404 -#: app/(app)/custom-exercise.tsx:427 +#: app/(app)/custom-exercise.tsx:430 #: app/(app)/custom-exercise.tsx:453 +#: app/(app)/custom-exercise.tsx:479 msgid "Search..." msgstr "Buscar..." -#: app/(app)/custom-exercise.tsx:416 +#: app/(app)/custom-exercise.tsx:442 +#: app/(app)/friend-exercise.tsx:83 msgid "Secondary Muscles" msgstr "Músculos secundarios" @@ -2934,34 +3209,39 @@ msgstr "Selecciona un día para ver los entrenamientos." msgid "Select a workout to view" msgstr "Selecciona un entrenamiento para ver" -#: app/(app)/settings.tsx:1311 +#: app/(app)/settings.tsx:1350 msgid "Select at least one day" msgstr "Selecciona al menos un día" -#: app/(app)/custom-exercise.tsx:382 +#: app/(app)/custom-exercise.tsx:408 msgid "Select body part" msgstr "Selecciona la parte del cuerpo" -#: app/(app)/custom-exercise.tsx:454 +#: app/(app)/custom-exercise.tsx:480 msgid "Select equipment" msgstr "Selecciona el equipamiento" -#: app/(app)/custom-exercise.tsx:428 +#: app/(app)/custom-exercise.tsx:454 msgid "Select secondary muscles" msgstr "Selecciona los músculos secundarios" -#: app/(app)/custom-exercise.tsx:405 +#: app/(app)/custom-exercise.tsx:431 msgid "Select target muscle" msgstr "Selecciona el músculo objetivo" -#: app/(app)/custom-exercise.tsx:475 +#: app/(app)/custom-exercise.tsx:501 msgid "Select tracking type" msgstr "Selecciona el tipo de seguimiento" -#: app/(app)/settings.tsx:924 +#: app/(app)/settings.tsx:960 msgid "Send notification in background after rest" msgstr "Enviar notificación en segundo plano tras el descanso" +#: app/(app)/friends.tsx:271 +#: app/(app)/friends.tsx:344 +msgid "Sent" +msgstr "Enviadas" + #: constants/dbTranslations.ts:33 msgid "serratus anterior" msgstr "serrato anterior" @@ -2990,6 +3270,11 @@ msgstr "Tipos de serie" msgid "Set your weekly workout goal and enter your body weight to get accurate stats and recommendations. You can also adjust your weight increment preferences, choose your preferred units, and much more." msgstr "Establece tu objetivo semanal de entrenamientos e introduce tu peso corporal para obtener estadísticas y recomendaciones precisas. También puedes ajustar tus preferencias de incremento de peso, elegir tus unidades preferidas y mucho más." +#: app/(app)/friend-plan.tsx:124 +#: app/(app)/friend-workout.tsx:83 +msgid "sets" +msgstr "series" + #: app/(app)/(workout)/workout-summary.tsx:574 #: app/(app)/(workout)/workout-summary.tsx:597 msgid "Sets" @@ -3007,12 +3292,48 @@ msgstr "Vista general de series" msgid "settings" msgstr "ajustes" -#: app/(app)/_layout.tsx:40 -#: components/AppMenu.tsx:189 +#: app/(app)/_layout.tsx:42 +#: components/AppMenu.tsx:207 #: constants/HelpData.ts:153 msgid "Settings" msgstr "Ajustes" +#: app/(app)/settings.tsx:1779 +msgid "Share body measurements with friends" +msgstr "Compartir medidas corporales con amigos" + +#: app/(app)/settings.tsx:1739 +msgid "Share completed workouts with friends" +msgstr "Compartir entrenamientos con amigos" + +#: app/(app)/settings.tsx:1697 +msgid "Share custom exercises with friends" +msgstr "Compartir ejercicios personalizados con amigos" + +#: app/(app)/(tabs)/(plans)/overview.tsx:306 +msgid "Share Plan" +msgstr "Compartir plan" + +#: app/(app)/settings.tsx:1620 +msgid "Share plans with friends" +msgstr "Compartir planes con amigos" + +#: app/(app)/settings.tsx:1658 +msgid "Share standalone workouts with friends" +msgstr "Compartir entrenamientos individuales con amigos" + +#: app/(app)/settings.tsx:1821 +msgid "Share strength PRs with friends" +msgstr "Compartir récords de fuerza con amigos" + +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:291 +msgid "Share Workout" +msgstr "Compartir entrenamiento" + +#: constants/HelpData.ts:173 +msgid "Sharing Your Content" +msgstr "Compartir tu contenido" + #: constants/dbTranslations.ts:57 msgid "shins" msgstr "espinillas" @@ -3022,28 +3343,36 @@ msgstr "espinillas" msgid "shoulders" msgstr "hombros" -#: app/(app)/settings.tsx:1452 +#: app/(app)/settings.tsx:1491 msgid "Show onboarding on home screen" msgstr "Mostrar onboarding en la pantalla de inicio" -#: app/(app)/settings.tsx:532 +#: app/(app)/settings.tsx:568 msgid "Sign in" msgstr "Iniciar sesión" -#: app/(app)/settings.tsx:525 +#: app/(app)/friends.tsx:51 +msgid "Sign In" +msgstr "Iniciar sesión" + +#: app/(app)/friends.tsx:48 +msgid "Sign in to use the Friends feature." +msgstr "Inicia sesión para usar la función de Amigos." + +#: app/(app)/settings.tsx:561 msgid "Sign in with Google" msgstr "Iniciar sesión con Google" -#: constants/HelpData.ts:174 +#: constants/HelpData.ts:194 msgid "Sign in with Google in Settings to enable cloud backups of all your workout data. Tap Backup at any time to save a snapshot; the date of your last backup is shown beneath the button. Tap Restore to download and apply your latest backup; confirm the prompt and the app will reload with your restored data. Your backups are stored securely and are tied to your Google account. If you switch devices or reinstall the app, simply sign in with the same Google account and tap Restore to get your data back." msgstr "Inicia sesión con Google en Ajustes para activar las copias de seguridad en la nube de todos tus datos de entrenamiento. Toca Copia de seguridad en cualquier momento para guardar una instantánea; la fecha de tu última copia se muestra bajo el botón. Toca Restaurar para descargar y aplicar tu última copia; confirma el aviso y la app se recargará con tus datos restaurados. Tus copias se almacenan de forma segura y están vinculadas a tu cuenta de Google. Si cambias de dispositivo o reinstalas la app, simplemente inicia sesión con la misma cuenta de Google y toca Restaurar para recuperar tus datos." #. placeholder {0}: user.displayName || user.email -#: app/(app)/settings.tsx:538 +#: app/(app)/settings.tsx:574 msgid "Signed in as {0}" msgstr "Sesión iniciada como {0}" -#: constants/HelpData.ts:168 +#: constants/HelpData.ts:188 msgid "Signing In" msgstr "Inicio de sesión" @@ -3051,16 +3380,16 @@ msgstr "Inicio de sesión" msgid "Single & Quick Workouts" msgstr "Entrenamientos individuales y rápidos" -#: app/(app)/custom-exercise.tsx:505 +#: app/(app)/custom-exercise.tsx:531 #: app/(app)/exercise-info.tsx:263 msgid "Single-arm / single-leg" msgstr "Un solo brazo / una sola pierna" -#: app/(app)/settings.tsx:722 +#: app/(app)/settings.tsx:758 msgid "Size unit" msgstr "Unidad de tamaño" -#: app/(app)/settings.tsx:1412 +#: app/(app)/settings.tsx:1451 msgid "Size: ~100MB" msgstr "Tamaño: ~100 MB" @@ -3102,10 +3431,18 @@ msgstr "Algunas imágenes no se pudieron eliminar. IDs de ejercicio fallidos: {0 msgid "Some images failed to download after retries. Failed exercise IDs: {0}" msgstr "Algunas imágenes no se pudieron descargar tras varios intentos. IDs de ejercicio fallidos: {0}" +#: app/(app)/friends.tsx:237 +msgid "Something went wrong. Please try again." +msgstr "Algo salió mal. Inténtalo de nuevo." + #: constants/dbTranslations.ts:34 msgid "spine" msgstr "columna vertebral" +#: app/(app)/friend-profile.tsx:234 +msgid "Standalone Workouts" +msgstr "Entrenamientos individuales" + #: constants/HelpData.ts:39 msgid "Standalone workouts live outside of plans and appear alongside your plans on the Plans screen. Create one by tapping New Workout, give it a name, and add exercises; you can run it at any time without needing an active plan. An estimated duration is shown on each standalone workout so you can plan your time before starting. Quick Workouts let you start a session immediately from the home screen: tap Quick Workout, add exercises as you go, and at the end you can save it as a standalone workout for future use or simply discard it. Like plans, the workout editor automatically saves a draft so you can safely leave and return without losing your work." msgstr "Los entrenamientos independientes están fuera de los planes y aparecen junto a tus planes en la pantalla Planes. Crea uno tocando Nuevo entrenamiento, dale un nombre y añade ejercicios; puedes ejecutarlo en cualquier momento sin necesitar un plan activo. Cada entrenamiento independiente muestra una duración estimada para que puedas planificar tu tiempo antes de empezar. Los entrenamientos rápidos te permiten iniciar una sesión de inmediato desde la pantalla de inicio: toca Entrenamiento rápido, añade ejercicios sobre la marcha y al final puedes guardarlo como entrenamiento independiente para uso futuro o simplemente descartarlo. Al igual que los planes, el editor de entrenamiento guarda automáticamente un borrador para que puedas salir y volver sin perder tu trabajo." @@ -3114,7 +3451,7 @@ msgstr "Los entrenamientos independientes están fuera de los planes y aparecen msgid "Start" msgstr "Iniciar" -#: app/(app)/(tabs)/(plans)/overview.tsx:282 +#: app/(app)/(tabs)/(plans)/overview.tsx:327 msgid "Start Plan" msgstr "Iniciar plan" @@ -3122,11 +3459,11 @@ msgstr "Iniciar plan" msgid "Start Timer" msgstr "Iniciar temporizador" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:267 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:319 msgid "Start Workout" msgstr "Iniciar entrenamiento" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:223 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:235 #: app/(app)/(tabs)/index.tsx:306 msgid "Starting Workout..." msgstr "Iniciando entrenamiento..." @@ -3137,7 +3474,7 @@ msgstr "bicicleta estática" #: app/(app)/(tabs)/_layout.tsx:74 #: app/(app)/(tabs)/(stats)/_layout.tsx:16 -#: app/(app)/settings.tsx:994 +#: app/(app)/settings.tsx:1030 msgid "Stats" msgstr "Estadísticas" @@ -3145,7 +3482,7 @@ msgstr "Estadísticas" msgid "Stats & History" msgstr "Estadísticas e historial" -#: app/(app)/custom-exercise.tsx:499 +#: app/(app)/custom-exercise.tsx:525 msgid "Stats Options" msgstr "Opciones de estadísticas" @@ -3169,7 +3506,15 @@ msgstr "Detener" msgid "Streak" msgstr "Racha" -#: app/(app)/settings.tsx:55 +#: app/(app)/friend-profile.tsx:491 +msgid "Strength PRs" +msgstr "Récords de fuerza" + +#: app/(app)/settings.tsx:1825 +msgid "Strength PRs are shared automatically after each workout." +msgstr "Los récords de fuerza se comparten automáticamente tras cada entrenamiento." + +#: app/(app)/settings.tsx:58 msgid "Su" msgstr "Do" @@ -3178,7 +3523,7 @@ msgstr "Do" msgid "Success" msgstr "Éxito" -#: app/(app)/settings.tsx:1088 +#: app/(app)/settings.tsx:1124 msgid "Suggest load and rep adjustments" msgstr "Sugerir ajustes de carga y reps" @@ -3205,8 +3550,8 @@ msgstr "Superserie" #. placeholder {0}: outgoingSnapshot.isFirstInSuperset ? "A" : "B" #. placeholder {0}: ss.isFirstInSuperset ? "A" : "B" -#: app/(app)/(workout)/workout-session.tsx:1405 -#: app/(app)/(workout)/workout-session.tsx:1491 +#: app/(app)/(workout)/workout-session.tsx:1436 +#: app/(app)/(workout)/workout-session.tsx:1522 msgid "Superset {0}" msgstr "Superserie {0}" @@ -3218,7 +3563,11 @@ msgstr "Superseries" msgid "Take full control of your training by designing your own personalised plan. Select exercises, set rep ranges, rest times, and more to create a plan that aligns perfectly with your fitness goals." msgstr "Toma el control total de tu entrenamiento diseñando tu propio plan personalizado. Selecciona ejercicios, establece rangos de reps, tiempos de descanso y más para crear un plan que se ajuste perfectamente a tus objetivos de fitness." -#: constants/HelpData.ts:169 +#: constants/HelpData.ts:179 +msgid "Tap any accepted friend in your Friends list to open their profile. Their profile shows the plans, standalone workouts, and custom exercises they have chosen to share. Tap Import on any item to add it directly to your own library. Imported plans and workouts are saved as new copies that you can edit freely without affecting the original. Imported custom exercises are added to your exercise library and available immediately when building workouts." +msgstr "Toca cualquier amigo aceptado en tu lista de Amigos para abrir su perfil. Su perfil muestra los planes, entrenamientos individuales y ejercicios personalizados que ha elegido compartir. Toca Importar en cualquier elemento para añadirlo directamente a tu propia biblioteca. Los planes y entrenamientos importados se guardan como nuevas copias que puedes editar libremente sin afectar al original. Los ejercicios personalizados importados se añaden a tu biblioteca de ejercicios y están disponibles inmediatamente al crear entrenamientos." + +#: constants/HelpData.ts:189 msgid "Tap Sign In With Google in Settings to connect your account. Signing in enables cloud backups so your data is safe if you switch devices or reinstall the app, and your name is shown in the home screen greeting. The app works fully offline without signing in, but cloud backups are unavailable. Your data is stored locally on your device and is not shared with anyone unless you choose to share it yourself." msgstr "Toca Iniciar sesión con Google en Ajustes para conectar tu cuenta. Al iniciar sesión se activan las copias de seguridad en la nube para que tus datos estén seguros si cambias de dispositivo o reinstala la app, y tu nombre aparece en el saludo de la pantalla de inicio. La app funciona completamente sin conexión sin iniciar sesión, pero las copias de seguridad en la nube no están disponibles. Tus datos se almacenan localmente en tu dispositivo y no se comparten con nadie a menos que tú decidas hacerlo." @@ -3230,11 +3579,15 @@ msgstr "Toca el icono de estrella en la esquina superior derecha de cualquier pa msgid "Target Distance ({distanceUnit})" msgstr "Distancia objetivo ({distanceUnit})" -#: app/(app)/custom-exercise.tsx:393 +#: app/(app)/friend-exercise.tsx:76 +msgid "Target Muscle" +msgstr "Músculo objetivo" + +#: app/(app)/custom-exercise.tsx:419 msgid "Target Muscle *" msgstr "Músculo objetivo *" -#: app/(app)/custom-exercise.tsx:202 +#: app/(app)/custom-exercise.tsx:207 msgid "Target muscle is required." msgstr "El músculo objetivo es obligatorio." @@ -3246,7 +3599,7 @@ msgstr "Músculo objetivo:" msgid "Target: {distanceMin} {distanceUnit}" msgstr "Objetivo: {distanceMin} {distanceUnit}" -#: app/(app)/settings.tsx:52 +#: app/(app)/settings.tsx:55 msgid "Th" msgstr "Ju" @@ -3294,6 +3647,14 @@ msgstr "Muslo (D)" msgid "This exercise is already in your workout. Please choose a different one." msgstr "Este ejercicio ya está en tu entrenamiento. Por favor, elige uno diferente." +#: app/(app)/friend-profile.tsx:140 +msgid "This friend hasn't shared any content yet." +msgstr "Este amigo aún no ha compartido ningún contenido." + +#: app/(app)/settings.tsx:88 +msgid "This removes all content you have shared with friends. Your friends and friend list are not affected." +msgstr "Esto elimina todo el contenido que has compartido con amigos. Tus amigos y lista de amigos no se ven afectados." + #: app/(app)/+not-found.tsx:18 msgid "This screen doesn't exist." msgstr "Esta pantalla no existe." @@ -3309,7 +3670,7 @@ msgstr "Jue" msgid "Thursday" msgstr "Jueves" -#: app/(app)/custom-exercise.tsx:65 +#: app/(app)/custom-exercise.tsx:70 #: components/WeeklySummaryCard.tsx:299 msgid "Time" msgstr "Tiempo" @@ -3336,7 +3697,7 @@ msgstr "Tiempo (s)" msgid "Time PR" msgstr "PR de tiempo" -#: app/(app)/(workout)/workout-session.tsx:552 +#: app/(app)/(workout)/workout-session.tsx:559 msgid "Time to do your next set!" msgstr "¡Es hora de tu próxima serie!" @@ -3345,11 +3706,11 @@ msgstr "¡Es hora de tu próxima serie!" msgid "Time: {0}" msgstr "Tiempo: {0}" -#: app/(app)/settings.tsx:365 +#: app/(app)/settings.tsx:401 msgid "To enable rest timer notifications, grant notification permissions in your device settings." msgstr "Para activar las notificaciones del temporizador de descanso, concede permisos de notificación en los ajustes de tu dispositivo." -#: app/(app)/settings.tsx:384 +#: app/(app)/settings.tsx:420 msgid "To enable workout reminders, grant notification permissions in your device settings." msgstr "Para activar los recordatorios de entrenamiento, concede permisos de notificación en los ajustes de tu dispositivo." @@ -3414,15 +3775,19 @@ msgstr "Ejercicios seguidos" msgid "Tracking" msgstr "Seguimiento" -#: app/(app)/custom-exercise.tsx:465 +#: app/(app)/friend-exercise.tsx:90 +msgid "Tracking Type" +msgstr "Tipo de seguimiento" + +#: app/(app)/custom-exercise.tsx:491 msgid "Tracking Type *" msgstr "Tipo de seguimiento *" -#: app/(app)/custom-exercise.tsx:485 +#: app/(app)/custom-exercise.tsx:511 msgid "Tracking type cannot be changed after creation." msgstr "El tipo de seguimiento no se puede cambiar después de la creación." -#: app/(app)/custom-exercise.tsx:205 +#: app/(app)/custom-exercise.tsx:210 msgid "Tracking type is required." msgstr "El tipo de seguimiento es obligatorio." @@ -3440,7 +3805,7 @@ msgstr "" msgid "Training" msgstr "Entrenamiento" -#: components/TrainingPlanCard.tsx:74 +#: components/TrainingPlanCard.tsx:77 msgid "Training Plan" msgstr "Plan de entrenamiento" @@ -3476,7 +3841,7 @@ msgstr "tríceps" msgid "Try Again" msgstr "Intentar de nuevo" -#: app/(app)/settings.tsx:50 +#: app/(app)/settings.tsx:53 msgid "Tu" msgstr "Ma" @@ -3499,7 +3864,11 @@ msgstr "Escribe para filtrar temas de ayuda" msgid "Unable to save your workout. Please try again later." msgstr "No se puede guardar tu entrenamiento. Por favor, inténtalo de nuevo más tarde." -#: app/(app)/settings.tsx:650 +#: app/(app)/friend-exercise.tsx:97 +msgid "Unilateral" +msgstr "Unilateral" + +#: app/(app)/settings.tsx:686 msgid "Units of measurement" msgstr "Unidades de medida" @@ -3511,7 +3880,17 @@ msgstr "Desconocido" msgid "Update Ready" msgstr "Actualización lista" -#: app/(app)/settings.tsx:634 +#. placeholder {0}: formatDistanceToNow(plan.updatedAt.toDate(), { addSuffix: true, }) +#. placeholder {0}: formatDistanceToNow(plan.updatedAt.toDate(), { addSuffix: true }) +#. placeholder {0}: formatDistanceToNow(workout.updatedAt.toDate(), { addSuffix: true, }) +#: app/(app)/friend-plan.tsx:75 +#: app/(app)/friend-profile.tsx:185 +#: app/(app)/friend-profile.tsx:276 +#: app/(app)/friend-workout.tsx:62 +msgid "Updated {0}" +msgstr "Actualizado {0}" + +#: app/(app)/settings.tsx:670 msgid "Uploading. Please wait..." msgstr "Subiendo. Por favor, espera..." @@ -3543,11 +3922,11 @@ msgstr "pecho superior" msgid "upper legs" msgstr "piernas superiores" -#: app/(app)/settings.tsx:979 +#: app/(app)/settings.tsx:1015 msgid "Using history from same workout" msgstr "Historial del mismo entrenamiento" -#: app/(app)/settings.tsx:978 +#: app/(app)/settings.tsx:1014 msgid "Using most recent from any workout" msgstr "El más reciente de cualquier entrenamiento" @@ -3555,7 +3934,7 @@ msgstr "El más reciente de cualquier entrenamiento" msgid "Values" msgstr "Valores" -#: app/(app)/settings.tsx:876 +#: app/(app)/settings.tsx:912 msgid "Vibrate after rest" msgstr "Vibrar tras el descanso" @@ -3624,7 +4003,7 @@ msgstr "Calentamiento, " msgid "warmup" msgstr "calentamiento" -#: app/(app)/settings.tsx:51 +#: app/(app)/settings.tsx:54 msgid "We" msgstr "Mi" @@ -3643,7 +4022,7 @@ msgstr "Miércoles" msgid "Week streak" msgstr "Racha semanal" -#: app/(app)/settings.tsx:558 +#: app/(app)/settings.tsx:594 msgid "Weekly goal" msgstr "Objetivo semanal" @@ -3667,7 +4046,7 @@ msgstr "Peso" msgid "Weight ({weightUnitLabel})" msgstr "Peso ({weightUnitLabel})" -#: app/(app)/settings.tsx:755 +#: app/(app)/settings.tsx:791 msgid "Weight increment" msgstr "Incremento de peso" @@ -3675,11 +4054,11 @@ msgstr "Incremento de peso" msgid "Weight Tracking for Bodyweight Exercises" msgstr "Registro de peso para ejercicios con peso corporal" -#: app/(app)/settings.tsx:670 +#: app/(app)/settings.tsx:706 msgid "Weight unit" msgstr "Unidad de peso" -#: app/(app)/custom-exercise.tsx:62 +#: app/(app)/custom-exercise.tsx:67 msgid "Weight/Reps" msgstr "Peso/Reps" @@ -3703,7 +4082,7 @@ msgstr "Bienvenido/a{userName}" msgid "When you open a workout that contains exercises you trained recently, a Recovery Check-in sheet appears if those exercises have a pending progression suggestion and your last session was at least 12 hours ago. For each relevant muscle group, you choose one of three options: Fresh (fully recovered), Mild soreness, or Still very sore. If a muscle is marked as still very sore, any upward progression suggestion for exercises targeting that muscle is paused and held at the current load until you re-evaluate at the start of the following session. Fresh or Mild soreness does not affect suggestions. Tap Skip for now to bypass the check-in entirely; a skipped check-in is treated the same as fresh recovery, so pending suggestions are unaffected." msgstr "Cuando abres un entrenamiento con ejercicios que entrenaste recientemente, aparece un cuestionario de Control de recuperación si esos ejercicios tienen una sugerencia de progresión pendiente y tu última sesión fue hace al menos 12 horas. Para cada grupo muscular relevante, eliges una de tres opciones: Fresco (completamente recuperado), Dolor muscular leve o Todavía muy dolorido. Si un músculo se marca como todavía muy dolorido, cualquier sugerencia de progresión ascendente para los ejercicios que trabajan ese músculo se pausa y se mantiene en la carga actual hasta que lo reevalúes al inicio de la siguiente sesión. Fresco o Dolor muscular leve no afectan a las sugerencias. Toca Omitir por ahora para saltarte el control completamente; un control omitido se trata igual que la recuperación completa, por lo que las sugerencias pendientes no se ven afectadas." -#: components/ExerciseFeedbackSheet.tsx:233 +#: components/ExerciseFeedbackSheet.tsx:247 msgid "Where did you feel it?" msgstr "¿Dónde lo sentiste?" @@ -3713,7 +4092,7 @@ msgstr "trabajando" #: app/(app)/(tabs)/(plans)/_layout.tsx:18 #: app/(app)/(workout)/_layout.tsx:17 -#: app/(app)/settings.tsx:734 +#: app/(app)/settings.tsx:770 #: components/RestDayCard.tsx:41 #: components/WeeklyScheduleDisplay.tsx:88 #: components/WorkoutDoneCard.tsx:50 @@ -3736,7 +4115,8 @@ msgstr "Calendario de entrenamientos" msgid "Workout Complete!" msgstr "¡Entrenamiento completado!" -#: app/(app)/_layout.tsx:33 +#: app/(app)/_layout.tsx:35 +#: app/(app)/_layout.tsx:55 #: app/(app)/(tabs)/(stats)/_layout.tsx:19 msgid "Workout Details" msgstr "Detalles del entrenamiento" @@ -3754,13 +4134,14 @@ msgstr "Entrenamiento en curso" msgid "Workout name" msgstr "Nombre del entrenamiento" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:54 -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:207 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:66 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:219 #: app/(app)/(workout)/workout-summary.tsx:518 +#: app/(app)/friend-workout.tsx:43 msgid "Workout not found." msgstr "Entrenamiento no encontrado." -#: app/(app)/settings.tsx:1255 +#: app/(app)/settings.tsx:1294 msgid "Workout reminders" msgstr "Recordatorios de entrenamiento" @@ -3804,7 +4185,7 @@ msgstr "x {0} reps " msgid "Yes" msgstr "Sí" -#: components/ExerciseFeedbackSheet.tsx:215 +#: components/ExerciseFeedbackSheet.tsx:229 msgid "Yes, increase the challenge" msgstr "Sí, aumentar el reto" @@ -3812,7 +4193,7 @@ msgstr "Sí, aumentar el reto" msgid "Yesterday" msgstr "Ayer" -#: app/(app)/(tabs)/(plans)/overview.tsx:150 +#: app/(app)/(tabs)/(plans)/overview.tsx:161 msgid "You activated this plan." msgstr "Has activado este plan." @@ -3824,6 +4205,10 @@ msgstr "Puedes ocultar esta pantalla de introducción en cualquier momento desde msgid "You can login at any time from the settings screen, if you choose to skip it now." msgstr "Puedes iniciar sesión en cualquier momento desde la pantalla de ajustes, si decides saltarte este paso ahora." +#: constants/HelpData.ts:174 +msgid "You can share plans, standalone workouts, custom exercises, body measurements, and strength PRs with your friends. All five categories have a global toggle in Privacy Settings, found in the Account section of Settings. Enabling the global toggle for a category shares all items in that category and syncs new data automatically whenever it changes. Plans and standalone workouts also have an individual Share toggle on each item's overview screen, so you can publish specific plans or workouts without sharing everything. A cloud icon on the plan or workout card confirms it is currently published. To remove shared data, disable the toggle in Privacy Settings and tap Delete Shared Data for that category. You can also delete all shared data for every category from the same screen." +msgstr "Puedes compartir planes, entrenamientos individuales, ejercicios personalizados, medidas corporales y récords de fuerza con tus amigos. Las cinco categorías tienen un interruptor global en la Configuración de privacidad, en la sección Cuenta de Ajustes. Al activar el interruptor global de una categoría se comparten todos los elementos de esa categoría y los nuevos datos se sincronizan automáticamente cada vez que cambian. Los planes y entrenamientos individuales también tienen un interruptor Compartir individual en la pantalla de resumen de cada elemento, para que puedas publicar planes o entrenamientos específicos sin compartir todo. Un icono de nube en la tarjeta del plan o entrenamiento confirma que está publicado actualmente. Para eliminar los datos compartidos, desactiva el interruptor en la Configuración de privacidad y toca Eliminar datos compartidos para esa categoría. También puedes eliminar todos los datos compartidos de cada categoría desde la misma pantalla." + #: components/ProgressionSummaryCard.tsx:22 msgid "You chose to keep it steady. Hold this load." msgstr "Elegiste mantenerlo igual. El peso se queda así." @@ -3851,11 +4236,11 @@ msgstr "Tienes cambios sin guardar. ¿Seguro que quieres descartarlos?" msgid "You modified this workout. Save those changes for future sessions?" msgstr "Has modificado este entrenamiento. ¿Guardar los cambios para sesiones futuras?" -#: app/(app)/settings.tsx:604 +#: app/(app)/settings.tsx:640 msgid "You need to sign in to use this feature" msgstr "Necesitas iniciar sesión para usar esta función" -#: app/(app)/custom-exercise.tsx:81 +#: app/(app)/custom-exercise.tsx:86 msgid "You'll lose what you've entered so far." msgstr "Perderás lo que has introducido hasta ahora." @@ -3871,10 +4256,10 @@ msgstr "Has alcanzado tu objetivo semanal. ¡Increíble trabajo!" msgid "Your journey to Swoletown begins today!" msgstr "¡Tu camino a Swoletown empieza hoy!" -#: app/(app)/(tabs)/(plans)/index.tsx:126 +#: app/(app)/(tabs)/(plans)/index.tsx:130 msgid "Your training plans" msgstr "Tus planes de entrenamiento" -#: app/(app)/(tabs)/(plans)/index.tsx:141 +#: app/(app)/(tabs)/(plans)/index.tsx:147 msgid "Your workouts" msgstr "Tus entrenamientos" diff --git a/locales/fr/messages.js b/locales/fr/messages.js index 6782adb7..72d15e81 100644 --- a/locales/fr/messages.js +++ b/locales/fr/messages.js @@ -1 +1 @@ -/*eslint-disable*/module.exports={messages:JSON.parse("{\"-2Ut5a\":[\"La bande Aperçus en haut de l'onglet Stats donne quatre points saillants en un coup d'œil pour la période sélectionnée : ta moyenne d'entraînements par semaine, ta plus grande progression de force parmi les exercices suivis, la partie du corps la plus entraînée, et ta série consécutive hebdomadaire actuelle. Ces données se mettent à jour automatiquement après chaque entraînement.\"],\"-5kO8P\":[\"Samedi\"],\"-BjMj_\":[\"Créer un entraînement\"],\"-FjWgX\":[\"Jeu\"],\"-Tpjjs\":[[\"0\"],\" séries\"],\"-WSEJS\":[\"Supprimer l'entraînement\"],\"-Xejuf\":[\"Hanches\"],\"-XvJee\":[\"record \",[\"0\"],[\"weightUnit\"],\" × \",[\"1\"]],\"-svcUj\":[\"Enregistrer cet entraînement ?\"],\"03mQOq\":[\"Impossible d'activer ce programme : \",[\"0\"]],\"06EUQy\":[\"Record absolu\"],\"0EHHPz\":[\"adducteurs\"],\"0EPpEZ\":[\"Ajouter une mesure personnalisée\"],\"0EcUWz\":[\"Abandonner les modifications ?\"],\"0OeId4\":[\"Créer un programme personnalisé\"],\"0P1btN\":[\"\\n🔔 Nouveau : Sons de la minuterie d'exercice !\\n\\nLa minuterie d'exercice joue maintenant des signaux sonores pour te garder concentré. Un bip de compte à rebours quand la minuterie approche de zéro et un son quand tu atteins ton objectif. Active ou désactive chaque son indépendamment dans les Paramètres.\\n\"],\"0SaB4K\":[\"Série d'échauffement\"],\"0U938S\":[\"Sélectionne au moins un jour\"],\"0V9gKq\":[\"\\n🔵 Nouveau : Modal de minuterie d'exercice !\\n\\nLes exercices basés sur le temps affichent maintenant un modal dédié avec un anneau de progression, pour suivre facilement ton effort et garder le rythme pendant les séries chronométrées.\\n\"],\"0caMy7\":[\"Historique\"],\"0dHvKo\":[\"Muscle cible :\"],\"0eRpDV\":[\"Difficile, proche de la limite\"],\"0f7U0k\":[\"Mer\"],\"0tJJBW\":[\"Préc. : \"],\"0vGEy2\":[\"\\n📊 Nouveau : Écran de statistiques amélioré !\\n\\nL'écran de statistiques a été repensé avec un nouveau look et des aperçus améliorés. Explore ton historique d'entraînement avec de meilleurs graphiques, des résumés plus clairs et des analyses plus détaillées de ta progression dans le temps.\\n\"],\"14ytif\":[\"Commencer l'entraînement\"],\"1DPB1m\":[\"\\n🗂️ Nouveau : Cinq nouveaux programmes préfaits !\\n\\nCinq nouveaux programmes prêts à l'emploi sont maintenant disponibles : Bro Split 5 jours, Push/Pull/Jambes 5 jours, Split 6 jours, Poids de corps et Haltères uniquement. Que tu t'entraînes à la maison ou en salle, il y a un programme pour démarrer immédiatement.\\n\"],\"1FnEj9\":[\"Mesures corporelles\"],\"1Kx4Hp\":[\"Erreur lors de la récupération de \",[\"0\"],\" : \",[\"1\"]],\"1Mx10o\":[\"Voir les stats\"],\"1QfxQT\":[\"Fermer\"],\"1Se9J7\":[\"vélo stationnaire\"],\"1UzENP\":[\"Non\"],\"1gbc4_\":[\"Nouvel entraînement\"],\"1hW6-f\":[\"Certaines images n'ont pas pu être téléchargées après plusieurs tentatives. IDs des exercices en échec : \",[\"0\"]],\"1j3Ob3\":[\"Calendrier des entraînements\"],\"1mm2JF\":[\"deltïödes\"],\"296mtr\":[\"barre hexagonale\"],\"29Hx9U\":[\"Stats\"],\"2FYpfJ\":[\"Plus\"],\"2ZZM6V\":[\"core\"],\"2bnWaQ\":[[\"completedCount\"],\"/\",[\"0\"],\" séries terminées\"],\"2cupe5\":[\"Appliquer à toutes les \",[\"0\"],\" séries\"],\"2dPYb7\":[\"Aucune mesure pour l'instant. Enregistre ta première entrée ci-dessus.\"],\"2dX9Kv\":[\"dos\"],\"2eB2c7\":[\"Entraîne-toi sans programme ! Crée des entraînements indépendants en dehors de tes programmes, parfaits pour les séances de mobilité, les échauffements ou tout ce qui est improvisé.\\n\\nOu lance directement un Entraînement rapide depuis l'écran d'accueil, ajoute des exercices au fur et à mesure, et tu peux le sauvegarder comme entraînement indépendant quand tu as terminé.\"],\"2gSypt\":[\"Équipement *\"],\"2j0v05\":[\"Toutes les images téléchargées avec succès !\"],\"2lfUf3\":[[\"streak\",\"plural\",{\"one\":[\"#\",\" semaine d'affilée\"],\"other\":[\"#\",\" semaines d'affilée\"]}]],\"2saL1j\":[\"1RM\"],\"2vS4Oc\":[\"Facile, j'aurais pu faire plus\"],\"2wR0QE\":[\"Ajouter un exercice\"],\"30xwUM\":[\"Tu es sûr de vouloir supprimer toutes les images animées ? Les images individuelles seront automatiquement re-téléchargées lors de leur affichage.\"],\"39y5bn\":[\"Vendredi\"],\"3A79ox\":[\"Réduire la charge\"],\"3L-1Z1\":[\"Erreur lors du chargement des exercices : \",[\"0\"]],\"3RoflF\":[\"\\n📈 Nouveau : Historique des exercices dans l'écran d'informations !\\n\\nL'écran d'informations sur les exercices inclut maintenant un historique complet de chaque fois que tu as effectué cet exercice, avec les poids, répétitions, temps et distance de chaque série des séances passées. Accède-y pendant un entraînement, depuis ton programme, ou partout où les informations sur les exercices sont disponibles.\\n\"],\"3ezHPX\":[\"Jouer un son après le repos\"],\"3hJ166\":[\"\\n🔍 Amélioré : Recherche d'exercices plus intelligente et accès facile à la bibliothèque d'exercices !\\n\\nLa recherche d'exercices reconnaît maintenant les abréviations courantes comme RDL, OHP, DB et KB, corrige les petites fautes de frappe et classe les résultats par pertinence pour que la meilleure correspondance apparaisse toujours en premier.\\n\\nTu peux aussi parcourir la bibliothèque complète d'exercices à tout moment depuis le menu, sans avoir besoin d'être dans un entraînement ou un plan.\\n\"],\"3hJypY\":[\"Aperçus\"],\"43lYJ-\":[\"Bienvenue\",[\"userName\"]],\"4BgR4M\":[\"Tu as atteint ton objectif hebdomadaire. Travail incroyable !\"],\"4GTHgi\":[\"Compte à rebours de la minuterie d'exercice\"],\"4M4P8M\":[\"Aucune valeur saisie\"],\"4OjqAQ\":[\"Continuer à modifier\"],\"4_WLmI\":[\"poids de corps\"],\"4j0zbV\":[\"Enregistrement du programme...\"],\"4jkyRj\":[\"échauffement\"],\"4mrNi3\":[[\"suggestedRepsMin\"],\"-\",[\"suggestedRepsMax\"],\" reps suggérées\"],\"4oRoD4\":[\"Configure les unités de poids, de taille et de distance, le nombre de séries par défaut par exercice, le temps de repos par défaut et l'incrément de poids des boutons ± pendant la séance. Ajuste la taille des boutons d'entraînement (Standard, Grand ou Très grand) et active Garder l'écran allumé pour éviter que l'écran se mette en veille. Dans Statistiques, tu peux exclure les séries d'échauffement du volume, doubler les répétitions pour les exercices unilatéraux ou doubler le poids pour les appareils appariés, utile si tu préfères noter le poids d'un seul haltère plutôt que le total. Renseigne ton poids corporel ici ; il est utilisé pour calculer la charge effective des exercices assistés.\"],\"4sGdeG\":[\"Graisse corporelle\"],\"50_FGa\":[\"Exercice\"],\"538Jsv\":[\"Annuler l'entraînement\"],\"58iwz8\":[\"Erreur lors du chargement des programmes\"],\"5SgD0L\":[\"Tu as des modifications non enregistrées. Es-tu sûr(e) de vouloir les abandonner ?\"],\"5Z05pb\":[\"Filtrer les thèmes d'aide\"],\"5aB9II\":[\"C'est l'heure de ta prochaine série !\"],\"5b4J4v\":[\"Tout le temps\"],\"5lWFkC\":[\"Se connecter\"],\"5w2VTM\":[\"Tu es sûr de vouloir télécharger toutes les images animées ? Cela peut prendre un moment.\"],\"5yIPLp\":[\"Oups !\"],\"66llpx\":[\"Ajouter une image\"],\"699xiu\":[\"Tu es sûr de vouloir restaurer la sauvegarde ?\"],\"6Bqki7\":[\"Objectif hebdomadaire atteint !\"],\"6Hcqaf\":[\"\\n↕️ Nouveau : Réorganiser les entraînements dans ton programme !\\n\\nTu peux maintenant réorganiser les entraînements directement depuis l'écran de création de programme et les cartes d'entraînement, pour avoir un contrôle total sur la mise en page de ton planning.\\n\"],\"6MR2yM\":[\"Parcours près de 1 000 exercices et filtre par partie du corps, muscle cible ou équipement. Utilise les chips de tri en haut pour classer les exercices par Par défaut, Programme actif, Récent ou Fréquent, afin que les exercices les plus pertinents pour toi apparaissent en premier. Quand tu remplaces un exercice, le filtre présélectionne automatiquement le muscle cible correspondant pour t'aider à trouver des alternatives plus rapidement. Appuie sur n'importe quel exercice pour voir sa démonstration animée, les muscles sollicités et un historique complet de chaque fois que tu l'as effectué, avec les poids, répétitions, temps ou distances par série. Télécharge toutes les animations d'exercices (~100 Mo) dans les Paramètres pour y accéder hors ligne.\"],\"6XIVae\":[\"Augmenter la charge\"],\"6_dCYd\":[\"Vue d'ensemble\"],\"6g63at\":[\"Explorer les programmes\"],\"6glEtt\":[\"Encore en récupération. Garder cette charge pour l'instant.\"],\"6igHT6\":[\"Modifier l'entraînement\"],\"6lAGPA\":[\"Ajoute un entraînement pour commencer\"],\"6lv7us\":[\"Poids (\",[\"weightUnitLabel\"],\")\"],\"6q7I63\":[\"taille\"],\"6u9LvN\":[[\"days\",\"plural\",{\"one\":[\"il y a \",\"#\",\" jour\"],\"other\":[\"il y a \",\"#\",\" jours\"]}]],\"6uHnph\":[\"Temps (Heure:Min)\"],\"6vinCF\":[\"Type de suivi *\"],\"6z9W13\":[\"Recommencer\"],\"716aO7\":[\"Le plus entraîné\"],\"75Qc-e\":[\"Compter les rép. ×2 pour le volume quand le paramètre est activé\"],\"77kllS\":[\"record \",[\"0\"],\" rép.\"],\"7F8buC\":[\"avant-bras\"],\"7FYy4K\":[\"Erreur lors de la sauvegarde de l'entraînement\"],\"7LBKtm\":[\"Aucun entraînement disponible\"],\"7LLkrj\":[\"muscles de la poigne\"],\"7MuXko\":[\"Personnel\"],\"7P_9OY\":[\"Ma\"],\"7YT_7y\":[\"Répétitions\"],\"7Z9Tzs\":[\"colonne vertébrale\"],\"7eMo-U\":[\"Retourner à l'accueil\"],\"7hAJKI\":[[\"0\",\"plural\",{\"one\":[\"série\"],\"other\":[\"séries\"]}]],\"7iTVa8\":[\"Muscles secondaires\"],\"7p3sn_\":[\"Temps : \",[\"0\"]],\"7x42zy\":[\"Aucune donnée pour cette période\"],\"7xB0qQ\":[\"Muscle cible *\"],\"87VAxI\":[\"Infos sur l'exercice\"],\"8Mlj-A\":[\"Objectif de reps non atteint. On maintient pour l'instant.\"],\"8Rd3od\":[\"Tu es sûr de vouloir annuler et supprimer cet entraînement ?\"],\"8V8f_Q\":[\"Dernier \",[\"metricLabel\"],\" : \",[\"0\"]],\"8YBh-G\":[\"Rép. ×2 comptées pour ces exercices\"],\"8ZJ9dh\":[\"Enregistrement du poids pour les exercices au poids de corps\"],\"8ZU8FI\":[\"Erreur lors du chargement des stats. Réessaie.\"],\"8_MCsG\":[\"\\n💾 Nouveau : Sauvegarde et reprise des brouillons de programme et d'entraînement !\\n\\nTon travail dans les éditeurs de programme et d'entraînement autonome est maintenant automatiquement sauvegardé comme brouillon. Si tu quittes en cours d'édition, tu seras invité à continuer là où tu t'es arrêté ou à supprimer le brouillon, pour ne jamais perdre ta progression par accident.\\n\"],\"8aTiea\":[\"Personnalisation\"],\"8cA6YX\":[\"Suis ta composition corporelle dans le temps depuis la section Mesures de l'onglet Statistiques. Utilise le formulaire Saisir une entrée pour enregistrer des valeurs pour chaque mesure active, puis appuie sur une entrée passée dans l'historique pour la consulter ou la modifier. Sur l'écran de détail de l'entrée, appuie sur un chip de mesure pour basculer le graphique entre différentes mesures et utilise le sélecteur de plage de temps pour zoomer ou dézoomer. Les mesures sont divisées en trois types : masse (poids, en kg ou lbs), longueur (circonférences comme la taille et les hanches, en cm ou pouces) et pourcentage (masse grasse). Les unités suivent tes préférences de poids et de taille dans Paramètres. Pour contrôler quelles mesures apparaissent dans le formulaire, appuie sur Gérer les mesures en haut de la section Saisir une entrée. Les mesures intégrées peuvent être activées ou désactivées ; tu peux également créer tes propres mesures personnalisées et choisir leur type. Les mesures personnalisées peuvent être masquées du formulaire à tout moment, et tes données historiques sont toujours conservées.\"],\"8jcZyX\":[\"Mesures intégrées\"],\"8mjpCE\":[\"Introduction à MuscleQuest\"],\"8uqQSD\":[\"Pas réussi à finir toutes les séries\"],\"8yLreB\":[\"pendant \",[\"0\"],\"s \"],\"8yw7nc\":[\"Bilan de récupération\"],\"91hJvI\":[\"Cible : \",[\"distanceMin\"],\" \",[\"distanceUnit\"]],\"94FTWy\":[\"Suppression terminée\"],\"95IyBI\":[\"Les exercices au poids de corps comme les tractions ou les dips ne suivent que les répétitions par défaut. Si tu veux noter le poids ajouté, comme une ceinture lestée ou un gilet, ouvre le récapitulatif des séries de cet exercice dans l'éditeur d'entraînement ou de programme et active Enregistrer le poids. Le réglage est sauvegardé par entraînement, tu peux donc avoir des entraînements en poids de corps uniquement et d'autres qui enregistrent la charge supplémentaire. Les graphiques de progression et l'historique refléteront le poids enregistré une fois le réglage activé.\"],\"97-TIS\":[\"Tu n'as pas pu finir toutes les séries. La charge baisse légèrement pour la prochaine fois.\"],\"9C6X7Q\":[\"Abandonner les modifications\"],\"9EGOsa\":[\"câble\"],\"9H3-WL\":[\"\\n⚙️ Nouveau : Trois nouveaux paramètres pour les stats !\\n\\nPersonnalise le calcul de ton volume et de tes stats avec trois nouvelles options dans les Paramètres :\\n\\n• Exclure les séries d'échauffement des stats pour ne pas fausser tes chiffres.\\n• Doubler automatiquement le poids des haltères, pour que tu puisses noter le poids d'un seul haltère et que le total soit compté pour toi.\\n• Doubler les répétitions pour les exercices unilatéraux (un bras/une jambe), pour que ces mouvements soient comptés correctement dans tes totaux de volume.\\n\"],\"9LmK3L\":[\"Images par Unsplash\"],\"9XoWik\":[\"grand dentelé\"],\"9eQmcp\":[[\"0\"],\" jours par semaine\"],\"A-gAFO\":[\"Crée tes propres exercices depuis le sélecteur d'exercices. Donne-lui un nom, une image optionnelle, une partie du corps, des muscles cibles, des muscles secondaires et de l'équipement. Choisis un type de suivi : poids + répétitions, temps, distance, répétitions seules ou assisté (qui prend en compte ton poids de corps pour des mouvements comme les tractions assistées). Active Unilatéral pour les exercices à un bras ou une jambe ; les répétitions peuvent être automatiquement doublées dans tes stats. Active Implements appariés si tu notes le poids d'un seul implement plutôt que le total : par exemple, si tu notes 20 kg pour un haltère, l'appli compte 40 kg dans ton volume.\"],\"A1-VaP\":[\"grand dorsal\"],\"A1_kH4\":[\"Minuterie d'exercice\"],\"A1taO8\":[\"Rechercher\"],\"AWokve\":[\"Historique du même entraînement\"],\"AeXO77\":[\"Compte\"],\"AqyJQg\":[\"Feedback après exercice\"],\"Ayx1au\":[\"Tu es sûr de vouloir supprimer ce programme ?\"],\"B8ZQ8n\":[\"Rép. min.\"],\"B9LtU1\":[\"Tu as des modifications non enregistrées de ta dernière session. Veux-tu continuer ?\"],\"BGO6Rp\":[\"Comment se sentent ces muscles depuis ta dernière séance ?\"],\"BTqs-Z\":[[\"0\",\"plural\",{\"one\":[\"#\",\" Série\"],\"other\":[\"#\",\" Séries\"]}]],\"BZDlVl\":[\"fléchisseurs de la hanche\"],\"BaG4Vp\":[\"Fréquent\"],\"BdnYlL\":[\"Durée moyenne\"],\"BpTc_M\":[\"Rechercher dans l'aide\"],\"Bqo02Q\":[\"Démarrer la minuterie\"],\"BrHgnn\":[\"\\n⏱️ Nouveau : Minuterie de repos ajustable !\\n\\nUn nouveau panneau coulissant te permet d'ajuster ta durée de repos à la volée pendant un entraînement. Ton temps de repos personnalisé est sauvegardé par série, donc chaque série se souvient exactement du temps de repos que tu préfères.\\n\"],\"BwTx3c\":[\"Tu es sûr de vouloir supprimer \",[\"0\"],\" ?\"],\"C4GKOD\":[[\"repRange\"],\" Rép., \"],\"CCTop_\":[\"Récent\"],\"CE-M2e\":[\"Infos\"],\"CV6Ez2\":[\"Appuie sur Se connecter avec Google dans les Paramètres pour connecter ton compte. La connexion active les sauvegardes cloud pour que tes données soient en sécurité si tu changes d'appareil ou réinstalles l'appli, et ton nom apparaît dans le message d'accueil. L'appli fonctionne entièrement hors ligne sans connexion, mais les sauvegardes cloud ne sont pas disponibles. Tes données sont stockées localement sur ton appareil et ne sont partagées avec personne, sauf si tu choisis de les partager toi-même.\"],\"CZKXmk\":[\"chevilles\"],\"CaKjcv\":[\"Entraînement rapide\"],\"CghlOu\":[\"abdominaux inférieurs\"],\"CiUwqB\":[\"Aller aux Entraînements\"],\"D0GOrZ\":[\"Tu dois te connecter pour utiliser cette fonctionnalité\"],\"D3h1sn\":[\"travail\"],\"D45Cr4\":[\"Sélectionner les muscles secondaires\"],\"D89zck\":[\"Dim\"],\"DBC3t5\":[\"Dimanche\"],\"DIS-zd\":[\"Impossible de supprimer le programme : \",[\"0\"]],\"DJMHhb\":[\"La dernière séance était une décharge. Comparaison ignorée.\"],\"DNhKLr\":[\"\\n🎯 Amélioré : Filtres d'exercices plus intelligents !\\n\\nQuand tu remplaces un exercice, le filtre présélectionne maintenant automatiquement le muscle cible correspondant. Seuls les filtres pertinents s'affichent en fonction de ta sélection, ce qui rend la recherche d'une alternative bien plus rapide.\\n\"],\"DPfwMq\":[\"Terminé\"],\"DTtUaj\":[\"Entre au moins une mesure à enregistrer.\"],\"DWFuyG\":[\"Supprimer l'exercice\"],\"DYOFso\":[\"stabilisateurs de la cheville\"],\"DdBQBl\":[\"Planning hebdomadaire\"],\"Dh5Ge5\":[\"Des douleurs ou des problèmes de forme ?\"],\"Di-cgt\":[\"Bienvenue dans MuscleQuest !\"],\"DqgDEk\":[\"Le plus récent de n'importe quel entraînement\"],\"Dvc8Qg\":[\"Description :\"],\"Dy8Cvh\":[\"quadriceps\"],\"Dy_8Fq\":[\"FERMER\"],\"E3kRqj\":[[\"uniqueWorkoutDaysCount\"],\" / \",[\"0\"],\" jours d'entraînement\"],\"EANWES\":[\"Impossible de charger l'historique\"],\"EMyNOr\":[[\"0\"],\" \",[\"1\"],\" (utilisé pour les exercices assistés)\"],\"E_QGRL\":[\"Désactivé\"],\"Ef7StM\":[\"Inconnu\"],\"EfdYnO\":[[\"0\"],[\"distanceUnit\"]],\"EkVHAp\":[\"Incrément de la minuterie de repos\"],\"EoQHhQ\":[\"tapis de course\"],\"Euo2Um\":[\"Temps (Min:Sec)\"],\"F37c1s\":[\"Ouvrir les Paramètres\"],\"F6pfE9\":[\"Actif\"],\"FCGpHg\":[\"Aucun exercice dans cet entraînement.\"],\"FHIDZO\":[\"Enregistrer et sélectionner\"],\"FPsvA8\":[\"Compris !\"],\"Fb5zs_\":[\"\\n⚖️ Nouveau : Enregistrer le poids pour les exercices au poids de corps !\\n\\nPour les exercices au poids de corps comme les tractions ou les dips, tu peux maintenant activer l'enregistrement du poids par entraînement. Parfait pour les variantes lestées, pour noter le poids ajouté et suivre ta progression dans le temps.\\n\"],\"Fe0wLe\":[\"Superseries\"],\"FnTClW\":[\"Tu atteins facilement les objectifs. Il est temps d'ajouter un peu plus de poids.\"],\"Fp1hl-\":[\"Chargement du programme...\"],\"FwCUad\":[\"L'équipement est obligatoire.\"],\"G-iXUH\":[\"épaules\"],\"G2R9Qq\":[\"fléchisseurs du poignet\"],\"G3myU-\":[\"Mardi\"],\"G49bAb\":[\"machine à levier\"],\"G6rTvo\":[\"Suivre (\",[\"0\"],\")\"],\"GCV1HM\":[\"Connecté en tant que \",[\"0\"]],\"GCqPY4\":[\"L'écran d'accueil affiche ta progression vers ton objectif d'entraînement hebdomadaire, qui correspond au nombre de jours par semaine où tu veux t'entraîner, défini dans les Paramètres. Une bande en haut indique le nombre de jours complétés et met en évidence chaque jour terminé. En dessous, les entraînements de ton programme actif sont listés avec leur statut d'avancement pour la semaine ; appuie sur Commencer sur n'importe quel entraînement pour le lancer. La carte affichée en dessous change selon ton statut : une carte Reprendre apparaît si une séance est en cours, une carte Jour de repos s'affiche les jours sans entraînement planifié, et une carte Entraînement terminé confirme que la séance du jour est complète. Quand tu atteins ton objectif hebdomadaire, une carte Résumé de la semaine apparaît avec le total d'entraînements, de séries et de volume pour la semaine, plus ta série consécutive, qui compte le nombre de semaines consécutives où tu as atteint ton objectif.\"],\"GGqR7k\":[\"Entraînements seuls et rapides\"],\"GLJjec\":[\"Jusqu'à l'échec\"],\"GLm0-9\":[\"Douleur ou problèmes de forme\"],\"GNurdZ\":[\"Supprimer l'exercice\"],\"GPeIuw\":[\"Distance\"],\"GS7yxz\":[\"Permission requise\"],\"GSOeV2\":[\"ischio-jambiers\"],\"GVN2lL\":[\"Créer un exercice\"],\"GWvJTL\":[\"À peu près bien\"],\"GX9tlq\":[\"cou\"],\"Gd-KuS\":[\"Gérer les mesures\"],\"Gf9sn6\":[\"Vérification des sauvegardes...\"],\"GhCGeL\":[\"Séries\"],\"GksdwI\":[\"Meilleures séries PR\"],\"HNWkJr\":[\"\\n📏 Nouveau : Suivi de distance pour les exercices personnalisés !\\n\\nLes exercices personnalisés peuvent maintenant utiliser un type de suivi par distance, parfait pour les mouvements cardio et de conditionnement comme les courses, les rameurs ou les poussées de traîneau. Note la distance de tes séries et suis ta progression comme pour n'importe quel autre exercice.\\n\"],\"HYL9fJ\":[\"Enregistrer un seul côté pour les exercices unilatéraux\"],\"Hp6ceF\":[\"Impossible de sauvegarder ton entraînement. Réessaie plus tard.\"],\"HpK_8d\":[\"Recharger\"],\"Hplwk7\":[\"Restauration en cours. Patiente...\"],\"I2Hpku\":[\"Enregistrer le poids\"],\"ICkQNB\":[\"Heure de rappel\"],\"IFowGw\":[\"corde\"],\"IHMx9j\":[\"Série de semaines\"],\"ILE1kp\":[\"bras\"],\"IRiG-a\":[\"Vibrer après le repos\"],\"IUwGEM\":[\"Enregistrer les modifications\"],\"IXxATP\":[\"Exercices personnalisés\"],\"IbbuFX\":[\"Suppression en cours. Veuillez patienter...\"],\"IuXB4Q\":[\"Ajouter une note...\"],\"Izf0kk\":[\"Pas de données de poids antérieures. On maintient pour l'instant.\"],\"JE-yVp\":[\"Gérer les mesures\"],\"JR5hAM\":[\"1 an\"],\"JTkSvz\":[\"Tu es sûr de vouloir supprimer cet entraînement ?\"],\"JVKmoO\":[\"La mise à jour n'a pas pu être téléchargée. Vérifie ta connexion internet et rouvre l'app pour réessayer.\"],\"JW7_2_\":[\"Téléchargement échoué\"],\"JWTR_A\":[\"Une erreur s'est produite lors du téléchargement des images.\"],\"JYRqp5\":[\"Sa\"],\"JbvV5d\":[\"Pendant une séance, glisse vers la gauche/droite ou utilise les boutons fléchés pour naviguer entre les séries. Entre ton poids et tes répétitions, puis appuie sur Terminer la série. Le temps écoulé total s'affiche en haut tout au long. Tu peux glisser la poignée d'une carte d'exercice pour réorganiser les exercices en cours de séance. Les exercices basés sur le temps ont un bouton Démarrer la minuterie qui ouvre un chronometre avec un anneau de progression indiquant quand tu atteins ton objectif, mais tu peux continuer aussi longtemps que tu veux. Les notes peuvent être ajoutées par exercice via l'icône de notes, par entraînement depuis l'écran de vue d'ensemble, ou par programme depuis l'écran de vue d'ensemble du programme. Si tu ajoutes, supprimes ou réorganises des exercices ou des séries pendant une séance, tu seras invité à la fin à sauvegarder ces modifications.\"],\"JfDOWo\":[\"La mise à jour est prête mais l'app n'a pas pu redémarrer automatiquement. Essaie d'appuyer sur le bouton ci-dessous, ou ferme et rouvre l'app manuellement.\"],\"JkpsKr\":[\"Téléchargement en cours. Veuillez patienter...\"],\"JmZ_-d\":[\"Terminer\"],\"JsIy35\":[\"Tu as activé ce programme.\"],\"JumwGu\":[\"cardio\"],\"Jv9TrU\":[\"obliques\"],\"KIL-9T\":[\"Suivant : \"],\"KKalG-\":[\"Épingle des exercices dans l'onglet Stats pour suivre leur progression de force dans le temps. Chaque exercice suivi affiche un graphique de tes performances sur la période sélectionnée, ton record personnel absolu, tes meilleures séries, et une liste des sessions récentes avec la meilleure série par jour. Les graphiques se mettent à jour automatiquement après chaque entraînement incluant cet exercice.\"],\"KM1Iw2\":[\"MuscleQuest\"],\"KSqQx0\":[\"Rép. max.\"],\"Km7tR4\":[\"Offre-moi un Café\"],\"KmiPdE\":[\"haltère\"],\"KxWSWU\":[\"Garder l'écran allumé pendant l'entraînement\"],\"LAC2eo\":[\"Rappels d'entraînement\"],\"LAHzG1\":[\"Voir/Modifier\"],\"LIrnc0\":[\"Aucun exercice ajouté\"],\"LZKayn\":[\"Rechercher dans l'aide…\"],\"LcPJBt\":[\"entraînements terminés\"],\"LhMjLm\":[\"Temps\"],\"LyPttd\":[\"Poitrine\"],\"M0GVkz\":[\"Sélectionne un jour pour voir les entraînements.\"],\"M1POMr\":[\"Bibliothèque d'exercices\"],\"M4hMaA\":[\"Entre un nom pour la mesure personnalisée.\"],\"M57U8X\":[\"Regroupe deux exercices en superserie pour qu'ils alternent automatiquement pendant une séance, idéal pour associer des muscles antagonistes ou rester efficace entre les séries. Appuie sur le menu trois points d'un exercice dans l'éditeur d'entraînement et choisis Créer une superserie, puis sélectionne le deuxième exercice. Un label de couleur identifie à quelle superserie appartient chaque exercice dans toute l'application. Quand tu termines une série sur un exercice, l'appli te déplace directement vers son partenaire de superserie.\"],\"MEt7-_\":[\"soléaire\"],\"MHk_Wu\":[\"Entrée introuvable.\"],\"MLQOxI\":[\"deltïödes postérieurs\"],\"MM-MTF\":[\"Superserie \",[\"0\"]],\"MQ9jL7\":[\"Plus qu'un entraînement pour atteindre ton objectif !\"],\"MQA2H9\":[\"Supprimer le programme\"],\"MTqmCb\":[\"Demander ou voter pour de nouvelles fonctionnalités\"],\"McFNQO\":[\"Suis ton parcours fitness avec des stats et des aperçus détaillés. Consulte l'historique de tes entraînements, analyse tes répartitions par partie du corps et visualise tes améliorations dans le temps avec des graphiques de progression des exercices.\"],\"MmDz7_\":[\"Envoi en cours. Patiente...\"],\"N4e_z1\":[\"Temps de repos : \",[\"restMinutes\"],\":\",[\"0\"]],\"N85c_3\":[\"Supprimer l'entraînement\"],\"NC2AI2\":[\"Longueur\"],\"NIuBdI\":[\"Programmes prêts à l'emploi\"],\"NKdWDE\":[\"système cardiovasculaire\"],\"NLBiJk\":[\"Saisir une entrée\"],\"NPG8SK\":[\"Poids du corps\"],\"NQJHen\":[\"Tu es sûr de vouloir recommencer cet entraînement ?\"],\"NVOqiK\":[\"Connecte-toi pour sécuriser tes données\"],\"NXoGPK\":[\"Modifier l'exercice\"],\"Ne5n-8\":[\"Ajouter des notes personnelles\"],\"NnRCUm\":[[\"0\"],\"s\"],\"Ns5WaC\":[\"Aucune sauvegarde trouvée\"],\"Nu4oKW\":[\"Description\"],\"O1GFNQ\":[\"Tous les muscles cibles\"],\"O2TAe0\":[\"barre\"],\"O2wCGL\":[\"Jouer les bips de compte à rebours (Minuterie d'exercice)\"],\"Otd3xX\":[\"Une semaine de décharge est une semaine de récupération planifiée où tu t'entraînes avec une intensité réduite pour permettre à ton corps de récupérer complètement avant le prochain bloc d'entraînement. Appuie sur Marquer comme semaine de décharge sur l'écran de vue d'ensemble du programme pour indiquer que la semaine en cours est une décharge. Pendant que la décharge est active, le questionnaire de feedback après exercice n'apparaît pas et aucun nouvel état de progression n'est créé ou mis à jour, de sorte que ton historique de suggestions n'est pas perturbé par les séances plus légères. La décharge se réinitialise automatiquement au début de la semaine suivante et le feedback normal ainsi que le suivi de progression reprennent sans aucune action manuelle. Si tu changes d'avis, appuie à nouveau sur le bouton pendant que la décharge est active pour l'annuler.\"],\"Ov8o8m\":[\"Démarrer le programme\"],\"OwNTSr\":[\"Enregistrer dans le programme\"],\"Owchfv\":[\"Récemment utilisé\"],\"OzAZw8\":[\"Cet écran n'existe pas.\"],\"P0mjNu\":[\"Supprimer l'entrée\"],\"P0svFp\":[\"Repos\"],\"P1svYv\":[\"abdominaux\"],\"P247ya\":[\"Partie du corps *\"],\"P3nVsi\":[\"\\n📅 Nouveau : Planning hebdomadaire pour ton programme !\\n\\nTu peux maintenant assigner des entraînements à des jours de la semaine spécifiques directement dans l'éditeur de programme. Appuie sur n'importe quel jour pour choisir un entraînement ou le marquer comme jour de repos. Utilise le bouton de suggestion automatique pour générer instantanément un planning équilibré basé sur ton objectif hebdomadaire.\\n\"],\"P3omNB\":[\"Sélectionne un entraînement\"],\"PBt59F\":[\"Exercices favoris\"],\"PFcCy0\":[\"x \",[\"0\"],\" rép. \"],\"PHWHEO\":[\"Tout accepter\"],\"PITZNx\":[\"poitrine\"],\"PN5Zzf\":[\"Unité de poids\"],\"PNapeY\":[\"+ Ajouter\"],\"POx12e\":[\"\\n↕️ Nouveau : Réorganiser les exercices dans la vue d'ensemble de l'entraînement !\\n\\nTu peux maintenant glisser-déposer les exercices et les superseries pour les réorganiser directement depuis la vue d'ensemble de l'entraînement pendant une séance.\\n\"],\"PSNHRi\":[\"* fonctionnalités en développement\"],\"P_0oX-\":[\"Assisté\"],\"PiK6Ld\":[\"Sam\"],\"PruBpO\":[\"Es-tu sûr de vouloir supprimer cette entrée de mesure ?\"],\"Q1Lq8I\":[\"Temps total\"],\"Q2QJ28\":[\"Jouer le son de l'objectif atteint (Minuterie d'exercice)\"],\"Q8bEQa\":[\"Une erreur s'est produite lors de la suppression des images.\"],\"Q9qAkA\":[\"Durée estimée : \",[\"0\"]],\"QENBWX\":[\"triceps\"],\"Qdwk82\":[\"Incrément de charge pour les haltères\"],\"Qjp-BQ\":[\"Ajouter une série\"],\"QlT4B5\":[\"Sessions récentes\"],\"Qmbwcr\":[\"Modifier le programme\"],\"QoHy-T\":[[\"weeks\",\"plural\",{\"one\":[\"il y a \",\"#\",\" semaine\"],\"other\":[\"il y a \",\"#\",\" semaines\"]}]],\"QrwEaQ\":[\"pectoraux\"],\"QzJCdZ\":[\"dorsaux\"],\"R-ABt9\":[\"Objectif hebdomadaire\"],\"R0gwbc\":[\"biceps\"],\"RCk1J0\":[\"machine à traîneau\"],\"RGfnXX\":[\"(jusqu'à l'échec)\"],\"RIHmRj\":[\"Bon rythme. Essaie d'ajouter une rep par série avant d'augmenter la charge.\"],\"RM5DG6\":[\"Exercices suivis\"],\"RN4XJV\":[\"Jour de repos\"],\"RU6ELr\":[\"Stats et historique\"],\"RXkbtG\":[\"Pousser plus fort la prochaine fois ?\"],\"RY_JyV\":[\"bas du dos\"],\"R_h8B2\":[\"Le plus utilisé\"],\"Rc-8oy\":[\"Téléchargement de la mise à jour\"],\"RmahBs\":[[\"0\"],\": \",[\"best\"],\"s (+\",[\"delta\"],\"s, \",[\"pctStr\"],\")\"],\"Rr5U7J\":[\"Les séries terminées apparaîtront ici\"],\"Rwc-xL\":[\"Record de temps\"],\"RxzN1M\":[\"Activé\"],\"S2uNE5\":[\"Continuer l'édition ?\"],\"SEyweA\":[\"\\n🐛 Correctif : Divers correctifs et améliorations !\\n\\nCorrection de la notification de minuterie de repos qui ne se déclenchait pas correctement, du retour à la ligne du nom de l'exercice pendant la séance, de la largeur du cercle de fin d'entraînement, des notes qui ne se mettaient pas à jour correctement pendant la saisie, et des détails d'entraînement qui s'ouvraient parfois dans le mauvais onglet. Les entraînements se chargent maintenant plus vite grâce à des améliorations de performances internes.\\n\"],\"SGISp8\":[\"Tu as tout fini à la limite. Reste là et prends-en possession.\"],\"SRhtpX\":[\"avant-bras\"],\"SUd4dA\":[\"\\n📏 Nouveau : Mesures corporelles !\\n\\nSuis ta composition corporelle en parallèle de tes entraînements depuis la nouvelle section Mesures de l'onglet Statistiques.\\n\\n• Enregistre poids, % de masse grasse, tour de taille, hanches, poitrine et plus\\n• Appuie sur une entrée passée pour modifier les valeurs ou consulter un graphique\\n• Gère les mesures affichées et ajoute tes propres mesures personnalisées\\n• Les unités suivent tes préférences de poids et de taille dans Paramètres\\n\"],\"SWtay1\":[\"Après avoir terminé la dernière série de travail d'un exercice, un questionnaire de feedback apparaît avec deux questions. La première demande comment l'effort s'est ressenti : Facile (tu aurais pu faire plus), À peu près bien, Difficile (proche de ta limite) ou Pas réussi à finir toutes les séries. La deuxième porte sur la douleur : Pas de douleur, Légère gêne ou Douleur ou problèmes de forme. Si tu réponds Facile, une troisième question apparaît pour savoir si tu veux te surpasser la prochaine fois. Cela te permet de maintenir délibérément la charge actuelle même quand une séance s'est sentie légère, de sorte que le système respecte ton intention. Si tu réponds Douleur, un champ de texte optionnel te permet de noter où tu l'as ressenti pour ta propre référence. Le questionnaire peut être fermé sans répondre si tu préfères ne pas enregistrer de feedback pour cet exercice lors de cette séance.\"],\"SZw9tS\":[\"Voir les détails\"],\"SadoC9\":[\"Smith machine\"],\"SbGW67\":[\" (jusqu'à l'échec) \"],\"ScJ9fj\":[\"Politique de confidentialité\"],\"SlfejT\":[\"Erreur\"],\"SmkA26\":[\"1RM \",[\"0\"],\" \",[\"unit\"]],\"SoWD_0\":[\"Enregistrer la série\"],\"SrVzRe\":[\"Pourcentage\"],\"St3y2e\":[\"Nom requis\"],\"SvOMfA\":[[\"0\"],\" entraînements\"],\"T0cOwV\":[\"Supprimer la série\"],\"T7QVyK\":[\"Quand tu ouvres un entraînement contenant des exercices que tu as pratiqués récemment, une feuille de Bilan de récupération apparaît si ces exercices ont une suggestion de progression en attente et que ta dernière séance remonte à au moins 12 heures. Pour chaque groupe musculaire concerné, tu choisis une de trois options : Frais (complètement récupéré), Légère courbature ou Encore très courbaturé. Si un muscle est marqué comme encore très courbaturé, toute suggestion de progression à la hausse pour les exercices ciblant ce muscle est mise en pause et maintenue à la charge actuelle jusqu'à ce que tu réévalues au début de la séance suivante. Frais ou Légère courbature ne modifie pas les suggestions. Appuie sur Passer pour l'instant pour contourner le bilan entièrement ; un bilan ignoré est traité comme une récupération complète, donc les suggestions en attente ne sont pas affectées.\"],\"TBTwj-\":[\"Suivre MuscleQuest sur Instagram\"],\"TJLDrx\":[\"Poids doublé pour le calcul du volume\"],\"T_qHwF\":[\"bas des jambes\"],\"Ta25TG\":[\"Aucun historique\"],\"TpqeIh\":[\"Erreur : \",[\"0\"]],\"Tz0i8g\":[\"Paramètres\"],\"TzLpDD\":[\"\\n🏋️ Nouveau : Entraînements autonomes et entraînements rapides !\\n\\nCrée des entraînements autonomes en dehors de tes programmes d'entraînement, parfaits pour les séances flexibles, le travail de mobilité ou tout ce qui se présente. Retrouve-les dans l'écran Programmes.\\n\\nOu démarre un Entraînement rapide depuis l'accueil, ajoute des exercices à la volée, et sauvegarde-le éventuellement comme entraînement autonome quand tu as terminé.\\n\"],\"U0HZma\":[\"Suivi\"],\"U4QKsL\":[\"Masquer / Afficher l'introduction\"],\"U8BTVm\":[\"Temps de repos restant :\"],\"UCtAiM\":[\"Pour activer les notifications de la minuterie de repos, autorise les notifications dans les paramètres de ton appareil.\"],\"UD8kHo\":[\"Suivant : \",[\"workoutName\"],\" le \",[\"0\"]],\"URmyfc\":[\"Détails\"],\"US8F_H\":[\"Plus de reps suggérées\"],\"USXXjt\":[\"Aucun résultat pour « \",[\"query\"],\" »\"],\"U_-GrY\":[\"Veuillez patienter pendant le téléchargement de la dernière version...\"],\"UlnAQR\":[\"Impossible de supprimer l'entraînement. Réessaie.\"],\"UneMBz\":[\"Programme actif\"],\"UnnFak\":[\"Super début de semaine !\"],\"Uorrgj\":[\"rhomboïdes\"],\"Uu14s5\":[[\"0\",\"plural\",{\"one\":[\"#\",\" série\"],\"other\":[\"#\",\" séries\"]}]],\"UyvU3-\":[\"Aide & infos\"],\"UzNvmf\":[\"• Sauvegarder et restaurer les données\"],\"V6wjuJ\":[\"Le type de suivi est obligatoire.\"],\"V6xf0O\":[\"Cet exercice est déjà dans ton entraînement. Choisis-en un autre.\"],\"V8MVAm\":[\"pectoraux supérieurs\"],\"V8dVu4\":[\"\\n🔗 Nouveau : Superseries !\\n\\nAssocie deux exercices en superserie directement dans l'éditeur de programme. Les séries sont synchronisées entre les deux exercices, et les superseries sont clairement regroupées avec un indicateur visuel dans toute l'application.\\n\"],\"V8yTm6\":[\"Effacer la recherche\"],\"VAcXNz\":[\"Mercredi\"],\"VCJb5r\":[\"Série \",[\"0\"],\" sur \",[\"totalSets\"]],\"VDkJml\":[\"La Progression adaptative analyse ton feedback d'effort sur des séances consécutives et suggère quand augmenter ton poids, tes reps ou tes séries. Active-la dans Paramètres, sous Progression adaptative. Une fois activée, une courte question de feedback apparaît après chaque exercice dans les entraînements basés sur un programme. Le système nécessite deux séances avec le même signal avant de recommander une augmentation, ce qui filtre les jours ponctuellement faciles et garantit une performance constante avant de suggérer une hausse. La douleur ou les séries non terminées sont prises en compte immédiatement, quelle que soit ton historique de séances. Une suggestion n'est jamais appliquée à ton entraînement sans ton accord explicite. Tu peux aussi configurer ton incrément de charge préféré par catégorie d'équipement dans la même section des Paramètres, par exemple 2,5 kg pour les exercices à la barre et 2,0 kg pour les haltères.\"],\"VFlRXJ\":[\"Maintenir comme ça cette séance.\"],\"VhVOxx\":[\"Ton voyage vers Swoletown commence aujourd'hui !\"],\"VhfZbD\":[\"Taille : ~100 Mo\"],\"W-pY1H\":[\"Impossible de sauvegarder l'exercice personnalisé. Réessaie.\"],\"W0qDyY\":[\"Écran d'accueil et objectif hebdomadaire\"],\"W3QcBP\":[\"Vue d'ensemble du programme\"],\"W3u9nh\":[\"Jusqu'à l'échec, \"],\"WDciil\":[\"\\n📋 Nouveau : Menu \\\"Plus\\\" et section Aide & infos !\\n\\nIl y a un nouvel onglet \\\"Plus\\\" dans la barre de navigation. Appuie dessus pour ouvrir un panneau coulissant où tu trouveras les Paramètres et une toute nouvelle section Aide & infos.\\n\\nLes Paramètres ont été déplacés ici depuis la barre d'onglets, et Aide & infos couvre tout, des programmes et entraînements aux stats et à ton compte, avec une barre de recherche pour trouver rapidement des réponses.\\n\"],\"WHwUfF\":[\"Erreur lors du chargement des détails de l'exercice\"],\"WIbOhZ\":[\"Progression adaptative\"],\"WJp2MH\":[\"Unité de taille\"],\"WKHqM-\":[\"Poids\"],\"WOi4Vm\":[\"Nom *\"],\"WSzg3A\":[\"Distance (\",[\"distanceUnit\"],\")\"],\"WU-3OC\":[\"Unilatéral bras / jambe\"],\"WaIjmh\":[\"Mollet (D)\"],\"WoEX6M\":[\"Suggérer des ajustements de charge et de reps\"],\"WzcO-J\":[\"Créer un programme\"],\"X9kySA\":[\"Favoris\"],\"X9r6cu\":[[\"goal\",\"plural\",{\"one\":[[\"completed\"],\" sur \",\"#\",\" entraînement cette semaine\"],\"other\":[[\"completed\"],\" sur \",\"#\",\" entraînements cette semaine\"]}]],\"XHHEUg\":[\"Personnaliser le programme\"],\"XJQdl_\":[\"Envoyer une notification en arrière-plan après le repos\"],\"XNRDYn\":[\"extenseurs du poignet\"],\"XdavYY\":[\"Entraînements\"],\"Xdcdfd\":[\"Séries et exercices\"],\"XoEooZ\":[\"Temps (s)\"],\"Xu14OQ\":[[\"0\",\"plural\",{\"one\":[\"#\",\" Rép.\"],\"other\":[\"#\",\" Rép.\"]}]],\"Xu2iGM\":[\"Ajouter du poids\"],\"Xv4OIW\":[\"Entraînement en cours\"],\"Xwd4Hm\":[\"coiffe des rotateurs\"],\"Y6QE0T\":[\"Sélectionner l'équipement\"],\"YANNVr\":[\"Entraînement\"],\"YDnEIW\":[\"Meilleur gain\"],\"YIix5Y\":[\"Rechercher...\"],\"YLIqcF\":[\"Bon retour\",[\"userName\"]],\"YXJbW8\":[\"Les entraînements indépendants sont en dehors des programmes et apparaissent avec tes programmes dans l'onglet Programmes. Crée-en un en appuyant sur Nouvel entraînement, donne-lui un nom et ajoute des exercices ; tu peux le lancer à tout moment sans avoir besoin d'un programme actif. Une durée estimée est affichée sur chaque entraînement indépendant pour que tu puisses planifier ton temps avant de commencer. Les entraînements rapides te permettent de démarrer une séance immédiatement depuis l'écran d'accueil : appuie sur Entraînement rapide, ajoute des exercices au fur et à mesure, et à la fin tu peux le sauvegarder comme entraînement indépendant pour une utilisation future ou simplement l'ignorer. Comme les programmes, l'éditeur d'entraînement sauvegarde automatiquement un brouillon.\"],\"YYzBv9\":[\"Lu\"],\"YekWWq\":[[\"0\",\"plural\",{\"one\":[\"#\",\" rép.\"],\"other\":[\"#\",\" rép.\"]}]],\"YiPU_R\":[\"deltïödes\"],\"YnHdfF\":[\"Série \",[\"0\"]],\"Yr-t8O\":[\"pieds\"],\"YuP-pS\":[\"« \",[\"label\"],\" » sera masqué du formulaire de saisie. Tes données historiques sont conservées.\"],\"Z3FXyt\":[\"Chargement...\"],\"Z8RW4m\":[\"Après avoir terminé un entraînement, l'écran de Résumé d'entraînement affiche une carte Prochaine séance listant des suggestions concrètes pour tes exercices. Chaque ligne indique le nom de l'exercice, le changement proposé (un nouveau poids cible, une plage de reps plus large ou une note pour réduire la charge) et une brève explication du pourquoi du changement suggéré. Appuie sur Accepter pour appliquer la suggestion à cet exercice pour ta prochaine séance, ou sur Ignorer pour la rejeter. Les suggestions acceptées sont pré-remplies dans les champs de poids et de reps la prochaine fois que tu ouvres cet entraînement, pour que tu commences la séance en visant déjà la bonne charge. Le bouton Tout accepter en haut applique toutes les suggestions en une fois. Les suggestions qui recommandent de maintenir la charge actuelle n'apparaissent pas dans la carte, car aucune action n'est nécessaire pour celles-là.\"],\"ZAWGCX\":[[\"0\"],\" secondes\"],\"ZAvcCf\":[[\"0\"],[\"weightUnit\"],\" × \",[\"1\"]],\"ZI8idP\":[\"Frais, complètement récupéré\"],\"Zm9Eu3\":[\"Taille des boutons pendant l'entraînement\"],\"Zvc_N1\":[\"1RM (\",[\"weightUnitLabel\"],\")\"],\"_-nVtu\":[\"C'était facile. On maintient pour l'instant et on confirme à la prochaine séance.\"],\"_2fO4v\":[\"Résumé de l'entraînement\"],\"_D5y8a\":[\"Séries par défaut\"],\"_K9jUO\":[\"ergomètre du haut du corps\"],\"_P2B4j\":[[\"biggestGainLabel\"],\" 1RM\"],\"_RhvUo\":[\"paramètres\"],\"_UGS0C\":[\"Nom de l'entraînement\"],\"_W-KPJ\":[\"Aucune mesure pour l'instant. Appuie pour enregistrer ta première entrée.\"],\"_WRCmH\":[[\"0\"],\" \",[\"1\"],\" | \",[\"2\"],\" Rép.\"],\"_XczSN\":[\"Sélectionner le muscle cible\"],\"_Xvx5t\":[\"\\n📈 Nouveau : Progression adaptative !\\n\\nMuscleQuest peut maintenant te suggérer quand augmenter ton poids ou tes reps selon ce que tu ressens pendant tes séances. Après chaque exercice, réponds à deux questions rapides sur l'effort et la douleur. Dès que tu as signalé le même résultat deux séances de suite, l'app suggère un changement. Toutes les suggestions apparaissent sur l'écran de Résumé d'entraînement, où tu peux accepter ou rejeter chacune individuellement. Les suggestions acceptées sont pré-remplies dans ta prochaine séance automatiquement.\\n\\nUn Bilan de récupération au début de ton prochain entraînement te permet de prendre en compte les courbatures avant d'appliquer une suggestion. Tu peux aussi marquer une semaine entière comme semaine de décharge depuis la vue d'ensemble du programme, ce qui met en pause le feedback et le suivi de progression pour cette semaine.\\n\\nActive-le dans Paramètres, sous Progression adaptative, et configure ton incrément de charge préféré par catégorie d'équipement.\\n\"],\"_cF7Rs\":[\"Volume\"],\"_f5DAr\":[\"Terminé le : \",[\"formattedDate\"]],\"a2Fu8q\":[\"Tu peux te connecter à tout moment depuis l'écran Paramètres, si tu choisis de passer pour l'instant.\"],\"a5BPTT\":[\"kettlebell\"],\"a8TA11\":[\"Prochaine séance\"],\"aAIQg2\":[\"Apparence\"],\"aMwZcE\":[\"Bras (G)\"],\"aN_GPe\":[\"Où tu l'as ressenti ?\"],\"ahW3x6\":[\"\\n📅 Nouveau : Calendrier d'entraînement !\\n\\nAppuie sur l'icône de calendrier dans la section Historique des entraînements de l'onglet Stats pour consulter ton historique par date. Les jours avec des entraînements sont mis en évidence, et appuyer sur un jour affiche les séances enregistrées ce jour-là.\\n\"],\"aj6ZJx\":[\"Connexion avec Google\"],\"b3e7Re\":[\"Redémarrer l'appli\"],\"b9OAHS\":[\"Ajouter un échauffement\"],\"bFeIdj\":[\"Série dégressive\"],\"bQdjFX\":[[\"0\"],\" note\"],\"bRAv_4\":[\"Entraînement \",[\"0\"]],\"bZS72M\":[[\"setsCount\",\"plural\",{\"one\":[\"#\",\" série\"],\"other\":[\"#\",\" séries\"]}]],\"bosqpS\":[\"Aucun entraînement terminé. Lance ton premier entraînement !\"],\"bqb_ci\":[\"\\n🐛 Correctif : Boutons de séance et modal de modification de série !\\n\\nCorrection d'un bug où tous les boutons (incrémenter/décrémenter, série suivante/précédente, terminer la série) cessaient de fonctionner après avoir terminé une série. Correction aussi d'une erreur dans le modal de modification de série. Les transitions de série se font maintenant instantanément pour un entraînement plus fluide.\\n\"],\"bwd2oE\":[\"Minuterie de repos terminée !\"],\"bzSI52\":[\"Abandonner\"],\"c2TGz5\":[[\"completed\"],\" entraînements cette semaine. Tu as explosé ton objectif !\"],\"cCbON-\":[\"\\n🔥 Amélioré : Gestion des séries d'échauffement !\\n\\nLes séries d'échauffement sont visuellement regroupées et stylisées séparément des séries de travail, et \\\"Appliquer à tous\\\" te permet de modifier en masse les séries d'échauffement ou de travail indépendamment.\\n\"],\"cF5b-5\":[[\"weeklyGoal\",\"plural\",{\"one\":[\"Suggestion auto (\",\"#\",\" jour)\"],\"other\":[\"Suggestion auto (\",\"#\",\" jours)\"]}]],\"cI6f7l\":[\"30 j\"],\"cU45Co\":[\"Ajouter un entraînement\"],\"cUD6H0\":[\"Prépare-toi...\"],\"cUY9dI\":[\"Tu es sûr de vouloir supprimer cet exercice ?\"],\"ckJ-os\":[\"Muscles\"],\"cnGeoo\":[\"Supprimer\"],\"crwali\":[\"Rappels\"],\"ctrAML\":[\"N'oublie pas de suivre ta progression !\"],\"cyR8-W\":[\"\\n🕐 Nouveau : Estimation de la durée d'entraînement !\\n\\nChaque carte d'entraînement affiche maintenant une durée estimée pour que tu puisses planifier tes séances d'un coup d'œil avant de commencer.\\n\"],\"d1z1ZY\":[\"La minuterie de repos démarre automatiquement après chaque série et compte à rebours jusqu'à zéro. Chaque série mémorise sa propre durée de repos, donc différentes séries au sein du même exercice peuvent avoir des durées de repos différentes. Utilise les boutons ± pour ajuster le temps restant à la volée pendant le repos. Configure la durée de repos par défaut, l'incrément de la minuterie, et si un son, une vibration ou une notification en arrière-plan se déclenche à la fin ; chaque option peut être activée/désactivée indépendamment dans les Paramètres.\"],\"dEgA5A\":[\"Annuler\"],\"dH9Y4t\":[\"Aucun entraînement ce jour-là.\"],\"dVK-Er\":[\"Une erreur d'affichage s'est produite. Appuie sur le bouton pour recharger.\"],\"dXCD6-\":[\"Télécharger toutes les animations d'exercices\"],\"dXoieq\":[\"Résumé\"],\"dYOPCE\":[\"Assisté \",[\"0\"],\" \",[\"1\"],\" | Résistance \",[\"2\"],\" \",[\"3\"],\" | \",[\"4\"],\" Rép.\"],\"dbWo0h\":[\"Se connecter avec Google\"],\"deoJBi\":[[\"0\"],\" rép.\"],\"dfunKV\":[\"Poids/Rép.\"],\"dpOqdQ\":[\"Jusqu'à l'échec\"],\"dqjuBA\":[\"90 j\"],\"dx0cCC\":[\"Garde le rythme !\"],\"e0dGJ7\":[\"Avantages de la connexion :\"],\"e0l-Z0\":[[\"scheduledDays\",\"plural\",{\"one\":[\"#\",\" jour/sem.\"],\"other\":[\"#\",\" jours/sem.\"]}]],\"e5h2IT\":[[\"0\"],\" notes\"],\"e9qdcV\":[\"Légère gêne\"],\"eLA0I2\":[\"Télécharger les images\"],\"eQm4BH\":[\"Après avoir terminé un entraînement, un écran récapitulatif affiche ta durée totale, les séries terminées et le volume total. Si tu as déjà effectué le même entraînement, une ligne de comparaison indique comment chaque indicateur se compare à la session précédente. Une bannière d'objectif hebdomadaire montre combien de séances tu as enregistrées cette semaine par rapport à ton objectif. Appuie sur n'importe quel exercice dans la liste pour le développer et consulter chaque série en détail. Lors d'un Entraînement rapide, tu seras invité à le sauvegarder comme entraînement autonome pour une utilisation future ou à le supprimer.\"],\"eYbd7b\":[\"Di\"],\"ecUA8p\":[\"Aujourd'hui\"],\"ehOkF-\":[\"Bases\"],\"emOtYn\":[\"Programmes prêts à l'emploi\"],\"ez-cQL\":[\"\\n🔔 Nouveau : Notifications de rappel d'entraînement !\\n\\nNe rate plus jamais une séance. Configure des rappels pour tes entraînements directement depuis l'application. Choisis les jours où tu veux être rappelé et une heure pour commencer.\\n\"],\"f2yjAZ\":[\"Pas de douleur\"],\"f7pPKh\":[\"Cuisse (G)\"],\"f8Vl8d\":[\"Nom de la mesure\"],\"fFHHFp\":[\"Mesures\"],\"fPpo2L\":[\"Superserie\"],\"fSu2Jl\":[\"Une nouvelle version a été téléchargée. Appuie sur le bouton ci-dessous pour redémarrer et appliquer la mise à jour.\"],\"fXVIZq\":[\"Valeurs\"],\"f_bxrN\":[\"Le nom est obligatoire.\"],\"feWdkU\":[\"Recommencer l'entraînement\"],\"fj5byd\":[\"N/A\"],\"fpMgHS\":[\"Lun\"],\"fqSfXY\":[\"Remplacer\"],\"fsJAR5\":[\"Incrément de charge pour la barre\"],\"ftiGCv\":[\"Tout l'équipement\"],\"fvyzOr\":[\"haut du dos\"],\"g36TSx\":[\"Unité de distance\"],\"g3UF2V\":[\"Accepter\"],\"gCVtjC\":[[\"0\"],\" Séries\"],\"gEOgEq\":[[\"0\"],\" Exercices\",[\"1\"]],\"gQYPDg\":[\"−\",[\"restTimerIncrement\"],\"s\"],\"gTdjGc\":[\"Impossible de supprimer l'entraînement. Réessaie.\"],\"giOl9F\":[\"Cuisse (D)\"],\"gkn1WJ\":[\"Exercice déjà ajouté\"],\"gzBfh2\":[\"Aucune série disponible\"],\"h-DKuf\":[\"vs. dernier « \",[\"0\"],\" »\"],\"h2ALJf\":[\"fessiers\"],\"h7CU4q\":[\"Comment tu t'es senti ?\"],\"hBjQ0O\":[[\"0\",\"plural\",{\"one\":[\"#\",\" entraînement\"],\"other\":[\"#\",\" entraînements\"]}]],\"hF_t4W\":[\"Volume (\",[\"volumeUnit\"],\")\"],\"hLONcx\":[\"Sauvegarder et restaurer\"],\"hPXEuO\":[\"En paire avec \",[\"0\"]],\"hXzOVo\":[\"Suivant\"],\"hnJ2UC\":[\"brachial\"],\"hnlGzG\":[\"Passer pour l'instant\"],\"hnrFBk\":[\"Jours de rappel\"],\"hpsdvR\":[\"\\n📋 Nouveau : Voir les détails d'un entraînement depuis l'accueil !\\n\\nTu peux maintenant appuyer sur n'importe quel entraînement récent depuis l'accueil pour voir ses détails complets. Chaque entraînement et vue d'ensemble des séries dispose aussi d'un nouveau bouton de détails pour accéder rapidement aux informations sur les exercices.\\n\"],\"hsoeHo\":[\"Détails de l'entraînement\"],\"hty0d5\":[\"Lundi\"],\"hvfche\":[[\"scheduledCount\",\"plural\",{\"one\":[\"#\",\" jour/sem.\"],\"other\":[\"#\",\" jours/sem.\"]}]],\"i-tNaY\":[\"Assistance/Rép.\"],\"i09UfG\":[\"Équipement :\"],\"i0qMbr\":[\"Accueil\"],\"i4Vk1Q\":[\"Exercices du programme actif\"],\"i6f8rt\":[\"Démarrage de l'entraînement...\"],\"iGokZG\":[\"Incrément de charge pour la poulie\"],\"iHmyze\":[\"Exercices\"],\"iQyKX1\":[\"Tu as choisi de maintenir. La charge reste comme ça.\"],\"iV1Jat\":[\"Tu es sûr de vouloir supprimer cette série ?\"],\"iYfCFU\":[\"Afficher l'accueil sur l'écran principal\"],\"i_48Se\":[\"Programme actif : \",[\"0\"]],\"i_nB8P\":[\"Aucun planning défini\"],\"ifRQL2\":[\"Série dégressive, \"],\"ikOJPT\":[\"tibias\"],\"irLwtB\":[\"Programme d'entraînement\"],\"irrqfe\":[\"Mesures personnalisées\"],\"iuwbqi\":[\"Impossible de sauvegarder l'entraînement. Réessaie.\"],\"ivpCYv\":[\"Abandonner les modifications ?\"],\"j-MPXl\":[\"Sauvegarde et restauration\"],\"jDTG0T\":[\"Suggestions de progression\"],\"jDh_CH\":[\"Les programmes sont des plans d'entraînement structurés composés de séances. Pour en créer un, va dans l'onglet Programmes, appuie sur Nouveau programme, donne-lui un nom et choisis une image de couverture. Ajoute des entraînements au programme, puis ajoute des exercices à chaque entraînement avec des séries et répétitions cibles. Utilise les boutons fléchés haut/bas d'une carte d'entraînement pour la réorganiser, ou le bouton X pour la supprimer ; les deux se trouvent en haut à droite de la carte. Assigne des entraînements à des jours spécifiques de la semaine dans l'éditeur de planning : appuie sur un jour pour choisir un entraînement ou le laisser comme jour de repos, et utilise le bouton de suggestion automatique pour les espacer régulièrement. Une fois ton programme prêt, ouvre-le et appuie sur Activer. Tu peux aussi ajouter des notes depuis l'écran de vue d'ensemble du programme. Chaque carte d'entraînement affiche une durée estimée avec le nombre d'exercices pour que tu puisses évaluer la longueur d'une séance d'un coup d'œil. Utilise les icônes de vue à côté du titre « Tes plans d'entraînement » pour basculer entre les affichages Carrousel, Liste et Grille ; ton affichage préféré est sauvegardé automatiquement. Ta progression dans l'éditeur est automatiquement sauvegardée comme brouillon, donc si tu le quittes en cours d'édition, tu seras invité à reprendre là où tu en étais ou à ignorer et repartir du dernier état sauvegardé.\"],\"jYjrmQ\":[\"Dernière sauvegarde : \",[\"0\"]],\"jfzZZ0\":[\"Ignorer la connexion\"],\"jpVuia\":[\"Enregistrer les modifications de l'entraînement ?\"],\"jxTU3u\":[\"machine Stepmill\"],\"jzJENZ\":[\"Suis ta progression\"],\"k4kpgL\":[\"Bienvenue dans MuscleQuest, ton compagnon de musculation personnel. Utilise ce guide pour découvrir les fonctionnalités et tirer le meilleur de ton entraînement.\"],\"k7Oi68\":[\"haut des jambes\"],\"kDJ_Ja\":[\"Bonne séance. Garder cette charge.\"],\"kFoQmI\":[\"abducteurs\"],\"kILzHz\":[\"Ajouter (\",[\"0\"],\")\"],\"kQe_xM\":[\"Douleur signalée. La charge reste inchangée jusqu'à ce que tu ailles mieux.\"],\"kSi1ha\":[\"+\",[\"suggestedWeight\"],[\"unit\"],\" suggéré\"],\"kdwbaT\":[\"Tout ignorer\"],\"kf4tdd\":[\"Sélectionner le type de suivi\"],\"kfxr8q\":[\"\\n📊 Nouveau : Résumé d'entraînement !\\n\\nAprès avoir terminé un entraînement, tu verras maintenant un résumé complet de ta séance : durée totale, séries et volume, plus une comparaison avec ta séance précédente. Appuie sur n'importe quel exercice pour afficher ses séries et poids individuels.\\n\"],\"kg0oKA\":[\" (jusqu'à l'échec)\"],\"kkDQ8m\":[\"Jeudi\"],\"konUZ1\":[\"Temps de repos par défaut\"],\"kvpjYu\":[\"Entrer le nom de l'exercice\"],\"l1P93s\":[\"Saisir le poids par haltère/câble, pas le total\"],\"l75CjT\":[\"Oui\"],\"lWy5a1\":[\"Programmes\"],\"lY9GM0\":[\"Le muscle cible est obligatoire.\"],\"lkz6PL\":[\"Durée\"],\"llGZy3\":[\"Aucun exercice suivi. Appuie sur + Ajouter pour commencer.\"],\"loRbvf\":[\"Aller à l'écran d'accueil !\"],\"m0YANP\":[\"Tu peux masquer cet écran d'accueil à tout moment depuis la page Paramètres dans la section Apparence. Si tu veux le revoir, tu peux le réactiver depuis la même page.\"],\"m16xKo\":[\"Ajouter\"],\"mAoTHw\":[\"Certaines images n'ont pas pu être supprimées. IDs des exercices en échec : \",[\"0\"]],\"mDmPnX\":[\"Par semaine (moy.)\"],\"mEQ95z\":[\"Impossible de sauvegarder l'image. Réessaie.\"],\"mF1US0\":[\"Toujours utiliser l'historique le plus récent\"],\"mFQ4KK\":[\"Doubler le poids pour le volume quand le paramètre est activé\"],\"mK5j7_\":[\"\\n🔃 Nouveau : Trie la bibliothèque d'exercices !\\n\\nLa bibliothèque d'exercices a maintenant des chips de tri pour trouver les exercices plus vite. Trie par Par défaut, Programme actif, Récent ou Fréquent pour voir les exercices les plus pertinents pour toi en haut.\\n\"],\"mRTnNi\":[\"Implements appariés\"],\"mSit7t\":[\"Impossible de récupérer les données. Réessaie.\"],\"mSj_dN\":[[\"0\",\"plural\",{\"one\":[\"+\",\"#\",\" de plus\"],\"other\":[\"+\",\"#\",\" de plus\"]}]],\"mT57-Q\":[\"Aller aux Paramètres\"],\"mob_am\":[\"Ve\"],\"mwX_w0\":[\"Changer l'image\"],\"mzI_c-\":[\"Télécharger\"],\"n00ykB\":[\"Tes entraînements\"],\"n1BXGc\":[\"Répartition d'entraînement (par séries)\"],\"nAEGxm\":[\"Oui, augmenter le défi\"],\"nJSX83\":[\"Rappels d'entraînement\"],\"nO6sra\":[[\"0\"],\": \",[\"best\"],\" \",[\"best\",\"plural\",{\"one\":[\"rép.\"],\"other\":[\"rép.\"]}],\" (+\",[\"delta\"],\", \",[\"pctStr\"],\")\"],\"nPGn3W\":[\"Échauffement, \"],\"nkkWxK\":[\"Lance ton parcours fitness avec des programmes conçus par des professionnels. Choisis parmi une variété d'options adaptées à différents objectifs et niveaux. \"],\"nmdLhD\":[\"Rép. : \",[\"repRange\"]],\"o2XlZw\":[\"Tu es sûr de vouloir supprimer cet entraînement ? Cette action est irréversible.\"],\"oB9lvM\":[\"Exclure les séries d'échauffement des stats\"],\"oOHOWH\":[\"\\n✨ Nouveau : Animations de séance !\\n\\nLa navigation entre les séries propose maintenant des transitions glissantes. Glisse vers la gauche ou la droite pour passer d'une série à l'autre, ou utilise les boutons fléchés existants pour le même effet.\\n\"],\"oOYj_W\":[\"Impossible de charger les entraînements\"],\"oRTTfk\":[\"L'onglet Stats affiche le nombre total d'entraînements, le volume total, le temps total et la durée moyenne des séances sur une période sélectionnable, avec un delta par rapport à la période précédente pour chaque indicateur. Des graphiques affichent le volume hebdomadaire et ta répartition d'entraînement par partie du corps. Parcours l'historique complet de tes entraînements et appuie sur une séance pour revoir chaque série en détail. Tu peux modifier ou supprimer des entraînements terminés depuis l'écran de détails. Appuie sur l'icône calendrier dans la section Historique pour ouvrir une vue calendrier : les jours avec des entraînements sont mis en évidence avec un cercle jaune.\"],\"oRvy2V\":[\"Suivi des exercices\"],\"oXsjxN\":[\"Mollet (G)\"],\"oYZpj8\":[\"• Défis et badges *\"],\"ocEDZS\":[\"Supprimer une série\"],\"oeF-HP\":[\"Impossible de se connecter. Réessaie.\"],\"oeeBm6\":[\"\\n🔔 Nouveau : Notifications de mise à jour dans l'application !\\n\\nUn nouveau modal de mise à jour s'affiche maintenant quand une mise à jour est disponible, pour que tu saches toujours quand des améliorations ont été téléchargées et sont prêtes à être appliquées.\\n\"],\"ofVE0I\":[\"Efface le champ de recherche\"],\"oiHVLP\":[\"Supprimer la superserie\"],\"oqKRAn\":[\"Chaque série peut être marquée comme Échauffement, Série dégressive, Jusqu'à l'échec, ou toute combinaison de ces options. Le badge affiché à côté d'une série indique son type actuel. Pour changer le type pendant une séance, appuie sur le menu (⋮) et active ou désactive l'option correspondante. Lors de la création d'un programme, utilise les cases à cocher dans l'éditeur de séries ; appuie sur Ajouter un échauffement pour insérer une série d'échauffement dédiée en haut de la liste. Les séries d'échauffement sont visuellement regroupées et séparées des séries de travail, et l'option Appliquer à tous dans le modal de modification n'affecte que les séries du même type. Les séries d'échauffement peuvent être exclues des calculs de volume et de stats dans les Paramètres.\"],\"oqUOKk\":[\"Série dégressive\"],\"osILGh\":[\"Distance cible (\",[\"distanceUnit\"],\")\"],\"ovBPCi\":[\"Par défaut\"],\"ovGl86\":[\"(jusqu'à l'échec) \"],\"p5nYkr\":[\"Tout afficher\"],\"p72uBF\":[\"Aucun programme trouvé\"],\"p8F9k_\":[\"Cou\"],\"pBGx0B\":[\"\\n🗂️ Nouveau : Options d'affichage des plans !\\n\\nL'écran Programmes dispose maintenant de trois modes d'affichage. Utilise les icônes à côté du titre « Tes plans d'entraînement » pour basculer entre les vues Carrousel, Liste et Grille. Ton affichage préféré est sauvegardé automatiquement.\\n\"],\"pE7tOx\":[\"Entraînement actif\"],\"pIX6X7\":[\"Instagram de MuscleQuest\"],\"pIuJtP\":[\"Entraînement introuvable.\"],\"pY_gY7\":[\"Record de rép.\"],\"p_C-3G\":[\"Légère courbature\"],\"pbzA-s\":[\"Description facultative\"],\"pfXEaj\":[\"Poids corporel\"],\"pkD36F\":[\"Tu es sûr de vouloir supprimer \\\"\",[\"0\"],\"\\\" ?\"],\"poLmqL\":[\"Choisir depuis l'appareil\"],\"psxXnW\":[\"Connecte-toi avec Google dans les Paramètres pour activer les sauvegardes cloud de toutes tes données d'entraînement. Appuie sur Sauvegarder à tout moment pour créer un instantané ; la date de ta dernière sauvegarde s'affiche sous le bouton. Appuie sur Restaurer pour télécharger et appliquer ta dernière sauvegarde ; confirme l'invite et l'appli se rechargera avec tes données restaurées. Tes sauvegardes sont stockées en sécurité et liées à ton compte Google. Si tu changes d'appareil ou réinstalles l'appli, connecte-toi avec le même compte Google et appuie sur Restaurer pour récupérer tes données.\"],\"pvW0MQ\":[\"Terminer la série\"],\"pwfNCc\":[\"+\",[\"restTimerIncrement\"],\"s\"],\"pz0gzh\":[\"Masquer la mesure\"],\"pzA-xG\":[\"Note des repères importants, des rappels et des insights personnels pour tes exercices, entraînements et programmes. Reste concentré et améliore ta technique avec des notes personnalisées tout au long de ton parcours. Les notes s'enregistrent automatiquement quand tu as terminé de modifier.\"],\"q3pTrs\":[\"Toutes les images supprimées avec succès !\"],\"qIATCE\":[\"\\n📋 Amélioré : Pré-remplissage plus intelligent de l'historique pendant l'entraînement !\\n\\nLes champs de séries se pré-remplissent maintenant de façon plus intelligente. Si un exercice n'a pas d'historique dans l'entraînement en cours, l'app utilise automatiquement la dernière fois que tu l'as effectué dans n'importe quelle séance, pour toujours avoir une référence utile.\\n\\nUn nouveau paramètre dans la section Entraînement te permet d'utiliser toujours l'historique le plus récent de tous tes entraînements, quelle que soit la routine d'origine.\\n\"],\"qJb6G2\":[\"Réessayer\"],\"qQ5ALI\":[\"Enregistrer les modifications du programme ?\"],\"qQ8Xkc\":[\"Incrément de charge pour les machines\"],\"qQLn75\":[\"Sélectionner la partie du corps\"],\"qUSLnH\":[\"Entrer une description\"],\"qZMNNX\":[\"Bras (D)\"],\"qaT7mT\":[\"Tu vas perdre ce que tu as saisi jusqu'à présent.\"],\"qdalvN\":[\"Semaine de décharge active. Comparaison en pause.\"],\"qeygIa\":[\"Me\"],\"qlKdB2\":[\"Non, garder comme ça\"],\"qtNMEu\":[\"quadriceps\"],\"qvcKXF\":[\"Bon travail aujourd'hui !\"],\"qvolLq\":[\"Masse\"],\"rCROTr\":[\"Offre-moi un café\"],\"rLgPvm\":[\"Sauvegarde\"],\"rPj8yN\":[\"Autres exercices\"],\"rZzMre\":[\"haut des bras\"],\"rickIy\":[\"Enregistrement de l'entraînement...\"],\"rlNJuG\":[\"Détail de l'entrée\"],\"rtypiF\":[\"🎉 Nouveautés\"],\"rzjsxH\":[\"Temps (Minutes:Secondes)\"],\"s53UX_\":[\"Volume par semaine (\",[\"volumeUnit\"],\")\"],\"s6qW4K\":[\"Le type de suivi ne peut pas être modifié après la création.\"],\"sAkBSh\":[[\"0\",\"plural\",{\"one\":[\"#\",\" exercice\"],\"other\":[\"#\",\" exercices\"]}]],\"sHe-bW\":[\"Donne-lui un nom pour le sauvegarder comme entraînement réutilisable.\"],\"sRh2_9\":[\"Tes programmes\"],\"sey42b\":[\"Entraînement terminé !\"],\"slcKOz\":[\"Pour activer les rappels d'entraînement, autorise les notifications dans les paramètres de ton appareil.\"],\"spvawa\":[\"Exclure les entraînements de décharge des stats d'exercices\"],\"t-VWgS\":[\"Entraînements par semaine\"],\"t1WtPm\":[\"vs PR\"],\"t7OD9_\":[\"trapèzes\"],\"t9rBTs\":[[\"0\"],\": \",[\"best\"],[\"unit\"],\" (+\",[\"delta\"],[\"unit\"],\", \",[\"pctStr\"],\")\"],\"tCHU1b\":[\"Parties du corps\"],\"tLdxsV\":[\"MuscleQuest.app\"],\"tXkhj_\":[\"Commencer\"],\"t_YqKh\":[\"Supprimer\"],\"tcZ16z\":[\"\\n💾 Nouveau : Sauvegarde des modifications d'entraînement dans ton programme !\\n\\nQuand tu termines une séance où tu as ajouté, supprimé ou réorganisé des exercices ou des séries, tu seras invité à sauvegarder ces modifications dans le programme original ou l'entraînement autonome, pour garder ton entraînement à jour automatiquement.\\n\"],\"tfDRzk\":[\"Enregistrer\"],\"tj-hng\":[\"poignets\"],\"tlcz2i\":[\"Aucune donnée pour cette période.\"],\"twA2hZ\":[\"jambes\"],\"tyb5gZ\":[\"Temps de repos (Minutes:Secondes)\"],\"u0F1Ey\":[\"Je\"],\"u0Vng2\":[\"Encore très courbaturé\"],\"u16ECS\":[\"Téléchargement terminé\"],\"uGkCJQ\":[\"barre EZ\"],\"uIVkKI\":[\"Connexion\"],\"uP80lb\":[\"Mise à jour prête\"],\"ue_JxE\":[\"Vue d'ensemble des séries\"],\"ufHAsd\":[\"Nom du programme\"],\"uyJsf6\":[\"À propos\"],\"v2e7py\":[\"Créer un programme\"],\"v39wLo\":[\"Reprendre\"],\"v67n_r\":[\"Active des rappels d'entraînement récurrents depuis les Paramètres. Sélectionne les jours de la semaine pour lesquels tu veux être rappelé en utilisant les pastilles de jours et choisis une heure. Tu recevras une notification à cette heure chaque jour sélectionné. La permission pour les notifications doit être accordée pour que les rappels fonctionnent.\"],\"vCrBBg\":[\"Prends le contrôle total de ton entraînement en concevant ton propre programme personnalisé. Sélectionne des exercices, définis des plages de répétitions, des temps de repos, et plus encore pour créer un programme parfaitement adapté à tes objectifs.\"],\"vFte8a\":[\"Créer une superserie\"],\"vLSd93\":[\"Types de séries\"],\"vLyv1R\":[\"Masquer\"],\"vPWLpz\":[\"Unités de mesure\"],\"vV1rrV\":[[\"suggestedRepsMin\"],\" reps suggérées\"],\"vbOlQu\":[\"Impossible de sélectionner une image. Réessaie.\"],\"vbfDgJ\":[\"Aucun entraînement\"],\"vcpc5o\":[\"Fermer le menu\"],\"vmatEA\":[\"Chargement des données, veuillez patienter...\"],\"vq2WxD\":[\"Mar\"],\"vqV9pV\":[\"Nouveau programme\"],\"vyQFtJ\":[[\"0\"],\" terminé !\"],\"w55mIe\":[\"programme actif\"],\"w95UZr\":[\"record \",[\"maxDist\"],[\"distanceUnit\"]],\"wBAK8Q\":[\"La partie du corps est obligatoire.\"],\"wL3cK8\":[\"Dernier\"],\"wL7wrB\":[\"Incrément de poids\"],\"wUwyC0\":[\"Série consécutive\"],\"wYwS57\":[\"Personnalise tes paramètres\"],\"wckWOP\":[\"Gérer\"],\"wgbq86\":[\"Redémarrage échoué\"],\"wpLp4M\":[\"Assistance\"],\"wvxWx2\":[\"trapèze\"],\"wxKcF0\":[\"À propos du développeur\"],\"x5LlnE\":[\"Options stats\"],\"xGVfLh\":[\"Continuer\"],\"xM_hqb\":[\"assistance \"],\"xMidTh\":[\"Toutes les parties du corps\"],\"xRGBk4\":[\"Explorer les programmes prêts à l'emploi\"],\"xVhQZV\":[\"Ven\"],\"xYxQCZ\":[[\"0\"],\" \",[\"1\"]],\"xx7Wjz\":[\"Impossible de charger les détails de l'exercice.\"],\"y04OSh\":[\"Historique des entraînements\"],\"y3CwcG\":[\"record \",[\"maxTime\"],\"s\"],\"y8le-Z\":[\"Entraînement\"],\"yAeHP4\":[\"Aucune donnée disponible.\"],\"yBSiRY\":[\"Semaine de décharge\"],\"yKu_3Y\":[\"Restaurer\"],\"yUWaVv\":[\"machine elliptique\"],\"yWCES-\":[\"Muscles secondaires :\"],\"y_0uwd\":[\"Hier\"],\"y_f0Ik\":[\"S'ouvre dans ton navigateur\"],\"yf16RU\":[\"Échauffement\"],\"ygCKqB\":[\"Arrêter\"],\"yhrNcC\":[\"Erreur de sauvegarde d'image\"],\"ykve2U\":[\"Ajouter une série\"],\"yu1K_Z\":[\"Aucune série\"],\"z1-0FW\":[\"Suis tes entraînements, surveille ta progression et atteins tes objectifs fitness. MuscleQuest rend ton parcours fitness simple et efficace.\\n\\nFais glisser les cartes d'introduction pour en savoir plus sur l'appli.\"],\"z44QLk\":[\"Restaurer la sauvegarde\"],\"z5uobd\":[\"Appuie sur l'icône étoile dans le coin supérieur droit de n'importe quel écran d'infos d'exercice pour le marquer comme favori. Les exercices favoris apparaissent en haut du sélecteur d'exercices lors de la création ou modification d'entraînements, afin que les exercices que tu utilises le plus soient toujours à portée de main.\"],\"zAhZMD\":[\"• Partager tes programmes avec d'autres *\"],\"zAt78k\":[\"Minuterie de repos\"],\"zDq2cZ\":[\"Tour de taille\"],\"zEHmq8\":[\"L'onglet Programmes inclut une bibliothèque de programmes d'entraînement prêts à l'emploi que tu peux démarrer immédiatement. Fais défiler au-delà de Tes programmes pour trouver la section Programmes prêts à l'emploi. Appuie sur n'importe quel programme pour prévisualiser ses entraînements et son planning, puis appuie sur Activer pour en faire ton programme actif. Tu peux modifier un programme prêt à l'emploi pour ajuster les exercices, les séries ou le planning hebdomadaire. Cela crée une copie du programme que tu peux modifier sans affecter l'original.\"],\"zIFP3N\":[\"Fixe ton objectif d'entraînement hebdomadaire et entre ton poids de corps pour obtenir des stats et recommandations précises. Tu peux aussi ajuster tes préférences d'incrément de poids, choisir tes unités préférées, et bien plus.\"],\"zNnnyF\":[\"mollets\"],\"zOwYV3\":[\"Tu as modifié cet entraînement. Enregistrer ces modifications pour les prochaines séances ?\"],\"zga9sT\":[\"OK\"],\"zhIkkH\":[\"Objectif : \",[\"goalLabel\"],[\"0\"]],\"zsaR7t\":[\"Équipement et suivi\"],\"zt6jiv\":[\"Pas de suivi de progression pour ce type d'exercice.\"],\"zuwyEJ\":[\"Ajoute des exercices pour commencer\"],\"zzDlyQ\":[\"Succès\"]}")}; \ No newline at end of file +/*eslint-disable*/module.exports={messages:JSON.parse("{\"-2Ut5a\":[\"La bande Aperçus en haut de l'onglet Stats donne quatre points saillants en un coup d'œil pour la période sélectionnée : ta moyenne d'entraînements par semaine, ta plus grande progression de force parmi les exercices suivis, la partie du corps la plus entraînée, et ta série consécutive hebdomadaire actuelle. Ces données se mettent à jour automatiquement après chaque entraînement.\"],\"-5kO8P\":[\"Samedi\"],\"-BjMj_\":[\"Créer un entraînement\"],\"-FjWgX\":[\"Jeu\"],\"-Tpjjs\":[[\"0\"],\" séries\"],\"-WSEJS\":[\"Supprimer l'entraînement\"],\"-Xejuf\":[\"Hanches\"],\"-XvJee\":[\"record \",[\"0\"],[\"weightUnit\"],\" × \",[\"1\"]],\"-rhD7g\":[\"Aucune demande d'ami en attente.\"],\"-svcUj\":[\"Enregistrer cet entraînement ?\"],\"03mQOq\":[\"Impossible d'activer ce programme : \",[\"0\"]],\"06EUQy\":[\"Record absolu\"],\"0EHHPz\":[\"adducteurs\"],\"0EPpEZ\":[\"Ajouter une mesure personnalisée\"],\"0EcUWz\":[\"Abandonner les modifications ?\"],\"0OeId4\":[\"Créer un programme personnalisé\"],\"0P1btN\":[\"\\n🔔 Nouveau : Sons de la minuterie d'exercice !\\n\\nLa minuterie d'exercice joue maintenant des signaux sonores pour te garder concentré. Un bip de compte à rebours quand la minuterie approche de zéro et un son quand tu atteins ton objectif. Active ou désactive chaque son indépendamment dans les Paramètres.\\n\"],\"0SaB4K\":[\"Série d'échauffement\"],\"0U938S\":[\"Sélectionne au moins un jour\"],\"0V9gKq\":[\"\\n🔵 Nouveau : Modal de minuterie d'exercice !\\n\\nLes exercices basés sur le temps affichent maintenant un modal dédié avec un anneau de progression, pour suivre facilement ton effort et garder le rythme pendant les séries chronométrées.\\n\"],\"0caMy7\":[\"Historique\"],\"0dHvKo\":[\"Muscle cible :\"],\"0eRpDV\":[\"Difficile, proche de la limite\"],\"0f7U0k\":[\"Mer\"],\"0tJJBW\":[\"Préc. : \"],\"0vGEy2\":[\"\\n📊 Nouveau : Écran de statistiques amélioré !\\n\\nL'écran de statistiques a été repensé avec un nouveau look et des aperçus améliorés. Explore ton historique d'entraînement avec de meilleurs graphiques, des résumés plus clairs et des analyses plus détaillées de ta progression dans le temps.\\n\"],\"14ytif\":[\"Commencer l'entraînement\"],\"1DF4Ah\":[\"Supprimer toutes les données partagées\"],\"1DPB1m\":[\"\\n🗂️ Nouveau : Cinq nouveaux programmes préfaits !\\n\\nCinq nouveaux programmes prêts à l'emploi sont maintenant disponibles : Bro Split 5 jours, Push/Pull/Jambes 5 jours, Split 6 jours, Poids de corps et Haltères uniquement. Que tu t'entraînes à la maison ou en salle, il y a un programme pour démarrer immédiatement.\\n\"],\"1FnEj9\":[\"Mesures corporelles\"],\"1Kx4Hp\":[\"Erreur lors de la récupération de \",[\"0\"],\" : \",[\"1\"]],\"1Mx10o\":[\"Voir les stats\"],\"1QfxQT\":[\"Fermer\"],\"1Se9J7\":[\"vélo stationnaire\"],\"1UzENP\":[\"Non\"],\"1gbc4_\":[\"Nouvel entraînement\"],\"1hW6-f\":[\"Certaines images n'ont pas pu être téléchargées après plusieurs tentatives. IDs des exercices en échec : \",[\"0\"]],\"1j3Ob3\":[\"Calendrier des entraînements\"],\"1mm2JF\":[\"deltïödes\"],\"296mtr\":[\"barre hexagonale\"],\"29Hx9U\":[\"Stats\"],\"2FYpfJ\":[\"Plus\"],\"2ZZM6V\":[\"core\"],\"2bnWaQ\":[[\"completedCount\"],\"/\",[\"0\"],\" séries terminées\"],\"2cupe5\":[\"Appliquer à toutes les \",[\"0\"],\" séries\"],\"2dPYb7\":[\"Aucune mesure pour l'instant. Enregistre ta première entrée ci-dessus.\"],\"2dX9Kv\":[\"dos\"],\"2eB2c7\":[\"Entraîne-toi sans programme ! Crée des entraînements indépendants en dehors de tes programmes, parfaits pour les séances de mobilité, les échauffements ou tout ce qui est improvisé.\\n\\nOu lance directement un Entraînement rapide depuis l'écran d'accueil, ajoute des exercices au fur et à mesure, et tu peux le sauvegarder comme entraînement indépendant quand tu as terminé.\"],\"2gSypt\":[\"Équipement *\"],\"2j0v05\":[\"Toutes les images téléchargées avec succès !\"],\"2lfUf3\":[[\"streak\",\"plural\",{\"one\":[\"#\",\" semaine d'affilée\"],\"other\":[\"#\",\" semaines d'affilée\"]}]],\"2saL1j\":[\"1RM\"],\"2vS4Oc\":[\"Facile, j'aurais pu faire plus\"],\"2wR0QE\":[\"Ajouter un exercice\"],\"30xwUM\":[\"Tu es sûr de vouloir supprimer toutes les images animées ? Les images individuelles seront automatiquement re-téléchargées lors de leur affichage.\"],\"39y5bn\":[\"Vendredi\"],\"3A79ox\":[\"Réduire la charge\"],\"3L-1Z1\":[\"Erreur lors du chargement des exercices : \",[\"0\"]],\"3RoflF\":[\"\\n📈 Nouveau : Historique des exercices dans l'écran d'informations !\\n\\nL'écran d'informations sur les exercices inclut maintenant un historique complet de chaque fois que tu as effectué cet exercice, avec les poids, répétitions, temps et distance de chaque série des séances passées. Accède-y pendant un entraînement, depuis ton programme, ou partout où les informations sur les exercices sont disponibles.\\n\"],\"3ezHPX\":[\"Jouer un son après le repos\"],\"3hJ166\":[\"\\n🔍 Amélioré : Recherche d'exercices plus intelligente et accès facile à la bibliothèque d'exercices !\\n\\nLa recherche d'exercices reconnaît maintenant les abréviations courantes comme RDL, OHP, DB et KB, corrige les petites fautes de frappe et classe les résultats par pertinence pour que la meilleure correspondance apparaisse toujours en premier.\\n\\nTu peux aussi parcourir la bibliothèque complète d'exercices à tout moment depuis le menu, sans avoir besoin d'être dans un entraînement ou un plan.\\n\"],\"3hJypY\":[\"Aperçus\"],\"43lYJ-\":[\"Bienvenue\",[\"userName\"]],\"4BgR4M\":[\"Tu as atteint ton objectif hebdomadaire. Travail incroyable !\"],\"4GTHgi\":[\"Compte à rebours de la minuterie d'exercice\"],\"4M4P8M\":[\"Aucune valeur saisie\"],\"4OjqAQ\":[\"Continuer à modifier\"],\"4Y9aig\":[\"Mis à jour \",[\"0\"]],\"4_WLmI\":[\"poids de corps\"],\"4j0zbV\":[\"Enregistrement du programme...\"],\"4jkyRj\":[\"échauffement\"],\"4mrNi3\":[[\"suggestedRepsMin\"],\"-\",[\"suggestedRepsMax\"],\" reps suggérées\"],\"4oRoD4\":[\"Configure les unités de poids, de taille et de distance, le nombre de séries par défaut par exercice, le temps de repos par défaut et l'incrément de poids des boutons ± pendant la séance. Ajuste la taille des boutons d'entraînement (Standard, Grand ou Très grand) et active Garder l'écran allumé pour éviter que l'écran se mette en veille. Dans Statistiques, tu peux exclure les séries d'échauffement du volume, doubler les répétitions pour les exercices unilatéraux ou doubler le poids pour les appareils appariés, utile si tu préfères noter le poids d'un seul haltère plutôt que le total. Renseigne ton poids corporel ici ; il est utilisé pour calculer la charge effective des exercices assistés.\"],\"4sGdeG\":[\"Graisse corporelle\"],\"5-5naM\":[\"Amis & social\"],\"50_FGa\":[\"Exercice\"],\"538Jsv\":[\"Annuler l'entraînement\"],\"58iwz8\":[\"Erreur lors du chargement des programmes\"],\"5Hrw0r\":[\"Ajouter à mes entraînements\"],\"5SgD0L\":[\"Tu as des modifications non enregistrées. Es-tu sûr(e) de vouloir les abandonner ?\"],\"5Z05pb\":[\"Filtrer les thèmes d'aide\"],\"5aB9II\":[\"C'est l'heure de ta prochaine série !\"],\"5b4J4v\":[\"Tout le temps\"],\"5lWFkC\":[\"Se connecter\"],\"5w2VTM\":[\"Tu es sûr de vouloir télécharger toutes les images animées ? Cela peut prendre un moment.\"],\"5yIPLp\":[\"Oups !\"],\"66llpx\":[\"Ajouter une image\"],\"699xiu\":[\"Tu es sûr de vouloir restaurer la sauvegarde ?\"],\"6Bqki7\":[\"Objectif hebdomadaire atteint !\"],\"6Hcqaf\":[\"\\n↕️ Nouveau : Réorganiser les entraînements dans ton programme !\\n\\nTu peux maintenant réorganiser les entraînements directement depuis l'écran de création de programme et les cartes d'entraînement, pour avoir un contrôle total sur la mise en page de ton planning.\\n\"],\"6MR2yM\":[\"Parcours près de 1 000 exercices et filtre par partie du corps, muscle cible ou équipement. Utilise les chips de tri en haut pour classer les exercices par Par défaut, Programme actif, Récent ou Fréquent, afin que les exercices les plus pertinents pour toi apparaissent en premier. Quand tu remplaces un exercice, le filtre présélectionne automatiquement le muscle cible correspondant pour t'aider à trouver des alternatives plus rapidement. Appuie sur n'importe quel exercice pour voir sa démonstration animée, les muscles sollicités et un historique complet de chaque fois que tu l'as effectué, avec les poids, répétitions, temps ou distances par série. Télécharge toutes les animations d'exercices (~100 Mo) dans les Paramètres pour y accéder hors ligne.\"],\"6XIVae\":[\"Augmenter la charge\"],\"6_dCYd\":[\"Vue d'ensemble\"],\"6g63at\":[\"Explorer les programmes\"],\"6glEtt\":[\"Encore en récupération. Garder cette charge pour l'instant.\"],\"6igHT6\":[\"Modifier l'entraînement\"],\"6lAGPA\":[\"Ajoute un entraînement pour commencer\"],\"6lv7us\":[\"Poids (\",[\"weightUnitLabel\"],\")\"],\"6q7I63\":[\"taille\"],\"6u9LvN\":[[\"days\",\"plural\",{\"one\":[\"il y a \",\"#\",\" jour\"],\"other\":[\"il y a \",\"#\",\" jours\"]}]],\"6uHnph\":[\"Temps (Heure:Min)\"],\"6vinCF\":[\"Type de suivi *\"],\"6z9W13\":[\"Recommencer\"],\"716aO7\":[\"Le plus entraîné\"],\"75Qc-e\":[\"Compter les rép. ×2 pour le volume quand le paramètre est activé\"],\"77kllS\":[\"record \",[\"0\"],\" rép.\"],\"7F8buC\":[\"avant-bras\"],\"7FYy4K\":[\"Erreur lors de la sauvegarde de l'entraînement\"],\"7LBKtm\":[\"Aucun entraînement disponible\"],\"7LLkrj\":[\"muscles de la poigne\"],\"7MuXko\":[\"Personnel\"],\"7P_9OY\":[\"Ma\"],\"7YT_7y\":[\"Répétitions\"],\"7Z9Tzs\":[\"colonne vertébrale\"],\"7eMo-U\":[\"Retourner à l'accueil\"],\"7hAJKI\":[[\"0\",\"plural\",{\"one\":[\"série\"],\"other\":[\"séries\"]}]],\"7iTVa8\":[\"Muscles secondaires\"],\"7p3sn_\":[\"Temps : \",[\"0\"]],\"7x42zy\":[\"Aucune donnée pour cette période\"],\"7xB0qQ\":[\"Muscle cible *\"],\"87VAxI\":[\"Infos sur l'exercice\"],\"8BG66J\":[\"Aucun entraînement terminé partagé pour l'instant\"],\"8JaOZF\":[\"Profil de l'ami\"],\"8Mlj-A\":[\"Objectif de reps non atteint. On maintient pour l'instant.\"],\"8Rd3od\":[\"Tu es sûr de vouloir annuler et supprimer cet entraînement ?\"],\"8V8f_Q\":[\"Dernier \",[\"metricLabel\"],\" : \",[\"0\"]],\"8YBh-G\":[\"Rép. ×2 comptées pour ces exercices\"],\"8ZJ9dh\":[\"Enregistrement du poids pour les exercices au poids de corps\"],\"8ZU8FI\":[\"Erreur lors du chargement des stats. Réessaie.\"],\"8_MCsG\":[\"\\n💾 Nouveau : Sauvegarde et reprise des brouillons de programme et d'entraînement !\\n\\nTon travail dans les éditeurs de programme et d'entraînement autonome est maintenant automatiquement sauvegardé comme brouillon. Si tu quittes en cours d'édition, tu seras invité à continuer là où tu t'es arrêté ou à supprimer le brouillon, pour ne jamais perdre ta progression par accident.\\n\"],\"8aTiea\":[\"Personnalisation\"],\"8cA6YX\":[\"Suis ta composition corporelle dans le temps depuis la section Mesures de l'onglet Statistiques. Utilise le formulaire Saisir une entrée pour enregistrer des valeurs pour chaque mesure active, puis appuie sur une entrée passée dans l'historique pour la consulter ou la modifier. Sur l'écran de détail de l'entrée, appuie sur un chip de mesure pour basculer le graphique entre différentes mesures et utilise le sélecteur de plage de temps pour zoomer ou dézoomer. Les mesures sont divisées en trois types : masse (poids, en kg ou lbs), longueur (circonférences comme la taille et les hanches, en cm ou pouces) et pourcentage (masse grasse). Les unités suivent tes préférences de poids et de taille dans Paramètres. Pour contrôler quelles mesures apparaissent dans le formulaire, appuie sur Gérer les mesures en haut de la section Saisir une entrée. Les mesures intégrées peuvent être activées ou désactivées ; tu peux également créer tes propres mesures personnalisées et choisir leur type. Les mesures personnalisées peuvent être masquées du formulaire à tout moment, et tes données historiques sont toujours conservées.\"],\"8jcZyX\":[\"Mesures intégrées\"],\"8mjpCE\":[\"Introduction à MuscleQuest\"],\"8uqQSD\":[\"Pas réussi à finir toutes les séries\"],\"8wbSm2\":[\"Aucune donnée de force partagée pour l'instant\"],\"8yLreB\":[\"pendant \",[\"0\"],\"s \"],\"8yw7nc\":[\"Bilan de récupération\"],\"91hJvI\":[\"Cible : \",[\"distanceMin\"],\" \",[\"distanceUnit\"]],\"94FTWy\":[\"Suppression terminée\"],\"95IyBI\":[\"Les exercices au poids de corps comme les tractions ou les dips ne suivent que les répétitions par défaut. Si tu veux noter le poids ajouté, comme une ceinture lestée ou un gilet, ouvre le récapitulatif des séries de cet exercice dans l'éditeur d'entraînement ou de programme et active Enregistrer le poids. Le réglage est sauvegardé par entraînement, tu peux donc avoir des entraînements en poids de corps uniquement et d'autres qui enregistrent la charge supplémentaire. Les graphiques de progression et l'historique refléteront le poids enregistré une fois le réglage activé.\"],\"97-TIS\":[\"Tu n'as pas pu finir toutes les séries. La charge baisse légèrement pour la prochaine fois.\"],\"9Anet0\":[\"Équipement\"],\"9C6X7Q\":[\"Abandonner les modifications\"],\"9EGOsa\":[\"câble\"],\"9H3-WL\":[\"\\n⚙️ Nouveau : Trois nouveaux paramètres pour les stats !\\n\\nPersonnalise le calcul de ton volume et de tes stats avec trois nouvelles options dans les Paramètres :\\n\\n• Exclure les séries d'échauffement des stats pour ne pas fausser tes chiffres.\\n• Doubler automatiquement le poids des haltères, pour que tu puisses noter le poids d'un seul haltère et que le total soit compté pour toi.\\n• Doubler les répétitions pour les exercices unilatéraux (un bras/une jambe), pour que ces mouvements soient comptés correctement dans tes totaux de volume.\\n\"],\"9HyV9h\":[\"Active pour ajouter un bouton de publication à chaque entraînement solo.\"],\"9LmK3L\":[\"Images par Unsplash\"],\"9XoWik\":[\"grand dentelé\"],\"9eQmcp\":[[\"0\"],\" jours par semaine\"],\"A-gAFO\":[\"Crée tes propres exercices depuis le sélecteur d'exercices. Donne-lui un nom, une image optionnelle, une partie du corps, des muscles cibles, des muscles secondaires et de l'équipement. Choisis un type de suivi : poids + répétitions, temps, distance, répétitions seules ou assisté (qui prend en compte ton poids de corps pour des mouvements comme les tractions assistées). Active Unilatéral pour les exercices à un bras ou une jambe ; les répétitions peuvent être automatiquement doublées dans tes stats. Active Implements appariés si tu notes le poids d'un seul implement plutôt que le total : par exemple, si tu notes 20 kg pour un haltère, l'appli compte 40 kg dans ton volume.\"],\"A1-VaP\":[\"grand dorsal\"],\"A1_kH4\":[\"Minuterie d'exercice\"],\"A1taO8\":[\"Rechercher\"],\"ATGYL1\":[\"Adresse e-mail\"],\"AWokve\":[\"Historique du même entraînement\"],\"AeXO77\":[\"Compte\"],\"AqyJQg\":[\"Feedback après exercice\"],\"Ayx1au\":[\"Tu es sûr de vouloir supprimer ce programme ?\"],\"B8ZQ8n\":[\"Rép. min.\"],\"B9LtU1\":[\"Tu as des modifications non enregistrées de ta dernière session. Veux-tu continuer ?\"],\"BEVzjL\":[\"Importation échouée\"],\"BGO6Rp\":[\"Comment se sentent ces muscles depuis ta dernière séance ?\"],\"BTqs-Z\":[[\"0\",\"plural\",{\"one\":[\"#\",\" Série\"],\"other\":[\"#\",\" Séries\"]}]],\"BZDlVl\":[\"fléchisseurs de la hanche\"],\"BaG4Vp\":[\"Fréquent\"],\"BdnYlL\":[\"Durée moyenne\"],\"BpTc_M\":[\"Rechercher dans l'aide\"],\"Bqo02Q\":[\"Démarrer la minuterie\"],\"BrHgnn\":[\"\\n⏱️ Nouveau : Minuterie de repos ajustable !\\n\\nUn nouveau panneau coulissant te permet d'ajuster ta durée de repos à la volée pendant un entraînement. Ton temps de repos personnalisé est sauvegardé par série, donc chaque série se souvient exactement du temps de repos que tu préfères.\\n\"],\"BwTx3c\":[\"Tu es sûr de vouloir supprimer \",[\"0\"],\" ?\"],\"C4GKOD\":[[\"repRange\"],\" Rép., \"],\"CCTop_\":[\"Récent\"],\"CE-M2e\":[\"Infos\"],\"CFL873\":[\"Active pour partager automatiquement chaque entraînement terminé.\"],\"CV6Ez2\":[\"Appuie sur Se connecter avec Google dans les Paramètres pour connecter ton compte. La connexion active les sauvegardes cloud pour que tes données soient en sécurité si tu changes d'appareil ou réinstalles l'appli, et ton nom apparaît dans le message d'accueil. L'appli fonctionne entièrement hors ligne sans connexion, mais les sauvegardes cloud ne sont pas disponibles. Tes données sont stockées localement sur ton appareil et ne sont partagées avec personne, sauf si tu choisis de les partager toi-même.\"],\"CZKXmk\":[\"chevilles\"],\"CaKjcv\":[\"Entraînement rapide\"],\"CghlOu\":[\"abdominaux inférieurs\"],\"CiUwqB\":[\"Aller aux Entraînements\"],\"CxQnhY\":[\"\\n👥 Nouveau : Amis & partage social !\\n\\nAjoute des amis en cherchant leur nom d'utilisateur depuis l'onglet Amis dans le menu. Envoie une demande et, une fois acceptée, vous pouvez parcourir le contenu partagé de l'autre. Un badge sur l'élément Amis du menu indique les demandes entrantes en attente.\\n\\nPartage tes programmes, entraînements solo, exercices personnalisés, mesures corporelles et records de force en activant Partager dans l'écran correspondant ou depuis les Paramètres de confidentialité dans la section Compte des Paramètres. Le contenu partagé se synchronise automatiquement à chaque modification, et une icône nuage sur les cartes programme et entraînement indique ce qui est actuellement publié. Tu peux supprimer toutes les données partagées d'une catégorie depuis les Paramètres de confidentialité à tout moment.\\n\\nAppuie sur le nom de n'importe quel ami accepté pour ouvrir son profil et importer ses programmes, entraînements solo ou exercices personnalisés directement dans ta propre bibliothèque.\\n\"],\"D-GweR\":[\"Connecte-toi pour utiliser la fonctionnalité Amis.\"],\"D0GOrZ\":[\"Tu dois te connecter pour utiliser cette fonctionnalité\"],\"D3h1sn\":[\"travail\"],\"D45Cr4\":[\"Sélectionner les muscles secondaires\"],\"D89zck\":[\"Dim\"],\"DBC3t5\":[\"Dimanche\"],\"DIS-zd\":[\"Impossible de supprimer le programme : \",[\"0\"]],\"DJMHhb\":[\"La dernière séance était une décharge. Comparaison ignorée.\"],\"DNhKLr\":[\"\\n🎯 Amélioré : Filtres d'exercices plus intelligents !\\n\\nQuand tu remplaces un exercice, le filtre présélectionne maintenant automatiquement le muscle cible correspondant. Seuls les filtres pertinents s'affichent en fonction de ta sélection, ce qui rend la recherche d'une alternative bien plus rapide.\\n\"],\"DPfwMq\":[\"Terminé\"],\"DTtUaj\":[\"Entre au moins une mesure à enregistrer.\"],\"DWFuyG\":[\"Supprimer l'exercice\"],\"DYOFso\":[\"stabilisateurs de la cheville\"],\"DdBQBl\":[\"Planning hebdomadaire\"],\"Dh5Ge5\":[\"Des douleurs ou des problèmes de forme ?\"],\"Di-cgt\":[\"Bienvenue dans MuscleQuest !\"],\"DqgDEk\":[\"Le plus récent de n'importe quel entraînement\"],\"Dvc8Qg\":[\"Description :\"],\"Dy8Cvh\":[\"quadriceps\"],\"Dy_8Fq\":[\"FERMER\"],\"E3kRqj\":[[\"uniqueWorkoutDaysCount\"],\" / \",[\"0\"],\" jours d'entraînement\"],\"EANWES\":[\"Impossible de charger l'historique\"],\"EHgz6Q\":[\"Impossible de mettre à jour le partage. Réessaie.\"],\"EMyNOr\":[[\"0\"],\" \",[\"1\"],\" (utilisé pour les exercices assistés)\"],\"E_QGRL\":[\"Désactivé\"],\"Ed3YeG\":[\"Chaque entraînement que tu termines est partagé automatiquement.\"],\"Ef7StM\":[\"Inconnu\"],\"EfdYnO\":[[\"0\"],[\"distanceUnit\"]],\"EjAXiq\":[\"Progression adaptative (bêta)\"],\"EkVHAp\":[\"Incrément de la minuterie de repos\"],\"EoQHhQ\":[\"tapis de course\"],\"Euo2Um\":[\"Temps (Min:Sec)\"],\"F37c1s\":[\"Ouvrir les Paramètres\"],\"F6pfE9\":[\"Actif\"],\"FCGpHg\":[\"Aucun exercice dans cet entraînement.\"],\"FHIDZO\":[\"Enregistrer et sélectionner\"],\"FPsvA8\":[\"Compris !\"],\"FXHR4B\":[\"Partie du corps\"],\"Fb5zs_\":[\"\\n⚖️ Nouveau : Enregistrer le poids pour les exercices au poids de corps !\\n\\nPour les exercices au poids de corps comme les tractions ou les dips, tu peux maintenant activer l'enregistrement du poids par entraînement. Parfait pour les variantes lestées, pour noter le poids ajouté et suivre ta progression dans le temps.\\n\"],\"Fe0wLe\":[\"Superseries\"],\"FnTClW\":[\"Tu atteins facilement les objectifs. Il est temps d'ajouter un peu plus de poids.\"],\"Fp1hl-\":[\"Chargement du programme...\"],\"FwCUad\":[\"L'équipement est obligatoire.\"],\"G-iXUH\":[\"épaules\"],\"G1onOm\":[\"Supprimer toutes les données partagées ?\"],\"G2R9Qq\":[\"fléchisseurs du poignet\"],\"G2nnKc\":[\"Ajouter à mes programmes\"],\"G3myU-\":[\"Mardi\"],\"G49bAb\":[\"machine à levier\"],\"G4JNdR\":[\"Exercice introuvable.\"],\"G6rTvo\":[\"Suivre (\",[\"0\"],\")\"],\"GB-X8R\":[\"Importer depuis ses amis\"],\"GCV1HM\":[\"Connecté en tant que \",[\"0\"]],\"GCqPY4\":[\"L'écran d'accueil affiche ta progression vers ton objectif d'entraînement hebdomadaire, qui correspond au nombre de jours par semaine où tu veux t'entraîner, défini dans les Paramètres. Une bande en haut indique le nombre de jours complétés et met en évidence chaque jour terminé. En dessous, les entraînements de ton programme actif sont listés avec leur statut d'avancement pour la semaine ; appuie sur Commencer sur n'importe quel entraînement pour le lancer. La carte affichée en dessous change selon ton statut : une carte Reprendre apparaît si une séance est en cours, une carte Jour de repos s'affiche les jours sans entraînement planifié, et une carte Entraînement terminé confirme que la séance du jour est complète. Quand tu atteins ton objectif hebdomadaire, une carte Résumé de la semaine apparaît avec le total d'entraînements, de séries et de volume pour la semaine, plus ta série consécutive, qui compte le nombre de semaines consécutives où tu as atteint ton objectif.\"],\"GGqR7k\":[\"Entraînements seuls et rapides\"],\"GLJjec\":[\"Jusqu'à l'échec\"],\"GLm0-9\":[\"Douleur ou problèmes de forme\"],\"GNurdZ\":[\"Supprimer l'exercice\"],\"GPeIuw\":[\"Distance\"],\"GS7yxz\":[\"Permission requise\"],\"GSOeV2\":[\"ischio-jambiers\"],\"GVN2lL\":[\"Créer un exercice\"],\"GWvJTL\":[\"À peu près bien\"],\"GX9tlq\":[\"cou\"],\"Gd-KuS\":[\"Gérer les mesures\"],\"Gf9sn6\":[\"Vérification des sauvegardes...\"],\"GhCGeL\":[\"Séries\"],\"GksdwI\":[\"Meilleures séries PR\"],\"HNWkJr\":[\"\\n📏 Nouveau : Suivi de distance pour les exercices personnalisés !\\n\\nLes exercices personnalisés peuvent maintenant utiliser un type de suivi par distance, parfait pour les mouvements cardio et de conditionnement comme les courses, les rameurs ou les poussées de traîneau. Note la distance de tes séries et suis ta progression comme pour n'importe quel autre exercice.\\n\"],\"HYL9fJ\":[\"Enregistrer un seul côté pour les exercices unilatéraux\"],\"Hp6ceF\":[\"Impossible de sauvegarder ton entraînement. Réessaie plus tard.\"],\"HpK_8d\":[\"Recharger\"],\"Hplwk7\":[\"Restauration en cours. Patiente...\"],\"I2Hpku\":[\"Enregistrer le poids\"],\"ICkQNB\":[\"Heure de rappel\"],\"IFowGw\":[\"corde\"],\"IHMx9j\":[\"Série de semaines\"],\"ILE1kp\":[\"bras\"],\"INkdlR\":[\"Aucun ami pour l'instant. Cherche par e-mail pour en ajouter un.\"],\"IRiG-a\":[\"Vibrer après le repos\"],\"IUwGEM\":[\"Enregistrer les modifications\"],\"IXxATP\":[\"Exercices personnalisés\"],\"IbbuFX\":[\"Suppression en cours. Veuillez patienter...\"],\"IuXB4Q\":[\"Ajouter une note...\"],\"Izf0kk\":[\"Pas de données de poids antérieures. On maintient pour l'instant.\"],\"JE-yVp\":[\"Gérer les mesures\"],\"JR5hAM\":[\"1 an\"],\"JTkSvz\":[\"Tu es sûr de vouloir supprimer cet entraînement ?\"],\"JVKmoO\":[\"La mise à jour n'a pas pu être téléchargée. Vérifie ta connexion internet et rouvre l'app pour réessayer.\"],\"JW7_2_\":[\"Téléchargement échoué\"],\"JWTR_A\":[\"Une erreur s'est produite lors du téléchargement des images.\"],\"JYRqp5\":[\"Sa\"],\"JbvV5d\":[\"Pendant une séance, glisse vers la gauche/droite ou utilise les boutons fléchés pour naviguer entre les séries. Entre ton poids et tes répétitions, puis appuie sur Terminer la série. Le temps écoulé total s'affiche en haut tout au long. Tu peux glisser la poignée d'une carte d'exercice pour réorganiser les exercices en cours de séance. Les exercices basés sur le temps ont un bouton Démarrer la minuterie qui ouvre un chronometre avec un anneau de progression indiquant quand tu atteins ton objectif, mais tu peux continuer aussi longtemps que tu veux. Les notes peuvent être ajoutées par exercice via l'icône de notes, par entraînement depuis l'écran de vue d'ensemble, ou par programme depuis l'écran de vue d'ensemble du programme. Si tu ajoutes, supprimes ou réorganises des exercices ou des séries pendant une séance, tu seras invité à la fin à sauvegarder ces modifications.\"],\"JfDOWo\":[\"La mise à jour est prête mais l'app n'a pas pu redémarrer automatiquement. Essaie d'appuyer sur le bouton ci-dessous, ou ferme et rouvre l'app manuellement.\"],\"JkpsKr\":[\"Téléchargement en cours. Veuillez patienter...\"],\"JmZ_-d\":[\"Terminer\"],\"JsIy35\":[\"Tu as activé ce programme.\"],\"JumwGu\":[\"cardio\"],\"Jv9TrU\":[\"obliques\"],\"KIL-9T\":[\"Suivant : \"],\"KKalG-\":[\"Épingle des exercices dans l'onglet Stats pour suivre leur progression de force dans le temps. Chaque exercice suivi affiche un graphique de tes performances sur la période sélectionnée, ton record personnel absolu, tes meilleures séries, et une liste des sessions récentes avec la meilleure série par jour. Les graphiques se mettent à jour automatiquement après chaque entraînement incluant cet exercice.\"],\"KM1Iw2\":[\"MuscleQuest\"],\"KSqQx0\":[\"Rép. max.\"],\"Km7tR4\":[\"Offre-moi un Café\"],\"KmiPdE\":[\"haltère\"],\"KxWSWU\":[\"Garder l'écran allumé pendant l'entraînement\"],\"LAC2eo\":[\"Rappels d'entraînement\"],\"LAHzG1\":[\"Voir/Modifier\"],\"LIrnc0\":[\"Aucun exercice ajouté\"],\"LLt1-u\":[\"Unilatéral\"],\"LZKayn\":[\"Rechercher dans l'aide…\"],\"LcPJBt\":[\"entraînements terminés\"],\"LhMjLm\":[\"Temps\"],\"LyPttd\":[\"Poitrine\"],\"M0GVkz\":[\"Sélectionne un jour pour voir les entraînements.\"],\"M1POMr\":[\"Bibliothèque d'exercices\"],\"M4hMaA\":[\"Entre un nom pour la mesure personnalisée.\"],\"M57U8X\":[\"Regroupe deux exercices en superserie pour qu'ils alternent automatiquement pendant une séance, idéal pour associer des muscles antagonistes ou rester efficace entre les séries. Appuie sur le menu trois points d'un exercice dans l'éditeur d'entraînement et choisis Créer une superserie, puis sélectionne le deuxième exercice. Un label de couleur identifie à quelle superserie appartient chaque exercice dans toute l'application. Quand tu termines une série sur un exercice, l'appli te déplace directement vers son partenaire de superserie.\"],\"MEt7-_\":[\"soléaire\"],\"MHk_Wu\":[\"Entrée introuvable.\"],\"MLQOxI\":[\"deltïödes postérieurs\"],\"MM-MTF\":[\"Superserie \",[\"0\"]],\"MQ9jL7\":[\"Plus qu'un entraînement pour atteindre ton objectif !\"],\"MQA2H9\":[\"Supprimer le programme\"],\"MTqmCb\":[\"Demander ou voter pour de nouvelles fonctionnalités\"],\"McFNQO\":[\"Suis ton parcours fitness avec des stats et des aperçus détaillés. Consulte l'historique de tes entraînements, analyse tes répartitions par partie du corps et visualise tes améliorations dans le temps avec des graphiques de progression des exercices.\"],\"MmDz7_\":[\"Envoi en cours. Patiente...\"],\"N4e_z1\":[\"Temps de repos : \",[\"restMinutes\"],\":\",[\"0\"]],\"N5Cyfw\":[\"Amis depuis \",[\"0\"]],\"N85c_3\":[\"Supprimer l'entraînement\"],\"NC2AI2\":[\"Longueur\"],\"NIuBdI\":[\"Programmes prêts à l'emploi\"],\"NKdWDE\":[\"système cardiovasculaire\"],\"NLBiJk\":[\"Saisir une entrée\"],\"NLYLjM\":[\"séries\"],\"NPG8SK\":[\"Poids du corps\"],\"NQJHen\":[\"Tu es sûr de vouloir recommencer cet entraînement ?\"],\"NVOqiK\":[\"Connecte-toi pour sécuriser tes données\"],\"NXoGPK\":[\"Modifier l'exercice\"],\"Ne5n-8\":[\"Ajouter des notes personnelles\"],\"NnRCUm\":[[\"0\"],\"s\"],\"Ns5WaC\":[\"Aucune sauvegarde trouvée\"],\"Nu4oKW\":[\"Description\"],\"O1GFNQ\":[\"Tous les muscles cibles\"],\"O1xiRM\":[\"reps\"],\"O2TAe0\":[\"barre\"],\"O2wCGL\":[\"Jouer les bips de compte à rebours (Minuterie d'exercice)\"],\"ODbgw_\":[\"Cela supprime tout le contenu que tu as partagé avec tes amis. Tes amis et ta liste d'amis ne sont pas affectés.\"],\"OdFJle\":[\"Active pour partager automatiquement tes exercices personnalisés.\"],\"Otd3xX\":[\"Une semaine de décharge est une semaine de récupération planifiée où tu t'entraînes avec une intensité réduite pour permettre à ton corps de récupérer complètement avant le prochain bloc d'entraînement. Appuie sur Marquer comme semaine de décharge sur l'écran de vue d'ensemble du programme pour indiquer que la semaine en cours est une décharge. Pendant que la décharge est active, le questionnaire de feedback après exercice n'apparaît pas et aucun nouvel état de progression n'est créé ou mis à jour, de sorte que ton historique de suggestions n'est pas perturbé par les séances plus légères. La décharge se réinitialise automatiquement au début de la semaine suivante et le feedback normal ainsi que le suivi de progression reprennent sans aucune action manuelle. Si tu changes d'avis, appuie à nouveau sur le bouton pendant que la décharge est active pour l'annuler.\"],\"Ov8o8m\":[\"Démarrer le programme\"],\"OwNTSr\":[\"Enregistrer dans le programme\"],\"Owchfv\":[\"Récemment utilisé\"],\"OzAZw8\":[\"Cet écran n'existe pas.\"],\"P0mjNu\":[\"Supprimer l'entrée\"],\"P0svFp\":[\"Repos\"],\"P1svYv\":[\"abdominaux\"],\"P247ya\":[\"Partie du corps *\"],\"P3NwXY\":[\"Partager l'entraînement\"],\"P3nVsi\":[\"\\n📅 Nouveau : Planning hebdomadaire pour ton programme !\\n\\nTu peux maintenant assigner des entraînements à des jours de la semaine spécifiques directement dans l'éditeur de programme. Appuie sur n'importe quel jour pour choisir un entraînement ou le marquer comme jour de repos. Utilise le bouton de suggestion automatique pour générer instantanément un planning équilibré basé sur ton objectif hebdomadaire.\\n\"],\"P3omNB\":[\"Sélectionne un entraînement\"],\"PBt59F\":[\"Exercices favoris\"],\"PFcCy0\":[\"x \",[\"0\"],\" rép. \"],\"PHWHEO\":[\"Tout accepter\"],\"PITZNx\":[\"poitrine\"],\"PN5Zzf\":[\"Unité de poids\"],\"PNapeY\":[\"+ Ajouter\"],\"POx12e\":[\"\\n↕️ Nouveau : Réorganiser les exercices dans la vue d'ensemble de l'entraînement !\\n\\nTu peux maintenant glisser-déposer les exercices et les superseries pour les réorganiser directement depuis la vue d'ensemble de l'entraînement pendant une séance.\\n\"],\"PSNHRi\":[\"* fonctionnalités en développement\"],\"PWfg7v\":[\"Demandes\"],\"P_0oX-\":[\"Assisté\"],\"PeTE4m\":[\"Programme introuvable.\"],\"PiK6Ld\":[\"Sam\"],\"PruBpO\":[\"Es-tu sûr de vouloir supprimer cette entrée de mesure ?\"],\"Q1Lq8I\":[\"Temps total\"],\"Q2QJ28\":[\"Jouer le son de l'objectif atteint (Minuterie d'exercice)\"],\"Q8bEQa\":[\"Une erreur s'est produite lors de la suppression des images.\"],\"Q9qAkA\":[\"Durée estimée : \",[\"0\"]],\"QENBWX\":[\"triceps\"],\"QOTvot\":[\"Partager ton contenu\"],\"Qdwk82\":[\"Incrément de charge pour les haltères\"],\"Qjp-BQ\":[\"Ajouter une série\"],\"QlT4B5\":[\"Sessions récentes\"],\"Qmbwcr\":[\"Modifier le programme\"],\"QoHy-T\":[[\"weeks\",\"plural\",{\"one\":[\"il y a \",\"#\",\" semaine\"],\"other\":[\"il y a \",\"#\",\" semaines\"]}]],\"QrwEaQ\":[\"pectoraux\"],\"QzJCdZ\":[\"dorsaux\"],\"R-ABt9\":[\"Objectif hebdomadaire\"],\"R0gwbc\":[\"biceps\"],\"RAMaAx\":[\"Reçues\"],\"RCk1J0\":[\"machine à traîneau\"],\"RGfnXX\":[\"(jusqu'à l'échec)\"],\"RIHmRj\":[\"Bon rythme. Essaie d'ajouter une rep par série avant d'augmenter la charge.\"],\"RM5DG6\":[\"Exercices suivis\"],\"RN4XJV\":[\"Jour de repos\"],\"RU6ELr\":[\"Stats et historique\"],\"RXkbtG\":[\"Pousser plus fort la prochaine fois ?\"],\"RY_JyV\":[\"bas du dos\"],\"R_h8B2\":[\"Le plus utilisé\"],\"Rc-8oy\":[\"Téléchargement de la mise à jour\"],\"RmahBs\":[[\"0\"],\": \",[\"best\"],\"s (+\",[\"delta\"],\"s, \",[\"pctStr\"],\")\"],\"Rr5U7J\":[\"Les séries terminées apparaîtront ici\"],\"Rwc-xL\":[\"Record de temps\"],\"RxzN1M\":[\"Activé\"],\"S2uNE5\":[\"Continuer l'édition ?\"],\"SEyweA\":[\"\\n🐛 Correctif : Divers correctifs et améliorations !\\n\\nCorrection de la notification de minuterie de repos qui ne se déclenchait pas correctement, du retour à la ligne du nom de l'exercice pendant la séance, de la largeur du cercle de fin d'entraînement, des notes qui ne se mettaient pas à jour correctement pendant la saisie, et des détails d'entraînement qui s'ouvraient parfois dans le mauvais onglet. Les entraînements se chargent maintenant plus vite grâce à des améliorations de performances internes.\\n\"],\"SGISp8\":[\"Tu as tout fini à la limite. Reste là et prends-en possession.\"],\"SRhtpX\":[\"avant-bras\"],\"SUd4dA\":[\"\\n📏 Nouveau : Mesures corporelles !\\n\\nSuis ta composition corporelle en parallèle de tes entraînements depuis la nouvelle section Mesures de l'onglet Statistiques.\\n\\n• Enregistre poids, % de masse grasse, tour de taille, hanches, poitrine et plus\\n• Appuie sur une entrée passée pour modifier les valeurs ou consulter un graphique\\n• Gère les mesures affichées et ajoute tes propres mesures personnalisées\\n• Les unités suivent tes préférences de poids et de taille dans Paramètres\\n\"],\"SWtay1\":[\"Après avoir terminé la dernière série de travail d'un exercice, un questionnaire de feedback apparaît avec deux questions. La première demande comment l'effort s'est ressenti : Facile (tu aurais pu faire plus), À peu près bien, Difficile (proche de ta limite) ou Pas réussi à finir toutes les séries. La deuxième porte sur la douleur : Pas de douleur, Légère gêne ou Douleur ou problèmes de forme. Si tu réponds Facile, une troisième question apparaît pour savoir si tu veux te surpasser la prochaine fois. Cela te permet de maintenir délibérément la charge actuelle même quand une séance s'est sentie légère, de sorte que le système respecte ton intention. Si tu réponds Douleur, un champ de texte optionnel te permet de noter où tu l'as ressenti pour ta propre référence. Le questionnaire peut être fermé sans répondre si tu préfères ne pas enregistrer de feedback pour cet exercice lors de cette séance.\"],\"SZw9tS\":[\"Voir les détails\"],\"SadoC9\":[\"Smith machine\"],\"SbGW67\":[\" (jusqu'à l'échec) \"],\"ScJ9fj\":[\"Politique de confidentialité\"],\"SdpDoo\":[\"Partager les entraînements avec mes amis\"],\"SlfejT\":[\"Erreur\"],\"SmkA26\":[\"1RM \",[\"0\"],\" \",[\"unit\"]],\"SoWD_0\":[\"Enregistrer la série\"],\"SrVzRe\":[\"Pourcentage\"],\"St3y2e\":[\"Nom requis\"],\"SvOMfA\":[[\"0\"],\" entraînements\"],\"SzQe8k\":[\"Ajouter à mes exercices\"],\"T0cOwV\":[\"Supprimer la série\"],\"T7QVyK\":[\"Quand tu ouvres un entraînement contenant des exercices que tu as pratiqués récemment, une feuille de Bilan de récupération apparaît si ces exercices ont une suggestion de progression en attente et que ta dernière séance remonte à au moins 12 heures. Pour chaque groupe musculaire concerné, tu choisis une de trois options : Frais (complètement récupéré), Légère courbature ou Encore très courbaturé. Si un muscle est marqué comme encore très courbaturé, toute suggestion de progression à la hausse pour les exercices ciblant ce muscle est mise en pause et maintenue à la charge actuelle jusqu'à ce que tu réévalues au début de la séance suivante. Frais ou Légère courbature ne modifie pas les suggestions. Appuie sur Passer pour l'instant pour contourner le bilan entièrement ; un bilan ignoré est traité comme une récupération complète, donc les suggestions en attente ne sont pas affectées.\"],\"TBTwj-\":[\"Suivre MuscleQuest sur Instagram\"],\"TJLDrx\":[\"Poids doublé pour le calcul du volume\"],\"T_qHwF\":[\"bas des jambes\"],\"Ta25TG\":[\"Aucun historique\"],\"Tfzp6S\":[\"Partager les records de force avec mes amis\"],\"TpqeIh\":[\"Erreur : \",[\"0\"]],\"Tz0i8g\":[\"Paramètres\"],\"TzLpDD\":[\"\\n🏋️ Nouveau : Entraînements autonomes et entraînements rapides !\\n\\nCrée des entraînements autonomes en dehors de tes programmes d'entraînement, parfaits pour les séances flexibles, le travail de mobilité ou tout ce qui se présente. Retrouve-les dans l'écran Programmes.\\n\\nOu démarre un Entraînement rapide depuis l'accueil, ajoute des exercices à la volée, et sauvegarde-le éventuellement comme entraînement autonome quand tu as terminé.\\n\"],\"U0HZma\":[\"Suivi\"],\"U4QKsL\":[\"Masquer / Afficher l'introduction\"],\"U8BTVm\":[\"Temps de repos restant :\"],\"UCtAiM\":[\"Pour activer les notifications de la minuterie de repos, autorise les notifications dans les paramètres de ton appareil.\"],\"UD8kHo\":[\"Suivant : \",[\"workoutName\"],\" le \",[\"0\"]],\"URmyfc\":[\"Détails\"],\"US8F_H\":[\"Plus de reps suggérées\"],\"USXXjt\":[\"Aucun résultat pour « \",[\"query\"],\" »\"],\"U_-GrY\":[\"Veuillez patienter pendant le téléchargement de la dernière version...\"],\"UbRKMZ\":[\"En attente\"],\"UlnAQR\":[\"Impossible de supprimer l'entraînement. Réessaie.\"],\"UneMBz\":[\"Programme actif\"],\"UnnFak\":[\"Super début de semaine !\"],\"Uorrgj\":[\"rhomboïdes\"],\"Uu14s5\":[[\"0\",\"plural\",{\"one\":[\"#\",\" série\"],\"other\":[\"#\",\" séries\"]}]],\"UyvU3-\":[\"Aide & infos\"],\"UzNvmf\":[\"• Sauvegarder et restaurer les données\"],\"V6wjuJ\":[\"Le type de suivi est obligatoire.\"],\"V6xf0O\":[\"Cet exercice est déjà dans ton entraînement. Choisis-en un autre.\"],\"V8MVAm\":[\"pectoraux supérieurs\"],\"V8dVu4\":[\"\\n🔗 Nouveau : Superseries !\\n\\nAssocie deux exercices en superserie directement dans l'éditeur de programme. Les séries sont synchronisées entre les deux exercices, et les superseries sont clairement regroupées avec un indicateur visuel dans toute l'application.\\n\"],\"V8yTm6\":[\"Effacer la recherche\"],\"VAcXNz\":[\"Mercredi\"],\"VCJb5r\":[\"Série \",[\"0\"],\" sur \",[\"totalSets\"]],\"VDkJml\":[\"La Progression adaptative analyse ton feedback d'effort sur des séances consécutives et suggère quand augmenter ton poids, tes reps ou tes séries. Active-la dans Paramètres, sous Progression adaptative. Une fois activée, une courte question de feedback apparaît après chaque exercice dans les entraînements basés sur un programme. Le système nécessite deux séances avec le même signal avant de recommander une augmentation, ce qui filtre les jours ponctuellement faciles et garantit une performance constante avant de suggérer une hausse. La douleur ou les séries non terminées sont prises en compte immédiatement, quelle que soit ton historique de séances. Une suggestion n'est jamais appliquée à ton entraînement sans ton accord explicite. Tu peux aussi configurer ton incrément de charge préféré par catégorie d'équipement dans la même section des Paramètres, par exemple 2,5 kg pour les exercices à la barre et 2,0 kg pour les haltères.\"],\"VFlRXJ\":[\"Maintenir comme ça cette séance.\"],\"VJVR1o\":[\"Partager le programme\"],\"VcD4kW\":[\"Cet ami n'a encore partagé aucun contenu.\"],\"VhVOxx\":[\"Ton voyage vers Swoletown commence aujourd'hui !\"],\"VhfZbD\":[\"Taille : ~100 Mo\"],\"W-pY1H\":[\"Impossible de sauvegarder l'exercice personnalisé. Réessaie.\"],\"W0qDyY\":[\"Écran d'accueil et objectif hebdomadaire\"],\"W3QcBP\":[\"Vue d'ensemble du programme\"],\"W3u9nh\":[\"Jusqu'à l'échec, \"],\"WDciil\":[\"\\n📋 Nouveau : Menu \\\"Plus\\\" et section Aide & infos !\\n\\nIl y a un nouvel onglet \\\"Plus\\\" dans la barre de navigation. Appuie dessus pour ouvrir un panneau coulissant où tu trouveras les Paramètres et une toute nouvelle section Aide & infos.\\n\\nLes Paramètres ont été déplacés ici depuis la barre d'onglets, et Aide & infos couvre tout, des programmes et entraînements aux stats et à ton compte, avec une barre de recherche pour trouver rapidement des réponses.\\n\"],\"WHwUfF\":[\"Erreur lors du chargement des détails de l'exercice\"],\"WIbOhZ\":[\"Progression adaptative\"],\"WJp2MH\":[\"Unité de taille\"],\"WKHqM-\":[\"Poids\"],\"WMvAhQ\":[\"Les exercices personnalisés que tu crées ou modifies sont partagés automatiquement.\"],\"WOi4Vm\":[\"Nom *\"],\"WSzg3A\":[\"Distance (\",[\"distanceUnit\"],\")\"],\"WU-3OC\":[\"Unilatéral bras / jambe\"],\"WaIjmh\":[\"Mollet (D)\"],\"Wjxizh\":[\"Toutes les données partagées ont été supprimées.\"],\"WoEX6M\":[\"Suggérer des ajustements de charge et de reps\"],\"WzcO-J\":[\"Créer un programme\"],\"X9kySA\":[\"Favoris\"],\"X9r6cu\":[[\"goal\",\"plural\",{\"one\":[[\"completed\"],\" sur \",\"#\",\" entraînement cette semaine\"],\"other\":[[\"completed\"],\" sur \",\"#\",\" entraînements cette semaine\"]}]],\"XBUsEY\":[\"Muscle ciblé\"],\"XHHEUg\":[\"Personnaliser le programme\"],\"XJQdl_\":[\"Envoyer une notification en arrière-plan après le repos\"],\"XNRDYn\":[\"extenseurs du poignet\"],\"XdavYY\":[\"Entraînements\"],\"Xdcdfd\":[\"Séries et exercices\"],\"XoEooZ\":[\"Temps (s)\"],\"Xu14OQ\":[[\"0\",\"plural\",{\"one\":[\"#\",\" Rép.\"],\"other\":[\"#\",\" Rép.\"]}]],\"Xu2iGM\":[\"Ajouter du poids\"],\"Xv4OIW\":[\"Entraînement en cours\"],\"Xwd4Hm\":[\"coiffe des rotateurs\"],\"Y35ibG\":[\"Les records de force sont partagés automatiquement après chaque entraînement.\"],\"Y6QE0T\":[\"Sélectionner l'équipement\"],\"YANNVr\":[\"Entraînement\"],\"YDnEIW\":[\"Meilleur gain\"],\"YIix5Y\":[\"Rechercher...\"],\"YLIqcF\":[\"Bon retour\",[\"userName\"]],\"YXJbW8\":[\"Les entraînements indépendants sont en dehors des programmes et apparaissent avec tes programmes dans l'onglet Programmes. Crée-en un en appuyant sur Nouvel entraînement, donne-lui un nom et ajoute des exercices ; tu peux le lancer à tout moment sans avoir besoin d'un programme actif. Une durée estimée est affichée sur chaque entraînement indépendant pour que tu puisses planifier ton temps avant de commencer. Les entraînements rapides te permettent de démarrer une séance immédiatement depuis l'écran d'accueil : appuie sur Entraînement rapide, ajoute des exercices au fur et à mesure, et à la fin tu peux le sauvegarder comme entraînement indépendant pour une utilisation future ou simplement l'ignorer. Comme les programmes, l'éditeur d'entraînement sauvegarde automatiquement un brouillon.\"],\"YYzBv9\":[\"Lu\"],\"YekWWq\":[[\"0\",\"plural\",{\"one\":[\"#\",\" rép.\"],\"other\":[\"#\",\" rép.\"]}]],\"YiPU_R\":[\"deltïödes\"],\"YnHdfF\":[\"Série \",[\"0\"]],\"Yr-t8O\":[\"pieds\"],\"YuP-pS\":[\"« \",[\"label\"],\" » sera masqué du formulaire de saisie. Tes données historiques sont conservées.\"],\"Z3FXyt\":[\"Chargement...\"],\"Z8RW4m\":[\"Après avoir terminé un entraînement, l'écran de Résumé d'entraînement affiche une carte Prochaine séance listant des suggestions concrètes pour tes exercices. Chaque ligne indique le nom de l'exercice, le changement proposé (un nouveau poids cible, une plage de reps plus large ou une note pour réduire la charge) et une brève explication du pourquoi du changement suggéré. Appuie sur Accepter pour appliquer la suggestion à cet exercice pour ta prochaine séance, ou sur Ignorer pour la rejeter. Les suggestions acceptées sont pré-remplies dans les champs de poids et de reps la prochaine fois que tu ouvres cet entraînement, pour que tu commences la séance en visant déjà la bonne charge. Le bouton Tout accepter en haut applique toutes les suggestions en une fois. Les suggestions qui recommandent de maintenir la charge actuelle n'apparaissent pas dans la carte, car aucune action n'est nécessaire pour celles-là.\"],\"ZARyDw\":[\"Ajouter des amis\"],\"ZAWGCX\":[[\"0\"],\" secondes\"],\"ZAvcCf\":[[\"0\"],[\"weightUnit\"],\" × \",[\"1\"]],\"ZI8idP\":[\"Frais, complètement récupéré\"],\"Zm9Eu3\":[\"Taille des boutons pendant l'entraînement\"],\"Zv7vjq\":[\"Partager les programmes avec mes amis\"],\"Zvc_N1\":[\"1RM (\",[\"weightUnitLabel\"],\")\"],\"_-nVtu\":[\"C'était facile. On maintient pour l'instant et on confirme à la prochaine séance.\"],\"_2fO4v\":[\"Résumé de l'entraînement\"],\"_D5y8a\":[\"Séries par défaut\"],\"_K9jUO\":[\"ergomètre du haut du corps\"],\"_P2B4j\":[[\"biggestGainLabel\"],\" 1RM\"],\"_RhvUo\":[\"paramètres\"],\"_UGS0C\":[\"Nom de l'entraînement\"],\"_W-KPJ\":[\"Aucune mesure pour l'instant. Appuie pour enregistrer ta première entrée.\"],\"_WRCmH\":[[\"0\"],\" \",[\"1\"],\" | \",[\"2\"],\" Rép.\"],\"_XczSN\":[\"Sélectionner le muscle cible\"],\"_cF7Rs\":[\"Volume\"],\"_f5DAr\":[\"Terminé le : \",[\"formattedDate\"]],\"a2Fu8q\":[\"Tu peux te connecter à tout moment depuis l'écran Paramètres, si tu choisis de passer pour l'instant.\"],\"a5BPTT\":[\"kettlebell\"],\"a8SF50\":[\"Ajoute un bouton de publication par entraînement.\"],\"a8TA11\":[\"Prochaine séance\"],\"a99tuk\":[\"Active pour ajouter un bouton de publication à chaque programme.\"],\"aAIQg2\":[\"Apparence\"],\"aMwZcE\":[\"Bras (G)\"],\"aN_GPe\":[\"Où tu l'as ressenti ?\"],\"aRwEh5\":[\"Partager les exercices personnalisés avec mes amis\"],\"ahW3x6\":[\"\\n📅 Nouveau : Calendrier d'entraînement !\\n\\nAppuie sur l'icône de calendrier dans la section Historique des entraînements de l'onglet Stats pour consulter ton historique par date. Les jours avec des entraînements sont mis en évidence, et appuyer sur un jour affiche les séances enregistrées ce jour-là.\\n\"],\"aj6ZJx\":[\"Connexion avec Google\"],\"b3e7Re\":[\"Redémarrer l'appli\"],\"b63Dw_\":[\"Aucun utilisateur trouvé avec cette adresse e-mail.\"],\"b9OAHS\":[\"Ajouter un échauffement\"],\"bFeIdj\":[\"Série dégressive\"],\"bQdjFX\":[[\"0\"],\" note\"],\"bRAv_4\":[\"Entraînement \",[\"0\"]],\"bZS72M\":[[\"setsCount\",\"plural\",{\"one\":[\"#\",\" série\"],\"other\":[\"#\",\" séries\"]}]],\"bosqpS\":[\"Aucun entraînement terminé. Lance ton premier entraînement !\"],\"bqb_ci\":[\"\\n🐛 Correctif : Boutons de séance et modal de modification de série !\\n\\nCorrection d'un bug où tous les boutons (incrémenter/décrémenter, série suivante/précédente, terminer la série) cessaient de fonctionner après avoir terminé une série. Correction aussi d'une erreur dans le modal de modification de série. Les transitions de série se font maintenant instantanément pour un entraînement plus fluide.\\n\"],\"bwd2oE\":[\"Minuterie de repos terminée !\"],\"bzSI52\":[\"Abandonner\"],\"c2TGz5\":[[\"completed\"],\" entraînements cette semaine. Tu as explosé ton objectif !\"],\"c7AAAa\":[\"\\n📈 Beta : Progression adaptative !\\n\\nMuscleQuest peut maintenant te suggérer quand augmenter ton poids ou tes reps selon ce que tu ressens pendant tes séances. Après chaque exercice, réponds à deux questions rapides sur l'effort et la douleur. Dès que tu as signalé le même résultat deux séances de suite, l'app suggère un changement. Toutes les suggestions apparaissent sur l'écran de Résumé d'entraînement, où tu peux accepter ou rejeter chacune individuellement. Les suggestions acceptées sont pré-remplies dans ta prochaine séance automatiquement.\\n\\nUn Bilan de récupération au début de ton prochain entraînement te permet de prendre en compte les courbatures avant d'appliquer une suggestion. Tu peux aussi marquer une semaine entière comme semaine de décharge depuis la vue d'ensemble du programme, ce qui met en pause le feedback et le suivi de progression pour cette semaine.\\n\\nActive-le dans Paramètres, sous Progression adaptative, et configure ton incrément de charge préféré par catégorie d'équipement.\\n\"],\"cCbON-\":[\"\\n🔥 Amélioré : Gestion des séries d'échauffement !\\n\\nLes séries d'échauffement sont visuellement regroupées et stylisées séparément des séries de travail, et \\\"Appliquer à tous\\\" te permet de modifier en masse les séries d'échauffement ou de travail indépendamment.\\n\"],\"cF5b-5\":[[\"weeklyGoal\",\"plural\",{\"one\":[\"Suggestion auto (\",\"#\",\" jour)\"],\"other\":[\"Suggestion auto (\",\"#\",\" jours)\"]}]],\"cI6f7l\":[\"30 j\"],\"cU45Co\":[\"Ajouter un entraînement\"],\"cUD6H0\":[\"Prépare-toi...\"],\"cUY9dI\":[\"Tu es sûr de vouloir supprimer cet exercice ?\"],\"ckJ-os\":[\"Muscles\"],\"cnGeoo\":[\"Supprimer\"],\"crwali\":[\"Rappels\"],\"ctrAML\":[\"N'oublie pas de suivre ta progression !\"],\"cyR8-W\":[\"\\n🕐 Nouveau : Estimation de la durée d'entraînement !\\n\\nChaque carte d'entraînement affiche maintenant une durée estimée pour que tu puisses planifier tes séances d'un coup d'œil avant de commencer.\\n\"],\"d1z1ZY\":[\"La minuterie de repos démarre automatiquement après chaque série et compte à rebours jusqu'à zéro. Chaque série mémorise sa propre durée de repos, donc différentes séries au sein du même exercice peuvent avoir des durées de repos différentes. Utilise les boutons ± pour ajuster le temps restant à la volée pendant le repos. Configure la durée de repos par défaut, l'incrément de la minuterie, et si un son, une vibration ou une notification en arrière-plan se déclenche à la fin ; chaque option peut être activée/désactivée indépendamment dans les Paramètres.\"],\"dEgA5A\":[\"Annuler\"],\"dH9Y4t\":[\"Aucun entraînement ce jour-là.\"],\"dVK-Er\":[\"Une erreur d'affichage s'est produite. Appuie sur le bouton pour recharger.\"],\"dXCD6-\":[\"Télécharger toutes les animations d'exercices\"],\"dXoieq\":[\"Résumé\"],\"dYOPCE\":[\"Assisté \",[\"0\"],\" \",[\"1\"],\" | Résistance \",[\"2\"],\" \",[\"3\"],\" | \",[\"4\"],\" Rép.\"],\"dbWo0h\":[\"Se connecter avec Google\"],\"deoJBi\":[[\"0\"],\" rép.\"],\"dfunKV\":[\"Poids/Rép.\"],\"dpOqdQ\":[\"Jusqu'à l'échec\"],\"dqjuBA\":[\"90 j\"],\"dx0cCC\":[\"Garde le rythme !\"],\"e0dGJ7\":[\"Avantages de la connexion :\"],\"e0l-Z0\":[[\"scheduledDays\",\"plural\",{\"one\":[\"#\",\" jour/sem.\"],\"other\":[\"#\",\" jours/sem.\"]}]],\"e52k4Y\":[\"Ouvre l'onglet Amis depuis le menu pour gérer tes connexions. Utilise la barre de recherche pour trouver d'autres utilisateurs par nom d'utilisateur et leur envoyer une demande d'ami. Les demandes entrantes apparaissent dans l'onglet Demandes ; appuie sur Accepter pour confirmer ou Refuser pour ignorer. Un badge sur l'élément Amis du menu indique combien de demandes sont en attente. Une fois une demande acceptée, les deux utilisateurs apparaissent dans la liste d'amis de l'autre et peuvent voir le contenu partagé de l'autre.\"],\"e5h2IT\":[[\"0\"],\" notes\"],\"e9qdcV\":[\"Légère gêne\"],\"eLA0I2\":[\"Télécharger les images\"],\"eQm4BH\":[\"Après avoir terminé un entraînement, un écran récapitulatif affiche ta durée totale, les séries terminées et le volume total. Si tu as déjà effectué le même entraînement, une ligne de comparaison indique comment chaque indicateur se compare à la session précédente. Une bannière d'objectif hebdomadaire montre combien de séances tu as enregistrées cette semaine par rapport à ton objectif. Appuie sur n'importe quel exercice dans la liste pour le développer et consulter chaque série en détail. Lors d'un Entraînement rapide, tu seras invité à le sauvegarder comme entraînement autonome pour une utilisation future ou à le supprimer.\"],\"eYbd7b\":[\"Di\"],\"ecUA8p\":[\"Aujourd'hui\"],\"ehOkF-\":[\"Bases\"],\"emOtYn\":[\"Programmes prêts à l'emploi\"],\"enD4RG\":[\"Impossible d'ajouter cet exercice. Réessaie.\"],\"ez-cQL\":[\"\\n🔔 Nouveau : Notifications de rappel d'entraînement !\\n\\nNe rate plus jamais une séance. Configure des rappels pour tes entraînements directement depuis l'application. Choisis les jours où tu veux être rappelé et une heure pour commencer.\\n\"],\"f2yjAZ\":[\"Pas de douleur\"],\"f7pPKh\":[\"Cuisse (G)\"],\"f8Vl8d\":[\"Nom de la mesure\"],\"fFHHFp\":[\"Mesures\"],\"fPpo2L\":[\"Superserie\"],\"fQWEzC\":[\"Aucun programme partagé pour l'instant\"],\"fSu2Jl\":[\"Une nouvelle version a été téléchargée. Appuie sur le bouton ci-dessous pour redémarrer et appliquer la mise à jour.\"],\"fWsBTs\":[\"Une erreur est survenue. Réessaie.\"],\"fXVIZq\":[\"Valeurs\"],\"f_bxrN\":[\"Le nom est obligatoire.\"],\"feWdkU\":[\"Recommencer l'entraînement\"],\"fj5byd\":[\"N/A\"],\"fpMgHS\":[\"Lun\"],\"fqSfXY\":[\"Remplacer\"],\"fsJAR5\":[\"Incrément de charge pour la barre\"],\"ftiGCv\":[\"Tout l'équipement\"],\"fvyzOr\":[\"haut du dos\"],\"g36TSx\":[\"Unité de distance\"],\"g3UF2V\":[\"Accepter\"],\"g3cPNV\":[\"Active pour partager automatiquement chaque mesure corporelle enregistrée.\"],\"gCVtjC\":[[\"0\"],\" Séries\"],\"gEOgEq\":[[\"0\"],\" Exercices\",[\"1\"]],\"gQYPDg\":[\"−\",[\"restTimerIncrement\"],\"s\"],\"gTdjGc\":[\"Impossible de supprimer l'entraînement. Réessaie.\"],\"giOl9F\":[\"Cuisse (D)\"],\"gkn1WJ\":[\"Exercice déjà ajouté\"],\"gloTI5\":[\"Appuie sur n'importe quel ami accepté dans ta liste d'amis pour ouvrir son profil. Son profil affiche les programmes, entraînements solo et exercices personnalisés qu'il a choisi de partager. Appuie sur Importer sur n'importe quel élément pour l'ajouter directement à ta propre bibliothèque. Les programmes et entraînements importés sont sauvegardés comme de nouvelles copies que tu peux modifier librement sans affecter l'original. Les exercices personnalisés importés sont ajoutés à ta bibliothèque d'exercices et disponibles immédiatement lors de la création d'entraînements.\"],\"gzBfh2\":[\"Aucune série disponible\"],\"h-DKuf\":[\"vs. dernier « \",[\"0\"],\" »\"],\"h2ALJf\":[\"fessiers\"],\"h69WC6\":[\"Envoyées\"],\"h7CU4q\":[\"Comment tu t'es senti ?\"],\"hBjQ0O\":[[\"0\",\"plural\",{\"one\":[\"#\",\" entraînement\"],\"other\":[\"#\",\" entraînements\"]}]],\"hF_t4W\":[\"Volume (\",[\"volumeUnit\"],\")\"],\"hLONcx\":[\"Sauvegarder et restaurer\"],\"hPXEuO\":[\"En paire avec \",[\"0\"]],\"hXzOVo\":[\"Suivant\"],\"hnJ2UC\":[\"brachial\"],\"hnlGzG\":[\"Passer pour l'instant\"],\"hnrFBk\":[\"Jours de rappel\"],\"hp8OtS\":[\"Ajouté\"],\"hpsdvR\":[\"\\n📋 Nouveau : Voir les détails d'un entraînement depuis l'accueil !\\n\\nTu peux maintenant appuyer sur n'importe quel entraînement récent depuis l'accueil pour voir ses détails complets. Chaque entraînement et vue d'ensemble des séries dispose aussi d'un nouveau bouton de détails pour accéder rapidement aux informations sur les exercices.\\n\"],\"hsoeHo\":[\"Détails de l'entraînement\"],\"hty0d5\":[\"Lundi\"],\"hupMcg\":[\"Retirer cet ami ? Il ne pourra plus voir ton contenu partagé.\"],\"hvfche\":[[\"scheduledCount\",\"plural\",{\"one\":[\"#\",\" jour/sem.\"],\"other\":[\"#\",\" jours/sem.\"]}]],\"i-mS1s\":[\"Les données partagées restent visibles par tes amis jusqu'à ce que tu les supprimes ci-dessous.\"],\"i-tNaY\":[\"Assistance/Rép.\"],\"i09UfG\":[\"Équipement :\"],\"i0qMbr\":[\"Accueil\"],\"i4Vk1Q\":[\"Exercices du programme actif\"],\"i6f8rt\":[\"Démarrage de l'entraînement...\"],\"iGokZG\":[\"Incrément de charge pour la poulie\"],\"iHjmbB\":[\"Ajouté à mes programmes\"],\"iHmyze\":[\"Exercices\"],\"iO73Kk\":[\"Tu peux partager tes programmes, entraînements solo, exercices personnalisés, mesures corporelles et records de force avec tes amis. Les cinq catégories ont un interrupteur global dans les Paramètres de confidentialité, dans la section Compte des Paramètres. Activer l'interrupteur global d'une catégorie partage tous les éléments de cette catégorie et synchronise automatiquement les nouvelles données à chaque modification. Les programmes et entraînements solo ont aussi un interrupteur Partager individuel sur l'écran de présentation de chaque élément, ce qui te permet de publier des programmes ou entraînements spécifiques sans tout partager. Une icône nuage sur la carte programme ou entraînement confirme qu'il est actuellement publié. Pour supprimer des données partagées, désactive l'interrupteur dans les Paramètres de confidentialité et appuie sur Supprimer les données partagées pour cette catégorie. Tu peux aussi supprimer toutes les données partagées de chaque catégorie depuis le même écran.\"],\"iQyKX1\":[\"Tu as choisi de maintenir. La charge reste comme ça.\"],\"iV1Jat\":[\"Tu es sûr de vouloir supprimer cette série ?\"],\"iYfCFU\":[\"Afficher l'accueil sur l'écran principal\"],\"i_48Se\":[\"Programme actif : \",[\"0\"]],\"i_nB8P\":[\"Aucun planning défini\"],\"ifRQL2\":[\"Série dégressive, \"],\"ikOJPT\":[\"tibias\"],\"irLwtB\":[\"Programme d'entraînement\"],\"irrqfe\":[\"Mesures personnalisées\"],\"iuwbqi\":[\"Impossible de sauvegarder l'entraînement. Réessaie.\"],\"ivpCYv\":[\"Abandonner les modifications ?\"],\"j-MPXl\":[\"Sauvegarde et restauration\"],\"jDTG0T\":[\"Suggestions de progression\"],\"jDh_CH\":[\"Les programmes sont des plans d'entraînement structurés composés de séances. Pour en créer un, va dans l'onglet Programmes, appuie sur Nouveau programme, donne-lui un nom et choisis une image de couverture. Ajoute des entraînements au programme, puis ajoute des exercices à chaque entraînement avec des séries et répétitions cibles. Utilise les boutons fléchés haut/bas d'une carte d'entraînement pour la réorganiser, ou le bouton X pour la supprimer ; les deux se trouvent en haut à droite de la carte. Assigne des entraînements à des jours spécifiques de la semaine dans l'éditeur de planning : appuie sur un jour pour choisir un entraînement ou le laisser comme jour de repos, et utilise le bouton de suggestion automatique pour les espacer régulièrement. Une fois ton programme prêt, ouvre-le et appuie sur Activer. Tu peux aussi ajouter des notes depuis l'écran de vue d'ensemble du programme. Chaque carte d'entraînement affiche une durée estimée avec le nombre d'exercices pour que tu puisses évaluer la longueur d'une séance d'un coup d'œil. Utilise les icônes de vue à côté du titre « Tes plans d'entraînement » pour basculer entre les affichages Carrousel, Liste et Grille ; ton affichage préféré est sauvegardé automatiquement. Ta progression dans l'éditeur est automatiquement sauvegardée comme brouillon, donc si tu le quittes en cours d'édition, tu seras invité à reprendre là où tu en étais ou à ignorer et repartir du dernier état sauvegardé.\"],\"jYjrmQ\":[\"Dernière sauvegarde : \",[\"0\"]],\"jbq7j2\":[\"Refuser\"],\"jfzZZ0\":[\"Ignorer la connexion\"],\"jpVuia\":[\"Enregistrer les modifications de l'entraînement ?\"],\"jxTU3u\":[\"machine Stepmill\"],\"jzJENZ\":[\"Suis ta progression\"],\"k4kpgL\":[\"Bienvenue dans MuscleQuest, ton compagnon de musculation personnel. Utilise ce guide pour découvrir les fonctionnalités et tirer le meilleur de ton entraînement.\"],\"k5alGf\":[\"Aucun entraînement partagé pour l'instant\"],\"k7Oi68\":[\"haut des jambes\"],\"kDJ_Ja\":[\"Bonne séance. Garder cette charge.\"],\"kFoQmI\":[\"abducteurs\"],\"kILzHz\":[\"Ajouter (\",[\"0\"],\")\"],\"kQe_xM\":[\"Douleur signalée. La charge reste inchangée jusqu'à ce que tu ailles mieux.\"],\"kSi1ha\":[\"+\",[\"suggestedWeight\"],[\"unit\"],\" suggéré\"],\"kdwbaT\":[\"Tout ignorer\"],\"kf4tdd\":[\"Sélectionner le type de suivi\"],\"kfxr8q\":[\"\\n📊 Nouveau : Résumé d'entraînement !\\n\\nAprès avoir terminé un entraînement, tu verras maintenant un résumé complet de ta séance : durée totale, séries et volume, plus une comparaison avec ta séance précédente. Appuie sur n'importe quel exercice pour afficher ses séries et poids individuels.\\n\"],\"kg0oKA\":[\" (jusqu'à l'échec)\"],\"kkDQ8m\":[\"Jeudi\"],\"konUZ1\":[\"Temps de repos par défaut\"],\"kvpjYu\":[\"Entrer le nom de l'exercice\"],\"l1P93s\":[\"Saisir le poids par haltère/câble, pas le total\"],\"l75CjT\":[\"Oui\"],\"lWy5a1\":[\"Programmes\"],\"lY9GM0\":[\"Le muscle cible est obligatoire.\"],\"lkz6PL\":[\"Durée\"],\"llGZy3\":[\"Aucun exercice suivi. Appuie sur + Ajouter pour commencer.\"],\"loRbvf\":[\"Aller à l'écran d'accueil !\"],\"m0YANP\":[\"Tu peux masquer cet écran d'accueil à tout moment depuis la page Paramètres dans la section Apparence. Si tu veux le revoir, tu peux le réactiver depuis la même page.\"],\"m16xKo\":[\"Ajouter\"],\"m2QQkt\":[\"Ajouté à mes entraînements\"],\"m66_4D\":[\"Type de suivi\"],\"mAoTHw\":[\"Certaines images n'ont pas pu être supprimées. IDs des exercices en échec : \",[\"0\"]],\"mDmPnX\":[\"Par semaine (moy.)\"],\"mEQ95z\":[\"Impossible de sauvegarder l'image. Réessaie.\"],\"mF1US0\":[\"Toujours utiliser l'historique le plus récent\"],\"mFQ4KK\":[\"Doubler le poids pour le volume quand le paramètre est activé\"],\"mK5j7_\":[\"\\n🔃 Nouveau : Trie la bibliothèque d'exercices !\\n\\nLa bibliothèque d'exercices a maintenant des chips de tri pour trouver les exercices plus vite. Trie par Par défaut, Programme actif, Récent ou Fréquent pour voir les exercices les plus pertinents pour toi en haut.\\n\"],\"mRTnNi\":[\"Implements appariés\"],\"mSit7t\":[\"Impossible de récupérer les données. Réessaie.\"],\"mSj_dN\":[[\"0\",\"plural\",{\"one\":[\"+\",\"#\",\" de plus\"],\"other\":[\"+\",\"#\",\" de plus\"]}]],\"mT57-Q\":[\"Aller aux Paramètres\"],\"mob_am\":[\"Ve\"],\"mwX_w0\":[\"Changer l'image\"],\"mzI_c-\":[\"Télécharger\"],\"n00ykB\":[\"Tes entraînements\"],\"n1BXGc\":[\"Répartition d'entraînement (par séries)\"],\"n1ekoW\":[\"Se connecter\"],\"nAEGxm\":[\"Oui, augmenter le défi\"],\"nJSX83\":[\"Rappels d'entraînement\"],\"nO6sra\":[[\"0\"],\": \",[\"best\"],\" \",[\"best\",\"plural\",{\"one\":[\"rép.\"],\"other\":[\"rép.\"]}],\" (+\",[\"delta\"],\", \",[\"pctStr\"],\")\"],\"nPGn3W\":[\"Échauffement, \"],\"nkkWxK\":[\"Lance ton parcours fitness avec des programmes conçus par des professionnels. Choisis parmi une variété d'options adaptées à différents objectifs et niveaux. \"],\"nmdLhD\":[\"Rép. : \",[\"repRange\"]],\"nmvpnF\":[\"Aucun exercice personnalisé partagé pour l'instant\"],\"o2XlZw\":[\"Tu es sûr de vouloir supprimer cet entraînement ? Cette action est irréversible.\"],\"oB9lvM\":[\"Exclure les séries d'échauffement des stats\"],\"oOHOWH\":[\"\\n✨ Nouveau : Animations de séance !\\n\\nLa navigation entre les séries propose maintenant des transitions glissantes. Glisse vers la gauche ou la droite pour passer d'une série à l'autre, ou utilise les boutons fléchés existants pour le même effet.\\n\"],\"oOYj_W\":[\"Impossible de charger les entraînements\"],\"oRTTfk\":[\"L'onglet Stats affiche le nombre total d'entraînements, le volume total, le temps total et la durée moyenne des séances sur une période sélectionnable, avec un delta par rapport à la période précédente pour chaque indicateur. Des graphiques affichent le volume hebdomadaire et ta répartition d'entraînement par partie du corps. Parcours l'historique complet de tes entraînements et appuie sur une séance pour revoir chaque série en détail. Tu peux modifier ou supprimer des entraînements terminés depuis l'écran de détails. Appuie sur l'icône calendrier dans la section Historique pour ouvrir une vue calendrier : les jours avec des entraînements sont mis en évidence avec un cercle jaune.\"],\"oRvy2V\":[\"Suivi des exercices\"],\"oXsjxN\":[\"Mollet (G)\"],\"oYZpj8\":[\"• Défis et badges *\"],\"ocEDZS\":[\"Supprimer une série\"],\"oeF-HP\":[\"Impossible de se connecter. Réessaie.\"],\"oeeBm6\":[\"\\n🔔 Nouveau : Notifications de mise à jour dans l'application !\\n\\nUn nouveau modal de mise à jour s'affiche maintenant quand une mise à jour est disponible, pour que tu saches toujours quand des améliorations ont été téléchargées et sont prêtes à être appliquées.\\n\"],\"ofVE0I\":[\"Efface le champ de recherche\"],\"oiHVLP\":[\"Supprimer la superserie\"],\"oqKRAn\":[\"Chaque série peut être marquée comme Échauffement, Série dégressive, Jusqu'à l'échec, ou toute combinaison de ces options. Le badge affiché à côté d'une série indique son type actuel. Pour changer le type pendant une séance, appuie sur le menu (⋮) et active ou désactive l'option correspondante. Lors de la création d'un programme, utilise les cases à cocher dans l'éditeur de séries ; appuie sur Ajouter un échauffement pour insérer une série d'échauffement dédiée en haut de la liste. Les séries d'échauffement sont visuellement regroupées et séparées des séries de travail, et l'option Appliquer à tous dans le modal de modification n'affecte que les séries du même type. Les séries d'échauffement peuvent être exclues des calculs de volume et de stats dans les Paramètres.\"],\"oqUOKk\":[\"Série dégressive\"],\"osILGh\":[\"Distance cible (\",[\"distanceUnit\"],\")\"],\"os_BJP\":[\"Aucune mesure partagée pour l'instant\"],\"ovBPCi\":[\"Par défaut\"],\"ovGl86\":[\"(jusqu'à l'échec) \"],\"p5nYkr\":[\"Tout afficher\"],\"p72uBF\":[\"Aucun programme trouvé\"],\"p8F9k_\":[\"Cou\"],\"pB7xVW\":[\"Records de force\"],\"pBGx0B\":[\"\\n🗂️ Nouveau : Options d'affichage des plans !\\n\\nL'écran Programmes dispose maintenant de trois modes d'affichage. Utilise les icônes à côté du titre « Tes plans d'entraînement » pour basculer entre les vues Carrousel, Liste et Grille. Ton affichage préféré est sauvegardé automatiquement.\\n\"],\"pE7tOx\":[\"Entraînement actif\"],\"pIX6X7\":[\"Instagram de MuscleQuest\"],\"pIuJtP\":[\"Entraînement introuvable.\"],\"pY_gY7\":[\"Record de rép.\"],\"p_C-3G\":[\"Légère courbature\"],\"pbzA-s\":[\"Description facultative\"],\"pfXEaj\":[\"Poids corporel\"],\"pkD36F\":[\"Tu es sûr de vouloir supprimer \\\"\",[\"0\"],\"\\\" ?\"],\"poLmqL\":[\"Choisir depuis l'appareil\"],\"psxXnW\":[\"Connecte-toi avec Google dans les Paramètres pour activer les sauvegardes cloud de toutes tes données d'entraînement. Appuie sur Sauvegarder à tout moment pour créer un instantané ; la date de ta dernière sauvegarde s'affiche sous le bouton. Appuie sur Restaurer pour télécharger et appliquer ta dernière sauvegarde ; confirme l'invite et l'appli se rechargera avec tes données restaurées. Tes sauvegardes sont stockées en sécurité et liées à ton compte Google. Si tu changes d'appareil ou réinstalles l'appli, connecte-toi avec le même compte Google et appuie sur Restaurer pour récupérer tes données.\"],\"pvW0MQ\":[\"Terminer la série\"],\"pwfNCc\":[\"+\",[\"restTimerIncrement\"],\"s\"],\"pz0gzh\":[\"Masquer la mesure\"],\"pzA-xG\":[\"Note des repères importants, des rappels et des insights personnels pour tes exercices, entraînements et programmes. Reste concentré et améliore ta technique avec des notes personnalisées tout au long de ton parcours. Les notes s'enregistrent automatiquement quand tu as terminé de modifier.\"],\"q3pTrs\":[\"Toutes les images supprimées avec succès !\"],\"qIATCE\":[\"\\n📋 Amélioré : Pré-remplissage plus intelligent de l'historique pendant l'entraînement !\\n\\nLes champs de séries se pré-remplissent maintenant de façon plus intelligente. Si un exercice n'a pas d'historique dans l'entraînement en cours, l'app utilise automatiquement la dernière fois que tu l'as effectué dans n'importe quelle séance, pour toujours avoir une référence utile.\\n\\nUn nouveau paramètre dans la section Entraînement te permet d'utiliser toujours l'historique le plus récent de tous tes entraînements, quelle que soit la routine d'origine.\\n\"],\"qJb6G2\":[\"Réessayer\"],\"qP4pOu\":[\"Partager les mesures corporelles avec mes amis\"],\"qQ5ALI\":[\"Enregistrer les modifications du programme ?\"],\"qQ8Xkc\":[\"Incrément de charge pour les machines\"],\"qQLn75\":[\"Sélectionner la partie du corps\"],\"qUSLnH\":[\"Entrer une description\"],\"qZMNNX\":[\"Bras (D)\"],\"qaT7mT\":[\"Tu vas perdre ce que tu as saisi jusqu'à présent.\"],\"qdLLeB\":[\"Entraînements récents\"],\"qdalvN\":[\"Semaine de décharge active. Comparaison en pause.\"],\"qeygIa\":[\"Me\"],\"qlKdB2\":[\"Non, garder comme ça\"],\"qtNMEu\":[\"quadriceps\"],\"qvcKXF\":[\"Bon travail aujourd'hui !\"],\"qvolLq\":[\"Masse\"],\"rCROTr\":[\"Offre-moi un café\"],\"rLgPvm\":[\"Sauvegarde\"],\"rPj8yN\":[\"Autres exercices\"],\"rXJFNV\":[\"Partager les entraînements solo avec mes amis\"],\"rZzMre\":[\"haut des bras\"],\"rickIy\":[\"Enregistrement de l'entraînement...\"],\"rjGI_Q\":[\"Confidentialité\"],\"rlNJuG\":[\"Détail de l'entrée\"],\"rtypiF\":[\"🎉 Nouveautés\"],\"rzjsxH\":[\"Temps (Minutes:Secondes)\"],\"s53UX_\":[\"Volume par semaine (\",[\"volumeUnit\"],\")\"],\"s6qW4K\":[\"Le type de suivi ne peut pas être modifié après la création.\"],\"sAkBSh\":[[\"0\",\"plural\",{\"one\":[\"#\",\" exercice\"],\"other\":[\"#\",\" exercices\"]}]],\"sHe-bW\":[\"Donne-lui un nom pour le sauvegarder comme entraînement réutilisable.\"],\"sOXSnZ\":[\"Détails de l'exercice\"],\"sRh2_9\":[\"Tes programmes\"],\"scHKm4\":[\"Entraînements solo\"],\"sey42b\":[\"Entraînement terminé !\"],\"slcKOz\":[\"Pour activer les rappels d'entraînement, autorise les notifications dans les paramètres de ton appareil.\"],\"spvawa\":[\"Exclure les entraînements de décharge des stats d'exercices\"],\"t-VWgS\":[\"Entraînements par semaine\"],\"t1WtPm\":[\"vs PR\"],\"t5tvzw\":[\"Ajoute un bouton de publication par programme.\"],\"t7OD9_\":[\"trapèzes\"],\"t9rBTs\":[[\"0\"],\": \",[\"best\"],[\"unit\"],\" (+\",[\"delta\"],[\"unit\"],\", \",[\"pctStr\"],\")\"],\"tBmnPU\":[\"Amis\"],\"tCHU1b\":[\"Parties du corps\"],\"tLdxsV\":[\"MuscleQuest.app\"],\"tXYsgg\":[\"Chaque mesure que tu enregistres est partagée automatiquement.\"],\"tXkhj_\":[\"Commencer\"],\"t_YqKh\":[\"Supprimer\"],\"tcZ16z\":[\"\\n💾 Nouveau : Sauvegarde des modifications d'entraînement dans ton programme !\\n\\nQuand tu termines une séance où tu as ajouté, supprimé ou réorganisé des exercices ou des séries, tu seras invité à sauvegarder ces modifications dans le programme original ou l'entraînement autonome, pour garder ton entraînement à jour automatiquement.\\n\"],\"tfDRzk\":[\"Enregistrer\"],\"tj-hng\":[\"poignets\"],\"tlcz2i\":[\"Aucune donnée pour cette période.\"],\"twA2hZ\":[\"jambes\"],\"tyb5gZ\":[\"Temps de repos (Minutes:Secondes)\"],\"u0F1Ey\":[\"Je\"],\"u0Vng2\":[\"Encore très courbaturé\"],\"u16ECS\":[\"Téléchargement terminé\"],\"uGkCJQ\":[\"barre EZ\"],\"uIVkKI\":[\"Connexion\"],\"uP80lb\":[\"Mise à jour prête\"],\"ue_JxE\":[\"Vue d'ensemble des séries\"],\"ufHAsd\":[\"Nom du programme\"],\"uyJsf6\":[\"À propos\"],\"v2e7py\":[\"Créer un programme\"],\"v39wLo\":[\"Reprendre\"],\"v67n_r\":[\"Active des rappels d'entraînement récurrents depuis les Paramètres. Sélectionne les jours de la semaine pour lesquels tu veux être rappelé en utilisant les pastilles de jours et choisis une heure. Tu recevras une notification à cette heure chaque jour sélectionné. La permission pour les notifications doit être accordée pour que les rappels fonctionnent.\"],\"vCrBBg\":[\"Prends le contrôle total de ton entraînement en concevant ton propre programme personnalisé. Sélectionne des exercices, définis des plages de répétitions, des temps de repos, et plus encore pour créer un programme parfaitement adapté à tes objectifs.\"],\"vFte8a\":[\"Créer une superserie\"],\"vLSd93\":[\"Types de séries\"],\"vLyv1R\":[\"Masquer\"],\"vPWLpz\":[\"Unités de mesure\"],\"vV1rrV\":[[\"suggestedRepsMin\"],\" reps suggérées\"],\"vbOlQu\":[\"Impossible de sélectionner une image. Réessaie.\"],\"vbfDgJ\":[\"Aucun entraînement\"],\"vcpc5o\":[\"Fermer le menu\"],\"vmatEA\":[\"Chargement des données, veuillez patienter...\"],\"vq2WxD\":[\"Mar\"],\"vqV9pV\":[\"Nouveau programme\"],\"vyQFtJ\":[[\"0\"],\" terminé !\"],\"w55mIe\":[\"programme actif\"],\"w95UZr\":[\"record \",[\"maxDist\"],[\"distanceUnit\"]],\"wBAK8Q\":[\"La partie du corps est obligatoire.\"],\"wL3cK8\":[\"Dernier\"],\"wL7wrB\":[\"Incrément de poids\"],\"wUwyC0\":[\"Série consécutive\"],\"wYwS57\":[\"Personnalise tes paramètres\"],\"wckWOP\":[\"Gérer\"],\"wgbq86\":[\"Redémarrage échoué\"],\"wiIJoN\":[\"Détails du programme\"],\"wpLp4M\":[\"Assistance\"],\"wvxWx2\":[\"trapèze\"],\"wxKcF0\":[\"À propos du développeur\"],\"x5LlnE\":[\"Options stats\"],\"xGVfLh\":[\"Continuer\"],\"xM_hqb\":[\"assistance \"],\"xMidTh\":[\"Toutes les parties du corps\"],\"xRGBk4\":[\"Explorer les programmes prêts à l'emploi\"],\"xVhQZV\":[\"Ven\"],\"xYxQCZ\":[[\"0\"],\" \",[\"1\"]],\"xx7Wjz\":[\"Impossible de charger les détails de l'exercice.\"],\"y04OSh\":[\"Historique des entraînements\"],\"y3CwcG\":[\"record \",[\"maxTime\"],\"s\"],\"y8le-Z\":[\"Entraînement\"],\"yAeHP4\":[\"Aucune donnée disponible.\"],\"yBSiRY\":[\"Semaine de décharge\"],\"yKu_3Y\":[\"Restaurer\"],\"yUWaVv\":[\"machine elliptique\"],\"yWCES-\":[\"Muscles secondaires :\"],\"y_0uwd\":[\"Hier\"],\"y_f0Ik\":[\"S'ouvre dans ton navigateur\"],\"yf16RU\":[\"Échauffement\"],\"ygCKqB\":[\"Arrêter\"],\"yhrNcC\":[\"Erreur de sauvegarde d'image\"],\"ykve2U\":[\"Ajouter une série\"],\"ysv0WA\":[\"Ajouté à mes exercices\"],\"yu1K_Z\":[\"Aucune série\"],\"z1-0FW\":[\"Suis tes entraînements, surveille ta progression et atteins tes objectifs fitness. MuscleQuest rend ton parcours fitness simple et efficace.\\n\\nFais glisser les cartes d'introduction pour en savoir plus sur l'appli.\"],\"z44QLk\":[\"Restaurer la sauvegarde\"],\"z5uobd\":[\"Appuie sur l'icône étoile dans le coin supérieur droit de n'importe quel écran d'infos d'exercice pour le marquer comme favori. Les exercices favoris apparaissent en haut du sélecteur d'exercices lors de la création ou modification d'entraînements, afin que les exercices que tu utilises le plus soient toujours à portée de main.\"],\"zAhZMD\":[\"• Partager tes programmes avec d'autres *\"],\"zAt78k\":[\"Minuterie de repos\"],\"zDq2cZ\":[\"Tour de taille\"],\"zEHmq8\":[\"L'onglet Programmes inclut une bibliothèque de programmes d'entraînement prêts à l'emploi que tu peux démarrer immédiatement. Fais défiler au-delà de Tes programmes pour trouver la section Programmes prêts à l'emploi. Appuie sur n'importe quel programme pour prévisualiser ses entraînements et son planning, puis appuie sur Activer pour en faire ton programme actif. Tu peux modifier un programme prêt à l'emploi pour ajuster les exercices, les séries ou le planning hebdomadaire. Cela crée une copie du programme que tu peux modifier sans affecter l'original.\"],\"zIFP3N\":[\"Fixe ton objectif d'entraînement hebdomadaire et entre ton poids de corps pour obtenir des stats et recommandations précises. Tu peux aussi ajuster tes préférences d'incrément de poids, choisir tes unités préférées, et bien plus.\"],\"zNnnyF\":[\"mollets\"],\"zOwYV3\":[\"Tu as modifié cet entraînement. Enregistrer ces modifications pour les prochaines séances ?\"],\"zeFzVj\":[\"Active pour partager automatiquement tes records de force après chaque entraînement.\"],\"zga9sT\":[\"OK\"],\"zhIkkH\":[\"Objectif : \",[\"goalLabel\"],[\"0\"]],\"zsaR7t\":[\"Équipement et suivi\"],\"zt6jiv\":[\"Pas de suivi de progression pour ce type d'exercice.\"],\"zuwyEJ\":[\"Ajoute des exercices pour commencer\"],\"zzDlyQ\":[\"Succès\"]}")}; \ No newline at end of file diff --git a/locales/fr/messages.po b/locales/fr/messages.po index ed9a46e7..4479cd79 100644 --- a/locales/fr/messages.po +++ b/locales/fr/messages.po @@ -165,6 +165,28 @@ msgstr "" "Correction d'un bug où tous les boutons (incrémenter/décrémenter, série suivante/précédente, terminer la série) cessaient de fonctionner après avoir terminé une série. Correction aussi d'une erreur dans le modal de modification de série. Les transitions de série se font maintenant instantanément pour un entraînement plus fluide.\n" "" +#: constants/WhatsNew.ts:305 +msgid "" +"\n" +"👥 New: Friends & Social Sharing!\n" +"\n" +"Add friends by searching for their username from the Friends tab in the menu. Send a request, and once accepted you can browse each other's shared content. A badge on the Friends menu item shows pending incoming requests.\n" +"\n" +"Share your plans, standalone workouts, custom exercises, body measurements, and strength PRs by toggling Share in the relevant screen or from Privacy Settings in the Account section of Settings. Shared content syncs automatically whenever it changes, and a cloud icon on plan and workout cards shows what is currently published. You can delete all shared data for any category from Privacy Settings at any time.\n" +"\n" +"Tap any accepted friend's name to open their profile and import their plans, standalone workouts, or custom exercises directly into your own library.\n" +"" +msgstr "" +"\n" +"👥 Nouveau : Amis & partage social !\n" +"\n" +"Ajoute des amis en cherchant leur nom d'utilisateur depuis l'onglet Amis dans le menu. Envoie une demande et, une fois acceptée, vous pouvez parcourir le contenu partagé de l'autre. Un badge sur l'élément Amis du menu indique les demandes entrantes en attente.\n" +"\n" +"Partage tes programmes, entraînements solo, exercices personnalisés, mesures corporelles et records de force en activant Partager dans l'écran correspondant ou depuis les Paramètres de confidentialité dans la section Compte des Paramètres. Le contenu partagé se synchronise automatiquement à chaque modification, et une icône nuage sur les cartes programme et entraînement indique ce qui est actuellement publié. Tu peux supprimer toutes les données partagées d'une catégorie depuis les Paramètres de confidentialité à tout moment.\n" +"\n" +"Appuie sur le nom de n'importe quel ami accepté pour ouvrir son profil et importer ses programmes, entraînements solo ou exercices personnalisés directement dans ta propre bibliothèque.\n" +"" + #: constants/WhatsNew.ts:204 msgid "" "\n" @@ -224,7 +246,7 @@ msgstr "" #: constants/WhatsNew.ts:293 msgid "" "\n" -"📈 New: Adaptive Progression!\n" +"📈 Beta: Adaptive Progression!\n" "\n" "MuscleQuest can now suggest when to increase your weight or reps based on how your sessions feel. After each exercise, answer two quick questions about effort and pain. Once you have reported the same signal for two sessions in a row, the app suggests a change. All suggestions appear in the Workout Summary screen, where you can accept or dismiss each one individually. Accepted suggestions are pre-filled into your next session automatically.\n" "\n" @@ -234,7 +256,7 @@ msgid "" "" msgstr "" "\n" -"📈 Nouveau : Progression adaptative !\n" +"📈 Beta : Progression adaptative !\n" "\n" "MuscleQuest peut maintenant te suggérer quand augmenter ton poids ou tes reps selon ce que tu ressens pendant tes séances. Après chaque exercice, réponds à deux questions rapides sur l'effort et la douleur. Dès que tu as signalé le même résultat deux séances de suite, l'app suggère un changement. Toutes les suggestions apparaissent sur l'écran de Résumé d'entraînement, où tu peux accepter ou rejeter chacune individuellement. Les suggestions acceptées sont pré-remplies dans ta prochaine séance automatiquement.\n" "\n" @@ -531,11 +553,11 @@ msgstr "" "L'écran Programmes dispose maintenant de trois modes d'affichage. Utilise les icônes à côté du titre « Tes plans d'entraînement » pour basculer entre les vues Carrousel, Liste et Grille. Ton affichage préféré est sauvegardé automatiquement.\n" "" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:179 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:191 msgid " (to Failure)" msgstr " (jusqu'à l'échec)" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:186 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:198 msgid " (to Failure) " msgstr " (jusqu'à l'échec) " @@ -581,7 +603,7 @@ msgid "{0, plural, one {# Set} other {# Sets}}" msgstr "{0, plural, one {# Série} other {# Séries}}" #. placeholder {0}: plan.workouts.length -#: components/TrainingPlanListItem.tsx:60 +#: components/TrainingPlanListItem.tsx:71 msgid "{0, plural, one {# workout} other {# workouts}}" msgstr "{0, plural, one {# entraînement} other {# entraînements}}" @@ -597,13 +619,13 @@ msgstr "{0, plural, one {série} other {séries}}" #. placeholder {0}: settings?.weightIncrement #. placeholder {1}: settings?.weightUnit -#: app/(app)/settings.tsx:758 +#: app/(app)/settings.tsx:794 msgid "{0} {1}" msgstr "{0} {1}" #. placeholder {0}: settings?.bodyWeight #. placeholder {1}: settings?.weightUnit -#: app/(app)/settings.tsx:583 +#: app/(app)/settings.tsx:619 msgid "{0} {1} (used for assisted exercises)" msgstr "{0} {1} (utilisé pour les exercices assistés)" @@ -620,7 +642,7 @@ msgid "{0} Complete!" msgstr "{0} terminé !" #. placeholder {0}: settings?.weeklyGoal -#: app/(app)/settings.tsx:561 +#: app/(app)/settings.tsx:597 msgid "{0} days per week" msgstr "{0} jours par semaine" @@ -628,7 +650,7 @@ msgstr "{0} jours par semaine" #. placeholder {0}: workout.exercises.length #. placeholder {1}: estimate ? ` · ~${formatDurationEstimate(estimate)}` : "" #. placeholder {1}: estimate ? ` · ~${formatDurationEstimateCompact(estimate)}` : "" -#: app/(app)/(tabs)/(plans)/overview.tsx:78 +#: app/(app)/(tabs)/(plans)/overview.tsx:82 #: app/(app)/(tabs)/index.tsx:57 msgid "{0} Exercises{1}" msgstr "{0} Exercices{1}" @@ -650,18 +672,18 @@ msgstr "{0} rép." #. placeholder {0}: settings?.restTimerIncrement #. placeholder {0}: settings?.timerCountdown || "5" -#: app/(app)/settings.tsx:786 -#: app/(app)/settings.tsx:812 +#: app/(app)/settings.tsx:822 +#: app/(app)/settings.tsx:848 msgid "{0} seconds" msgstr "{0} secondes" #. placeholder {0}: settings?.defaultSets -#: app/(app)/settings.tsx:1369 +#: app/(app)/settings.tsx:1408 msgid "{0} sets" msgstr "{0} séries" #. placeholder {0}: item.sets.length -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:176 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:188 #: components/WorkoutDetailsScreen.tsx:141 msgid "{0} Sets" msgstr "{0} Séries" @@ -786,7 +808,7 @@ msgid "+ Add" msgstr "+ Ajouter" #: app/(app)/(workout)/index.tsx:1153 -#: app/(app)/(workout)/workout-session.tsx:1559 +#: app/(app)/(workout)/workout-session.tsx:1591 msgid "+{restTimerIncrement}s" msgstr "+{restTimerIncrement}s" @@ -795,7 +817,7 @@ msgid "+{suggestedWeight}{unit} suggested" msgstr "+{suggestedWeight}{unit} suggéré" #: app/(app)/(workout)/index.tsx:1142 -#: app/(app)/(workout)/workout-session.tsx:1548 +#: app/(app)/(workout)/workout-session.tsx:1580 msgid "−{restTimerIncrement}s" msgstr "−{restTimerIncrement}s" @@ -836,7 +858,7 @@ msgstr "Une semaine de décharge est une semaine de récupération planifiée o msgid "A new version has been downloaded. Tap the button below to restart and apply the update." msgstr "Une nouvelle version a été téléchargée. Appuie sur le bouton ci-dessous pour redémarrer et appliquer la mise à jour." -#: app/_layout.tsx:91 +#: app/_layout.tsx:97 msgid "A render error has occurred. Press the button to reload." msgstr "Une erreur d'affichage s'est produite. Appuie sur le bouton pour recharger." @@ -844,15 +866,15 @@ msgstr "Une erreur d'affichage s'est produite. Appuie sur le bouton pour recharg msgid "abductors" msgstr "abducteurs" -#: app/(app)/settings.tsx:1560 +#: app/(app)/settings.tsx:1873 msgid "About" msgstr "À propos" -#: components/ExerciseFeedbackSheet.tsx:37 +#: components/ExerciseFeedbackSheet.tsx:38 msgid "About right" msgstr "À peu près bien" -#: app/(app)/settings.tsx:1649 +#: app/(app)/settings.tsx:1962 msgid "About the developer" msgstr "À propos du développeur" @@ -860,6 +882,7 @@ msgstr "À propos du développeur" msgid "abs" msgstr "abdominaux" +#: components/friends/FriendRequestItem.tsx:47 #: components/ProgressionSummaryCard.tsx:145 msgid "Accept" msgstr "Accepter" @@ -868,13 +891,13 @@ msgstr "Accepter" msgid "Accept all" msgstr "Tout accepter" -#: constants/HelpData.ts:164 +#: constants/HelpData.ts:184 msgid "Account" msgstr "Compte" -#: app/(app)/(tabs)/(plans)/overview.tsx:222 -#: components/TrainingPlanCard.tsx:80 -#: components/TrainingPlanListItem.tsx:54 +#: app/(app)/(tabs)/(plans)/overview.tsx:233 +#: components/TrainingPlanCard.tsx:83 +#: components/TrainingPlanListItem.tsx:56 msgid "Active" msgstr "Actif" @@ -899,16 +922,23 @@ msgstr "Programme actif : {0}" msgid "Active Workout" msgstr "Entraînement actif" -#: app/(app)/settings.tsx:1076 #: constants/HelpData.ts:64 msgid "Adaptive Progression" msgstr "Progression adaptative" +#: app/(app)/settings.tsx:1112 +msgid "Adaptive Progression (beta)" +msgstr "Progression adaptative (bêta)" + #: constants/HelpData.ts:69 msgid "Adaptive Progression analyses your effort feedback over consecutive sessions and suggests when to increase your weight, reps, or sets. Enable it in Settings under Adaptive Progression. Once on, a short feedback prompt appears after each exercise in plan-based workouts. The engine requires two sessions with the same signal before recommending an upward change, filtering out one-off easy days and ensuring consistent performance before suggesting an increase. Pain or failed sets act immediately regardless of your session history. A suggestion is never applied to your workout without your explicit approval. You can also configure your preferred load increment per equipment category in the same section of Settings, for example 2.5 kg for barbell exercises and 2.0 kg for dumbbells." msgstr "La Progression adaptative analyse ton feedback d'effort sur des séances consécutives et suggère quand augmenter ton poids, tes reps ou tes séries. Active-la dans Paramètres, sous Progression adaptative. Une fois activée, une courte question de feedback apparaît après chaque exercice dans les entraînements basés sur un programme. Le système nécessite deux séances avec le même signal avant de recommander une augmentation, ce qui filtre les jours ponctuellement faciles et garantit une performance constante avant de suggérer une hausse. La douleur ou les séries non terminées sont prises en compte immédiatement, quelle que soit ton historique de séances. Une suggestion n'est jamais appliquée à ton entraînement sans ton accord explicite. Tu peux aussi configurer ton incrément de charge préféré par catégorie d'équipement dans la même section des Paramètres, par exemple 2,5 kg pour les exercices à la barre et 2,0 kg pour les haltères." #: app/(app)/(tabs)/(stats)/measurements-manage.tsx:167 +#: app/(app)/friend-profile.tsx:218 +#: app/(app)/friend-profile.tsx:310 +#: app/(app)/friend-profile.tsx:397 +#: app/(app)/friends.tsx:291 #: components/Notes.tsx:87 msgid "Add" msgstr "Ajouter" @@ -944,7 +974,7 @@ msgstr "Ajouter un exercice" msgid "Add exercises to get started" msgstr "Ajoute des exercices pour commencer" -#: app/(app)/custom-exercise.tsx:324 +#: app/(app)/custom-exercise.tsx:350 msgid "Add Image" msgstr "Ajouter une image" @@ -957,6 +987,18 @@ msgstr "Ajouter des notes personnelles" msgid "Add Set" msgstr "Ajouter une série" +#: app/(app)/friend-exercise.tsx:161 +msgid "Add to my exercises" +msgstr "Ajouter à mes exercices" + +#: app/(app)/friend-plan.tsx:177 +msgid "Add to my plans" +msgstr "Ajouter à mes programmes" + +#: app/(app)/friend-workout.tsx:136 +msgid "Add to my workouts" +msgstr "Ajouter à mes entraînements" + #: app/(app)/(create-plan)/sets-overview.tsx:257 msgid "Add Warm-up" msgstr "Ajouter un échauffement" @@ -969,6 +1011,28 @@ msgstr "Ajouter du poids" msgid "Add Workout" msgstr "Ajouter un entraînement" +#: app/(app)/friend-profile.tsx:216 +#: app/(app)/friend-profile.tsx:308 +#: app/(app)/friend-profile.tsx:395 +msgid "Added" +msgstr "Ajouté" + +#: app/(app)/friend-exercise.tsx:159 +msgid "Added to my exercises" +msgstr "Ajouté à mes exercices" + +#: app/(app)/friend-plan.tsx:175 +msgid "Added to my plans" +msgstr "Ajouté à mes programmes" + +#: app/(app)/friend-workout.tsx:134 +msgid "Added to my workouts" +msgstr "Ajouté à mes entraînements" + +#: constants/HelpData.ts:168 +msgid "Adding Friends" +msgstr "Ajouter des amis" + #: constants/dbTranslations.ts:22 msgid "adductors" msgstr "adducteurs" @@ -1003,6 +1067,10 @@ msgstr "Toutes les images supprimées avec succès !" msgid "All images downloaded successfully!" msgstr "Toutes les images téléchargées avec succès !" +#: app/(app)/settings.tsx:98 +msgid "All shared data has been removed." +msgstr "Toutes les données partagées ont été supprimées." + #: components/FilterRow.tsx:62 #: components/FilterRow.tsx:114 #: components/FilterRow.tsx:204 @@ -1017,7 +1085,7 @@ msgstr "Tout le temps" msgid "All-time PR" msgstr "Record absolu" -#: app/(app)/settings.tsx:974 +#: app/(app)/settings.tsx:1010 msgid "Always use most recent exercise history" msgstr "Toujours utiliser l'historique le plus récent" @@ -1037,11 +1105,11 @@ msgstr "stabilisateurs de la cheville" msgid "ankles" msgstr "chevilles" -#: components/ExerciseFeedbackSheet.tsx:191 +#: components/ExerciseFeedbackSheet.tsx:205 msgid "Any pain or form breakdown?" msgstr "Des douleurs ou des problèmes de forme ?" -#: app/(app)/settings.tsx:1440 +#: app/(app)/settings.tsx:1479 msgid "Appearance" msgstr "Apparence" @@ -1055,7 +1123,7 @@ msgid "Are you sure you want to cancel and delete this workout?" msgstr "Tu es sûr de vouloir annuler et supprimer cet entraînement ?" #. placeholder {0}: workout?.name ?? "" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:81 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:93 msgid "Are you sure you want to delete \"{0}\"?" msgstr "Tu es sûr de vouloir supprimer \"{0}\" ?" @@ -1071,11 +1139,11 @@ msgstr "Tu es sûr de vouloir supprimer cet exercice ?" msgid "Are you sure you want to delete this measurement entry?" msgstr "Es-tu sûr de vouloir supprimer cette entrée de mesure ?" -#: app/(app)/(tabs)/(plans)/overview.tsx:118 +#: app/(app)/(tabs)/(plans)/overview.tsx:129 msgid "Are you sure you want to delete this plan?" msgstr "Tu es sûr de vouloir supprimer ce programme ?" -#: app/(app)/(workout)/workout-session.tsx:710 +#: app/(app)/(workout)/workout-session.tsx:717 msgid "Are you sure you want to delete this set?" msgstr "Tu es sûr de vouloir supprimer cette série ?" @@ -1100,7 +1168,7 @@ msgstr "Tu es sûr de vouloir supprimer cet entraînement ?" msgid "Are you sure you want to restart this workout?" msgstr "Tu es sûr de vouloir recommencer cet entraînement ?" -#: app/(app)/settings.tsx:460 +#: app/(app)/settings.tsx:496 msgid "Are you sure you want to restore the backup?" msgstr "Tu es sûr de vouloir restaurer la sauvegarde ?" @@ -1129,7 +1197,7 @@ msgstr "Assistance" msgid "assistance " msgstr "assistance " -#: app/(app)/custom-exercise.tsx:63 +#: app/(app)/custom-exercise.tsx:68 msgid "Assistance/Reps" msgstr "Assistance/Rép." @@ -1142,15 +1210,15 @@ msgstr "Durée moyenne" msgid "back" msgstr "dos" -#: app/(app)/settings.tsx:622 +#: app/(app)/settings.tsx:658 msgid "Backup" msgstr "Sauvegarde" -#: constants/HelpData.ts:173 +#: constants/HelpData.ts:193 msgid "Backup & Restore" msgstr "Sauvegarde et restauration" -#: app/(app)/settings.tsx:600 +#: app/(app)/settings.tsx:636 msgid "Backup and restore" msgstr "Sauvegarder et restaurer" @@ -1158,11 +1226,11 @@ msgstr "Sauvegarder et restaurer" msgid "barbell" msgstr "barre" -#: app/(app)/settings.tsx:1122 +#: app/(app)/settings.tsx:1160 msgid "Barbell load increment" msgstr "Incrément de charge pour la barre" -#: app/(app)/custom-exercise.tsx:309 +#: app/(app)/custom-exercise.tsx:335 msgid "Basics" msgstr "Bases" @@ -1202,15 +1270,20 @@ msgid "Body Fat" msgstr "Graisse corporelle" #: app/(app)/(tabs)/(stats)/index.tsx:553 +#: app/(app)/friend-profile.tsx:458 #: constants/HelpData.ts:143 msgid "Body Measurements" msgstr "Mesures corporelles" -#: app/(app)/custom-exercise.tsx:372 +#: app/(app)/friend-exercise.tsx:70 +msgid "Body Part" +msgstr "Partie du corps" + +#: app/(app)/custom-exercise.tsx:398 msgid "Body Part *" msgstr "Partie du corps *" -#: app/(app)/custom-exercise.tsx:201 +#: app/(app)/custom-exercise.tsx:206 msgid "Body part is required." msgstr "La partie du corps est obligatoire." @@ -1222,7 +1295,7 @@ msgstr "Parties du corps" msgid "body weight" msgstr "poids de corps" -#: app/(app)/settings.tsx:580 +#: app/(app)/settings.tsx:616 msgid "Body weight" msgstr "Poids du corps" @@ -1246,15 +1319,15 @@ msgstr "Parcours près de 1 000 exercices et filtre par partie du corps, muscle msgid "Built-in Metrics" msgstr "Mesures intégrées" -#: app/(app)/settings.tsx:1484 +#: app/(app)/settings.tsx:1523 msgid "Button size during workout" msgstr "Taille des boutons pendant l'entraînement" -#: app/(app)/settings.tsx:1596 +#: app/(app)/settings.tsx:1909 msgid "Buy me a coffee" msgstr "Offre-moi un café" -#: components/AppMenu.tsx:202 +#: components/AppMenu.tsx:220 msgid "Buy Me a Coffee" msgstr "Offre-moi un Café" @@ -1262,7 +1335,7 @@ msgstr "Offre-moi un Café" msgid "cable" msgstr "câble" -#: app/(app)/settings.tsx:1176 +#: app/(app)/settings.tsx:1214 msgid "Cable load increment" msgstr "Incrément de charge pour la poulie" @@ -1281,17 +1354,19 @@ msgstr "mollets" #: app/(app)/(create-plan)/create-workout.tsx:174 #: app/(app)/(create-plan)/create.tsx:234 #: app/(app)/(create-plan)/create.tsx:279 -#: app/(app)/(tabs)/(plans)/overview.tsx:121 -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:83 +#: app/(app)/(tabs)/(plans)/overview.tsx:132 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:95 #: app/(app)/(tabs)/(stats)/history-details.tsx:173 #: app/(app)/(tabs)/(stats)/measurements-detail.tsx:118 #: app/(app)/(tabs)/(stats)/measurements-manage.tsx:85 #: app/(app)/(workout)/index.tsx:405 #: app/(app)/(workout)/index.tsx:1007 -#: app/(app)/(workout)/workout-session.tsx:711 -#: app/(app)/settings.tsx:387 -#: app/(app)/settings.tsx:462 +#: app/(app)/(workout)/workout-session.tsx:718 +#: app/(app)/settings.tsx:90 +#: app/(app)/settings.tsx:423 +#: app/(app)/settings.tsx:498 #: components/EditSetModal.tsx:454 +#: components/friends/FriendListItem.tsx:24 #: components/SettingsModal.tsx:282 #: components/WorkoutCard.tsx:87 #: hooks/useImageManagement.ts:25 @@ -1315,11 +1390,11 @@ msgstr "cardio" msgid "cardiovascular system" msgstr "système cardiovasculaire" -#: app/(app)/custom-exercise.tsx:324 +#: app/(app)/custom-exercise.tsx:350 msgid "Change Image" msgstr "Changer l'image" -#: app/(app)/settings.tsx:606 +#: app/(app)/settings.tsx:642 msgid "Checking for backups..." msgstr "Vérification des sauvegardes..." @@ -1344,8 +1419,8 @@ msgstr "Effacer la recherche" msgid "Clears the search field" msgstr "Efface le champ de recherche" -#: components/AppMenu.tsx:146 -#: components/AppMenu.tsx:168 +#: components/AppMenu.tsx:156 +#: components/AppMenu.tsx:178 msgid "Close menu" msgstr "Fermer le menu" @@ -1383,15 +1458,19 @@ msgstr "Continuer l'édition ?" msgid "core" msgstr "core" -#: components/ExerciseFeedbackSheet.tsx:39 +#: app/(app)/friend-exercise.tsx:143 +msgid "Could not add this exercise. Please try again." +msgstr "Impossible d'ajouter cet exercice. Réessaie." + +#: components/ExerciseFeedbackSheet.tsx:40 msgid "Couldn't finish all sets" msgstr "Pas réussi à finir toutes les séries" -#: app/(app)/custom-exercise.tsx:508 +#: app/(app)/custom-exercise.tsx:534 msgid "Count reps ×2 for volume when the setting is enabled" msgstr "Compter les rép. ×2 pour le volume quand le paramètre est activé" -#: app/(app)/settings.tsx:1035 +#: app/(app)/settings.tsx:1071 msgid "Counting reps ×2 for these exercises" msgstr "Rép. ×2 comptées pour ces exercices" @@ -1404,7 +1483,7 @@ msgid "Create a Plan" msgstr "Créer un programme" #: app/(app)/(create-plan)/exercises.tsx:360 -#: app/(app)/custom-exercise.tsx:71 +#: app/(app)/custom-exercise.tsx:76 msgid "Create Exercise" msgstr "Créer un exercice" @@ -1426,10 +1505,15 @@ msgstr "Créer un entraînement" msgid "Create your own exercises from the exercise picker. Give it a name, an optional image, body part, target muscles, secondary muscles, and equipment. Choose a tracking type: weight + reps, time, distance, reps only, or assisted (which factors in your body weight for movements like assisted pull-ups). Toggle Unilateral for single-arm or single-leg exercises; reps can be automatically doubled in your stats. Toggle Paired Implements if you track the weight of one implement rather than the total: for example, if you log 20 kg for one dumbbell, the app counts 40 kg toward your volume." msgstr "Crée tes propres exercices depuis le sélecteur d'exercices. Donne-lui un nom, une image optionnelle, une partie du corps, des muscles cibles, des muscles secondaires et de l'équipement. Choisis un type de suivi : poids + répétitions, temps, distance, répétitions seules ou assisté (qui prend en compte ton poids de corps pour des mouvements comme les tractions assistées). Active Unilatéral pour les exercices à un bras ou une jambe ; les répétitions peuvent être automatiquement doublées dans tes stats. Active Implements appariés si tu notes le poids d'un seul implement plutôt que le total : par exemple, si tu notes 20 kg pour un haltère, l'appli compte 40 kg dans ton volume." +#: app/(app)/friend-profile.tsx:326 #: constants/HelpData.ts:113 msgid "Custom Exercises" msgstr "Exercices personnalisés" +#: app/(app)/settings.tsx:1701 +msgid "Custom exercises you create or edit are shared automatically." +msgstr "Les exercices personnalisés que tu crées ou modifies sont partagés automatiquement." + #: app/(app)/(tabs)/(stats)/measurements-manage.tsx:204 msgid "Custom Metrics" msgstr "Mesures personnalisées" @@ -1438,7 +1522,7 @@ msgstr "Mesures personnalisées" msgid "Customisation" msgstr "Personnalisation" -#: app/(app)/(tabs)/(plans)/overview.tsx:306 +#: app/(app)/(tabs)/(plans)/overview.tsx:351 msgid "Customise Plan" msgstr "Personnaliser le programme" @@ -1446,30 +1530,43 @@ msgstr "Personnaliser le programme" msgid "Customise Your Settings" msgstr "Personnalise tes paramètres" +#: components/friends/FriendRequestItem.tsx:56 +msgid "Decline" +msgstr "Refuser" + #: components/ExerciseSortChips.tsx:27 msgid "Default" msgstr "Par défaut" -#: app/(app)/settings.tsx:1392 +#: app/(app)/settings.tsx:1431 msgid "Default rest time" msgstr "Temps de repos par défaut" -#: app/(app)/settings.tsx:1366 +#: app/(app)/settings.tsx:1405 msgid "Default sets" msgstr "Séries par défaut" -#: app/(app)/(tabs)/(plans)/overview.tsx:125 -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:85 +#: app/(app)/(tabs)/(plans)/overview.tsx:136 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:97 #: app/(app)/(tabs)/(stats)/history-details.tsx:175 #: app/(app)/(tabs)/(stats)/measurements-detail.tsx:120 #: app/(app)/(workout)/index.tsx:407 #: app/(app)/(workout)/index.tsx:629 -#: app/(app)/(workout)/workout-session.tsx:713 +#: app/(app)/(workout)/workout-session.tsx:720 +#: app/(app)/settings.tsx:92 #: components/WorkoutCard.tsx:298 #: hooks/useImageManagement.ts:46 msgid "Delete" msgstr "Supprimer" +#: app/(app)/settings.tsx:1862 +msgid "Delete all shared data" +msgstr "Supprimer toutes les données partagées" + +#: app/(app)/settings.tsx:87 +msgid "Delete all shared data?" +msgstr "Supprimer toutes les données partagées ?" + #: hooks/useImageManagement.ts:103 msgid "Delete Complete" msgstr "Suppression terminée" @@ -1483,25 +1580,25 @@ msgstr "Supprimer l'entrée" msgid "Delete Exercise" msgstr "Supprimer l'exercice" -#: app/(app)/(tabs)/(plans)/overview.tsx:117 +#: app/(app)/(tabs)/(plans)/overview.tsx:128 msgid "Delete Plan" msgstr "Supprimer le programme" -#: app/(app)/(workout)/workout-session.tsx:710 +#: app/(app)/(workout)/workout-session.tsx:717 #: components/SessionSetInfo.tsx:251 msgid "Delete Set" msgstr "Supprimer la série" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:80 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:92 #: app/(app)/(tabs)/(stats)/history-details.tsx:170 msgid "Delete Workout" msgstr "Supprimer l'entraînement" -#: app/(app)/settings.tsx:1427 +#: app/(app)/settings.tsx:1466 msgid "Deleting. Please wait..." msgstr "Suppression en cours. Veuillez patienter..." -#: app/(app)/(tabs)/(plans)/overview.tsx:265 +#: app/(app)/(tabs)/(plans)/overview.tsx:276 #: app/(app)/(tabs)/index.tsx:472 #: constants/HelpData.ts:88 msgid "Deload Week" @@ -1519,7 +1616,8 @@ msgstr "deltïödes" msgid "delts" msgstr "deltïödes" -#: app/(app)/custom-exercise.tsx:347 +#: app/(app)/custom-exercise.tsx:373 +#: app/(app)/friend-exercise.tsx:109 msgid "Description" msgstr "Description" @@ -1531,19 +1629,19 @@ msgstr "Description :" msgid "Details" msgstr "Détails" -#: app/(app)/settings.tsx:831 -#: app/(app)/settings.tsx:856 -#: app/(app)/settings.tsx:881 -#: app/(app)/settings.tsx:904 -#: app/(app)/settings.tsx:929 -#: app/(app)/settings.tsx:954 -#: app/(app)/settings.tsx:1011 -#: app/(app)/settings.tsx:1036 -#: app/(app)/settings.tsx:1061 -#: app/(app)/settings.tsx:1093 -#: app/(app)/settings.tsx:1227 -#: app/(app)/settings.tsx:1258 -#: app/(app)/settings.tsx:1455 +#: app/(app)/settings.tsx:867 +#: app/(app)/settings.tsx:892 +#: app/(app)/settings.tsx:917 +#: app/(app)/settings.tsx:940 +#: app/(app)/settings.tsx:965 +#: app/(app)/settings.tsx:990 +#: app/(app)/settings.tsx:1047 +#: app/(app)/settings.tsx:1072 +#: app/(app)/settings.tsx:1097 +#: app/(app)/settings.tsx:1129 +#: app/(app)/settings.tsx:1265 +#: app/(app)/settings.tsx:1297 +#: app/(app)/settings.tsx:1494 msgid "Disabled" msgstr "Désactivé" @@ -1552,7 +1650,7 @@ msgstr "Désactivé" #: app/(app)/(workout)/index.tsx:808 #: app/(app)/(workout)/index.tsx:841 #: app/(app)/(workout)/index.tsx:1037 -#: app/(app)/custom-exercise.tsx:85 +#: app/(app)/custom-exercise.tsx:90 msgid "Discard" msgstr "Abandonner" @@ -1561,7 +1659,7 @@ msgstr "Abandonner" msgid "Discard Changes" msgstr "Abandonner les modifications" -#: app/(app)/custom-exercise.tsx:80 +#: app/(app)/custom-exercise.tsx:85 msgid "Discard changes?" msgstr "Abandonner les modifications ?" @@ -1576,12 +1674,12 @@ msgstr "Abandonner les modifications ?" msgid "Dismiss" msgstr "Fermer" -#: app/(app)/(tabs)/(plans)/overview.tsx:320 +#: app/(app)/(tabs)/(plans)/overview.tsx:365 msgid "DISMISS" msgstr "FERMER" #: app/(app)/(tabs)/(stats)/edit-history.tsx:268 -#: app/(app)/custom-exercise.tsx:66 +#: app/(app)/custom-exercise.tsx:71 msgid "Distance" msgstr "Distance" @@ -1591,21 +1689,22 @@ msgstr "Distance" msgid "Distance ({distanceUnit})" msgstr "Distance ({distanceUnit})" -#: app/(app)/settings.tsx:697 +#: app/(app)/settings.tsx:733 msgid "Distance unit" msgstr "Unité de distance" #: app/(app)/(workout)/workout-summary.tsx:656 -#: components/ExerciseFeedbackSheet.tsx:261 +#: app/(app)/settings.tsx:98 +#: components/ExerciseFeedbackSheet.tsx:275 #: components/RecoveryCheckInSheet.tsx:191 msgid "Done" msgstr "Terminé" -#: app/(app)/custom-exercise.tsx:528 +#: app/(app)/custom-exercise.tsx:554 msgid "Double the weight for volume when the setting is enabled" msgstr "Doubler le poids pour le volume quand le paramètre est activé" -#: app/(app)/settings.tsx:1060 +#: app/(app)/settings.tsx:1096 msgid "Doubling weight for volume calculations" msgstr "Poids doublé pour le calcul du volume" @@ -1613,7 +1712,7 @@ msgstr "Poids doublé pour le calcul du volume" msgid "Download" msgstr "Télécharger" -#: app/(app)/settings.tsx:1409 +#: app/(app)/settings.tsx:1448 msgid "Download all exercise animations" msgstr "Télécharger toutes les animations d'exercices" @@ -1635,7 +1734,7 @@ msgstr "Télécharger les images" msgid "Downloading Update" msgstr "Téléchargement de la mise à jour" -#: app/(app)/settings.tsx:1426 +#: app/(app)/settings.tsx:1465 msgid "Downloading. Please wait..." msgstr "Téléchargement en cours. Veuillez patienter..." @@ -1657,7 +1756,7 @@ msgstr "Série dégressive, " msgid "dumbbell" msgstr "haltère" -#: app/(app)/settings.tsx:1149 +#: app/(app)/settings.tsx:1187 msgid "Dumbbell load increment" msgstr "Incrément de charge pour les haltères" @@ -1670,25 +1769,33 @@ msgstr "Durée" msgid "During a session, swipe left/right or use the arrow buttons to move between sets. Enter your weight and reps, then tap Complete Set. The total elapsed time is shown in the header throughout. You can drag the handle on any exercise card to reorder exercises while the session is in progress. Time-based exercises have a Start Timer button that opens a count-up timer with a progress ring that shows you when you hit your goal time but you can keep going as long as you like. Notes can be added per-exercise via the notes icon in the exercise header, per workout from the workout overview screen, or per plan from the plan overview screen. If you add, remove, or reorder exercises or sets during a session, you will be prompted at the end to save those changes back to the original workout or plan." msgstr "Pendant une séance, glisse vers la gauche/droite ou utilise les boutons fléchés pour naviguer entre les séries. Entre ton poids et tes répétitions, puis appuie sur Terminer la série. Le temps écoulé total s'affiche en haut tout au long. Tu peux glisser la poignée d'une carte d'exercice pour réorganiser les exercices en cours de séance. Les exercices basés sur le temps ont un bouton Démarrer la minuterie qui ouvre un chronometre avec un anneau de progression indiquant quand tu atteins ton objectif, mais tu peux continuer aussi longtemps que tu veux. Les notes peuvent être ajoutées par exercice via l'icône de notes, par entraînement depuis l'écran de vue d'ensemble, ou par programme depuis l'écran de vue d'ensemble du programme. Si tu ajoutes, supprimes ou réorganises des exercices ou des séries pendant une séance, tu seras invité à la fin à sauvegarder ces modifications." +#: app/(app)/settings.tsx:1783 +msgid "Each measurement entry you record is shared automatically." +msgstr "Chaque mesure que tu enregistres est partagée automatiquement." + #: constants/HelpData.ts:99 msgid "Each set can be flagged as a Warm-up, Drop Set, To Failure, or any combination of these. The badge shown next to a set displays its current type. To change the type during a session, tap the menu (⋮) and toggle the relevant option on or off. When building a plan, use the checkboxes in the set editor; tap Add Warm-up to insert a dedicated warm-up set at the top of the list. Warm-up sets are visually grouped and separated from working sets, and the Apply to All option in the edit modal only affects sets of the same type. Warm-up sets can be excluded from volume and stats calculations in Settings." msgstr "Chaque série peut être marquée comme Échauffement, Série dégressive, Jusqu'à l'échec, ou toute combinaison de ces options. Le badge affiché à côté d'une série indique son type actuel. Pour changer le type pendant une séance, appuie sur le menu (⋮) et active ou désactive l'option correspondante. Lors de la création d'un programme, utilise les cases à cocher dans l'éditeur de séries ; appuie sur Ajouter un échauffement pour insérer une série d'échauffement dédiée en haut de la liste. Les séries d'échauffement sont visuellement regroupées et séparées des séries de travail, et l'option Appliquer à tous dans le modal de modification n'affecte que les séries du même type. Les séries d'échauffement peuvent être exclues des calculs de volume et de stats dans les Paramètres." -#: components/ExerciseFeedbackSheet.tsx:36 +#: app/(app)/settings.tsx:1743 +msgid "Each workout you complete is shared automatically." +msgstr "Chaque entraînement que tu termines est partagé automatiquement." + +#: components/ExerciseFeedbackSheet.tsx:37 msgid "Easy, could do more" msgstr "Facile, j'aurais pu faire plus" -#: app/(app)/custom-exercise.tsx:71 +#: app/(app)/custom-exercise.tsx:76 #: app/(app)/exercise-info.tsx:307 msgid "Edit Exercise" msgstr "Modifier l'exercice" -#: app/(app)/(tabs)/(plans)/overview.tsx:308 +#: app/(app)/(tabs)/(plans)/overview.tsx:353 msgid "Edit Plan" msgstr "Modifier le programme" #: app/(app)/(create-plan)/create-workout.tsx:247 -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:276 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:328 #: app/(app)/(tabs)/(stats)/_layout.tsx:22 msgid "Edit Workout" msgstr "Modifier l'entraînement" @@ -1697,24 +1804,60 @@ msgstr "Modifier l'entraînement" msgid "elliptical machine" msgstr "machine elliptique" +#: app/(app)/friends.tsx:209 +msgid "Email address" +msgstr "Adresse e-mail" + #: constants/HelpData.ts:159 msgid "Enable recurring workout reminders from Settings. Select the days of the week you want to be reminded using the day chips and choose a time. You will receive a notification at that time on each selected day. Notification permission must be granted for reminders to work." msgstr "Active des rappels d'entraînement récurrents depuis les Paramètres. Sélectionne les jours de la semaine pour lesquels tu veux être rappelé en utilisant les pastilles de jours et choisis une heure. Tu recevras une notification à cette heure chaque jour sélectionné. La permission pour les notifications doit être accordée pour que les rappels fonctionnent." -#: app/(app)/settings.tsx:830 -#: app/(app)/settings.tsx:855 -#: app/(app)/settings.tsx:880 -#: app/(app)/settings.tsx:904 -#: app/(app)/settings.tsx:928 -#: app/(app)/settings.tsx:953 -#: app/(app)/settings.tsx:1010 -#: app/(app)/settings.tsx:1092 -#: app/(app)/settings.tsx:1226 -#: app/(app)/settings.tsx:1258 -#: app/(app)/settings.tsx:1455 +#: app/(app)/settings.tsx:1628 +msgid "Enable to add a publish toggle to each plan." +msgstr "Active pour ajouter un bouton de publication à chaque programme." + +#: app/(app)/settings.tsx:1666 +msgid "Enable to add a publish toggle to each standalone workout." +msgstr "Active pour ajouter un bouton de publication à chaque entraînement solo." + +#: app/(app)/settings.tsx:1708 +msgid "Enable to automatically share custom exercises you create or edit." +msgstr "Active pour partager automatiquement tes exercices personnalisés." + +#: app/(app)/settings.tsx:1790 +msgid "Enable to automatically share each body measurement you record." +msgstr "Active pour partager automatiquement chaque mesure corporelle enregistrée." + +#: app/(app)/settings.tsx:1749 +msgid "Enable to automatically share each workout you complete." +msgstr "Active pour partager automatiquement chaque entraînement terminé." + +#: app/(app)/settings.tsx:1832 +msgid "Enable to automatically share strength PRs after each workout." +msgstr "Active pour partager automatiquement tes records de force après chaque entraînement." + +#: app/(app)/settings.tsx:866 +#: app/(app)/settings.tsx:891 +#: app/(app)/settings.tsx:916 +#: app/(app)/settings.tsx:940 +#: app/(app)/settings.tsx:964 +#: app/(app)/settings.tsx:989 +#: app/(app)/settings.tsx:1046 +#: app/(app)/settings.tsx:1128 +#: app/(app)/settings.tsx:1264 +#: app/(app)/settings.tsx:1297 +#: app/(app)/settings.tsx:1494 msgid "Enabled" msgstr "Activé" +#: app/(app)/settings.tsx:1624 +msgid "Enables a per-plan publish toggle." +msgstr "Ajoute un bouton de publication par programme." + +#: app/(app)/settings.tsx:1662 +msgid "Enables a per-workout publish toggle." +msgstr "Ajoute un bouton de publication par entraînement." + #: app/(app)/(tabs)/(stats)/measurements-manage.tsx:65 msgid "Enter a name for the custom metric." msgstr "Entre un nom pour la mesure personnalisée." @@ -1723,15 +1866,15 @@ msgstr "Entre un nom pour la mesure personnalisée." msgid "Enter at least one measurement to log." msgstr "Entre au moins une mesure à enregistrer." -#: app/(app)/custom-exercise.tsx:350 +#: app/(app)/custom-exercise.tsx:376 msgid "Enter description" msgstr "Entrer une description" -#: app/(app)/custom-exercise.tsx:331 +#: app/(app)/custom-exercise.tsx:357 msgid "Enter exercise name" msgstr "Entrer le nom de l'exercice" -#: app/(app)/settings.tsx:1056 +#: app/(app)/settings.tsx:1092 msgid "Enter weight per dumbbell/cable, not total" msgstr "Saisir le poids par haltère/câble, pas le total" @@ -1743,15 +1886,19 @@ msgstr "Détail de l'entrée" msgid "Entry not found." msgstr "Entrée introuvable." -#: app/(app)/custom-exercise.tsx:442 +#: app/(app)/friend-exercise.tsx:64 +msgid "Equipment" +msgstr "Équipement" + +#: app/(app)/custom-exercise.tsx:468 msgid "Equipment *" msgstr "Équipement *" -#: app/(app)/custom-exercise.tsx:438 +#: app/(app)/custom-exercise.tsx:464 msgid "Equipment & Tracking" msgstr "Équipement et suivi" -#: app/(app)/custom-exercise.tsx:203 +#: app/(app)/custom-exercise.tsx:208 msgid "Equipment is required." msgstr "L'équipement est obligatoire." @@ -1760,13 +1907,13 @@ msgid "Equipment:" msgstr "Équipement :" #: app/(app)/(create-plan)/image-search.tsx:43 -#: app/(app)/(tabs)/(plans)/overview.tsx:134 -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:94 +#: app/(app)/(tabs)/(plans)/overview.tsx:145 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:106 #: app/(app)/(workout)/index.tsx:871 #: app/(app)/(workout)/index.tsx:1065 -#: app/(app)/custom-exercise.tsx:129 -#: app/(app)/custom-exercise.tsx:178 -#: app/(app)/custom-exercise.tsx:286 +#: app/(app)/custom-exercise.tsx:134 +#: app/(app)/custom-exercise.tsx:183 +#: app/(app)/custom-exercise.tsx:312 #: app/login.tsx:69 #: components/FilterRow.tsx:86 #: components/FilterRow.tsx:132 @@ -1795,7 +1942,7 @@ msgstr "Erreur lors du chargement des détails de l'exercice" msgid "Error loading exercises: {0}" msgstr "Erreur lors du chargement des exercices : {0}" -#: app/(app)/(tabs)/(plans)/index.tsx:93 +#: app/(app)/(tabs)/(plans)/index.tsx:97 msgid "Error loading plans" msgstr "Erreur lors du chargement des programmes" @@ -1809,8 +1956,8 @@ msgstr "Erreur lors de la sauvegarde de l'entraînement" #. placeholder {0}: error.message #. placeholder {0}: settingsError.message -#: app/(app)/(tabs)/(plans)/overview.tsx:174 -#: app/(app)/(workout)/workout-session.tsx:1355 +#: app/(app)/(tabs)/(plans)/overview.tsx:185 +#: app/(app)/(workout)/workout-session.tsx:1386 #: components/WorkoutDetailsScreen.tsx:175 msgid "Error: {0}" msgstr "Erreur : {0}" @@ -1820,15 +1967,15 @@ msgstr "Erreur : {0}" msgid "Estimated Duration: {0}" msgstr "Durée estimée : {0}" -#: app/(app)/settings.tsx:1222 +#: app/(app)/settings.tsx:1260 msgid "Exclude deload workouts from exercise stats" msgstr "Exclure les entraînements de décharge des stats d'exercices" -#: app/(app)/settings.tsx:1006 +#: app/(app)/settings.tsx:1042 msgid "Exclude warmup sets from stats" msgstr "Exclure les séries d'échauffement des stats" -#: app/(app)/settings.tsx:1349 +#: app/(app)/settings.tsx:1388 msgid "Exercise" msgstr "Exercice" @@ -1839,21 +1986,29 @@ msgstr "Exercice" msgid "Exercise Already Added" msgstr "Exercice déjà ajouté" -#: app/(app)/_layout.tsx:37 +#: app/(app)/_layout.tsx:59 +msgid "Exercise Details" +msgstr "Détails de l'exercice" + +#: app/(app)/_layout.tsx:39 msgid "Exercise Info" msgstr "Infos sur l'exercice" -#: app/(app)/_layout.tsx:44 -#: components/AppMenu.tsx:184 +#: app/(app)/_layout.tsx:46 +#: components/AppMenu.tsx:202 #: constants/HelpData.ts:103 msgid "Exercise Library" msgstr "Bibliothèque d'exercices" +#: app/(app)/friend-exercise.tsx:47 +msgid "Exercise not found." +msgstr "Exercice introuvable." + #: components/ExerciseTimerModal.tsx:159 msgid "Exercise Timer" msgstr "Minuterie d'exercice" -#: app/(app)/settings.tsx:809 +#: app/(app)/settings.tsx:845 msgid "Exercise timer countdown" msgstr "Compte à rebours de la minuterie d'exercice" @@ -1881,12 +2036,12 @@ msgid "ez barbell" msgstr "barre EZ" #. placeholder {0}: error.message -#: app/(app)/(tabs)/(plans)/overview.tsx:155 +#: app/(app)/(tabs)/(plans)/overview.tsx:166 msgid "Failed to activate this plan: {0}" msgstr "Impossible d'activer ce programme : {0}" #. placeholder {0}: error.message -#: app/(app)/(tabs)/(plans)/overview.tsx:135 +#: app/(app)/(tabs)/(plans)/overview.tsx:146 msgid "Failed to delete plan: {0}" msgstr "Impossible de supprimer le programme : {0}" @@ -1894,17 +2049,17 @@ msgstr "Impossible de supprimer le programme : {0}" msgid "Failed to delete the workout. Please try again." msgstr "Impossible de supprimer l'entraînement. Réessaie." -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:95 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:107 msgid "Failed to delete workout. Please try again." msgstr "Impossible de supprimer l'entraînement. Réessaie." -#: app/(app)/custom-exercise.tsx:129 +#: app/(app)/custom-exercise.tsx:134 #: components/FilterRow.tsx:86 #: components/FilterRow.tsx:132 msgid "Failed to fetch data. Please try again." msgstr "Impossible de récupérer les données. Réessaie." -#: app/(app)/custom-exercise.tsx:178 +#: app/(app)/custom-exercise.tsx:183 msgid "Failed to load exercise details." msgstr "Impossible de charger les détails de l'exercice." @@ -1912,7 +2067,7 @@ msgstr "Impossible de charger les détails de l'exercice." msgid "Failed to load history" msgstr "Impossible de charger l'historique" -#: app/(app)/(tabs)/(plans)/index.tsx:147 +#: app/(app)/(tabs)/(plans)/index.tsx:153 msgid "Failed to load workouts" msgstr "Impossible de charger les entraînements" @@ -1920,11 +2075,11 @@ msgstr "Impossible de charger les entraînements" msgid "Failed to pick image. Please try again." msgstr "Impossible de sélectionner une image. Réessaie." -#: app/(app)/custom-exercise.tsx:287 +#: app/(app)/custom-exercise.tsx:313 msgid "Failed to save custom exercise. Please try again." msgstr "Impossible de sauvegarder l'exercice personnalisé. Réessaie." -#: app/(app)/custom-exercise.tsx:226 +#: app/(app)/custom-exercise.tsx:231 msgid "Failed to save the image. Please try again." msgstr "Impossible de sauvegarder l'image. Réessaie." @@ -1937,6 +2092,10 @@ msgstr "Impossible de sauvegarder l'entraînement. Réessaie." msgid "Failed to sign in. Please try again." msgstr "Impossible de se connecter. Réessaie." +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:304 +msgid "Failed to update sharing. Please try again." +msgstr "Impossible de mettre à jour le partage. Réessaie." + #: components/ExerciseList.tsx:41 msgid "Favorites" msgstr "Favoris" @@ -1957,7 +2116,7 @@ msgstr "C'était facile. On maintient pour l'instant et on confirme à la procha msgid "Finish" msgstr "Terminer" -#: app/(app)/settings.tsx:1632 +#: app/(app)/settings.tsx:1945 msgid "Follow MuscleQuest on Instagram" msgstr "Suivre MuscleQuest sur Instagram" @@ -1970,7 +2129,7 @@ msgstr "pendant {0}s " msgid "forearms" msgstr "avant-bras" -#: app/(app)/settings.tsx:53 +#: app/(app)/settings.tsx:56 msgid "Fr" msgstr "Ve" @@ -1993,6 +2152,27 @@ msgstr "Ven" msgid "Friday" msgstr "Vendredi" +#: app/(app)/_layout.tsx:50 +msgid "Friend Profile" +msgstr "Profil de l'ami" + +#: app/(app)/friends.tsx:39 +#: app/(app)/friends.tsx:58 +#: app/(app)/friends.tsx:69 +#: app/(app)/friends.tsx:264 +#: components/AppMenu.tsx:194 +msgid "Friends" +msgstr "Amis" + +#: constants/HelpData.ts:164 +msgid "Friends & Social" +msgstr "Amis & social" + +#. placeholder {0}: formatDistanceToNow(friend.since.toDate(), { addSuffix: true }) +#: app/(app)/friend-profile.tsx:121 +msgid "Friends since {0}" +msgstr "Amis depuis {0}" + #: components/ExerciseTimerModal.tsx:165 msgid "Get Ready..." msgstr "Prépare-toi..." @@ -2060,12 +2240,12 @@ msgstr "Regroupe deux exercices en superserie pour qu'ils alternent automatiquem msgid "hamstrings" msgstr "ischio-jambiers" -#: components/ExerciseFeedbackSheet.tsx:38 +#: components/ExerciseFeedbackSheet.tsx:39 msgid "Hard, near limit" msgstr "Difficile, proche de la limite" -#: app/(app)/_layout.tsx:41 -#: components/AppMenu.tsx:194 +#: app/(app)/_layout.tsx:43 +#: components/AppMenu.tsx:212 msgid "Help & Info" msgstr "Aide & infos" @@ -2112,11 +2292,11 @@ msgstr "Écran d'accueil et objectif hebdomadaire" msgid "How are these muscles feeling since your last session?" msgstr "Comment se sentent ces muscles depuis ta dernière séance ?" -#: components/ExerciseFeedbackSheet.tsx:173 +#: components/ExerciseFeedbackSheet.tsx:187 msgid "How did that feel?" msgstr "Comment tu t'es senti ?" -#: app/(app)/custom-exercise.tsx:225 +#: app/(app)/custom-exercise.tsx:230 msgid "Image Save Error" msgstr "Erreur de sauvegarde d'image" @@ -2124,6 +2304,19 @@ msgstr "Erreur de sauvegarde d'image" msgid "Images by Unsplash" msgstr "Images par Unsplash" +#: app/(app)/friend-exercise.tsx:142 +msgid "Import failed" +msgstr "Importation échouée" + +#: constants/HelpData.ts:178 +msgid "Importing from Friends" +msgstr "Importer depuis ses amis" + +#: app/(app)/friends.tsx:278 +#: app/(app)/friends.tsx:331 +msgid "Incoming" +msgstr "Reçues" + #: app/(app)/exercise-info.tsx:202 msgid "Info" msgstr "Infos" @@ -2137,11 +2330,11 @@ msgstr "Aperçus" msgid "Jumpstart your fitness journey with professionally designed training plans. Choose from a variety of options tailored to different goals and experience levels. " msgstr "Lance ton parcours fitness avec des programmes conçus par des professionnels. Choisis parmi une variété d'options adaptées à différents objectifs et niveaux. " -#: app/(app)/custom-exercise.tsx:83 +#: app/(app)/custom-exercise.tsx:88 msgid "Keep editing" msgstr "Continuer à modifier" -#: app/(app)/settings.tsx:949 +#: app/(app)/settings.tsx:985 msgid "Keep screen on during workout" msgstr "Garder l'écran allumé pendant l'entraînement" @@ -2154,7 +2347,7 @@ msgid "kettlebell" msgstr "kettlebell" #. placeholder {0}: lastBackupDate.toLocaleDateString() -#: app/(app)/settings.tsx:608 +#: app/(app)/settings.tsx:644 msgid "Last backup: {0}" msgstr "Dernière sauvegarde : {0}" @@ -2195,15 +2388,15 @@ msgstr "machine à levier" msgid "Load up" msgstr "Augmenter la charge" -#: app/_layout.tsx:199 +#: app/_layout.tsx:213 msgid "Loading data, please wait..." msgstr "Chargement des données, veuillez patienter..." -#: app/(app)/(tabs)/(plans)/overview.tsx:187 +#: app/(app)/(tabs)/(plans)/overview.tsx:198 msgid "Loading Plan..." msgstr "Chargement du programme..." -#: app/(app)/(tabs)/(plans)/overview.tsx:166 +#: app/(app)/(tabs)/(plans)/overview.tsx:177 #: components/WorkoutDetailsScreen.tsx:166 msgid "Loading..." msgstr "Chargement..." @@ -2213,11 +2406,11 @@ msgstr "Chargement..." msgid "Log Entry" msgstr "Saisir une entrée" -#: app/(app)/settings.tsx:528 +#: app/(app)/settings.tsx:564 msgid "Log in to secure your data" msgstr "Connecte-toi pour sécuriser tes données" -#: app/(app)/settings.tsx:1031 +#: app/(app)/settings.tsx:1067 msgid "Log one side only for single-arm/leg exercises" msgstr "Enregistrer un seul côté pour les exercices unilatéraux" @@ -2237,7 +2430,7 @@ msgstr "bas du dos" msgid "lower legs" msgstr "bas des jambes" -#: app/(app)/settings.tsx:1203 +#: app/(app)/settings.tsx:1241 msgid "Machine load increment" msgstr "Incrément de charge pour les machines" @@ -2281,11 +2474,11 @@ msgstr "Légère courbature" msgid "Min Reps" msgstr "Rép. min." -#: components/ExerciseFeedbackSheet.tsx:46 +#: components/ExerciseFeedbackSheet.tsx:47 msgid "Minor discomfort" msgstr "Légère gêne" -#: app/(app)/settings.tsx:49 +#: app/(app)/settings.tsx:52 msgid "Mo" msgstr "Lu" @@ -2328,15 +2521,15 @@ msgstr "MuscleQuest" msgid "MuscleQuest Introduction" msgstr "Introduction à MuscleQuest" -#: app/(app)/settings.tsx:1613 +#: app/(app)/settings.tsx:1926 msgid "MuscleQuest.app" msgstr "MuscleQuest.app" -#: components/AppMenu.tsx:208 +#: components/AppMenu.tsx:226 msgid "MuscleQuest's Instagram" msgstr "Instagram de MuscleQuest" -#: app/(app)/custom-exercise.tsx:368 +#: app/(app)/custom-exercise.tsx:394 msgid "Muscles" msgstr "Muscles" @@ -2344,11 +2537,11 @@ msgstr "Muscles" msgid "N/A" msgstr "N/A" -#: app/(app)/custom-exercise.tsx:328 +#: app/(app)/custom-exercise.tsx:354 msgid "Name *" msgstr "Nom *" -#: app/(app)/custom-exercise.tsx:200 +#: app/(app)/custom-exercise.tsx:205 msgid "Name is required." msgstr "Le nom est obligatoire." @@ -2364,11 +2557,11 @@ msgstr "cou" msgid "Neck" msgstr "Cou" -#: app/(app)/(tabs)/(plans)/index.tsx:118 +#: app/(app)/(tabs)/(plans)/index.tsx:122 msgid "New Plan" msgstr "Nouveau programme" -#: app/(app)/(tabs)/(plans)/index.tsx:110 +#: app/(app)/(tabs)/(plans)/index.tsx:114 msgid "New Workout" msgstr "Nouvel entraînement" @@ -2380,8 +2573,8 @@ msgstr "Suivant" msgid "Next Session" msgstr "Prochaine séance" -#: app/(app)/(workout)/workout-session.tsx:1415 -#: app/(app)/(workout)/workout-session.tsx:1502 +#: app/(app)/(workout)/workout-session.tsx:1446 +#: app/(app)/(workout)/workout-session.tsx:1533 msgid "Next: " msgstr "Suivant : " @@ -2396,10 +2589,18 @@ msgstr "Suivant : {workoutName} le {0}" msgid "No" msgstr "Non" -#: app/(app)/settings.tsx:609 +#: app/(app)/settings.tsx:645 msgid "No backups found" msgstr "Aucune sauvegarde trouvée" +#: app/(app)/friend-profile.tsx:423 +msgid "No completed workouts shared yet" +msgstr "Aucun entraînement terminé partagé pour l'instant" + +#: app/(app)/friend-profile.tsx:336 +msgid "No custom exercises shared yet" +msgstr "Aucun exercice personnalisé partagé pour l'instant" + #: components/charts/BodyPartChart.tsx:198 msgid "No data available." msgstr "Aucune donnée disponible." @@ -2416,7 +2617,7 @@ msgstr "Aucune donnée pour cette période." msgid "No exercises added yet" msgstr "Aucun exercice ajouté" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:252 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:264 msgid "No exercises in this workout yet." msgstr "Aucun exercice dans cet entraînement." @@ -2424,10 +2625,18 @@ msgstr "Aucun exercice dans cet entraînement." msgid "No exercises tracked yet. Tap + Add to start." msgstr "Aucun exercice suivi. Appuie sur + Ajouter pour commencer." +#: app/(app)/friends.tsx:141 +msgid "No friends yet. Search by email to add someone." +msgstr "Aucun ami pour l'instant. Cherche par e-mail pour en ajouter un." + #: app/(app)/exercise-info.tsx:407 msgid "No history yet" msgstr "Aucun historique" +#: app/(app)/friend-profile.tsx:468 +msgid "No measurements shared yet" +msgstr "Aucune mesure partagée pour l'instant" + #: app/(app)/(tabs)/(stats)/measurements.tsx:265 msgid "No measurements yet. Log your first entry above." msgstr "Aucune mesure pour l'instant. Enregistre ta première entrée ci-dessus." @@ -2436,10 +2645,18 @@ msgstr "Aucune mesure pour l'instant. Enregistre ta première entrée ci-dessus. msgid "No measurements yet. Tap to log your first entry." msgstr "Aucune mesure pour l'instant. Appuie pour enregistrer ta première entrée." -#: components/ExerciseFeedbackSheet.tsx:45 +#: components/ExerciseFeedbackSheet.tsx:46 msgid "No pain" msgstr "Pas de douleur" +#: app/(app)/friends.tsx:317 +msgid "No pending friend requests." +msgstr "Aucune demande d'ami en attente." + +#: app/(app)/friend-profile.tsx:156 +msgid "No plans shared yet" +msgstr "Aucun programme partagé pour l'instant" + #: components/ProgressionSummaryCard.tsx:26 msgid "No prior weight data. Hold steady for now." msgstr "Pas de données de poids antérieures. On maintient pour l'instant." @@ -2456,7 +2673,7 @@ msgstr "Aucun résultat pour « {query} »" msgid "No schedule set" msgstr "Aucun planning défini" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:176 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:188 msgid "No Sets" msgstr "Aucune série" @@ -2465,10 +2682,18 @@ msgstr "Aucune série" msgid "No Sets Available" msgstr "Aucune série disponible" -#: components/PlanList.tsx:46 +#: app/(app)/friend-profile.tsx:501 +msgid "No strength data shared yet" +msgstr "Aucune donnée de force partagée pour l'instant" + +#: components/PlanList.tsx:50 msgid "No training plans found" msgstr "Aucun programme trouvé" +#: app/(app)/friends.tsx:228 +msgid "No user found with that email address." +msgstr "Aucun utilisateur trouvé avec cette adresse e-mail." + #: app/(app)/(tabs)/(stats)/measurements.tsx:131 msgid "No values entered" msgstr "Aucune valeur saisie" @@ -2485,11 +2710,15 @@ msgstr "Aucun entraînement terminé. Lance ton premier entraînement !" msgid "No workouts on this day." msgstr "Aucun entraînement ce jour-là." -#: app/(app)/(tabs)/(plans)/index.tsx:160 +#: app/(app)/friend-profile.tsx:244 +msgid "No workouts shared yet" +msgstr "Aucun entraînement partagé pour l'instant" + +#: app/(app)/(tabs)/(plans)/index.tsx:166 msgid "No workouts yet" msgstr "Aucun entraînement" -#: components/ExerciseFeedbackSheet.tsx:221 +#: components/ExerciseFeedbackSheet.tsx:235 msgid "No, keep it the same" msgstr "Non, garder comme ça" @@ -2503,10 +2732,10 @@ msgstr "obliques" #: app/(app)/(workout)/exercises.tsx:109 #: app/(app)/(workout)/exercises.tsx:130 #: app/(app)/(workout)/index.tsx:873 -#: app/(app)/custom-exercise.tsx:130 -#: app/(app)/custom-exercise.tsx:179 -#: app/(app)/custom-exercise.tsx:227 -#: app/(app)/custom-exercise.tsx:288 +#: app/(app)/custom-exercise.tsx:135 +#: app/(app)/custom-exercise.tsx:184 +#: app/(app)/custom-exercise.tsx:232 +#: app/(app)/custom-exercise.tsx:314 #: app/login.tsx:70 #: components/FilterRow.tsx:87 #: components/FilterRow.tsx:133 @@ -2521,16 +2750,20 @@ msgstr "Plus qu'un entraînement pour atteindre ton objectif !" msgid "Oops!" msgstr "Oups !" -#: app/(app)/settings.tsx:386 +#: app/(app)/settings.tsx:422 msgid "Open Settings" msgstr "Ouvrir les Paramètres" -#: components/AppMenu.tsx:204 -#: components/AppMenu.tsx:210 +#: constants/HelpData.ts:169 +msgid "Open the Friends tab from the menu to manage your connections. Use the search bar to find other users by username and send them a friend request. Incoming requests appear in the Requests tab; tap Accept to confirm or Decline to ignore. A badge on the Friends menu item shows how many pending requests are waiting. Once a request is accepted, both users appear in each other's Friends list and can view each other's shared content." +msgstr "Ouvre l'onglet Amis depuis le menu pour gérer tes connexions. Utilise la barre de recherche pour trouver d'autres utilisateurs par nom d'utilisateur et leur envoyer une demande d'ami. Les demandes entrantes apparaissent dans l'onglet Demandes ; appuie sur Accepter pour confirmer ou Refuser pour ignorer. Un badge sur l'élément Amis du menu indique combien de demandes sont en attente. Une fois une demande acceptée, les deux utilisateurs apparaissent dans la liste d'amis de l'autre et peuvent voir le contenu partagé de l'autre." + +#: components/AppMenu.tsx:222 +#: components/AppMenu.tsx:228 msgid "Opens in your browser" msgstr "S'ouvre dans ton navigateur" -#: components/ExerciseFeedbackSheet.tsx:243 +#: components/ExerciseFeedbackSheet.tsx:257 msgid "Optional description" msgstr "Description facultative" @@ -2543,7 +2776,7 @@ msgstr "Autres exercices" msgid "Overview" msgstr "Vue d'ensemble" -#: components/ExerciseFeedbackSheet.tsx:47 +#: components/ExerciseFeedbackSheet.tsx:48 msgid "Pain or form issues" msgstr "Douleur ou problèmes de forme" @@ -2551,7 +2784,7 @@ msgstr "Douleur ou problèmes de forme" msgid "Pain reported. Keeping load unchanged until you feel better." msgstr "Douleur signalée. La charge reste inchangée jusqu'à ce que tu ailles mieux." -#: app/(app)/custom-exercise.tsx:525 +#: app/(app)/custom-exercise.tsx:551 #: app/(app)/exercise-info.tsx:277 msgid "Paired implements" msgstr "Implements appariés" @@ -2565,6 +2798,10 @@ msgstr "En paire avec {0}" msgid "pectorals" msgstr "pectoraux" +#: app/(app)/friends.tsx:377 +msgid "Pending" +msgstr "En attente" + #: components/stats/InsightsStrip.tsx:74 msgid "Per week (avg)" msgstr "Par semaine (moy.)" @@ -2573,12 +2810,12 @@ msgstr "Par semaine (moy.)" msgid "Percent" msgstr "Pourcentage" -#: app/(app)/settings.tsx:364 -#: app/(app)/settings.tsx:383 +#: app/(app)/settings.tsx:400 +#: app/(app)/settings.tsx:419 msgid "Permission Required" msgstr "Permission requise" -#: app/(app)/settings.tsx:511 +#: app/(app)/settings.tsx:547 msgid "Personal" msgstr "Personnel" @@ -2586,12 +2823,21 @@ msgstr "Personnel" msgid "Pin exercises in the Stats tab to track their strength progression over time. Each tracked exercise shows a chart of your performance over the selected time range, your all-time personal record, your top sets, and a list of recent sessions showing the best set per day. Charts update automatically after each workout that includes that exercise." msgstr "Épingle des exercices dans l'onglet Stats pour suivre leur progression de force dans le temps. Chaque exercice suivi affiche un graphique de tes performances sur la période sélectionnée, ton record personnel absolu, tes meilleures séries, et une liste des sessions récentes avec la meilleure série par jour. Les graphiques se mettent à jour automatiquement après chaque entraînement incluant cet exercice." +#: app/(app)/_layout.tsx:52 +msgid "Plan Details" +msgstr "Détails du programme" + +#: app/(app)/friend-plan.tsx:56 +msgid "Plan not found." +msgstr "Programme introuvable." + #: app/(app)/(tabs)/(plans)/_layout.tsx:17 msgid "Plan Overview" msgstr "Vue d'ensemble du programme" #: app/(app)/(tabs)/_layout.tsx:49 #: app/(app)/(tabs)/(plans)/_layout.tsx:16 +#: app/(app)/friend-profile.tsx:146 #: constants/HelpData.ts:28 msgid "Plans" msgstr "Programmes" @@ -2600,15 +2846,15 @@ msgstr "Programmes" msgid "Plans are structured training programmes made up of workouts. To create one, go to the Plans tab, tap New Plan, give it a name, and pick a cover image. Add workouts to the plan, then add exercises to each workout with target sets and reps. Use the up/down arrow buttons on a workout card to reorder it, or the X button to remove it; both are in the top right of the card. Assign workouts to specific days of the week in the schedule editor: tap any day to pick a workout or leave it as a rest day, and use the auto-suggest button to space them out evenly. Once your plan is ready, open it and tap Activate. You can also add notes to a plan from the plan overview screen. Each workout card shows an estimated duration alongside the exercise count so you can gauge the session length at a glance. Use the view icons next to the \"Your Training Plans\" heading to switch between Carousel, List, and Grid layouts; your chosen view is saved automatically. Your progress in the plan editor is automatically saved as a draft, so if you leave mid-edit you will be prompted to continue where you left off or discard and start from the last saved state." msgstr "Les programmes sont des plans d'entraînement structurés composés de séances. Pour en créer un, va dans l'onglet Programmes, appuie sur Nouveau programme, donne-lui un nom et choisis une image de couverture. Ajoute des entraînements au programme, puis ajoute des exercices à chaque entraînement avec des séries et répétitions cibles. Utilise les boutons fléchés haut/bas d'une carte d'entraînement pour la réorganiser, ou le bouton X pour la supprimer ; les deux se trouvent en haut à droite de la carte. Assigne des entraînements à des jours spécifiques de la semaine dans l'éditeur de planning : appuie sur un jour pour choisir un entraînement ou le laisser comme jour de repos, et utilise le bouton de suggestion automatique pour les espacer régulièrement. Une fois ton programme prêt, ouvre-le et appuie sur Activer. Tu peux aussi ajouter des notes depuis l'écran de vue d'ensemble du programme. Chaque carte d'entraînement affiche une durée estimée avec le nombre d'exercices pour que tu puisses évaluer la longueur d'une séance d'un coup d'œil. Utilise les icônes de vue à côté du titre « Tes plans d'entraînement » pour basculer entre les affichages Carrousel, Liste et Grille ; ton affichage préféré est sauvegardé automatiquement. Ta progression dans l'éditeur est automatiquement sauvegardée comme brouillon, donc si tu le quittes en cours d'édition, tu seras invité à reprendre là où tu en étais ou à ignorer et repartir du dernier état sauvegardé." -#: app/(app)/settings.tsx:826 +#: app/(app)/settings.tsx:862 msgid "Play countdown beeps (Exercise Timer)" msgstr "Jouer les bips de compte à rebours (Minuterie d'exercice)" -#: app/(app)/settings.tsx:851 +#: app/(app)/settings.tsx:887 msgid "Play goal achieved sound (Exercise Timer)" msgstr "Jouer le son de l'objectif atteint (Minuterie d'exercice)" -#: app/(app)/settings.tsx:901 +#: app/(app)/settings.tsx:937 msgid "Play sound after rest" msgstr "Jouer un son après le repos" @@ -2620,7 +2866,7 @@ msgstr "Veuillez patienter pendant le téléchargement de la dernière version.. msgid "Post-Exercise Feedback" msgstr "Feedback après exercice" -#: app/(app)/(tabs)/(plans)/index.tsx:134 +#: app/(app)/(tabs)/(plans)/index.tsx:140 msgid "Premade plans" msgstr "Programmes prêts à l'emploi" @@ -2628,12 +2874,20 @@ msgstr "Programmes prêts à l'emploi" msgid "Premade Plans" msgstr "Programmes prêts à l'emploi" -#: app/(app)/(workout)/workout-session.tsx:1417 -#: app/(app)/(workout)/workout-session.tsx:1504 +#: app/(app)/(workout)/workout-session.tsx:1448 +#: app/(app)/(workout)/workout-session.tsx:1535 msgid "Prev: " msgstr "Préc. : " -#: app/(app)/settings.tsx:1668 +#: app/(app)/settings.tsx:1604 +msgid "Previously shared data always remains visible to your friends until you delete it below." +msgstr "Les données partagées restent visibles par tes amis jusqu'à ce que tu les supprimes ci-dessous." + +#: app/(app)/settings.tsx:1601 +msgid "Privacy" +msgstr "Confidentialité" + +#: app/(app)/settings.tsx:1981 msgid "Privacy policy" msgstr "Politique de confidentialité" @@ -2641,7 +2895,7 @@ msgstr "Politique de confidentialité" msgid "Progression Suggestions" msgstr "Suggestions de progression" -#: components/ExerciseFeedbackSheet.tsx:211 +#: components/ExerciseFeedbackSheet.tsx:225 msgid "Push harder next time?" msgstr "Pousser plus fort la prochaine fois ?" @@ -2670,6 +2924,10 @@ msgstr "Récent" msgid "Recent Sessions" msgstr "Sessions récentes" +#: app/(app)/friend-profile.tsx:413 +msgid "Recent Workouts" +msgstr "Entraînements récents" + #: hooks/useExerciseSort.ts:57 msgid "Recently Used" msgstr "Récemment utilisé" @@ -2683,23 +2941,24 @@ msgstr "Bilan de récupération" msgid "Reduce load" msgstr "Réduire la charge" -#: app/_layout.tsx:94 +#: app/_layout.tsx:100 msgid "Reload" msgstr "Recharger" -#: app/(app)/settings.tsx:1280 +#: app/(app)/settings.tsx:1319 msgid "Reminder days" msgstr "Jours de rappel" -#: app/(app)/settings.tsx:1335 +#: app/(app)/settings.tsx:1374 msgid "Reminder time" msgstr "Heure de rappel" -#: app/(app)/settings.tsx:1243 +#: app/(app)/settings.tsx:1282 msgid "Reminders" msgstr "Rappels" #: app/(app)/(create-plan)/create.tsx:283 +#: components/friends/FriendListItem.tsx:26 #: components/WorkoutCard.tsx:89 msgid "Remove" msgstr "Supprimer" @@ -2717,6 +2976,10 @@ msgstr "Supprimer l'exercice" msgid "Remove Superset" msgstr "Supprimer la superserie" +#: components/friends/FriendListItem.tsx:22 +msgid "Remove this friend? They will no longer be able to see your shared content." +msgstr "Retirer cet ami ? Il ne pourra plus voir ton contenu partagé." + #: app/(app)/(create-plan)/create.tsx:275 msgid "Remove Workout" msgstr "Supprimer l'entraînement" @@ -2734,12 +2997,17 @@ msgstr "Objectif de reps non atteint. On maintient pour l'instant." msgid "Replace" msgstr "Remplacer" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:186 +#: app/(app)/friend-plan.tsx:130 +#: app/(app)/friend-workout.tsx:89 +msgid "reps" +msgstr "reps" + +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:198 #: app/(app)/(tabs)/(stats)/edit-history.tsx:201 #: app/(app)/(tabs)/(stats)/edit-history.tsx:205 #: app/(app)/(tabs)/(stats)/edit-history.tsx:242 #: app/(app)/(tabs)/(stats)/edit-history.tsx:246 -#: app/(app)/custom-exercise.tsx:64 +#: app/(app)/custom-exercise.tsx:69 #: components/charts/ExerciseProgressionChart.tsx:377 #: components/SessionSetInfo.tsx:435 #: components/WorkoutCard.tsx:276 @@ -2751,10 +3019,14 @@ msgstr "Répétitions" msgid "Reps: {repRange}" msgstr "Rép. : {repRange}" -#: app/(app)/settings.tsx:1577 +#: app/(app)/settings.tsx:1890 msgid "Request or vote for new features" msgstr "Demander ou voter pour de nouvelles fonctionnalités" +#: app/(app)/friends.tsx:62 +msgid "Requests" +msgstr "Demandes" + #: app/(app)/(create-plan)/sets-overview.tsx:173 #: components/PlanScheduleEditor.tsx:94 #: components/PlanScheduleEditor.tsx:189 @@ -2771,7 +3043,7 @@ msgid "Rest Time (Minutes:Seconds)" msgstr "Temps de repos (Minutes:Secondes)" #: app/(app)/(workout)/index.tsx:1134 -#: app/(app)/(workout)/workout-session.tsx:1540 +#: app/(app)/(workout)/workout-session.tsx:1572 msgid "Rest Time Left:" msgstr "Temps de repos restant :" @@ -2784,11 +3056,11 @@ msgstr "Temps de repos : {restMinutes}:{0}" msgid "Rest Timer" msgstr "Minuterie de repos" -#: app/(app)/(workout)/workout-session.tsx:551 +#: app/(app)/(workout)/workout-session.tsx:558 msgid "Rest Timer Finished!" msgstr "Minuterie de repos terminée !" -#: app/(app)/settings.tsx:783 +#: app/(app)/settings.tsx:819 msgid "Rest timer increment" msgstr "Incrément de la minuterie de repos" @@ -2808,16 +3080,16 @@ msgstr "Redémarrage échoué" msgid "Restart Workout" msgstr "Recommencer l'entraînement" -#: app/(app)/settings.tsx:464 -#: app/(app)/settings.tsx:625 +#: app/(app)/settings.tsx:500 +#: app/(app)/settings.tsx:661 msgid "Restore" msgstr "Restaurer" -#: app/(app)/settings.tsx:459 +#: app/(app)/settings.tsx:495 msgid "Restore Backup" msgstr "Restaurer la sauvegarde" -#: app/(app)/settings.tsx:635 +#: app/(app)/settings.tsx:671 msgid "Restoring. Please wait..." msgstr "Restauration en cours. Patiente..." @@ -2837,7 +3109,7 @@ msgstr "corde" msgid "rotator cuff" msgstr "coiffe des rotateurs" -#: app/(app)/settings.tsx:54 +#: app/(app)/settings.tsx:57 msgid "Sa" msgstr "Sa" @@ -2856,12 +3128,12 @@ msgstr "Samedi" #: app/(app)/(create-plan)/create.tsx:363 #: app/(app)/(workout)/index.tsx:843 #: app/(app)/(workout)/index.tsx:1071 -#: app/(app)/custom-exercise.tsx:549 +#: app/(app)/custom-exercise.tsx:575 #: components/SettingsModal.tsx:296 msgid "Save" msgstr "Enregistrer" -#: app/(app)/custom-exercise.tsx:549 +#: app/(app)/custom-exercise.tsx:575 msgid "Save and select" msgstr "Enregistrer et sélectionner" @@ -2901,6 +3173,8 @@ msgstr "Enregistrement de l'entraînement..." #: app/(app)/(tabs)/(stats)/exercises.tsx:166 #: app/(app)/(workout)/exercises.tsx:233 #: app/(app)/exercise-library.tsx:91 +#: app/(app)/friends.tsx:59 +#: app/(app)/friends.tsx:219 msgid "Search" msgstr "Rechercher" @@ -2912,13 +3186,14 @@ msgstr "Rechercher dans l'aide" msgid "Search help…" msgstr "Rechercher dans l'aide…" -#: app/(app)/custom-exercise.tsx:404 -#: app/(app)/custom-exercise.tsx:427 +#: app/(app)/custom-exercise.tsx:430 #: app/(app)/custom-exercise.tsx:453 +#: app/(app)/custom-exercise.tsx:479 msgid "Search..." msgstr "Rechercher..." -#: app/(app)/custom-exercise.tsx:416 +#: app/(app)/custom-exercise.tsx:442 +#: app/(app)/friend-exercise.tsx:83 msgid "Secondary Muscles" msgstr "Muscles secondaires" @@ -2934,34 +3209,39 @@ msgstr "Sélectionne un jour pour voir les entraînements." msgid "Select a workout to view" msgstr "Sélectionne un entraînement" -#: app/(app)/settings.tsx:1311 +#: app/(app)/settings.tsx:1350 msgid "Select at least one day" msgstr "Sélectionne au moins un jour" -#: app/(app)/custom-exercise.tsx:382 +#: app/(app)/custom-exercise.tsx:408 msgid "Select body part" msgstr "Sélectionner la partie du corps" -#: app/(app)/custom-exercise.tsx:454 +#: app/(app)/custom-exercise.tsx:480 msgid "Select equipment" msgstr "Sélectionner l'équipement" -#: app/(app)/custom-exercise.tsx:428 +#: app/(app)/custom-exercise.tsx:454 msgid "Select secondary muscles" msgstr "Sélectionner les muscles secondaires" -#: app/(app)/custom-exercise.tsx:405 +#: app/(app)/custom-exercise.tsx:431 msgid "Select target muscle" msgstr "Sélectionner le muscle cible" -#: app/(app)/custom-exercise.tsx:475 +#: app/(app)/custom-exercise.tsx:501 msgid "Select tracking type" msgstr "Sélectionner le type de suivi" -#: app/(app)/settings.tsx:924 +#: app/(app)/settings.tsx:960 msgid "Send notification in background after rest" msgstr "Envoyer une notification en arrière-plan après le repos" +#: app/(app)/friends.tsx:271 +#: app/(app)/friends.tsx:344 +msgid "Sent" +msgstr "Envoyées" + #: constants/dbTranslations.ts:33 msgid "serratus anterior" msgstr "grand dentelé" @@ -2990,6 +3270,11 @@ msgstr "Types de séries" msgid "Set your weekly workout goal and enter your body weight to get accurate stats and recommendations. You can also adjust your weight increment preferences, choose your preferred units, and much more." msgstr "Fixe ton objectif d'entraînement hebdomadaire et entre ton poids de corps pour obtenir des stats et recommandations précises. Tu peux aussi ajuster tes préférences d'incrément de poids, choisir tes unités préférées, et bien plus." +#: app/(app)/friend-plan.tsx:124 +#: app/(app)/friend-workout.tsx:83 +msgid "sets" +msgstr "séries" + #: app/(app)/(workout)/workout-summary.tsx:574 #: app/(app)/(workout)/workout-summary.tsx:597 msgid "Sets" @@ -3007,12 +3292,48 @@ msgstr "Vue d'ensemble des séries" msgid "settings" msgstr "paramètres" -#: app/(app)/_layout.tsx:40 -#: components/AppMenu.tsx:189 +#: app/(app)/_layout.tsx:42 +#: components/AppMenu.tsx:207 #: constants/HelpData.ts:153 msgid "Settings" msgstr "Paramètres" +#: app/(app)/settings.tsx:1779 +msgid "Share body measurements with friends" +msgstr "Partager les mesures corporelles avec mes amis" + +#: app/(app)/settings.tsx:1739 +msgid "Share completed workouts with friends" +msgstr "Partager les entraînements avec mes amis" + +#: app/(app)/settings.tsx:1697 +msgid "Share custom exercises with friends" +msgstr "Partager les exercices personnalisés avec mes amis" + +#: app/(app)/(tabs)/(plans)/overview.tsx:306 +msgid "Share Plan" +msgstr "Partager le programme" + +#: app/(app)/settings.tsx:1620 +msgid "Share plans with friends" +msgstr "Partager les programmes avec mes amis" + +#: app/(app)/settings.tsx:1658 +msgid "Share standalone workouts with friends" +msgstr "Partager les entraînements solo avec mes amis" + +#: app/(app)/settings.tsx:1821 +msgid "Share strength PRs with friends" +msgstr "Partager les records de force avec mes amis" + +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:291 +msgid "Share Workout" +msgstr "Partager l'entraînement" + +#: constants/HelpData.ts:173 +msgid "Sharing Your Content" +msgstr "Partager ton contenu" + #: constants/dbTranslations.ts:57 msgid "shins" msgstr "tibias" @@ -3022,28 +3343,36 @@ msgstr "tibias" msgid "shoulders" msgstr "épaules" -#: app/(app)/settings.tsx:1452 +#: app/(app)/settings.tsx:1491 msgid "Show onboarding on home screen" msgstr "Afficher l'accueil sur l'écran principal" -#: app/(app)/settings.tsx:532 +#: app/(app)/settings.tsx:568 msgid "Sign in" msgstr "Se connecter" -#: app/(app)/settings.tsx:525 +#: app/(app)/friends.tsx:51 +msgid "Sign In" +msgstr "Se connecter" + +#: app/(app)/friends.tsx:48 +msgid "Sign in to use the Friends feature." +msgstr "Connecte-toi pour utiliser la fonctionnalité Amis." + +#: app/(app)/settings.tsx:561 msgid "Sign in with Google" msgstr "Se connecter avec Google" -#: constants/HelpData.ts:174 +#: constants/HelpData.ts:194 msgid "Sign in with Google in Settings to enable cloud backups of all your workout data. Tap Backup at any time to save a snapshot; the date of your last backup is shown beneath the button. Tap Restore to download and apply your latest backup; confirm the prompt and the app will reload with your restored data. Your backups are stored securely and are tied to your Google account. If you switch devices or reinstall the app, simply sign in with the same Google account and tap Restore to get your data back." msgstr "Connecte-toi avec Google dans les Paramètres pour activer les sauvegardes cloud de toutes tes données d'entraînement. Appuie sur Sauvegarder à tout moment pour créer un instantané ; la date de ta dernière sauvegarde s'affiche sous le bouton. Appuie sur Restaurer pour télécharger et appliquer ta dernière sauvegarde ; confirme l'invite et l'appli se rechargera avec tes données restaurées. Tes sauvegardes sont stockées en sécurité et liées à ton compte Google. Si tu changes d'appareil ou réinstalles l'appli, connecte-toi avec le même compte Google et appuie sur Restaurer pour récupérer tes données." #. placeholder {0}: user.displayName || user.email -#: app/(app)/settings.tsx:538 +#: app/(app)/settings.tsx:574 msgid "Signed in as {0}" msgstr "Connecté en tant que {0}" -#: constants/HelpData.ts:168 +#: constants/HelpData.ts:188 msgid "Signing In" msgstr "Connexion" @@ -3051,16 +3380,16 @@ msgstr "Connexion" msgid "Single & Quick Workouts" msgstr "Entraînements seuls et rapides" -#: app/(app)/custom-exercise.tsx:505 +#: app/(app)/custom-exercise.tsx:531 #: app/(app)/exercise-info.tsx:263 msgid "Single-arm / single-leg" msgstr "Unilatéral bras / jambe" -#: app/(app)/settings.tsx:722 +#: app/(app)/settings.tsx:758 msgid "Size unit" msgstr "Unité de taille" -#: app/(app)/settings.tsx:1412 +#: app/(app)/settings.tsx:1451 msgid "Size: ~100MB" msgstr "Taille : ~100 Mo" @@ -3102,10 +3431,18 @@ msgstr "Certaines images n'ont pas pu être supprimées. IDs des exercices en é msgid "Some images failed to download after retries. Failed exercise IDs: {0}" msgstr "Certaines images n'ont pas pu être téléchargées après plusieurs tentatives. IDs des exercices en échec : {0}" +#: app/(app)/friends.tsx:237 +msgid "Something went wrong. Please try again." +msgstr "Une erreur est survenue. Réessaie." + #: constants/dbTranslations.ts:34 msgid "spine" msgstr "colonne vertébrale" +#: app/(app)/friend-profile.tsx:234 +msgid "Standalone Workouts" +msgstr "Entraînements solo" + #: constants/HelpData.ts:39 msgid "Standalone workouts live outside of plans and appear alongside your plans on the Plans screen. Create one by tapping New Workout, give it a name, and add exercises; you can run it at any time without needing an active plan. An estimated duration is shown on each standalone workout so you can plan your time before starting. Quick Workouts let you start a session immediately from the home screen: tap Quick Workout, add exercises as you go, and at the end you can save it as a standalone workout for future use or simply discard it. Like plans, the workout editor automatically saves a draft so you can safely leave and return without losing your work." msgstr "Les entraînements indépendants sont en dehors des programmes et apparaissent avec tes programmes dans l'onglet Programmes. Crée-en un en appuyant sur Nouvel entraînement, donne-lui un nom et ajoute des exercices ; tu peux le lancer à tout moment sans avoir besoin d'un programme actif. Une durée estimée est affichée sur chaque entraînement indépendant pour que tu puisses planifier ton temps avant de commencer. Les entraînements rapides te permettent de démarrer une séance immédiatement depuis l'écran d'accueil : appuie sur Entraînement rapide, ajoute des exercices au fur et à mesure, et à la fin tu peux le sauvegarder comme entraînement indépendant pour une utilisation future ou simplement l'ignorer. Comme les programmes, l'éditeur d'entraînement sauvegarde automatiquement un brouillon." @@ -3114,7 +3451,7 @@ msgstr "Les entraînements indépendants sont en dehors des programmes et appara msgid "Start" msgstr "Commencer" -#: app/(app)/(tabs)/(plans)/overview.tsx:282 +#: app/(app)/(tabs)/(plans)/overview.tsx:327 msgid "Start Plan" msgstr "Démarrer le programme" @@ -3122,11 +3459,11 @@ msgstr "Démarrer le programme" msgid "Start Timer" msgstr "Démarrer la minuterie" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:267 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:319 msgid "Start Workout" msgstr "Commencer l'entraînement" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:223 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:235 #: app/(app)/(tabs)/index.tsx:306 msgid "Starting Workout..." msgstr "Démarrage de l'entraînement..." @@ -3137,7 +3474,7 @@ msgstr "vélo stationnaire" #: app/(app)/(tabs)/_layout.tsx:74 #: app/(app)/(tabs)/(stats)/_layout.tsx:16 -#: app/(app)/settings.tsx:994 +#: app/(app)/settings.tsx:1030 msgid "Stats" msgstr "Stats" @@ -3145,7 +3482,7 @@ msgstr "Stats" msgid "Stats & History" msgstr "Stats et historique" -#: app/(app)/custom-exercise.tsx:499 +#: app/(app)/custom-exercise.tsx:525 msgid "Stats Options" msgstr "Options stats" @@ -3169,7 +3506,15 @@ msgstr "Arrêter" msgid "Streak" msgstr "Série consécutive" -#: app/(app)/settings.tsx:55 +#: app/(app)/friend-profile.tsx:491 +msgid "Strength PRs" +msgstr "Records de force" + +#: app/(app)/settings.tsx:1825 +msgid "Strength PRs are shared automatically after each workout." +msgstr "Les records de force sont partagés automatiquement après chaque entraînement." + +#: app/(app)/settings.tsx:58 msgid "Su" msgstr "Di" @@ -3178,7 +3523,7 @@ msgstr "Di" msgid "Success" msgstr "Succès" -#: app/(app)/settings.tsx:1088 +#: app/(app)/settings.tsx:1124 msgid "Suggest load and rep adjustments" msgstr "Suggérer des ajustements de charge et de reps" @@ -3205,8 +3550,8 @@ msgstr "Superserie" #. placeholder {0}: outgoingSnapshot.isFirstInSuperset ? "A" : "B" #. placeholder {0}: ss.isFirstInSuperset ? "A" : "B" -#: app/(app)/(workout)/workout-session.tsx:1405 -#: app/(app)/(workout)/workout-session.tsx:1491 +#: app/(app)/(workout)/workout-session.tsx:1436 +#: app/(app)/(workout)/workout-session.tsx:1522 msgid "Superset {0}" msgstr "Superserie {0}" @@ -3218,7 +3563,11 @@ msgstr "Superseries" msgid "Take full control of your training by designing your own personalised plan. Select exercises, set rep ranges, rest times, and more to create a plan that aligns perfectly with your fitness goals." msgstr "Prends le contrôle total de ton entraînement en concevant ton propre programme personnalisé. Sélectionne des exercices, définis des plages de répétitions, des temps de repos, et plus encore pour créer un programme parfaitement adapté à tes objectifs." -#: constants/HelpData.ts:169 +#: constants/HelpData.ts:179 +msgid "Tap any accepted friend in your Friends list to open their profile. Their profile shows the plans, standalone workouts, and custom exercises they have chosen to share. Tap Import on any item to add it directly to your own library. Imported plans and workouts are saved as new copies that you can edit freely without affecting the original. Imported custom exercises are added to your exercise library and available immediately when building workouts." +msgstr "Appuie sur n'importe quel ami accepté dans ta liste d'amis pour ouvrir son profil. Son profil affiche les programmes, entraînements solo et exercices personnalisés qu'il a choisi de partager. Appuie sur Importer sur n'importe quel élément pour l'ajouter directement à ta propre bibliothèque. Les programmes et entraînements importés sont sauvegardés comme de nouvelles copies que tu peux modifier librement sans affecter l'original. Les exercices personnalisés importés sont ajoutés à ta bibliothèque d'exercices et disponibles immédiatement lors de la création d'entraînements." + +#: constants/HelpData.ts:189 msgid "Tap Sign In With Google in Settings to connect your account. Signing in enables cloud backups so your data is safe if you switch devices or reinstall the app, and your name is shown in the home screen greeting. The app works fully offline without signing in, but cloud backups are unavailable. Your data is stored locally on your device and is not shared with anyone unless you choose to share it yourself." msgstr "Appuie sur Se connecter avec Google dans les Paramètres pour connecter ton compte. La connexion active les sauvegardes cloud pour que tes données soient en sécurité si tu changes d'appareil ou réinstalles l'appli, et ton nom apparaît dans le message d'accueil. L'appli fonctionne entièrement hors ligne sans connexion, mais les sauvegardes cloud ne sont pas disponibles. Tes données sont stockées localement sur ton appareil et ne sont partagées avec personne, sauf si tu choisis de les partager toi-même." @@ -3230,11 +3579,15 @@ msgstr "Appuie sur l'icône étoile dans le coin supérieur droit de n'importe q msgid "Target Distance ({distanceUnit})" msgstr "Distance cible ({distanceUnit})" -#: app/(app)/custom-exercise.tsx:393 +#: app/(app)/friend-exercise.tsx:76 +msgid "Target Muscle" +msgstr "Muscle ciblé" + +#: app/(app)/custom-exercise.tsx:419 msgid "Target Muscle *" msgstr "Muscle cible *" -#: app/(app)/custom-exercise.tsx:202 +#: app/(app)/custom-exercise.tsx:207 msgid "Target muscle is required." msgstr "Le muscle cible est obligatoire." @@ -3246,7 +3599,7 @@ msgstr "Muscle cible :" msgid "Target: {distanceMin} {distanceUnit}" msgstr "Cible : {distanceMin} {distanceUnit}" -#: app/(app)/settings.tsx:52 +#: app/(app)/settings.tsx:55 msgid "Th" msgstr "Je" @@ -3294,6 +3647,14 @@ msgstr "Cuisse (D)" msgid "This exercise is already in your workout. Please choose a different one." msgstr "Cet exercice est déjà dans ton entraînement. Choisis-en un autre." +#: app/(app)/friend-profile.tsx:140 +msgid "This friend hasn't shared any content yet." +msgstr "Cet ami n'a encore partagé aucun contenu." + +#: app/(app)/settings.tsx:88 +msgid "This removes all content you have shared with friends. Your friends and friend list are not affected." +msgstr "Cela supprime tout le contenu que tu as partagé avec tes amis. Tes amis et ta liste d'amis ne sont pas affectés." + #: app/(app)/+not-found.tsx:18 msgid "This screen doesn't exist." msgstr "Cet écran n'existe pas." @@ -3309,7 +3670,7 @@ msgstr "Jeu" msgid "Thursday" msgstr "Jeudi" -#: app/(app)/custom-exercise.tsx:65 +#: app/(app)/custom-exercise.tsx:70 #: components/WeeklySummaryCard.tsx:299 msgid "Time" msgstr "Temps" @@ -3336,7 +3697,7 @@ msgstr "Temps (s)" msgid "Time PR" msgstr "Record de temps" -#: app/(app)/(workout)/workout-session.tsx:552 +#: app/(app)/(workout)/workout-session.tsx:559 msgid "Time to do your next set!" msgstr "C'est l'heure de ta prochaine série !" @@ -3345,11 +3706,11 @@ msgstr "C'est l'heure de ta prochaine série !" msgid "Time: {0}" msgstr "Temps : {0}" -#: app/(app)/settings.tsx:365 +#: app/(app)/settings.tsx:401 msgid "To enable rest timer notifications, grant notification permissions in your device settings." msgstr "Pour activer les notifications de la minuterie de repos, autorise les notifications dans les paramètres de ton appareil." -#: app/(app)/settings.tsx:384 +#: app/(app)/settings.tsx:420 msgid "To enable workout reminders, grant notification permissions in your device settings." msgstr "Pour activer les rappels d'entraînement, autorise les notifications dans les paramètres de ton appareil." @@ -3414,15 +3775,19 @@ msgstr "Exercices suivis" msgid "Tracking" msgstr "Suivi" -#: app/(app)/custom-exercise.tsx:465 +#: app/(app)/friend-exercise.tsx:90 +msgid "Tracking Type" +msgstr "Type de suivi" + +#: app/(app)/custom-exercise.tsx:491 msgid "Tracking Type *" msgstr "Type de suivi *" -#: app/(app)/custom-exercise.tsx:485 +#: app/(app)/custom-exercise.tsx:511 msgid "Tracking type cannot be changed after creation." msgstr "Le type de suivi ne peut pas être modifié après la création." -#: app/(app)/custom-exercise.tsx:205 +#: app/(app)/custom-exercise.tsx:210 msgid "Tracking type is required." msgstr "Le type de suivi est obligatoire." @@ -3440,7 +3805,7 @@ msgstr "" msgid "Training" msgstr "Entraînement" -#: components/TrainingPlanCard.tsx:74 +#: components/TrainingPlanCard.tsx:77 msgid "Training Plan" msgstr "Programme d'entraînement" @@ -3476,7 +3841,7 @@ msgstr "triceps" msgid "Try Again" msgstr "Réessayer" -#: app/(app)/settings.tsx:50 +#: app/(app)/settings.tsx:53 msgid "Tu" msgstr "Ma" @@ -3499,7 +3864,11 @@ msgstr "Filtrer les thèmes d'aide" msgid "Unable to save your workout. Please try again later." msgstr "Impossible de sauvegarder ton entraînement. Réessaie plus tard." -#: app/(app)/settings.tsx:650 +#: app/(app)/friend-exercise.tsx:97 +msgid "Unilateral" +msgstr "Unilatéral" + +#: app/(app)/settings.tsx:686 msgid "Units of measurement" msgstr "Unités de mesure" @@ -3511,7 +3880,17 @@ msgstr "Inconnu" msgid "Update Ready" msgstr "Mise à jour prête" -#: app/(app)/settings.tsx:634 +#. placeholder {0}: formatDistanceToNow(plan.updatedAt.toDate(), { addSuffix: true, }) +#. placeholder {0}: formatDistanceToNow(plan.updatedAt.toDate(), { addSuffix: true }) +#. placeholder {0}: formatDistanceToNow(workout.updatedAt.toDate(), { addSuffix: true, }) +#: app/(app)/friend-plan.tsx:75 +#: app/(app)/friend-profile.tsx:185 +#: app/(app)/friend-profile.tsx:276 +#: app/(app)/friend-workout.tsx:62 +msgid "Updated {0}" +msgstr "Mis à jour {0}" + +#: app/(app)/settings.tsx:670 msgid "Uploading. Please wait..." msgstr "Envoi en cours. Patiente..." @@ -3543,11 +3922,11 @@ msgstr "pectoraux supérieurs" msgid "upper legs" msgstr "haut des jambes" -#: app/(app)/settings.tsx:979 +#: app/(app)/settings.tsx:1015 msgid "Using history from same workout" msgstr "Historique du même entraînement" -#: app/(app)/settings.tsx:978 +#: app/(app)/settings.tsx:1014 msgid "Using most recent from any workout" msgstr "Le plus récent de n'importe quel entraînement" @@ -3555,7 +3934,7 @@ msgstr "Le plus récent de n'importe quel entraînement" msgid "Values" msgstr "Valeurs" -#: app/(app)/settings.tsx:876 +#: app/(app)/settings.tsx:912 msgid "Vibrate after rest" msgstr "Vibrer après le repos" @@ -3624,7 +4003,7 @@ msgstr "Échauffement, " msgid "warmup" msgstr "échauffement" -#: app/(app)/settings.tsx:51 +#: app/(app)/settings.tsx:54 msgid "We" msgstr "Me" @@ -3643,7 +4022,7 @@ msgstr "Mercredi" msgid "Week streak" msgstr "Série de semaines" -#: app/(app)/settings.tsx:558 +#: app/(app)/settings.tsx:594 msgid "Weekly goal" msgstr "Objectif hebdomadaire" @@ -3667,7 +4046,7 @@ msgstr "Poids" msgid "Weight ({weightUnitLabel})" msgstr "Poids ({weightUnitLabel})" -#: app/(app)/settings.tsx:755 +#: app/(app)/settings.tsx:791 msgid "Weight increment" msgstr "Incrément de poids" @@ -3675,11 +4054,11 @@ msgstr "Incrément de poids" msgid "Weight Tracking for Bodyweight Exercises" msgstr "Enregistrement du poids pour les exercices au poids de corps" -#: app/(app)/settings.tsx:670 +#: app/(app)/settings.tsx:706 msgid "Weight unit" msgstr "Unité de poids" -#: app/(app)/custom-exercise.tsx:62 +#: app/(app)/custom-exercise.tsx:67 msgid "Weight/Reps" msgstr "Poids/Rép." @@ -3703,7 +4082,7 @@ msgstr "Bienvenue{userName}" msgid "When you open a workout that contains exercises you trained recently, a Recovery Check-in sheet appears if those exercises have a pending progression suggestion and your last session was at least 12 hours ago. For each relevant muscle group, you choose one of three options: Fresh (fully recovered), Mild soreness, or Still very sore. If a muscle is marked as still very sore, any upward progression suggestion for exercises targeting that muscle is paused and held at the current load until you re-evaluate at the start of the following session. Fresh or Mild soreness does not affect suggestions. Tap Skip for now to bypass the check-in entirely; a skipped check-in is treated the same as fresh recovery, so pending suggestions are unaffected." msgstr "Quand tu ouvres un entraînement contenant des exercices que tu as pratiqués récemment, une feuille de Bilan de récupération apparaît si ces exercices ont une suggestion de progression en attente et que ta dernière séance remonte à au moins 12 heures. Pour chaque groupe musculaire concerné, tu choisis une de trois options : Frais (complètement récupéré), Légère courbature ou Encore très courbaturé. Si un muscle est marqué comme encore très courbaturé, toute suggestion de progression à la hausse pour les exercices ciblant ce muscle est mise en pause et maintenue à la charge actuelle jusqu'à ce que tu réévalues au début de la séance suivante. Frais ou Légère courbature ne modifie pas les suggestions. Appuie sur Passer pour l'instant pour contourner le bilan entièrement ; un bilan ignoré est traité comme une récupération complète, donc les suggestions en attente ne sont pas affectées." -#: components/ExerciseFeedbackSheet.tsx:233 +#: components/ExerciseFeedbackSheet.tsx:247 msgid "Where did you feel it?" msgstr "Où tu l'as ressenti ?" @@ -3713,7 +4092,7 @@ msgstr "travail" #: app/(app)/(tabs)/(plans)/_layout.tsx:18 #: app/(app)/(workout)/_layout.tsx:17 -#: app/(app)/settings.tsx:734 +#: app/(app)/settings.tsx:770 #: components/RestDayCard.tsx:41 #: components/WeeklyScheduleDisplay.tsx:88 #: components/WorkoutDoneCard.tsx:50 @@ -3736,7 +4115,8 @@ msgstr "Calendrier des entraînements" msgid "Workout Complete!" msgstr "Entraînement terminé !" -#: app/(app)/_layout.tsx:33 +#: app/(app)/_layout.tsx:35 +#: app/(app)/_layout.tsx:55 #: app/(app)/(tabs)/(stats)/_layout.tsx:19 msgid "Workout Details" msgstr "Détails de l'entraînement" @@ -3754,13 +4134,14 @@ msgstr "Entraînement en cours" msgid "Workout name" msgstr "Nom de l'entraînement" -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:54 -#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:207 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:66 +#: app/(app)/(tabs)/(plans)/standalone-workout.tsx:219 #: app/(app)/(workout)/workout-summary.tsx:518 +#: app/(app)/friend-workout.tsx:43 msgid "Workout not found." msgstr "Entraînement introuvable." -#: app/(app)/settings.tsx:1255 +#: app/(app)/settings.tsx:1294 msgid "Workout reminders" msgstr "Rappels d'entraînement" @@ -3804,7 +4185,7 @@ msgstr "x {0} rép. " msgid "Yes" msgstr "Oui" -#: components/ExerciseFeedbackSheet.tsx:215 +#: components/ExerciseFeedbackSheet.tsx:229 msgid "Yes, increase the challenge" msgstr "Oui, augmenter le défi" @@ -3812,7 +4193,7 @@ msgstr "Oui, augmenter le défi" msgid "Yesterday" msgstr "Hier" -#: app/(app)/(tabs)/(plans)/overview.tsx:150 +#: app/(app)/(tabs)/(plans)/overview.tsx:161 msgid "You activated this plan." msgstr "Tu as activé ce programme." @@ -3824,6 +4205,10 @@ msgstr "Tu peux masquer cet écran d'accueil à tout moment depuis la page Param msgid "You can login at any time from the settings screen, if you choose to skip it now." msgstr "Tu peux te connecter à tout moment depuis l'écran Paramètres, si tu choisis de passer pour l'instant." +#: constants/HelpData.ts:174 +msgid "You can share plans, standalone workouts, custom exercises, body measurements, and strength PRs with your friends. All five categories have a global toggle in Privacy Settings, found in the Account section of Settings. Enabling the global toggle for a category shares all items in that category and syncs new data automatically whenever it changes. Plans and standalone workouts also have an individual Share toggle on each item's overview screen, so you can publish specific plans or workouts without sharing everything. A cloud icon on the plan or workout card confirms it is currently published. To remove shared data, disable the toggle in Privacy Settings and tap Delete Shared Data for that category. You can also delete all shared data for every category from the same screen." +msgstr "Tu peux partager tes programmes, entraînements solo, exercices personnalisés, mesures corporelles et records de force avec tes amis. Les cinq catégories ont un interrupteur global dans les Paramètres de confidentialité, dans la section Compte des Paramètres. Activer l'interrupteur global d'une catégorie partage tous les éléments de cette catégorie et synchronise automatiquement les nouvelles données à chaque modification. Les programmes et entraînements solo ont aussi un interrupteur Partager individuel sur l'écran de présentation de chaque élément, ce qui te permet de publier des programmes ou entraînements spécifiques sans tout partager. Une icône nuage sur la carte programme ou entraînement confirme qu'il est actuellement publié. Pour supprimer des données partagées, désactive l'interrupteur dans les Paramètres de confidentialité et appuie sur Supprimer les données partagées pour cette catégorie. Tu peux aussi supprimer toutes les données partagées de chaque catégorie depuis le même écran." + #: components/ProgressionSummaryCard.tsx:22 msgid "You chose to keep it steady. Hold this load." msgstr "Tu as choisi de maintenir. La charge reste comme ça." @@ -3851,11 +4236,11 @@ msgstr "Tu as des modifications non enregistrées. Es-tu sûr(e) de vouloir les msgid "You modified this workout. Save those changes for future sessions?" msgstr "Tu as modifié cet entraînement. Enregistrer ces modifications pour les prochaines séances ?" -#: app/(app)/settings.tsx:604 +#: app/(app)/settings.tsx:640 msgid "You need to sign in to use this feature" msgstr "Tu dois te connecter pour utiliser cette fonctionnalité" -#: app/(app)/custom-exercise.tsx:81 +#: app/(app)/custom-exercise.tsx:86 msgid "You'll lose what you've entered so far." msgstr "Tu vas perdre ce que tu as saisi jusqu'à présent." @@ -3871,10 +4256,10 @@ msgstr "Tu as atteint ton objectif hebdomadaire. Travail incroyable !" msgid "Your journey to Swoletown begins today!" msgstr "Ton voyage vers Swoletown commence aujourd'hui !" -#: app/(app)/(tabs)/(plans)/index.tsx:126 +#: app/(app)/(tabs)/(plans)/index.tsx:130 msgid "Your training plans" msgstr "Tes programmes" -#: app/(app)/(tabs)/(plans)/index.tsx:141 +#: app/(app)/(tabs)/(plans)/index.tsx:147 msgid "Your workouts" msgstr "Tes entraînements" diff --git a/package-lock.json b/package-lock.json index b92b7868..376db817 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,6 +7,8 @@ "name": "musclequest", "dependencies": { "@bugsnag/expo": "^54.0.0", + "@bugsnag/expo-performance": "^54.0.0", + "@bugsnag/plugin-react-navigation-performance": "^3.4.1", "@expo-google-fonts/inter": "^0.2.3", "@expo/vector-icons": "^15.0.3", "@formatjs/intl-locale": "^5.3.8", @@ -22,6 +24,7 @@ "@react-native-firebase/app": "^23.8.8", "@react-native-firebase/app-check": "23.8.8", "@react-native-firebase/auth": "^23.8.8", + "@react-native-firebase/firestore": "^23.8.8", "@react-native-firebase/storage": "^23.8.8", "@react-native-google-signin/google-signin": "^12.2.1", "@react-navigation/native": "^7.0.14", @@ -29,7 +32,7 @@ "@tanstack/react-query": "^5.51.21", "date-fns": "^3.6.0", "dotenv": "^17.4.2", - "expo": "^54.0.0", + "expo": "~54.0.35", "expo-application": "~7.0.8", "expo-asset": "~12.0.13", "expo-audio": "~1.1.1", @@ -38,24 +41,24 @@ "expo-crypto": "~15.0.9", "expo-dev-client": "~6.0.21", "expo-device": "~8.0.10", - "expo-file-system": "~19.0.22", - "expo-font": "~14.0.11", + "expo-file-system": "~19.0.23", + "expo-font": "~14.0.12", "expo-image": "~3.0.11", "expo-image-picker": "~17.0.11", "expo-insights": "~0.10.8", "expo-keep-awake": "~15.0.8", "expo-linear-gradient": "~15.0.8", "expo-linking": "~8.0.12", - "expo-localization": "~17.0.8", + "expo-localization": "~17.0.9", "expo-navigation-bar": "~5.0.10", "expo-notifications": "~0.32.17", - "expo-router": "~6.0.23", + "expo-router": "~6.0.24", "expo-secure-store": "~15.0.8", "expo-splash-screen": "~31.0.13", "expo-sqlite": "~16.0.10", "expo-status-bar": "~3.0.9", "expo-system-ui": "~6.0.9", - "expo-updates": "~29.0.17", + "expo-updates": "~29.0.18", "expo-web-browser": "~15.0.11", "p-limit": "^6.1.0", "promise": "^8.3.0", @@ -80,7 +83,7 @@ }, "devDependencies": { "@babel/core": "^7.20.0", - "@bugsnag/plugin-expo-eas-sourcemaps": "^54.0.0", + "@bugsnag/plugin-expo-eas-sourcemaps": "^54.1.0", "@bugsnag/source-maps": "^2.3.3", "@lingui/babel-plugin-lingui-macro": "^6.1.0", "@lingui/cli": "^6.1.0", @@ -131,9 +134,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.29.3", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.3.tgz", - "integrity": "sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -170,13 +173,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.29.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", - "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz", + "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.29.0", - "@babel/types": "^7.29.0", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" @@ -186,25 +189,25 @@ } }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.27.3", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", - "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.29.7.tgz", + "integrity": "sha512-OoK6239jHPuSQOoS0kfTVKn0b/rVTk0seKq4Gd2UMLtmOVLjDC0ki3e+c90Trqv2gMfvJFqkiljrr568+qddiw==", "license": "MIT", "dependencies": { - "@babel/types": "^7.27.3" + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", - "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.28.6", - "@babel/helper-validator-option": "^7.27.1", + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" @@ -214,17 +217,17 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.29.3", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.29.3.tgz", - "integrity": "sha512-RpLYy2sb51oNLjuu1iD3bwBqCBWUzjO0ocp+iaCP/lJtb2CPLcnC2Fftw+4sAzaMELGeWTgExSKADbdo0GFVzA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.29.7.tgz", + "integrity": "sha512-IY3ZD9Tmooqr3TUhc3DUWxiuo8xx1DWLhd5M7hQ+ZWJamqM2BbalrBJb2MisSLoYorOj75U03qULCxQTY9r3hg==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.3", - "@babel/helper-member-expression-to-functions": "^7.28.5", - "@babel/helper-optimise-call-expression": "^7.27.1", - "@babel/helper-replace-supers": "^7.28.6", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/traverse": "^7.29.0", + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-member-expression-to-functions": "^7.29.7", + "@babel/helper-optimise-call-expression": "^7.29.7", + "@babel/helper-replace-supers": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7", + "@babel/traverse": "^7.29.7", "semver": "^6.3.1" }, "engines": { @@ -235,12 +238,12 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz", - "integrity": "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.29.7.tgz", + "integrity": "sha512-907Uymvqgg1dwUA+7IGwFAOSYzQOuzPXKNJ1yxzwPffzkYFg2q2eHi1fIOs6sXkG9NbIUMunnUlkYsfRFNvomg==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-annotate-as-pure": "^7.29.7", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, @@ -268,35 +271,35 @@ } }, "node_modules/@babel/helper-globals": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz", - "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.29.7.tgz", + "integrity": "sha512-j+7JYmk1JYDtACIGj0QJqqWZjoUpMoEikQGADMaHgCMCSDqd2+P32rfcibUNrGOMWrlzK1WJBdxrB3JJQZwWtg==", "license": "MIT", "dependencies": { - "@babel/traverse": "^7.28.5", - "@babel/types": "^7.28.5" + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", - "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", "license": "MIT", "dependencies": { - "@babel/traverse": "^7.28.6", - "@babel/types": "^7.28.6" + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -320,35 +323,35 @@ } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", - "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.29.7.tgz", + "integrity": "sha512-+kmGVjcT9RGYzoDwdwEqEvGgKe3BYq+O1iGzjFubaNgZHwYHP6lsF2Yghf4kEuv9BV7tYDZ913aBW9am6YKong==", "license": "MIT", "dependencies": { - "@babel/types": "^7.27.1" + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", - "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz", - "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.29.7.tgz", + "integrity": "sha512-16AMiW26DbXWBbr3B8wNozKM0ydMLB892vaOaJW/fPJdnT8vJk5sdkQcU/isqUxyCE0cEoa8wZOcbgDuC4b6Og==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-wrap-function": "^7.27.1", - "@babel/traverse": "^7.27.1" + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-wrap-function": "^7.29.7", + "@babel/traverse": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -358,14 +361,14 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.28.6.tgz", - "integrity": "sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.29.7.tgz", + "integrity": "sha512-atfGXWSeCiF4DnKZIfmJfQRkSw9b9gNNXR1kqKjbhG4pGYCOnkp8OcTB8E3NXjBu8NpheSnOeNKz8KT7UNFTmQ==", "license": "MIT", "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.28.5", - "@babel/helper-optimise-call-expression": "^7.27.1", - "@babel/traverse": "^7.28.6" + "@babel/helper-member-expression-to-functions": "^7.29.7", + "@babel/helper-optimise-call-expression": "^7.29.7", + "@babel/traverse": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -375,54 +378,54 @@ } }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", - "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.29.7.tgz", + "integrity": "sha512-brcMGQaVzIeUb+6/bs1Av0f8YuNNjKY2JyvfRCsFuFsdKccEQ5Ges2y74D74NZ1Rz8lKJ9ksJkfqwQFJ/iNEyQ==", "license": "MIT", "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", - "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.6.tgz", - "integrity": "sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.29.7.tgz", + "integrity": "sha512-iES0Skag9ERIF68aXadpO6dbXa03mNWK3sEqJaMnLNs/eC3l0lkImdfoy6Y09/SfkpawdAB4RjQ7PVA7TcVGdw==", "license": "MIT", "dependencies": { - "@babel/template": "^7.28.6", - "@babel/traverse": "^7.28.6", - "@babel/types": "^7.28.6" + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -528,12 +531,12 @@ } }, "node_modules/@babel/parser": { - "version": "7.29.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.3.tgz", - "integrity": "sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", "license": "MIT", "dependencies": { - "@babel/types": "^7.29.0" + "@babel/types": "^7.29.7" }, "bin": { "parser": "bin/babel-parser.js" @@ -543,14 +546,14 @@ } }, "node_modules/@babel/plugin-proposal-decorators": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.29.0.tgz", - "integrity": "sha512-CVBVv3VY/XRMxRYq5dwr2DS7/MvqPm23cOCjbwNnVrfOqcWlnefua1uUs0sjdKOGjvPUG633o07uWzJq4oI6dA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.29.7.tgz", + "integrity": "sha512-EtU0Hi3GvrTqD56xKmZvV/uCXK2ZbwVNPNLAquVItcAZpUhkXwWlo3Fmj0c2LxgSf2I8IDULeAepwNP1OefLXg==", "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.28.6", - "@babel/helper-plugin-utils": "^7.28.6", - "@babel/plugin-syntax-decorators": "^7.28.6" + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/plugin-syntax-decorators": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -560,12 +563,12 @@ } }, "node_modules/@babel/plugin-proposal-export-default-from": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.27.1.tgz", - "integrity": "sha512-hjlsMBl1aJc5lp8MoCDEZCiYzlgdRAShOjAfRw6X+GlpLpUPU7c3XNLsKFZbQk/1cRzBlJ7CXg3xJAJMrFa1Uw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.29.7.tgz", + "integrity": "sha512-p+G5BNXDcy3bOXplhY4HybQ1GxH3i2Tppmdm/3epyRu2VgJJZuUlZ61MqRTg582Q7ZLBdP7fePYvsumSEkMxcQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -626,12 +629,12 @@ } }, "node_modules/@babel/plugin-syntax-decorators": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.28.6.tgz", - "integrity": "sha512-71EYI0ONURHJBL4rSFXnITXqXrrY8q4P0q006DPfN+Rk+ASM+++IBXem/ruokgBZR8YNEWZ8R6B+rCb8VcUTqA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.29.7.tgz", + "integrity": "sha512-9MTTLbF39X6sqM92JPEsoI7++26hjZvzkxKZy64aMhWLH2mPkJ/Q3AV4QLmls3R14FpSpkOwQQfUh962JGQxxg==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -653,12 +656,12 @@ } }, "node_modules/@babel/plugin-syntax-export-default-from": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.28.6.tgz", - "integrity": "sha512-Svlx1fjJFnNz0LZeUaybRukSxZI3KkpApUmIRzEdXC5k8ErTOz0OD0kNrICi5Vc3GlpP5ZCeRyRO+mfWTSz+iQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.29.7.tgz", + "integrity": "sha512-foag0BB37ROhdeIX9O8G0jX7hw0UekJc04cHMrYLOnrErsnBKqJGHJ8eDRpoCFZBvEPPygmmtw4qyU97qa4oOw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -668,12 +671,12 @@ } }, "node_modules/@babel/plugin-syntax-flow": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.28.6.tgz", - "integrity": "sha512-D+OrJumc9McXNEBI/JmFnc/0uCM2/Y3PEBG3gfV3QIYkKv5pvnpzFrl1kYCrcHJP8nOeFB/SHi1IHz29pNGuew==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.29.7.tgz", + "integrity": "sha512-ajMX6QPcyomotqwpzhkYGxcK2i/us0rs1Qo9QvUpa+Fca0FTmqrzKrctoIYLMxcOhGZldGT/BAVkRGTWBiR8gQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -722,12 +725,12 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz", - "integrity": "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.29.7.tgz", + "integrity": "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -869,14 +872,14 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.29.0.tgz", - "integrity": "sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.29.7.tgz", + "integrity": "sha512-d98gXZkgswvkyohMBABkhm3GeXhYj8psWfwQ2C7gtfrKGTykQa/iOIi+JJhwMjPlZ6Vm2XN+DCf3Es1EoG4ZLA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6", - "@babel/helper-remap-async-to-generator": "^7.27.1", - "@babel/traverse": "^7.29.0" + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-remap-async-to-generator": "^7.29.7", + "@babel/traverse": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -886,14 +889,14 @@ } }, "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.28.6.tgz", - "integrity": "sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.29.7.tgz", + "integrity": "sha512-pcUb2SS+RMo9TWVBwKGI5ShtoG7R+zBsFmCKDa6fe8c+hPr3XJlZgoE5j6i8W7gDjhyvy+85vmYexanvXh3d1w==", "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.28.6", - "@babel/helper-plugin-utils": "^7.28.6", - "@babel/helper-remap-async-to-generator": "^7.27.1" + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-remap-async-to-generator": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -903,12 +906,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.6.tgz", - "integrity": "sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.29.7.tgz", + "integrity": "sha512-ONyr4+AZhKh8yKWInVxU9AXA9EbsyeLcL6V0dJy6M2/62vuvpGm29zzuymbTpdc451GEpDIdAyPLP3r+P61yKQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -934,13 +937,13 @@ } }, "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.6.tgz", - "integrity": "sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.29.7.tgz", + "integrity": "sha512-kibJgmEdX2iMwsHY2tSZNDgj8PwIlCQz7FK9KuGKO8zsuoUwSEhoNnNVp/emKWrbY4HeO6kkXfdMqRKKKXBm2A==", "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.28.6", - "@babel/helper-plugin-utils": "^7.28.6" + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -970,13 +973,13 @@ } }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.28.6.tgz", - "integrity": "sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.29.7.tgz", + "integrity": "sha512-RK7/IyU5phpuCdBAuig5VkzG/EnbDaui5SQGdU9BFrHdV+mV4cUjLMQ9lJDjLNtWHsqtiefpGZUXQP2BiTYMsA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6", - "@babel/template": "^7.28.6" + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/template": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -986,13 +989,13 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz", - "integrity": "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.29.7.tgz", + "integrity": "sha512-iPX8aD6H9zV5s7ZsqTdNocPN/MGQ5sSMnElKrktxjJRMnB2jN/1p2+R7GkfD6CAYoVFqy5A4XnSIUeGgJzIWpg==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.28.5" + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/traverse": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1002,12 +1005,12 @@ } }, "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz", - "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.29.7.tgz", + "integrity": "sha512-24B2nOy2TeJSMheqwPD4DDQOV/elLSIlKxjZt4i05H5AgdPdWR3n18HnNrcJ+j76WJd9gbwb9jPjNYUy6RautA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1017,13 +1020,13 @@ } }, "node_modules/@babel/plugin-transform-flow-strip-types": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.27.1.tgz", - "integrity": "sha512-G5eDKsu50udECw7DL2AcsysXiQyB7Nfg521t2OAJ4tbfTJ27doHLeF/vlI1NZGlLdbb/v+ibvtL1YBQqYOwJGg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.29.7.tgz", + "integrity": "sha512-wRHeUjUjCZnMHmiO5bRgjFLcoEh7JyTdByOW11ahhwNa4V0bmeGEaIvt51yq0zQp2yWIpqfxXXPyUP6GFJZHOQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/plugin-syntax-flow": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/plugin-syntax-flow": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1033,13 +1036,13 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz", - "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.29.7.tgz", + "integrity": "sha512-zeSIHh0+E1Um1WJRXCFlHQYu2ieJNdivLLjlBEp+dIBu3S51n+SZZmIXjxnItw6pz56Cn+KvK68BIBVsxq2JiQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1049,14 +1052,14 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz", - "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.29.7.tgz", + "integrity": "sha512-otRWaHXE6fbAGkePvaj/kvs3HsqXfPhlnzwSOlnFgbqCPMd975dW+4wZ00WFBt+/YlBGcJwNrARQTOJOb4ZrIg==", "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.27.1" + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/traverse": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1066,12 +1069,12 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz", - "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.29.7.tgz", + "integrity": "sha512-DZ/oLP21ZuWx1vKqnoNv6/tvEK48AQOBRai40CX9dTjGluvT/YZCyY3rryDtyUqCEoyNroy5KKPwX2iQCiRvyw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1081,12 +1084,12 @@ } }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.6.tgz", - "integrity": "sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.29.7.tgz", + "integrity": "sha512-A0H91hh6W8MFRkp5TqJmMr39jzGD1A1E1Ysiv2O06Sfbhkapm+XyIzxWCEh5kqwOZ1/8QZ0dY3SeQ7XBqfJd5Q==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1112,13 +1115,13 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.29.0.tgz", - "integrity": "sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.29.7.tgz", + "integrity": "sha512-vuFoLwr4qnv2xbZ16SQd6uPcH5FNrLHhk/Jzo++0XJFcaDsr4gjJVg6j398oMHiC+83k/GiBzviwF5KBJkPUtQ==", "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.28.5", - "@babel/helper-plugin-utils": "^7.28.6" + "@babel/helper-create-regexp-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1143,12 +1146,12 @@ } }, "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.28.6.tgz", - "integrity": "sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.29.7.tgz", + "integrity": "sha512-zR7fv/z14OjgHl4AgRtkDBvBMhIzCxqV/qN/2BCRC7LjFwvuzjYe7gDWxC4Wl/SNsLM6SE1IWvRPYMgSJaUvNw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1158,16 +1161,16 @@ } }, "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.6.tgz", - "integrity": "sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.29.7.tgz", + "integrity": "sha512-Ld98jn4c0smUywL57m7SgsHq3OpThOa6LqZJif3G6jYOovPleoFhVrBJ1WegRApSFB2wu4+RelAj9AC9G08Z4A==", "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.28.6", - "@babel/helper-plugin-utils": "^7.28.6", - "@babel/plugin-transform-destructuring": "^7.28.5", - "@babel/plugin-transform-parameters": "^7.27.7", - "@babel/traverse": "^7.28.6" + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/plugin-transform-destructuring": "^7.29.7", + "@babel/plugin-transform-parameters": "^7.29.7", + "@babel/traverse": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1177,12 +1180,12 @@ } }, "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.28.6.tgz", - "integrity": "sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.29.7.tgz", + "integrity": "sha512-sLsyndxK2VwX6yNUOakMb7Sh553ZTe/vVM1XJ+9Z5aW1ytsc8xOIwmyk05NNjN60vkc5/KqoTH6hB4V41LJhng==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1208,12 +1211,12 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.27.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz", - "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.29.7.tgz", + "integrity": "sha512-ZDOBqV/qLYJI0YElr8DcENEyARsFQeESqWXH6gZlghYXuPPjvweuDhP4VyEi4BlUBlLRFZVjxoZDMjxhLW766g==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1223,13 +1226,13 @@ } }, "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.28.6.tgz", - "integrity": "sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.29.7.tgz", + "integrity": "sha512-/6Rz4DK1ETDEM/bWHsPHcaEe7ZaT1EqSXjtSP/L0DijOYuaUhiRiOKcwpZ8P7zR4xXEHc2ITdiCgBm9Tpyv9ug==", "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.28.6", - "@babel/helper-plugin-utils": "^7.28.6" + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1239,14 +1242,14 @@ } }, "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.28.6.tgz", - "integrity": "sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.29.7.tgz", + "integrity": "sha512-+BNo06dnrzdNNqCm1X6YUaVv0DKk8Q+JYcoZfOkLhYWNCXzlwTSRq8zGWayT1csjcpNXV9CQTBRRbmTLZac5cA==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.3", - "@babel/helper-create-class-features-plugin": "^7.28.6", - "@babel/helper-plugin-utils": "^7.28.6" + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1256,12 +1259,12 @@ } }, "node_modules/@babel/plugin-transform-react-display-name": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.28.0.tgz", - "integrity": "sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.29.7.tgz", + "integrity": "sha512-+1wdDMGNb4UPeY3Q4L5yLiYe6TXPXubs4NjrgRFw13hPRLJfEMw2Q5OXkee6/IfdqePIeW4Jjwe3aBh7SdKz4Q==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1271,16 +1274,16 @@ } }, "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.28.6.tgz", - "integrity": "sha512-61bxqhiRfAACulXSLd/GxqmAedUSrRZIu/cbaT18T1CetkTmtDN15it7i80ru4DVqRK1WMxQhXs+Lf9kajm5Ow==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.29.7.tgz", + "integrity": "sha512-WsZulLVBUHXVj2cUcPVx6UE21TpalB6bHbSFErKT0Ib++ax24jjXe73FqlWvdylFOjiuPHYi6VCcgRad1ItN+A==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.3", - "@babel/helper-module-imports": "^7.28.6", - "@babel/helper-plugin-utils": "^7.28.6", - "@babel/plugin-syntax-jsx": "^7.28.6", - "@babel/types": "^7.28.6" + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/plugin-syntax-jsx": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1290,12 +1293,12 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-development": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.27.1.tgz", - "integrity": "sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.29.7.tgz", + "integrity": "sha512-Xfy3UVMF04+ypnFbkhvfqtmvwfe92qwQdbGZVonhE+6v35GzlofmOnA1szaZqzb9xYWr0nl1e5EMmzi0DNON1g==", "license": "MIT", "dependencies": { - "@babel/plugin-transform-react-jsx": "^7.27.1" + "@babel/plugin-transform-react-jsx": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1305,12 +1308,12 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", - "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.29.7.tgz", + "integrity": "sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1320,12 +1323,12 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-source": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", - "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.29.7.tgz", + "integrity": "sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1335,13 +1338,13 @@ } }, "node_modules/@babel/plugin-transform-react-pure-annotations": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.27.1.tgz", - "integrity": "sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.29.7.tgz", + "integrity": "sha512-H5E+HBgDpr6Q5t+Aj11tL7XkIui1jhbIoArVQnqjgXo5/3YxkN7ZEBcWF4RQlB0T4rrxJQbXS6kiFV6B7XTqUA==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1351,12 +1354,12 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.29.0.tgz", - "integrity": "sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.29.7.tgz", + "integrity": "sha512-rNNFV0DBAJp988xW2DOntfDoYn1eR8GGF5AT5vYc+rjyfaQkM242c9tZUHHPe7KYaiJizXPWhQTzzdbXySyhBw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1366,13 +1369,13 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.29.0.tgz", - "integrity": "sha512-jlaRT5dJtMaMCV6fAuLbsQMSwz/QkvaHOHOSXRitGGwSpR1blCY4KUKoyP2tYO8vJcqYe8cEj96cqSztv3uF9w==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.29.7.tgz", + "integrity": "sha512-xmAscdE/AsqRW7vutbPNoUmu/nF5SrLKPs7aoJgEjo35lLKA/Bc0i2rMv/hr1+Y0o1bQCiVtith3u2vdgRL39Q==", "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.28.6", - "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", "babel-plugin-polyfill-corejs2": "^0.4.14", "babel-plugin-polyfill-corejs3": "^0.13.0", "babel-plugin-polyfill-regenerator": "^0.6.5", @@ -1401,13 +1404,13 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.28.6.tgz", - "integrity": "sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.29.7.tgz", + "integrity": "sha512-/u5K1QWada7tbYNqTjMh96718g9NTwh9tfPJMsSmVsQwGT447FskV+KcfeXkXq2GWki4EM/MuTdmBec+hOuVTQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1417,12 +1420,12 @@ } }, "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz", - "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.29.7.tgz", + "integrity": "sha512-BCHzNYJGe9l7EpwwDBN/ztlL2NYFFq8hp9ddjtUEM9f2O7S7kKV/lL6Fwo7IF7NSkYhPK2vO+86nIGltA90MsA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1482,17 +1485,17 @@ } }, "node_modules/@babel/preset-react": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.28.5.tgz", - "integrity": "sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.29.7.tgz", + "integrity": "sha512-C+PV1TFUPTmBQGoPBL8j2QmLpZ117YTCwxIZeJOM96GbYMFSc7/pOXU5lVykwnZxyTqQxRsvoRk6f2FktZgGHA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-validator-option": "^7.27.1", - "@babel/plugin-transform-react-display-name": "^7.28.0", - "@babel/plugin-transform-react-jsx": "^7.27.1", - "@babel/plugin-transform-react-jsx-development": "^7.27.1", - "@babel/plugin-transform-react-pure-annotations": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "@babel/plugin-transform-react-display-name": "^7.29.7", + "@babel/plugin-transform-react-jsx": "^7.29.7", + "@babel/plugin-transform-react-jsx-development": "^7.29.7", + "@babel/plugin-transform-react-pure-annotations": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1530,31 +1533,45 @@ } }, "node_modules/@babel/template": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", - "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.28.6", - "@babel/parser": "^7.28.6", - "@babel/types": "^7.28.6" + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template/node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", - "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz", + "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.29.0", - "@babel/generator": "^7.29.0", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.29.0", - "@babel/template": "^7.28.6", - "@babel/types": "^7.29.0", + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7", "debug": "^4.3.1" }, "engines": { @@ -1580,14 +1597,28 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/traverse/node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/types": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", - "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5" + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1630,12 +1661,28 @@ "stack-generator": "^2.0.3" } }, + "node_modules/@bugsnag/core-performance": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@bugsnag/core-performance/-/core-performance-3.2.0.tgz", + "integrity": "sha512-g2tNpwhme3l0QvOe3VVUhAFXDubPfm/9kRg++ELrAPiA2QVMQNPwBUS73ICFfLBCnPIa+P8StsGpYg6vUddfEA==", + "dependencies": { + "@bugsnag/cuid": "^3.1.1" + } + }, "node_modules/@bugsnag/cuid": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/@bugsnag/cuid/-/cuid-3.2.2.tgz", "integrity": "sha512-7onuYLTMqMmHE9BBPG0YER4nFsU1rB+me1/YIeMusqcLbVbKKuG9u9+BDVDpje5e0llkkrVNOKYwmzM9DRIo7A==", "license": "MIT" }, + "node_modules/@bugsnag/delivery-fetch-performance": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@bugsnag/delivery-fetch-performance/-/delivery-fetch-performance-3.2.0.tgz", + "integrity": "sha512-U5CzG7cN0z4CimaWeIXnkBm7D01OPXZItYRviTVtBOnl2FLY4xuHa+B8Veh39WKLztqG0RMI9YlD4I0zI09faA==", + "dependencies": { + "@bugsnag/core-performance": "^3.2.0" + } + }, "node_modules/@bugsnag/expo": { "version": "54.1.0", "resolved": "https://registry.npmjs.org/@bugsnag/expo/-/expo-54.1.0.tgz", @@ -1665,6 +1712,19 @@ "react": "*" } }, + "node_modules/@bugsnag/expo-performance": { + "version": "54.0.0", + "resolved": "https://registry.npmjs.org/@bugsnag/expo-performance/-/expo-performance-54.0.0.tgz", + "integrity": "sha512-scJlSS8BFKI+HIXD/WNWsyaXqqy1F3Gp4xsK3mSjDniVeZkMw3HYp5c8F1JUBUkXqppecUUoqNFja7vbdhR2bw==", + "dependencies": { + "@bugsnag/react-native-performance": "^3.3.0" + }, + "peerDependencies": { + "expo": "^54.0.0", + "expo-constants": "~18.0.8", + "react": "*" + } + }, "node_modules/@bugsnag/expo/node_modules/@bugsnag/delivery-expo": { "version": "54.1.0", "resolved": "https://registry.npmjs.org/@bugsnag/delivery-expo/-/delivery-expo-54.1.0.tgz", @@ -1807,6 +1867,33 @@ "@bugsnag/core": "^8.0.0" } }, + "node_modules/@bugsnag/plugin-react-navigation-performance": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@bugsnag/plugin-react-navigation-performance/-/plugin-react-navigation-performance-3.4.1.tgz", + "integrity": "sha512-3snmtcZ/Md+cPqE9gra+r9p+3lwelmt8jSm42IyAFDLHx4XXrE16PwdUO5ihvfFg6b+/kZFw0J+AGLhEe23d6w==", + "peerDependencies": { + "@bugsnag/core-performance": "*", + "@bugsnag/react-native-performance": "^3.0.0", + "@react-navigation/native": "*", + "react": "*" + } + }, + "node_modules/@bugsnag/react-native-performance": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@bugsnag/react-native-performance/-/react-native-performance-3.4.1.tgz", + "integrity": "sha512-6dcmz20+yOrnyq6wdDe8HQZa84DiPzi9LKktJsYwoO0E+nRhR6YCaUQhU1SsDtnsl/PwB3SvF5dMr7dAAH6vJA==", + "dependencies": { + "@bugsnag/core-performance": "^3.2.0", + "@bugsnag/cuid": "^3.1.1", + "@bugsnag/delivery-fetch-performance": "^3.2.0", + "@bugsnag/request-tracker-performance": "^3.2.0" + }, + "peerDependencies": { + "@react-native-community/netinfo": ">= 9.4.1", + "react": "*", + "react-native": "*" + } + }, "node_modules/@bugsnag/request-tracker": { "version": "8.9.0", "resolved": "https://registry.npmjs.org/@bugsnag/request-tracker/-/request-tracker-8.9.0.tgz", @@ -1816,6 +1903,14 @@ "@bugsnag/core": "^8.9.0" } }, + "node_modules/@bugsnag/request-tracker-performance": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@bugsnag/request-tracker-performance/-/request-tracker-performance-3.2.0.tgz", + "integrity": "sha512-mo9UcwynXL3vUB/g4TR4r7nZpc/l/IFHYUoamboBILidJmsZZvFA3fXw60o02jCs8sMu54EbRuL0l01Q5hysjg==", + "dependencies": { + "@bugsnag/core-performance": "^3.2.0" + } + }, "node_modules/@bugsnag/safe-json-stringify": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@bugsnag/safe-json-stringify/-/safe-json-stringify-6.1.0.tgz", @@ -2541,6 +2636,15 @@ "integrity": "sha512-iHK9FI+dnE45X5c2Z5hSFwNH4zUWethizpbv3XUn0FIGw5jwvzriENz0a6wCdkI4/d+1QkurnHo5XHti7TbNJA==", "license": "MIT" }, + "node_modules/@expo/code-signing-certificates": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@expo/code-signing-certificates/-/code-signing-certificates-0.0.6.tgz", + "integrity": "sha512-iNe0puxwBNEcuua9gmTGzq+SuMDa0iATai1FlFTMHJ/vUmKvN/V//drXoLJkVb5i5H3iE/n/qIJxyoBnXouD0w==", + "license": "MIT", + "dependencies": { + "node-forge": "^1.3.3" + } + }, "node_modules/@expo/config": { "version": "12.0.13", "resolved": "https://registry.npmjs.org/@expo/config/-/config-12.0.13.tgz", @@ -2769,6 +2873,31 @@ } } }, + "node_modules/@expo/env": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@expo/env/-/env-2.0.11.tgz", + "integrity": "sha512-xV+ps6YCW7XIPVUwFVCRN2nox09dnRwy8uIjwHWTODu0zFw4kp4omnVkl0OOjuu2XOe7tdgAHxikrkJt9xB/7Q==", + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "debug": "^4.3.4", + "dotenv": "~16.4.5", + "dotenv-expand": "~11.0.6", + "getenv": "^2.0.0" + } + }, + "node_modules/@expo/env/node_modules/dotenv": { + "version": "16.4.7", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", + "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/@expo/fingerprint": { "version": "0.15.5", "resolved": "https://registry.npmjs.org/@expo/fingerprint/-/fingerprint-0.15.5.tgz", @@ -2892,6 +3021,33 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@expo/image-utils": { + "version": "0.8.14", + "resolved": "https://registry.npmjs.org/@expo/image-utils/-/image-utils-0.8.14.tgz", + "integrity": "sha512-5Sn+jG4Cw+shC2wDMXoqSAJnvERbiwzHn05FpWtD5IBflfTIs5gUmjzwiGVyjOdlMSQhgRrw/AymPbmO9h9mpQ==", + "license": "MIT", + "dependencies": { + "@expo/require-utils": "^55.0.5", + "@expo/spawn-async": "^1.7.2", + "chalk": "^4.0.0", + "getenv": "^2.0.0", + "jimp-compact": "0.16.1", + "parse-png": "^2.1.0", + "semver": "^7.6.0" + } + }, + "node_modules/@expo/image-utils/node_modules/semver": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", + "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@expo/json-file": { "version": "10.0.14", "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-10.0.14.tgz", @@ -2924,146 +3080,16 @@ "metro-transform-worker": "0.83.3" } }, - "node_modules/@expo/metro-config": { - "version": "54.0.15", - "resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-54.0.15.tgz", - "integrity": "sha512-SqIya4VZ9KHM1S9g+xR0A+QKw1Tfs7Gacx6bQNJ98vs4+O7I5+QP5mHZIB0QSZLUV8opiXebHYTiTu+0OAsIUw==", + "node_modules/@expo/metro-runtime": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@expo/metro-runtime/-/metro-runtime-6.1.2.tgz", + "integrity": "sha512-nvM+Qv45QH7pmYvP8JB1G8JpScrWND3KrMA6ZKe62cwwNiX/BjHU28Ear0v/4bQWXlOY0mv6B8CDIm8JxXde9g==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.20.0", - "@babel/core": "^7.20.0", - "@babel/generator": "^7.20.5", - "@expo/config": "~12.0.13", - "@expo/env": "~2.0.8", - "@expo/json-file": "~10.0.8", - "@expo/metro": "~54.2.0", - "@expo/spawn-async": "^1.7.2", - "browserslist": "^4.25.0", - "chalk": "^4.1.0", - "debug": "^4.3.2", - "dotenv": "~16.4.5", - "dotenv-expand": "~11.0.6", - "getenv": "^2.0.0", - "glob": "^13.0.0", - "hermes-parser": "^0.29.1", - "jsc-safe-url": "^0.2.4", - "lightningcss": "^1.30.1", - "picomatch": "^4.0.3", - "postcss": "~8.4.32", - "resolve-from": "^5.0.0" - }, - "peerDependencies": { - "expo": "*" - }, - "peerDependenciesMeta": { - "expo": { - "optional": true - } - } - }, - "node_modules/@expo/metro-config/node_modules/@expo/env": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@expo/env/-/env-2.0.11.tgz", - "integrity": "sha512-xV+ps6YCW7XIPVUwFVCRN2nox09dnRwy8uIjwHWTODu0zFw4kp4omnVkl0OOjuu2XOe7tdgAHxikrkJt9xB/7Q==", - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "debug": "^4.3.4", - "dotenv": "~16.4.5", - "dotenv-expand": "~11.0.6", - "getenv": "^2.0.0" - } - }, - "node_modules/@expo/metro-config/node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "license": "MIT", - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/@expo/metro-config/node_modules/brace-expansion": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", - "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/@expo/metro-config/node_modules/dotenv": { - "version": "16.4.7", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", - "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - }, - "node_modules/@expo/metro-config/node_modules/glob": { - "version": "13.0.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", - "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", - "license": "BlueOak-1.0.0", - "dependencies": { - "minimatch": "^10.2.2", - "minipass": "^7.1.3", - "path-scurry": "^2.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@expo/metro-config/node_modules/hermes-estree": { - "version": "0.29.1", - "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.29.1.tgz", - "integrity": "sha512-jl+x31n4/w+wEqm0I2r4CMimukLbLQEYpisys5oCre611CI5fc9TxhqkBBCJ1edDG4Kza0f7CgNz8xVMLZQOmQ==", - "license": "MIT" - }, - "node_modules/@expo/metro-config/node_modules/hermes-parser": { - "version": "0.29.1", - "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.29.1.tgz", - "integrity": "sha512-xBHWmUtRC5e/UL0tI7Ivt2riA/YBq9+SiYFU7C1oBa/j2jYGlIF9043oak1F47ihuDIxQ5nbsKueYJDRY02UgA==", - "license": "MIT", - "dependencies": { - "hermes-estree": "0.29.1" - } - }, - "node_modules/@expo/metro-config/node_modules/minimatch": { - "version": "10.2.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", - "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", - "license": "BlueOak-1.0.0", - "dependencies": { - "brace-expansion": "^5.0.5" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@expo/metro-runtime": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@expo/metro-runtime/-/metro-runtime-6.1.2.tgz", - "integrity": "sha512-nvM+Qv45QH7pmYvP8JB1G8JpScrWND3KrMA6ZKe62cwwNiX/BjHU28Ear0v/4bQWXlOY0mv6B8CDIm8JxXde9g==", - "license": "MIT", - "dependencies": { - "anser": "^1.4.9", - "pretty-format": "^29.7.0", - "stacktrace-parser": "^0.1.10", - "whatwg-fetch": "^3.0.0" + "anser": "^1.4.9", + "pretty-format": "^29.7.0", + "stacktrace-parser": "^0.1.10", + "whatwg-fetch": "^3.0.0" }, "peerDependencies": { "expo": "*", @@ -3109,20 +3135,42 @@ "node": ">=20.19.4" } }, + "node_modules/@expo/osascript": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@expo/osascript/-/osascript-2.6.0.tgz", + "integrity": "sha512-QvqDBlJXa8CS2vRORJ4wEflY1m0vVI07uSJdIRgBrLxRPBcsrXxrtU7+wXRXMqfq9zLwNP9XbvRsXF2omoDylg==", + "license": "MIT", + "dependencies": { + "@expo/spawn-async": "^1.8.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@expo/package-manager": { - "version": "1.9.10", - "resolved": "https://registry.npmjs.org/@expo/package-manager/-/package-manager-1.9.10.tgz", - "integrity": "sha512-axJm+NOj3jVxep49va/+L3KkF3YW/dkV+RwzqUJedZrv4LeTqOG4rhrCaCPXHTvLqCTDKu6j0Xyd28N7mnxsGA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@expo/package-manager/-/package-manager-1.12.1.tgz", + "integrity": "sha512-fQLiFAcFRWF53mtuLK32SUJQ1ahhrTcBZPZPedYTiUT5ha5FF+UO6bPtCc0Y/hgj0/m3HCGBAuSHjbg2kI9oPQ==", "license": "MIT", "dependencies": { - "@expo/json-file": "^10.0.8", - "@expo/spawn-async": "^1.7.2", + "@expo/json-file": "^10.2.0", + "@expo/spawn-async": "^1.8.0", "chalk": "^4.0.0", "npm-package-arg": "^11.0.0", "ora": "^3.4.0", "resolve-workspace-root": "^2.0.0" } }, + "node_modules/@expo/package-manager/node_modules/@expo/json-file": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-10.2.0.tgz", + "integrity": "sha512-S6XzKe3R9GQeHiUPXc3xJjOv2VJhOEwFYf7xdC2z2cUqt3kZJ9mSO877sNQloVdnW/SUCtPY3bexlM7nwq+CAQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.20.0", + "json5": "^2.2.3" + } + }, "node_modules/@expo/package-manager/node_modules/ansi-regex": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", @@ -3305,9 +3353,9 @@ } }, "node_modules/@expo/plist": { - "version": "0.4.8", - "resolved": "https://registry.npmjs.org/@expo/plist/-/plist-0.4.8.tgz", - "integrity": "sha512-pfNtErGGzzRwHP+5+RqswzPDKkZrx+Cli0mzjQaus1ZWFsog5ibL+nVT3NcporW51o8ggnt7x813vtRbPiyOrQ==", + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@expo/plist/-/plist-0.4.9.tgz", + "integrity": "sha512-MPVpmKGfnQEnrCzgxuXcmPP/y/t6AVm+DcSb2Myp21LKWv1N3l8uFxMggesfF4ixAxkRlGmMMx9GyDC9M+XklQ==", "license": "MIT", "dependencies": { "@xmldom/xmldom": "^0.8.8", @@ -3347,12 +3395,12 @@ "license": "MIT" }, "node_modules/@expo/spawn-async": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@expo/spawn-async/-/spawn-async-1.7.2.tgz", - "integrity": "sha512-QdWi16+CHB9JYP7gma19OVVg0BFkvU8zNj9GjWorYI8Iv8FUxjOCcYRuAmX4s/h91e4e7BPsskc8cSrZYho9Ew==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@expo/spawn-async/-/spawn-async-1.8.0.tgz", + "integrity": "sha512-eb9xxd/LbuEGSdua4NumCu/McVB9EM+F/JxB9pWgnERw4HQ9XyTNH1KapG6oqLWR8TuRK2LQfzJlmNi94CVobw==", "license": "MIT", "dependencies": { - "cross-spawn": "^7.0.3" + "cross-spawn": "^7.0.6" }, "engines": { "node": ">=12" @@ -3382,9 +3430,9 @@ "license": "MIT" }, "node_modules/@expo/xcpretty": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/@expo/xcpretty/-/xcpretty-4.4.3.tgz", - "integrity": "sha512-wC562eD3gS6vO2tWHToFhlFnmHKfKHgF1oyvojeSkLK/ZYop1bMU+7cOMiF9Sq70CzcsLy/EMRy/uRc76QmNRw==", + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/@expo/xcpretty/-/xcpretty-4.4.4.tgz", + "integrity": "sha512-4aQzz9vgxcNXFfo/iyNgDDYfsU5XGKKxWxZopw0cVotHiW+U8IJbIxMaxsINs6bHhtkG3StKNPcOrn3eBuxKPw==", "license": "BSD-3-Clause", "dependencies": { "@babel/code-frame": "^7.20.0", @@ -5674,6 +5722,17 @@ } } }, + "node_modules/@react-native-firebase/firestore": { + "version": "23.8.8", + "resolved": "https://registry.npmjs.org/@react-native-firebase/firestore/-/firestore-23.8.8.tgz", + "integrity": "sha512-oGD7EN/NHEz/U5GJNJVZtUF17G4hCp36uB4kjdJ6+UCFn+vgfGS/uMio2kXCMVBO6bmgI2qbfClWryirZ3xmcQ==", + "dependencies": { + "react-native-url-polyfill": "3.0.0" + }, + "peerDependencies": { + "@react-native-firebase/app": "23.8.8" + } + }, "node_modules/@react-native-firebase/storage": { "version": "23.8.8", "resolved": "https://registry.npmjs.org/@react-native-firebase/storage/-/storage-23.8.8.tgz", @@ -5712,6 +5771,99 @@ "node": ">= 20.19.4" } }, + "node_modules/@react-native/babel-plugin-codegen": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.81.5.tgz", + "integrity": "sha512-oF71cIH6je3fSLi6VPjjC3Sgyyn57JLHXs+mHWc9MoCiJJcM4nqsS5J38zv1XQ8d3zOW2JtHro+LF0tagj2bfQ==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.3", + "@react-native/codegen": "0.81.5" + }, + "engines": { + "node": ">= 20.19.4" + } + }, + "node_modules/@react-native/babel-preset": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/babel-preset/-/babel-preset-0.81.5.tgz", + "integrity": "sha512-UoI/x/5tCmi+pZ3c1+Ypr1DaRMDLI3y+Q70pVLLVgrnC3DHsHRIbHcCHIeG/IJvoeFqFM2sTdhSOLJrf8lOPrA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.25.2", + "@babel/plugin-proposal-export-default-from": "^7.24.7", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-default-from": "^7.24.7", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-transform-arrow-functions": "^7.24.7", + "@babel/plugin-transform-async-generator-functions": "^7.25.4", + "@babel/plugin-transform-async-to-generator": "^7.24.7", + "@babel/plugin-transform-block-scoping": "^7.25.0", + "@babel/plugin-transform-class-properties": "^7.25.4", + "@babel/plugin-transform-classes": "^7.25.4", + "@babel/plugin-transform-computed-properties": "^7.24.7", + "@babel/plugin-transform-destructuring": "^7.24.8", + "@babel/plugin-transform-flow-strip-types": "^7.25.2", + "@babel/plugin-transform-for-of": "^7.24.7", + "@babel/plugin-transform-function-name": "^7.25.1", + "@babel/plugin-transform-literals": "^7.25.2", + "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", + "@babel/plugin-transform-modules-commonjs": "^7.24.8", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", + "@babel/plugin-transform-numeric-separator": "^7.24.7", + "@babel/plugin-transform-object-rest-spread": "^7.24.7", + "@babel/plugin-transform-optional-catch-binding": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.8", + "@babel/plugin-transform-parameters": "^7.24.7", + "@babel/plugin-transform-private-methods": "^7.24.7", + "@babel/plugin-transform-private-property-in-object": "^7.24.7", + "@babel/plugin-transform-react-display-name": "^7.24.7", + "@babel/plugin-transform-react-jsx": "^7.25.2", + "@babel/plugin-transform-react-jsx-self": "^7.24.7", + "@babel/plugin-transform-react-jsx-source": "^7.24.7", + "@babel/plugin-transform-regenerator": "^7.24.7", + "@babel/plugin-transform-runtime": "^7.24.7", + "@babel/plugin-transform-shorthand-properties": "^7.24.7", + "@babel/plugin-transform-spread": "^7.24.7", + "@babel/plugin-transform-sticky-regex": "^7.24.7", + "@babel/plugin-transform-typescript": "^7.25.2", + "@babel/plugin-transform-unicode-regex": "^7.24.7", + "@babel/template": "^7.25.0", + "@react-native/babel-plugin-codegen": "0.81.5", + "babel-plugin-syntax-hermes-parser": "0.29.1", + "babel-plugin-transform-flow-enums": "^0.0.2", + "react-refresh": "^0.14.0" + }, + "engines": { + "node": ">= 20.19.4" + }, + "peerDependencies": { + "@babel/core": "*" + } + }, + "node_modules/@react-native/codegen": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/codegen/-/codegen-0.81.5.tgz", + "integrity": "sha512-a2TDA03Up8lpSa9sh5VRGCQDXgCTOyDOFH+aqyinxp1HChG8uk89/G+nkJ9FPd0rqgi25eCTR16TWdS3b+fA6g==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.25.2", + "@babel/parser": "^7.25.3", + "glob": "^7.1.1", + "hermes-parser": "0.29.1", + "invariant": "^2.2.4", + "nullthrows": "^1.1.1", + "yargs": "^17.6.2" + }, + "engines": { + "node": ">= 20.19.4" + }, + "peerDependencies": { + "@babel/core": "*" + } + }, "node_modules/@react-native/community-cli-plugin": { "version": "0.81.5", "resolved": "https://registry.npmjs.org/@react-native/community-cli-plugin/-/community-cli-plugin-0.81.5.tgz", @@ -7299,6 +7451,29 @@ "win32" ] }, + "node_modules/@urql/core": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@urql/core/-/core-5.2.0.tgz", + "integrity": "sha512-/n0ieD0mvvDnVAXEQgX/7qJiVcvYvNkOHeBvkwtylfjydar123caCXcl58PXFY11oU1oquJocVXHxLAbtv4x1A==", + "license": "MIT", + "dependencies": { + "@0no-co/graphql.web": "^1.0.13", + "wonka": "^6.3.2" + } + }, + "node_modules/@urql/exchange-retry": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@urql/exchange-retry/-/exchange-retry-1.3.2.tgz", + "integrity": "sha512-TQMCz2pFJMfpNxmSfX1VSfTjwUIFx/mL+p1bnfM1xjjdla7Z+KnGMW/EhFbpckp3LyWAH4PgOsMwOMnIN+MBFg==", + "license": "MIT", + "dependencies": { + "@urql/core": "^5.1.2", + "wonka": "^6.3.2" + }, + "peerDependencies": { + "@urql/core": "^5.0.0" + } + }, "node_modules/@xmldom/xmldom": { "version": "0.8.13", "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.13.tgz", @@ -7832,226 +8007,55 @@ "integrity": "sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w==", "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.28.6", - "@babel/helper-define-polyfill-provider": "^0.6.8", - "semver": "^6.3.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz", - "integrity": "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==", - "license": "MIT", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.5", - "core-js-compat": "^3.43.0" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.8.tgz", - "integrity": "sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg==", - "license": "MIT", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.8" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-react-compiler": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-react-compiler/-/babel-plugin-react-compiler-1.0.0.tgz", - "integrity": "sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.26.0" - } - }, - "node_modules/babel-plugin-react-native-web": { - "version": "0.21.2", - "resolved": "https://registry.npmjs.org/babel-plugin-react-native-web/-/babel-plugin-react-native-web-0.21.2.tgz", - "integrity": "sha512-SPD0J6qjJn8231i0HZhlAGH6NORe+QvRSQM2mwQEzJ2Fb3E4ruWTiiicPlHjmeWShDXLcvoorOCXjeR7k/lyWA==", - "license": "MIT" - }, - "node_modules/babel-plugin-transform-flow-enums": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-enums/-/babel-plugin-transform-flow-enums-0.0.2.tgz", - "integrity": "sha512-g4aaCrDDOsWjbm0PUUeVnkcVd6AKJsVc/MbnPhEotEpkeJQP6b8nzewohQi7+QS8UyPehOhGWn0nOwjvWpmMvQ==", - "license": "MIT", - "dependencies": { - "@babel/plugin-syntax-flow": "^7.12.1" - } - }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", - "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==", - "license": "MIT", - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-import-attributes": "^7.24.7", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5" - }, - "peerDependencies": { - "@babel/core": "^7.0.0 || ^8.0.0-0" - } - }, - "node_modules/babel-preset-expo": { - "version": "54.0.10", - "resolved": "https://registry.npmjs.org/babel-preset-expo/-/babel-preset-expo-54.0.10.tgz", - "integrity": "sha512-wTt7POavLFypLcPW/uC5v8y+mtQKDJiyGLzYCjqr9tx0Qc3vCXcDKk1iCFIj/++Iy5CWhhTflEa7VvVPNWeCfw==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.25.9", - "@babel/plugin-proposal-decorators": "^7.12.9", - "@babel/plugin-proposal-export-default-from": "^7.24.7", - "@babel/plugin-syntax-export-default-from": "^7.24.7", - "@babel/plugin-transform-class-static-block": "^7.27.1", - "@babel/plugin-transform-export-namespace-from": "^7.25.9", - "@babel/plugin-transform-flow-strip-types": "^7.25.2", - "@babel/plugin-transform-modules-commonjs": "^7.24.8", - "@babel/plugin-transform-object-rest-spread": "^7.24.7", - "@babel/plugin-transform-parameters": "^7.24.7", - "@babel/plugin-transform-private-methods": "^7.24.7", - "@babel/plugin-transform-private-property-in-object": "^7.24.7", - "@babel/plugin-transform-runtime": "^7.24.7", - "@babel/preset-react": "^7.22.15", - "@babel/preset-typescript": "^7.23.0", - "@react-native/babel-preset": "0.81.5", - "babel-plugin-react-compiler": "^1.0.0", - "babel-plugin-react-native-web": "~0.21.0", - "babel-plugin-syntax-hermes-parser": "^0.29.1", - "babel-plugin-transform-flow-enums": "^0.0.2", - "debug": "^4.3.4", - "resolve-from": "^5.0.0" - }, - "peerDependencies": { - "@babel/runtime": "^7.20.0", - "expo": "*", - "react-refresh": ">=0.14.0 <1.0.0" - }, - "peerDependenciesMeta": { - "@babel/runtime": { - "optional": true - }, - "expo": { - "optional": true - } - } - }, - "node_modules/babel-preset-expo/node_modules/@react-native/babel-plugin-codegen": { - "version": "0.81.5", - "resolved": "https://registry.npmjs.org/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.81.5.tgz", - "integrity": "sha512-oF71cIH6je3fSLi6VPjjC3Sgyyn57JLHXs+mHWc9MoCiJJcM4nqsS5J38zv1XQ8d3zOW2JtHro+LF0tagj2bfQ==", - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.25.3", - "@react-native/codegen": "0.81.5" - }, - "engines": { - "node": ">= 20.19.4" - } - }, - "node_modules/babel-preset-expo/node_modules/@react-native/babel-preset": { - "version": "0.81.5", - "resolved": "https://registry.npmjs.org/@react-native/babel-preset/-/babel-preset-0.81.5.tgz", - "integrity": "sha512-UoI/x/5tCmi+pZ3c1+Ypr1DaRMDLI3y+Q70pVLLVgrnC3DHsHRIbHcCHIeG/IJvoeFqFM2sTdhSOLJrf8lOPrA==", - "license": "MIT", - "dependencies": { - "@babel/core": "^7.25.2", - "@babel/plugin-proposal-export-default-from": "^7.24.7", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-default-from": "^7.24.7", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-transform-arrow-functions": "^7.24.7", - "@babel/plugin-transform-async-generator-functions": "^7.25.4", - "@babel/plugin-transform-async-to-generator": "^7.24.7", - "@babel/plugin-transform-block-scoping": "^7.25.0", - "@babel/plugin-transform-class-properties": "^7.25.4", - "@babel/plugin-transform-classes": "^7.25.4", - "@babel/plugin-transform-computed-properties": "^7.24.7", - "@babel/plugin-transform-destructuring": "^7.24.8", - "@babel/plugin-transform-flow-strip-types": "^7.25.2", - "@babel/plugin-transform-for-of": "^7.24.7", - "@babel/plugin-transform-function-name": "^7.25.1", - "@babel/plugin-transform-literals": "^7.25.2", - "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", - "@babel/plugin-transform-modules-commonjs": "^7.24.8", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", - "@babel/plugin-transform-numeric-separator": "^7.24.7", - "@babel/plugin-transform-object-rest-spread": "^7.24.7", - "@babel/plugin-transform-optional-catch-binding": "^7.24.7", - "@babel/plugin-transform-optional-chaining": "^7.24.8", - "@babel/plugin-transform-parameters": "^7.24.7", - "@babel/plugin-transform-private-methods": "^7.24.7", - "@babel/plugin-transform-private-property-in-object": "^7.24.7", - "@babel/plugin-transform-react-display-name": "^7.24.7", - "@babel/plugin-transform-react-jsx": "^7.25.2", - "@babel/plugin-transform-react-jsx-self": "^7.24.7", - "@babel/plugin-transform-react-jsx-source": "^7.24.7", - "@babel/plugin-transform-regenerator": "^7.24.7", - "@babel/plugin-transform-runtime": "^7.24.7", - "@babel/plugin-transform-shorthand-properties": "^7.24.7", - "@babel/plugin-transform-spread": "^7.24.7", - "@babel/plugin-transform-sticky-regex": "^7.24.7", - "@babel/plugin-transform-typescript": "^7.25.2", - "@babel/plugin-transform-unicode-regex": "^7.24.7", - "@babel/template": "^7.25.0", - "@react-native/babel-plugin-codegen": "0.81.5", - "babel-plugin-syntax-hermes-parser": "0.29.1", - "babel-plugin-transform-flow-enums": "^0.0.2", - "react-refresh": "^0.14.0" - }, - "engines": { - "node": ">= 20.19.4" + "@babel/compat-data": "^7.28.6", + "@babel/helper-define-polyfill-provider": "^0.6.8", + "semver": "^6.3.1" }, "peerDependencies": { - "@babel/core": "*" + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/babel-preset-expo/node_modules/@react-native/codegen": { - "version": "0.81.5", - "resolved": "https://registry.npmjs.org/@react-native/codegen/-/codegen-0.81.5.tgz", - "integrity": "sha512-a2TDA03Up8lpSa9sh5VRGCQDXgCTOyDOFH+aqyinxp1HChG8uk89/G+nkJ9FPd0rqgi25eCTR16TWdS3b+fA6g==", + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz", + "integrity": "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==", "license": "MIT", "dependencies": { - "@babel/core": "^7.25.2", - "@babel/parser": "^7.25.3", - "glob": "^7.1.1", - "hermes-parser": "0.29.1", - "invariant": "^2.2.4", - "nullthrows": "^1.1.1", - "yargs": "^17.6.2" + "@babel/helper-define-polyfill-provider": "^0.6.5", + "core-js-compat": "^3.43.0" }, - "engines": { - "node": ">= 20.19.4" + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.8.tgz", + "integrity": "sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg==", + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.8" }, "peerDependencies": { - "@babel/core": "*" + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-react-compiler": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-react-compiler/-/babel-plugin-react-compiler-1.0.0.tgz", + "integrity": "sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.26.0" } }, - "node_modules/babel-preset-expo/node_modules/babel-plugin-syntax-hermes-parser": { + "node_modules/babel-plugin-react-native-web": { + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/babel-plugin-react-native-web/-/babel-plugin-react-native-web-0.21.2.tgz", + "integrity": "sha512-SPD0J6qjJn8231i0HZhlAGH6NORe+QvRSQM2mwQEzJ2Fb3E4ruWTiiicPlHjmeWShDXLcvoorOCXjeR7k/lyWA==", + "license": "MIT" + }, + "node_modules/babel-plugin-syntax-hermes-parser": { "version": "0.29.1", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-hermes-parser/-/babel-plugin-syntax-hermes-parser-0.29.1.tgz", "integrity": "sha512-2WFYnoWGdmih1I1J5eIqxATOeycOqRwYxAQBu3cUu/rhwInwHUg7k60AFNbuGjSDL8tje5GDrAnxzRLcu2pYcA==", @@ -8060,19 +8064,39 @@ "hermes-parser": "0.29.1" } }, - "node_modules/babel-preset-expo/node_modules/hermes-estree": { - "version": "0.29.1", - "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.29.1.tgz", - "integrity": "sha512-jl+x31n4/w+wEqm0I2r4CMimukLbLQEYpisys5oCre611CI5fc9TxhqkBBCJ1edDG4Kza0f7CgNz8xVMLZQOmQ==", - "license": "MIT" + "node_modules/babel-plugin-transform-flow-enums": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-enums/-/babel-plugin-transform-flow-enums-0.0.2.tgz", + "integrity": "sha512-g4aaCrDDOsWjbm0PUUeVnkcVd6AKJsVc/MbnPhEotEpkeJQP6b8nzewohQi7+QS8UyPehOhGWn0nOwjvWpmMvQ==", + "license": "MIT", + "dependencies": { + "@babel/plugin-syntax-flow": "^7.12.1" + } }, - "node_modules/babel-preset-expo/node_modules/hermes-parser": { - "version": "0.29.1", - "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.29.1.tgz", - "integrity": "sha512-xBHWmUtRC5e/UL0tI7Ivt2riA/YBq9+SiYFU7C1oBa/j2jYGlIF9043oak1F47ihuDIxQ5nbsKueYJDRY02UgA==", + "node_modules/babel-preset-current-node-syntax": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", + "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==", "license": "MIT", "dependencies": { - "hermes-estree": "0.29.1" + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" + }, + "peerDependencies": { + "@babel/core": "^7.0.0 || ^8.0.0-0" } }, "node_modules/babel-preset-jest": { @@ -8184,9 +8208,9 @@ } }, "node_modules/brace-expansion": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", - "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz", + "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -10946,28 +10970,28 @@ } }, "node_modules/expo": { - "version": "54.0.34", - "resolved": "https://registry.npmjs.org/expo/-/expo-54.0.34.tgz", - "integrity": "sha512-XkVHguZZDC8BcTQxHAd14/TQFbDp1Wt0Z/KApO9t68Ll5A127hLCPzU+a9gytfCIiyL/V1IpF1vIcOLKEVAoNQ==", + "version": "54.0.35", + "resolved": "https://registry.npmjs.org/expo/-/expo-54.0.35.tgz", + "integrity": "sha512-E+tXpQwjGm5fK/uwa55p0Xx/kuo5dXDKfVJ95IargTNa5KiFt26lSTXXa9KnHbI4EDLwFD38/xTKZvzPTlGTdg==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.20.0", - "@expo/cli": "54.0.24", + "@expo/cli": "54.0.25", "@expo/config": "~12.0.13", "@expo/config-plugins": "~54.0.4", "@expo/devtools": "0.1.8", "@expo/fingerprint": "0.15.5", "@expo/metro": "~54.2.0", - "@expo/metro-config": "54.0.15", + "@expo/metro-config": "54.0.16", "@expo/vector-icons": "^15.0.3", "@ungap/structured-clone": "^1.3.0", - "babel-preset-expo": "~54.0.10", + "babel-preset-expo": "~54.0.11", "expo-asset": "~12.0.13", "expo-constants": "~18.0.13", - "expo-file-system": "~19.0.22", - "expo-font": "~14.0.11", + "expo-file-system": "~19.0.23", + "expo-font": "~14.0.12", "expo-keep-awake": "~15.0.8", - "expo-modules-autolinking": "3.0.25", + "expo-modules-autolinking": "3.0.26", "expo-modules-core": "3.0.30", "pretty-format": "^29.7.0", "react-refresh": "^0.14.2", @@ -11021,33 +11045,6 @@ "react-native": "*" } }, - "node_modules/expo-asset/node_modules/@expo/image-utils": { - "version": "0.8.14", - "resolved": "https://registry.npmjs.org/@expo/image-utils/-/image-utils-0.8.14.tgz", - "integrity": "sha512-5Sn+jG4Cw+shC2wDMXoqSAJnvERbiwzHn05FpWtD5IBflfTIs5gUmjzwiGVyjOdlMSQhgRrw/AymPbmO9h9mpQ==", - "license": "MIT", - "dependencies": { - "@expo/require-utils": "^55.0.5", - "@expo/spawn-async": "^1.7.2", - "chalk": "^4.0.0", - "getenv": "^2.0.0", - "jimp-compact": "0.16.1", - "parse-png": "^2.1.0", - "semver": "^7.6.0" - } - }, - "node_modules/expo-asset/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/expo-audio": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/expo-audio/-/expo-audio-1.1.1.tgz", @@ -11098,31 +11095,6 @@ "react-native": "*" } }, - "node_modules/expo-constants/node_modules/@expo/env": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@expo/env/-/env-2.0.11.tgz", - "integrity": "sha512-xV+ps6YCW7XIPVUwFVCRN2nox09dnRwy8uIjwHWTODu0zFw4kp4omnVkl0OOjuu2XOe7tdgAHxikrkJt9xB/7Q==", - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "debug": "^4.3.4", - "dotenv": "~16.4.5", - "dotenv-expand": "~11.0.6", - "getenv": "^2.0.0" - } - }, - "node_modules/expo-constants/node_modules/dotenv": { - "version": "16.4.7", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", - "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - }, "node_modules/expo-crypto": { "version": "15.0.9", "resolved": "https://registry.npmjs.org/expo-crypto/-/expo-crypto-15.0.9.tgz", @@ -11205,9 +11177,9 @@ "license": "MIT" }, "node_modules/expo-file-system": { - "version": "19.0.22", - "resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-19.0.22.tgz", - "integrity": "sha512-l9pgahSc7sJD0bP9vBNeXvZjy8QKDpVHVxWmei/ESQOrzmoj5BidziqLVsyZdxsi+PfdbTtttLTAmddH/JafYA==", + "version": "19.0.23", + "resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-19.0.23.tgz", + "integrity": "sha512-MeGkid9OeNILfT/qonaXHp4f2c15xaB28U/bcN7pqZej0Kx0+6+V7e9ZIXpPHm07zVatxA+QkMTPQEGfmvVOxA==", "license": "MIT", "peerDependencies": { "expo": "*", @@ -11215,9 +11187,9 @@ } }, "node_modules/expo-font": { - "version": "14.0.11", - "resolved": "https://registry.npmjs.org/expo-font/-/expo-font-14.0.11.tgz", - "integrity": "sha512-ga0q61ny4s/kr4k8JX9hVH69exVSIfcIc19+qZ7gt71Mqtm7xy2c6kwsPTCyhBW2Ro5yXTT8EaZOpuRi35rHbg==", + "version": "14.0.12", + "resolved": "https://registry.npmjs.org/expo-font/-/expo-font-14.0.12.tgz", + "integrity": "sha512-QQzunE2Mxk45AsCWm3tK7OpVljbtVnKD58q4/qliev+cbye1IOduUnRIdD+P7DyButw17G9MTX795kgaQiz5hQ==", "license": "MIT", "dependencies": { "fontfaceobserver": "^2.1.0" @@ -11320,9 +11292,10 @@ } }, "node_modules/expo-localization": { - "version": "17.0.8", - "resolved": "https://registry.npmjs.org/expo-localization/-/expo-localization-17.0.8.tgz", - "integrity": "sha512-UrdwklZBDJ+t+ZszMMiE0SXZ2eJxcquCuQcl6EvGHM9K+e6YqKVRQ+w8qE+iIB3H75v2RJy6MHAaLK+Mqeo04g==", + "version": "17.0.9", + "resolved": "https://registry.npmjs.org/expo-localization/-/expo-localization-17.0.9.tgz", + "integrity": "sha512-k5eYHr7iLMob3M8cHH6bgDrDRmqnZG8xKGLhpx8ST+LsFXmSgYpJ/t0VwWm0gz64C/K669XhObdG3D6QwCGqhw==", + "license": "MIT", "dependencies": { "rtl-detect": "^1.0.2" }, @@ -11345,9 +11318,9 @@ } }, "node_modules/expo-modules-autolinking": { - "version": "3.0.25", - "resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-3.0.25.tgz", - "integrity": "sha512-YmHWctJlwvOuLZccg3cOXvSiXVJrPMKl7g2YR0YHWoGL9v2RvcmgaPJWPSLVW+voNEgEPsbo5UmUrAqbnYcBeg==", + "version": "3.0.26", + "resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-3.0.26.tgz", + "integrity": "sha512-WOaud6UKg16ciCOj8raKcMOoKFMHLXKI29U29yhgu1lf+Y7VxJyCktUcYo6AM+ccZ7zLD1uWZdMtgnpf+95OXA==", "license": "MIT", "dependencies": { "@expo/spawn-async": "^1.7.2", @@ -11409,37 +11382,10 @@ "react-native": "*" } }, - "node_modules/expo-notifications/node_modules/@expo/image-utils": { - "version": "0.8.14", - "resolved": "https://registry.npmjs.org/@expo/image-utils/-/image-utils-0.8.14.tgz", - "integrity": "sha512-5Sn+jG4Cw+shC2wDMXoqSAJnvERbiwzHn05FpWtD5IBflfTIs5gUmjzwiGVyjOdlMSQhgRrw/AymPbmO9h9mpQ==", - "license": "MIT", - "dependencies": { - "@expo/require-utils": "^55.0.5", - "@expo/spawn-async": "^1.7.2", - "chalk": "^4.0.0", - "getenv": "^2.0.0", - "jimp-compact": "0.16.1", - "parse-png": "^2.1.0", - "semver": "^7.6.0" - } - }, - "node_modules/expo-notifications/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/expo-router": { - "version": "6.0.23", - "resolved": "https://registry.npmjs.org/expo-router/-/expo-router-6.0.23.tgz", - "integrity": "sha512-qCxVAiCrCyu0npky6azEZ6dJDMt77OmCzEbpF6RbUTlfkaCA417LvY14SBkk0xyGruSxy/7pvJOI6tuThaUVCA==", + "version": "6.0.24", + "resolved": "https://registry.npmjs.org/expo-router/-/expo-router-6.0.24.tgz", + "integrity": "sha512-KIssKXnwjrdCxPWC8GsMTfKTwng40VrCsO16O9x6fKlfUwBW8itxY9PpCGyQeMJkiEADa+DUhtrDgl+uHg4/DA==", "license": "MIT", "dependencies": { "@expo/metro-runtime": "^6.1.2", @@ -11452,7 +11398,7 @@ "client-only": "^0.0.1", "debug": "^4.3.4", "escape-string-regexp": "^4.0.0", - "expo-server": "^1.0.5", + "expo-server": "^1.0.7", "fast-deep-equal": "^3.1.3", "invariant": "^2.2.4", "nanoid": "^3.3.8", @@ -11472,7 +11418,7 @@ "@testing-library/react-native": ">= 12.0.0", "expo": "*", "expo-constants": "^18.0.13", - "expo-linking": "^8.0.11", + "expo-linking": "^8.0.12", "react": "*", "react-dom": "*", "react-native": "*", @@ -11529,9 +11475,9 @@ } }, "node_modules/expo-server": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/expo-server/-/expo-server-1.0.6.tgz", - "integrity": "sha512-vb5TBtskvEdzYuW79lATXutOEBfW5m6U4EFpNjCVZTnI7S//SAsLQkYEpn+EDfn84m6VQfzSGkIVR6YPaScKFA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/expo-server/-/expo-server-1.0.7.tgz", + "integrity": "sha512-mcmyML3oXcqFUXUxtdtCL1O00ztNI2v76d+MdniXRUgHNxIcHZ05zo+DqBaOOT6LQnPk4vA4YHqQl7iGUfRb3g==", "license": "MIT", "engines": { "node": ">=20.16.0" @@ -11549,21 +11495,6 @@ "expo": "*" } }, - "node_modules/expo-splash-screen/node_modules/@expo/image-utils": { - "version": "0.8.14", - "resolved": "https://registry.npmjs.org/@expo/image-utils/-/image-utils-0.8.14.tgz", - "integrity": "sha512-5Sn+jG4Cw+shC2wDMXoqSAJnvERbiwzHn05FpWtD5IBflfTIs5gUmjzwiGVyjOdlMSQhgRrw/AymPbmO9h9mpQ==", - "license": "MIT", - "dependencies": { - "@expo/require-utils": "^55.0.5", - "@expo/spawn-async": "^1.7.2", - "chalk": "^4.0.0", - "getenv": "^2.0.0", - "jimp-compact": "0.16.1", - "parse-png": "^2.1.0", - "semver": "^7.6.0" - } - }, "node_modules/expo-splash-screen/node_modules/@expo/prebuild-config": { "version": "54.0.8", "resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-54.0.8.tgz", @@ -11651,13 +11582,13 @@ } }, "node_modules/expo-updates": { - "version": "29.0.17", - "resolved": "https://registry.npmjs.org/expo-updates/-/expo-updates-29.0.17.tgz", - "integrity": "sha512-9h78cs6Q2rs/dEY7zAgyEm/m6J5rHy8RNpRyhilEAvrzrGLHChVZJT+bSR2RwNJg1DtwUNEjCgZrxDlM7LnNkg==", + "version": "29.0.18", + "resolved": "https://registry.npmjs.org/expo-updates/-/expo-updates-29.0.18.tgz", + "integrity": "sha512-qn0YDM7wVwghQAaxb9NYzzwrmj+v8Djz5H+Zft4/myG9SPg4ICAfDy52IVF0K+/GH/oNgsFfzmmLl6hIkDu42g==", "license": "MIT", "dependencies": { "@expo/code-signing-certificates": "^0.0.6", - "@expo/plist": "^0.4.8", + "@expo/plist": "^0.4.9", "@expo/spawn-async": "^1.7.2", "arg": "4.1.0", "chalk": "^4.1.2", @@ -11689,15 +11620,6 @@ "expo": "*" } }, - "node_modules/expo-updates/node_modules/@expo/code-signing-certificates": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/@expo/code-signing-certificates/-/code-signing-certificates-0.0.6.tgz", - "integrity": "sha512-iNe0puxwBNEcuua9gmTGzq+SuMDa0iATai1FlFTMHJ/vUmKvN/V//drXoLJkVb5i5H3iE/n/qIJxyoBnXouD0w==", - "license": "MIT", - "dependencies": { - "node-forge": "^1.3.3" - } - }, "node_modules/expo-updates/node_modules/arg": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.0.tgz", @@ -11766,15 +11688,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/expo-updates/node_modules/node-forge": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.4.0.tgz", - "integrity": "sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==", - "license": "(BSD-3-Clause OR GPL-2.0)", - "engines": { - "node": ">= 6.13.0" - } - }, "node_modules/expo-web-browser": { "version": "15.0.11", "resolved": "https://registry.npmjs.org/expo-web-browser/-/expo-web-browser-15.0.11.tgz", @@ -11786,9 +11699,9 @@ } }, "node_modules/expo/node_modules/@expo/cli": { - "version": "54.0.24", - "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-54.0.24.tgz", - "integrity": "sha512-5xse1bEgnVUBhOrtttc6xTNJVvjyTRavpzuF0/0nuj+312vfSbk7EiRbG+xJ2pW/iZxnhLPJkFCrPYG0nmheAQ==", + "version": "54.0.25", + "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-54.0.25.tgz", + "integrity": "sha512-WnUqIb8oMBhtwSfIqdCHCzcaDIpLNXItRVd5miuvWi4GO0SGo89PSsAkbVJ+LJgcaY+v5rbgMELJS9I/CqOulA==", "license": "MIT", "dependencies": { "@0no-co/graphql.web": "^1.0.8", @@ -11798,12 +11711,12 @@ "@expo/devcert": "^1.2.1", "@expo/env": "~2.0.8", "@expo/image-utils": "^0.8.8", - "@expo/json-file": "^10.0.8", + "@expo/json-file": "^10.0.16", "@expo/metro": "~54.2.0", - "@expo/metro-config": "~54.0.15", + "@expo/metro-config": "~54.0.16", "@expo/osascript": "^2.3.8", "@expo/package-manager": "^1.9.10", - "@expo/plist": "^0.4.8", + "@expo/plist": "^0.4.9", "@expo/prebuild-config": "^54.0.8", "@expo/schema-utils": "^0.1.8", "@expo/spawn-async": "^1.7.2", @@ -11823,7 +11736,7 @@ "connect": "^3.7.0", "debug": "^4.3.4", "env-editor": "^0.4.1", - "expo-server": "^1.0.6", + "expo-server": "^1.0.7", "freeport-async": "^2.0.0", "getenv": "^2.0.0", "glob": "^13.0.0", @@ -11872,97 +11785,91 @@ } } }, - "node_modules/expo/node_modules/@expo/code-signing-certificates": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/@expo/code-signing-certificates/-/code-signing-certificates-0.0.6.tgz", - "integrity": "sha512-iNe0puxwBNEcuua9gmTGzq+SuMDa0iATai1FlFTMHJ/vUmKvN/V//drXoLJkVb5i5H3iE/n/qIJxyoBnXouD0w==", - "license": "MIT", - "dependencies": { - "node-forge": "^1.3.3" - } - }, - "node_modules/expo/node_modules/@expo/env": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@expo/env/-/env-2.0.11.tgz", - "integrity": "sha512-xV+ps6YCW7XIPVUwFVCRN2nox09dnRwy8uIjwHWTODu0zFw4kp4omnVkl0OOjuu2XOe7tdgAHxikrkJt9xB/7Q==", - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "debug": "^4.3.4", - "dotenv": "~16.4.5", - "dotenv-expand": "~11.0.6", - "getenv": "^2.0.0" - } - }, - "node_modules/expo/node_modules/@expo/image-utils": { - "version": "0.8.14", - "resolved": "https://registry.npmjs.org/@expo/image-utils/-/image-utils-0.8.14.tgz", - "integrity": "sha512-5Sn+jG4Cw+shC2wDMXoqSAJnvERbiwzHn05FpWtD5IBflfTIs5gUmjzwiGVyjOdlMSQhgRrw/AymPbmO9h9mpQ==", + "node_modules/expo/node_modules/@expo/cli/node_modules/@expo/prebuild-config": { + "version": "54.0.8", + "resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-54.0.8.tgz", + "integrity": "sha512-EA7N4dloty2t5Rde+HP0IEE+nkAQiu4A/+QGZGT9mFnZ5KKjPPkqSyYcRvP5bhQE10D+tvz6X0ngZpulbMdbsg==", "license": "MIT", "dependencies": { - "@expo/require-utils": "^55.0.5", - "@expo/spawn-async": "^1.7.2", - "chalk": "^4.0.0", - "getenv": "^2.0.0", - "jimp-compact": "0.16.1", - "parse-png": "^2.1.0", - "semver": "^7.6.0" + "@expo/config": "~12.0.13", + "@expo/config-plugins": "~54.0.4", + "@expo/config-types": "^54.0.10", + "@expo/image-utils": "^0.8.8", + "@expo/json-file": "^10.0.8", + "@react-native/normalize-colors": "0.81.5", + "debug": "^4.3.1", + "resolve-from": "^5.0.0", + "semver": "^7.6.0", + "xml2js": "0.6.0" + }, + "peerDependencies": { + "expo": "*" } }, - "node_modules/expo/node_modules/@expo/osascript": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@expo/osascript/-/osascript-2.4.3.tgz", - "integrity": "sha512-wbuj3EebM7W9hN/Wp4xTzKd6rQ2zKJzAxkFxkOOwyysLp0HOAgQ4/5RINyoS241pZUX2rUHq7mAJ7pcCQ8U0Ow==", + "node_modules/expo/node_modules/@expo/json-file": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-10.2.0.tgz", + "integrity": "sha512-S6XzKe3R9GQeHiUPXc3xJjOv2VJhOEwFYf7xdC2z2cUqt3kZJ9mSO877sNQloVdnW/SUCtPY3bexlM7nwq+CAQ==", "license": "MIT", "dependencies": { - "@expo/spawn-async": "^1.7.2" - }, - "engines": { - "node": ">=12" + "@babel/code-frame": "^7.20.0", + "json5": "^2.2.3" } }, - "node_modules/expo/node_modules/@expo/prebuild-config": { - "version": "54.0.8", - "resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-54.0.8.tgz", - "integrity": "sha512-EA7N4dloty2t5Rde+HP0IEE+nkAQiu4A/+QGZGT9mFnZ5KKjPPkqSyYcRvP5bhQE10D+tvz6X0ngZpulbMdbsg==", + "node_modules/expo/node_modules/@expo/metro-config": { + "version": "54.0.16", + "resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-54.0.16.tgz", + "integrity": "sha512-3LLb9ZQl0VlqSlsalJ7+CYjfz60PBoSDHvpE1UF71aTM1Nx0Vb4LhXo7bCCC+PYP9q/GPB58LLbIROQ8PjKX2w==", "license": "MIT", "dependencies": { + "@babel/code-frame": "^7.20.0", + "@babel/core": "^7.20.0", + "@babel/generator": "^7.20.5", "@expo/config": "~12.0.13", - "@expo/config-plugins": "~54.0.4", - "@expo/config-types": "^54.0.10", - "@expo/image-utils": "^0.8.8", - "@expo/json-file": "^10.0.8", - "@react-native/normalize-colors": "0.81.5", - "debug": "^4.3.1", - "resolve-from": "^5.0.0", - "semver": "^7.6.0", - "xml2js": "0.6.0" + "@expo/env": "~2.0.8", + "@expo/json-file": "~10.0.16", + "@expo/metro": "~54.2.0", + "@expo/spawn-async": "^1.7.2", + "browserslist": "^4.25.0", + "chalk": "^4.1.0", + "debug": "^4.3.2", + "dotenv": "~16.4.5", + "dotenv-expand": "~11.0.6", + "getenv": "^2.0.0", + "glob": "^13.0.0", + "hermes-parser": "^0.29.1", + "jsc-safe-url": "^0.2.4", + "lightningcss": "^1.30.1", + "picomatch": "^4.0.3", + "postcss": "~8.4.32", + "resolve-from": "^5.0.0" }, "peerDependencies": { "expo": "*" + }, + "peerDependenciesMeta": { + "expo": { + "optional": true + } } }, - "node_modules/expo/node_modules/@urql/core": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@urql/core/-/core-5.2.0.tgz", - "integrity": "sha512-/n0ieD0mvvDnVAXEQgX/7qJiVcvYvNkOHeBvkwtylfjydar123caCXcl58PXFY11oU1oquJocVXHxLAbtv4x1A==", + "node_modules/expo/node_modules/@expo/metro-config/node_modules/@expo/json-file": { + "version": "10.0.16", + "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-10.0.16.tgz", + "integrity": "sha512-fcVkWEj+hLuP2yt5W0aw6LmDRqSPWDLUSxOMcmFeV+algmIF59sQVKCwB9btjQLd4V6x9N0pISkQEkBubUHrCw==", "license": "MIT", "dependencies": { - "@0no-co/graphql.web": "^1.0.13", - "wonka": "^6.3.2" + "@babel/code-frame": "~7.10.4", + "json5": "^2.2.3" } }, - "node_modules/expo/node_modules/@urql/exchange-retry": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@urql/exchange-retry/-/exchange-retry-1.3.2.tgz", - "integrity": "sha512-TQMCz2pFJMfpNxmSfX1VSfTjwUIFx/mL+p1bnfM1xjjdla7Z+KnGMW/EhFbpckp3LyWAH4PgOsMwOMnIN+MBFg==", + "node_modules/expo/node_modules/@expo/metro-config/node_modules/@expo/json-file/node_modules/@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", "license": "MIT", "dependencies": { - "@urql/core": "^5.1.2", - "wonka": "^6.3.2" - }, - "peerDependencies": { - "@urql/core": "^5.0.0" + "@babel/highlight": "^7.10.4" } }, "node_modules/expo/node_modules/ansi-regex": { @@ -11986,6 +11893,49 @@ "node": ">=4" } }, + "node_modules/expo/node_modules/babel-preset-expo": { + "version": "54.0.11", + "resolved": "https://registry.npmjs.org/babel-preset-expo/-/babel-preset-expo-54.0.11.tgz", + "integrity": "sha512-dEpeFDtYEFzmWtWVwvt7sUCZH0fxXPfbJlgXd7XNZSQDa/Ki/hTOj9exMTzqR2oyPHDNcE9VxYCJ4oS6xw4Pjg==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/plugin-proposal-decorators": "^7.12.9", + "@babel/plugin-proposal-export-default-from": "^7.24.7", + "@babel/plugin-syntax-export-default-from": "^7.24.7", + "@babel/plugin-transform-class-static-block": "^7.27.1", + "@babel/plugin-transform-export-namespace-from": "^7.25.9", + "@babel/plugin-transform-flow-strip-types": "^7.25.2", + "@babel/plugin-transform-modules-commonjs": "^7.24.8", + "@babel/plugin-transform-object-rest-spread": "^7.24.7", + "@babel/plugin-transform-parameters": "^7.24.7", + "@babel/plugin-transform-private-methods": "^7.24.7", + "@babel/plugin-transform-private-property-in-object": "^7.24.7", + "@babel/plugin-transform-runtime": "^7.24.7", + "@babel/preset-react": "^7.22.15", + "@babel/preset-typescript": "^7.23.0", + "@react-native/babel-preset": "0.81.5", + "babel-plugin-react-compiler": "^1.0.0", + "babel-plugin-react-native-web": "~0.21.0", + "babel-plugin-syntax-hermes-parser": "^0.29.1", + "babel-plugin-transform-flow-enums": "^0.0.2", + "debug": "^4.3.4", + "resolve-from": "^5.0.0" + }, + "peerDependencies": { + "@babel/runtime": "^7.20.0", + "expo": "*", + "react-refresh": ">=0.14.0 <1.0.0" + }, + "peerDependenciesMeta": { + "@babel/runtime": { + "optional": true + }, + "expo": { + "optional": true + } + } + }, "node_modules/expo/node_modules/balanced-match": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", @@ -11995,6 +11945,18 @@ "node": "18 || 20 || >=22" } }, + "node_modules/expo/node_modules/brace-expansion": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/expo/node_modules/cli-cursor": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", @@ -12060,18 +12022,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/expo/node_modules/glob/node_modules/brace-expansion": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", - "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - } - }, "node_modules/expo/node_modules/glob/node_modules/minimatch": { "version": "10.2.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", @@ -12131,30 +12081,6 @@ "node": ">=4" } }, - "node_modules/expo/node_modules/minimatch": { - "version": "9.0.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", - "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.2" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/expo/node_modules/node-forge": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.4.0.tgz", - "integrity": "sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==", - "license": "(BSD-3-Clause OR GPL-2.0)", - "engines": { - "node": ">= 6.13.0" - } - }, "node_modules/expo/node_modules/onetime": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", @@ -12198,14 +12124,6 @@ "node": ">=4" } }, - "node_modules/expo/node_modules/qrcode-terminal": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/qrcode-terminal/-/qrcode-terminal-0.11.0.tgz", - "integrity": "sha512-Uu7ii+FQy4Qf82G4xu7ShHhjhGahEpCWc3x8UavY3CTcWV+ufmmCtwkr7ZKsX42jdL0kr1B5FKUeqJvAn51jzQ==", - "bin": { - "qrcode-terminal": "bin/qrcode-terminal.js" - } - }, "node_modules/expo/node_modules/restore-cursor": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", @@ -12220,9 +12138,9 @@ } }, "node_modules/expo/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", + "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -13085,6 +13003,21 @@ "node": ">= 0.4" } }, + "node_modules/hermes-estree": { + "version": "0.29.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.29.1.tgz", + "integrity": "sha512-jl+x31n4/w+wEqm0I2r4CMimukLbLQEYpisys5oCre611CI5fc9TxhqkBBCJ1edDG4Kza0f7CgNz8xVMLZQOmQ==", + "license": "MIT" + }, + "node_modules/hermes-parser": { + "version": "0.29.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.29.1.tgz", + "integrity": "sha512-xBHWmUtRC5e/UL0tI7Ivt2riA/YBq9+SiYFU7C1oBa/j2jYGlIF9043oak1F47ihuDIxQ5nbsKueYJDRY02UgA==", + "license": "MIT", + "dependencies": { + "hermes-estree": "0.29.1" + } + }, "node_modules/hoist-non-react-statics": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", @@ -16161,6 +16094,21 @@ "node": ">=4" } }, + "node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", @@ -16202,6 +16150,18 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/minizlib": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, "node_modules/moment": { "version": "2.30.1", "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", @@ -16308,6 +16268,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/node-forge": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.4.0.tgz", + "integrity": "sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==", + "license": "(BSD-3-Clause OR GPL-2.0)", + "engines": { + "node": ">= 6.13.0" + } + }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -16384,9 +16353,9 @@ "license": "ISC" }, "node_modules/npm-package-arg/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", + "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -17468,6 +17437,14 @@ ], "license": "MIT" }, + "node_modules/qrcode-terminal": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/qrcode-terminal/-/qrcode-terminal-0.11.0.tgz", + "integrity": "sha512-Uu7ii+FQy4Qf82G4xu7ShHhjhGahEpCWc3x8UavY3CTcWV+ufmmCtwkr7ZKsX42jdL0kr1B5FKUeqJvAn51jzQ==", + "bin": { + "qrcode-terminal": "bin/qrcode-terminal.js" + } + }, "node_modules/query-string": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz", @@ -17948,6 +17925,17 @@ "resolved": "https://registry.npmjs.org/react-native-swipe-gestures/-/react-native-swipe-gestures-1.0.5.tgz", "integrity": "sha512-Ns7Bn9H/Tyw278+5SQx9oAblDZ7JixyzeOczcBK8dipQk2pD7Djkcfnf1nB/8RErAmMLL9iXgW0QHqiII8AhKw==" }, + "node_modules/react-native-url-polyfill": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/react-native-url-polyfill/-/react-native-url-polyfill-3.0.0.tgz", + "integrity": "sha512-aA5CiuUCUb/lbrliVCJ6lZ17/RpNJzvTO/C7gC/YmDQhTUoRD5q5HlJfwLWcxz4VgAhHwXKzhxH+wUN24tAdqg==", + "dependencies": { + "whatwg-url-without-unicode": "8.0.0-3" + }, + "peerDependencies": { + "react-native": "*" + } + }, "node_modules/react-native-web": { "version": "0.21.2", "resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.21.2.tgz", @@ -18016,27 +18004,6 @@ "node": ">=10" } }, - "node_modules/react-native/node_modules/@react-native/codegen": { - "version": "0.81.5", - "resolved": "https://registry.npmjs.org/@react-native/codegen/-/codegen-0.81.5.tgz", - "integrity": "sha512-a2TDA03Up8lpSa9sh5VRGCQDXgCTOyDOFH+aqyinxp1HChG8uk89/G+nkJ9FPd0rqgi25eCTR16TWdS3b+fA6g==", - "license": "MIT", - "dependencies": { - "@babel/core": "^7.25.2", - "@babel/parser": "^7.25.3", - "glob": "^7.1.1", - "hermes-parser": "0.29.1", - "invariant": "^2.2.4", - "nullthrows": "^1.1.1", - "yargs": "^17.6.2" - }, - "engines": { - "node": ">= 20.19.4" - }, - "peerDependencies": { - "@babel/core": "*" - } - }, "node_modules/react-native/node_modules/@react-native/js-polyfills": { "version": "0.81.5", "resolved": "https://registry.npmjs.org/@react-native/js-polyfills/-/js-polyfills-0.81.5.tgz", @@ -18069,15 +18036,6 @@ } } }, - "node_modules/react-native/node_modules/babel-plugin-syntax-hermes-parser": { - "version": "0.29.1", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-hermes-parser/-/babel-plugin-syntax-hermes-parser-0.29.1.tgz", - "integrity": "sha512-2WFYnoWGdmih1I1J5eIqxATOeycOqRwYxAQBu3cUu/rhwInwHUg7k60AFNbuGjSDL8tje5GDrAnxzRLcu2pYcA==", - "license": "MIT", - "dependencies": { - "hermes-parser": "0.29.1" - } - }, "node_modules/react-native/node_modules/commander": { "version": "12.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", @@ -18087,21 +18045,6 @@ "node": ">=18" } }, - "node_modules/react-native/node_modules/hermes-estree": { - "version": "0.29.1", - "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.29.1.tgz", - "integrity": "sha512-jl+x31n4/w+wEqm0I2r4CMimukLbLQEYpisys5oCre611CI5fc9TxhqkBBCJ1edDG4Kza0f7CgNz8xVMLZQOmQ==", - "license": "MIT" - }, - "node_modules/react-native/node_modules/hermes-parser": { - "version": "0.29.1", - "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.29.1.tgz", - "integrity": "sha512-xBHWmUtRC5e/UL0tI7Ivt2riA/YBq9+SiYFU7C1oBa/j2jYGlIF9043oak1F47ihuDIxQ5nbsKueYJDRY02UgA==", - "license": "MIT", - "dependencies": { - "hermes-estree": "0.29.1" - } - }, "node_modules/react-native/node_modules/metro-runtime": { "version": "0.83.7", "resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.83.7.tgz", @@ -19805,10 +19748,9 @@ } }, "node_modules/tar": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.7.tgz", - "integrity": "sha512-fov56fJiRuThVFXD6o6/Q354S7pnWMJIVlDBYijsTNx6jKSE4pvrDTs6lUnmGvNyfJwFQQwWy3owKz1ucIhveQ==", - "deprecated": "Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "version": "7.5.16", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.16.tgz", + "integrity": "sha512-56adEpPMouktRlBLXiaYFFzZ/3+JXa8P9n7WbR+ibIjtviN55mEaOkiysCnPnWm+7kkui1Dn8J9l+g6zV8731w==", "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/fs-minipass": "^4.0.0", @@ -19821,18 +19763,6 @@ "node": ">=18" } }, - "node_modules/tar/node_modules/minizlib": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", - "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", - "license": "MIT", - "dependencies": { - "minipass": "^7.1.2" - }, - "engines": { - "node": ">= 18" - } - }, "node_modules/tar/node_modules/yallist": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", diff --git a/package.json b/package.json index 267ac1f5..c0383628 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "test": "jest", "test-watchAll": "jest --watchAll", "lint": "expo lint", - "eas-build-on-success": "node scripts/bugsnag-eas-upload.js", + "eas-build-on-success": "npx bugsnag-eas-build-on-success", "extract": "lingui extract", "compile": "lingui compile" }, @@ -37,6 +37,8 @@ }, "dependencies": { "@bugsnag/expo": "^54.0.0", + "@bugsnag/expo-performance": "^54.0.0", + "@bugsnag/plugin-react-navigation-performance": "^3.4.1", "@expo-google-fonts/inter": "^0.2.3", "@expo/vector-icons": "^15.0.3", "@formatjs/intl-locale": "^5.3.8", @@ -52,6 +54,7 @@ "@react-native-firebase/app": "^23.8.8", "@react-native-firebase/app-check": "23.8.8", "@react-native-firebase/auth": "^23.8.8", + "@react-native-firebase/firestore": "^23.8.8", "@react-native-firebase/storage": "^23.8.8", "@react-native-google-signin/google-signin": "^12.2.1", "@react-navigation/native": "^7.0.14", @@ -59,7 +62,7 @@ "@tanstack/react-query": "^5.51.21", "date-fns": "^3.6.0", "dotenv": "^17.4.2", - "expo": "^54.0.0", + "expo": "~54.0.35", "expo-application": "~7.0.8", "expo-asset": "~12.0.13", "expo-audio": "~1.1.1", @@ -68,24 +71,24 @@ "expo-crypto": "~15.0.9", "expo-dev-client": "~6.0.21", "expo-device": "~8.0.10", - "expo-file-system": "~19.0.22", - "expo-font": "~14.0.11", + "expo-file-system": "~19.0.23", + "expo-font": "~14.0.12", "expo-image": "~3.0.11", "expo-image-picker": "~17.0.11", "expo-insights": "~0.10.8", "expo-keep-awake": "~15.0.8", "expo-linear-gradient": "~15.0.8", "expo-linking": "~8.0.12", - "expo-localization": "~17.0.8", + "expo-localization": "~17.0.9", "expo-navigation-bar": "~5.0.10", "expo-notifications": "~0.32.17", - "expo-router": "~6.0.23", + "expo-router": "~6.0.24", "expo-secure-store": "~15.0.8", "expo-splash-screen": "~31.0.13", "expo-sqlite": "~16.0.10", "expo-status-bar": "~3.0.9", "expo-system-ui": "~6.0.9", - "expo-updates": "~29.0.17", + "expo-updates": "~29.0.18", "expo-web-browser": "~15.0.11", "p-limit": "^6.1.0", "promise": "^8.3.0", @@ -110,7 +113,7 @@ }, "devDependencies": { "@babel/core": "^7.20.0", - "@bugsnag/plugin-expo-eas-sourcemaps": "^54.0.0", + "@bugsnag/plugin-expo-eas-sourcemaps": "^54.1.0", "@bugsnag/source-maps": "^2.3.3", "@lingui/babel-plugin-lingui-macro": "^6.1.0", "@lingui/cli": "^6.1.0", diff --git a/store/socialStore.ts b/store/socialStore.ts new file mode 100644 index 00000000..c6aa93af --- /dev/null +++ b/store/socialStore.ts @@ -0,0 +1,42 @@ +import { create } from "zustand"; +import { FriendInfo, FirestorePrivateSettings } from "../types/firestore"; + +export interface PendingRequest { + id: string; + fromUid: string; + displayName: string; + email: string; + photoURL: string; + createdAt: Date; +} + +export interface SentRequest { + id: string; + toUid: string; + displayName: string; + email: string; + photoURL: string; + createdAt: Date; +} + +interface SocialStore { + pendingRequests: PendingRequest[]; + sentRequests: SentRequest[]; + friends: FriendInfo[]; + privacySettings: FirestorePrivateSettings | null; + setPendingRequests: (requests: PendingRequest[]) => void; + setSentRequests: (requests: SentRequest[]) => void; + setFriends: (friends: FriendInfo[]) => void; + setPrivacySettings: (settings: FirestorePrivateSettings | null) => void; +} + +export const useSocialStore = create((set) => ({ + pendingRequests: [], + sentRequests: [], + friends: [], + privacySettings: null, + setPendingRequests: (pendingRequests) => set({ pendingRequests }), + setSentRequests: (sentRequests) => set({ sentRequests }), + setFriends: (friends) => set({ friends }), + setPrivacySettings: (privacySettings) => set({ privacySettings }), +})); diff --git a/types/firestore.ts b/types/firestore.ts new file mode 100644 index 00000000..e0249ba0 --- /dev/null +++ b/types/firestore.ts @@ -0,0 +1,157 @@ +import { FirebaseFirestoreTypes } from "@react-native-firebase/firestore"; + +export interface FirestoreUser { + displayName: string; + email: string; + photoURL: string; + createdAt: FirebaseFirestoreTypes.Timestamp; +} + +export interface FirestorePrivateSettings { + sharePlans: boolean; + shareStandaloneWorkouts: boolean; + shareCustomExercises: boolean; + shareCompletedWorkouts: boolean; + shareBodyMeasurements: boolean; + shareStrengthProgress: boolean; +} + +export interface FriendRequest { + from: string; + to: string; + status: "pending" | "accepted" | "declined"; + createdAt: FirebaseFirestoreTypes.Timestamp; +} + +export interface FriendEntry { + since: FirebaseFirestoreTypes.Timestamp; +} + +// Enriched friend shape used in the UI (profile data joined in) +export interface FriendInfo { + uid: string; + displayName: string; + email: string; + photoURL: string; + since: FirebaseFirestoreTypes.Timestamp; +} + +// Shared plan / standalone workout shapes +export interface SharedExerciseSet { + repsMin: number | null; + repsMax: number | null; + restMinutes: number; + restSeconds: number; + time: number | null; + distance: number | null; + isWarmup: boolean; + isDropSet: boolean; + isToFailure: boolean; +} + +export interface SharedExercise { + appExerciseId: number | null; + name: string; + equipment: string; + bodyPart: string; + targetMuscle: string; + secondaryMuscles: string[]; + trackingType: string; + isUnilateral: boolean; + doubleWeight: boolean; + animatedUrl: string | null; + sets: SharedExerciseSet[]; + exerciseOrder: number; + supersetGroupId: string | null; + trackingTypeOverride: string | null; +} + +export interface SharedWorkoutItem { + name: string; + workoutOrder: number; + exercises: SharedExercise[]; +} + +export interface SharedPlan { + localPlanId: number; + name: string; + imageUrl: string | null; + publishedAt: FirebaseFirestoreTypes.Timestamp; + updatedAt: FirebaseFirestoreTypes.Timestamp; + workouts: SharedWorkoutItem[]; +} + +export interface SharedStandaloneWorkout { + localWorkoutId: number; + name: string; + imageUrl: string | null; + publishedAt: FirebaseFirestoreTypes.Timestamp; + updatedAt: FirebaseFirestoreTypes.Timestamp; + exercises: SharedExercise[]; +} + +export interface SharedCustomExercise { + localExerciseId: number; + name: string; + equipment: string; + bodyPart: string; + targetMuscle: string; + secondaryMuscles: string[]; + description: string | null; + trackingType: string; + isUnilateral: boolean; + doubleWeight: boolean; + animatedUrl: string | null; + publishedAt: FirebaseFirestoreTypes.Timestamp; + updatedAt: FirebaseFirestoreTypes.Timestamp; +} + +export interface SharedCompletedSet { + setNumber: number; + weight: number | null; + reps: number | null; + time: number | null; + distance: number | null; + isWarmup: boolean; + isDropSet: boolean; + isToFailure: boolean; +} + +export interface SharedCompletedExercise { + name: string; + sets: SharedCompletedSet[]; +} + +export interface SharedCompletedWorkout { + localWorkoutId: number; + planName: string | null; + workoutName: string | null; + dateCompleted: FirebaseFirestoreTypes.Timestamp; + durationSeconds: number; + totalSetsCompleted: number; + isDeload: boolean; + exercises: SharedCompletedExercise[]; +} + +export interface SharedMeasurement { + localEntryId: number; + recordedAt: FirebaseFirestoreTypes.Timestamp; + values: Record; +} + +export interface SharedStrengthSet { + weight: number | null; + reps: number | null; + time: number | null; + distance: number | null; + date: FirebaseFirestoreTypes.Timestamp; +} + +export interface SharedStrengthPR { + exerciseName: string; + appExerciseId: number | null; + trackingType: string; + allTimePR: number; + allTimePRDate: FirebaseFirestoreTypes.Timestamp; + topPRSets: SharedStrengthSet[]; +} diff --git a/utils/__tests__/importUtils.test.ts b/utils/__tests__/importUtils.test.ts new file mode 100644 index 00000000..ce8dfb70 --- /dev/null +++ b/utils/__tests__/importUtils.test.ts @@ -0,0 +1,84 @@ +import { resolveExerciseId } from "@/utils/importUtils"; +import { SharedExercise } from "@/types/firestore"; +import { SQLiteDatabase } from "expo-sqlite"; + +const baseExercise: SharedExercise = { + appExerciseId: null, + name: "Cable Row", + equipment: "cable", + bodyPart: "back", + targetMuscle: "lats", + secondaryMuscles: ["biceps"], + trackingType: "reps", + isUnilateral: false, + doubleWeight: false, + animatedUrl: null, + sets: [], + exerciseOrder: 0, + supersetGroupId: null, + trackingTypeOverride: null, +}; + +const makeMockDb = (overrides: Partial = {}) => + ({ + getFirstAsync: jest.fn(), + runAsync: jest.fn().mockResolvedValue({ lastInsertRowId: 99, changes: 1 }), + ...overrides, + }) as unknown as SQLiteDatabase; + +describe("resolveExerciseId", () => { + it("returns exercise_id from exercises table when appExerciseId is set and found", async () => { + const db = makeMockDb({ + getFirstAsync: jest.fn().mockResolvedValue({ exercise_id: 7 }), + }); + const exercise: SharedExercise = { ...baseExercise, appExerciseId: 42 }; + const result = await resolveExerciseId(db, exercise); + expect(result).toBe(7); + expect(db.getFirstAsync).toHaveBeenCalledWith( + "SELECT exercise_id FROM exercises WHERE app_exercise_id = ? LIMIT 1", + [42], + ); + }); + + it("returns existing custom exercise_id when custom exercise found by name", async () => { + const db = makeMockDb({ + getFirstAsync: jest.fn().mockResolvedValue({ exercise_id: 5 }), + }); + const result = await resolveExerciseId(db, baseExercise); + expect(result).toBe(5); + expect(db.getFirstAsync).toHaveBeenCalledWith( + "SELECT exercise_id FROM exercises WHERE app_exercise_id IS NULL AND name = ? LIMIT 1", + ["Cable Row"], + ); + }); + + it("inserts and returns new exercise_id when custom exercise not found", async () => { + const db = makeMockDb({ + getFirstAsync: jest.fn().mockResolvedValue(null), + runAsync: jest + .fn() + .mockResolvedValue({ lastInsertRowId: 88, changes: 1 }), + }); + const result = await resolveExerciseId(db, baseExercise); + expect(result).toBe(88); + expect(db.runAsync).toHaveBeenCalledWith( + expect.stringContaining("INSERT INTO exercises"), + expect.arrayContaining(["Cable Row", "back", "lats", "cable"]), + ); + }); + + it("inserts custom exercise with JSON-encoded secondary_muscles", async () => { + const db = makeMockDb({ + getFirstAsync: jest.fn().mockResolvedValue(null), + runAsync: jest + .fn() + .mockResolvedValue({ lastInsertRowId: 10, changes: 1 }), + }); + await resolveExerciseId(db, { + ...baseExercise, + secondaryMuscles: ["biceps", "forearms"], + }); + const insertArgs = (db.runAsync as jest.Mock).mock.calls[0][1]; + expect(insertArgs).toContain(JSON.stringify(["biceps", "forearms"])); + }); +}); diff --git a/utils/database.ts b/utils/database.ts index bdcf6deb..6a4584cf 100644 --- a/utils/database.ts +++ b/utils/database.ts @@ -2790,3 +2790,385 @@ export const getProgressionStatesForWorkout = async ( throw error; } }; + +// --------------------------------------------------------------------------- +// Sharing helpers +// --------------------------------------------------------------------------- + +interface RawPlanRow { + id: number; + name: string; + image_url: string | null; + is_active: number; + app_plan_id: number | null; +} + +interface RawPlanWorkoutRow { + workout_id: number; + workout_name: string; + workout_order: number; + exercise_id: number | null; + app_exercise_id: number | null; + exercise_name: string | null; + animated_url: string | null; + equipment: string | null; + body_part: string | null; + target_muscle: string | null; + secondary_muscles: string | null; + tracking_type: string | null; + is_unilateral: number; + double_weight: number; + tracking_type_override: string | null; + sets: string | null; + exercise_order: number; + superset_group_id: string | null; +} + +export const fetchFullPlanForSharing = async ( + planId: number, +): Promise<{ + plan: RawPlanRow; + workouts: { + workout_id: number; + workout_name: string; + workout_order: number; + exercises: RawPlanWorkoutRow[]; + }[]; +} | null> => { + const db = await openDatabase("userData.db"); + + const plan = await db.getFirstAsync( + `SELECT id, name, image_url, is_active, app_plan_id FROM user_plans WHERE id = ? AND is_deleted = FALSE`, + [planId], + ); + if (!plan) return null; + + const rows = await db.getAllAsync( + `SELECT + uw.id AS workout_id, uw.name AS workout_name, uw.workout_order, + e.exercise_id, e.app_exercise_id, e.name AS exercise_name, + e.animated_url, e.equipment, e.body_part, e.target_muscle, + e.secondary_muscles, e.tracking_type, e.is_unilateral, e.double_weight, + uwe.tracking_type_override, uwe.sets, uwe.exercise_order, + uwe.superset_group_id + FROM user_workouts uw + LEFT JOIN user_workout_exercises uwe + ON uwe.workout_id = uw.id AND uwe.is_deleted = FALSE + LEFT JOIN exercises e ON e.exercise_id = uwe.exercise_id + WHERE uw.plan_id = ? AND uw.is_deleted = FALSE + ORDER BY uw.workout_order, uwe.exercise_order`, + [planId], + ); + + const workoutsMap = new Map< + number, + { + workout_id: number; + workout_name: string; + workout_order: number; + exercises: RawPlanWorkoutRow[]; + } + >(); + for (const row of rows) { + if (!workoutsMap.has(row.workout_id)) { + workoutsMap.set(row.workout_id, { + workout_id: row.workout_id, + workout_name: row.workout_name, + workout_order: row.workout_order, + exercises: [], + }); + } + if (row.exercise_id) { + workoutsMap.get(row.workout_id)!.exercises.push(row); + } + } + + return { plan, workouts: Array.from(workoutsMap.values()) }; +}; + +interface RawStandaloneWorkoutRow { + workout_id: number; + workout_name: string; + image_url: string | null; + exercise_id: number | null; + app_exercise_id: number | null; + exercise_name: string | null; + animated_url: string | null; + equipment: string | null; + body_part: string | null; + target_muscle: string | null; + secondary_muscles: string | null; + tracking_type: string | null; + is_unilateral: number; + double_weight: number; + tracking_type_override: string | null; + sets: string | null; + exercise_order: number; + superset_group_id: string | null; +} + +export const fetchStandaloneWorkoutForSharing = async ( + workoutId: number, +): Promise<{ + workout_id: number; + workout_name: string; + image_url: string | null; + exercises: RawStandaloneWorkoutRow[]; +} | null> => { + const db = await openDatabase("userData.db"); + + const wRow = await db.getFirstAsync<{ + id: number; + name: string; + image_url: string | null; + }>( + `SELECT id, name, image_url FROM user_workouts WHERE id = ? AND plan_id IS NULL AND is_deleted = FALSE`, + [workoutId], + ); + if (!wRow) return null; + + const rows = await db.getAllAsync( + `SELECT + uw.id AS workout_id, uw.name AS workout_name, uw.image_url, + e.exercise_id, e.app_exercise_id, e.name AS exercise_name, + e.animated_url, e.equipment, e.body_part, e.target_muscle, + e.secondary_muscles, e.tracking_type, e.is_unilateral, e.double_weight, + uwe.tracking_type_override, uwe.sets, uwe.exercise_order, + uwe.superset_group_id + FROM user_workouts uw + LEFT JOIN user_workout_exercises uwe + ON uwe.workout_id = uw.id AND uwe.is_deleted = FALSE + LEFT JOIN exercises e ON e.exercise_id = uwe.exercise_id + WHERE uw.id = ? AND uw.is_deleted = FALSE + ORDER BY uwe.exercise_order`, + [workoutId], + ); + + const exercises = rows.filter((r) => r.exercise_id != null); + return { + workout_id: wRow.id, + workout_name: wRow.name, + image_url: wRow.image_url, + exercises, + }; +}; + +export const fetchCompletedWorkoutForSharing = async ( + completedWorkoutId: number, +): Promise<{ + id: number; + plan_name: string | null; + workout_name: string | null; + date_completed: string; + duration: number; + total_sets_completed: number; + is_deload: number; + exercises: { + completed_exercise_id: number; + exercise_name: string; + sets: { + set_number: number; + weight: number | null; + reps: number | null; + time: number | null; + distance: number | null; + is_warmup: number; + is_drop_set: number; + is_to_failure: number; + }[]; + }[]; +} | null> => { + const db = await openDatabase("userData.db"); + + const cw = await db.getFirstAsync<{ + id: number; + plan_name: string | null; + workout_name: string | null; + date_completed: string; + duration: number; + total_sets_completed: number; + is_deload: number; + }>( + `SELECT cw.id, up.name AS plan_name, uw.name AS workout_name, + cw.date_completed, cw.duration, cw.total_sets_completed, cw.is_deload + FROM completed_workouts cw + LEFT JOIN user_plans up ON up.id = cw.plan_id + LEFT JOIN user_workouts uw ON uw.id = cw.workout_id + WHERE cw.id = ? AND cw.is_deleted = 0`, + [completedWorkoutId], + ); + if (!cw) return null; + + const setRows = await db.getAllAsync<{ + completed_exercise_id: number; + exercise_name: string; + set_number: number; + weight: number | null; + reps: number | null; + time: number | null; + distance: number | null; + is_warmup: number; + is_drop_set: number; + is_to_failure: number; + }>( + `SELECT ce.id AS completed_exercise_id, e.name AS exercise_name, + cs.set_number, cs.weight, cs.reps, cs.time, cs.distance, + cs.is_warmup, cs.is_drop_set, cs.is_to_failure + FROM completed_exercises ce + JOIN exercises e ON e.exercise_id = ce.exercise_id + JOIN completed_sets cs ON cs.completed_exercise_id = ce.id AND cs.is_deleted = 0 + WHERE ce.completed_workout_id = ? AND ce.is_deleted = 0 + ORDER BY ce.id, cs.set_number`, + [completedWorkoutId], + ); + + const exMap = new Map< + number, + { + completed_exercise_id: number; + exercise_name: string; + sets: typeof setRows; + } + >(); + for (const row of setRows) { + if (!exMap.has(row.completed_exercise_id)) { + exMap.set(row.completed_exercise_id, { + completed_exercise_id: row.completed_exercise_id, + exercise_name: row.exercise_name, + sets: [], + }); + } + exMap.get(row.completed_exercise_id)!.sets.push(row); + } + + return { ...cw, exercises: Array.from(exMap.values()) }; +}; + +export const fetchBodyMeasurementEntryForSharing = async ( + entryId: number, +): Promise<{ + id: number; + recorded_at: string; + values: Record; +} | null> => { + const db = await openDatabase("userData.db"); + + const entry = await db.getFirstAsync<{ id: number; recorded_at: string }>( + `SELECT id, recorded_at FROM body_measurement_entries WHERE id = ?`, + [entryId], + ); + if (!entry) return null; + + const valueRows = await db.getAllAsync<{ key: string; value: number }>( + `SELECT bmd.key, bmv.value + FROM body_measurement_values bmv + JOIN body_metric_definitions bmd ON bmd.id = bmv.metric_id + WHERE bmv.entry_id = ?`, + [entryId], + ); + + const values: Record = {}; + for (const v of valueRows) { + values[v.key] = v.value; + } + + return { id: entry.id, recorded_at: entry.recorded_at, values }; +}; + +export interface ExercisePRData { + exercise_id: number; + app_exercise_id: number | null; + exercise_name: string; + tracking_type: string; + all_time_pr: number; + all_time_pr_date: string; + top_sets: { + weight: number | null; + reps: number | null; + time: number | null; + distance: number | null; + date_completed: string; + }[]; +} + +export const fetchPRDataForExercises = async ( + exerciseIds: number[], +): Promise => { + if (exerciseIds.length === 0) return []; + const db = await openDatabase("userData.db"); + const placeholders = exerciseIds.map(() => "?").join(", "); + + const pmExpr = `CASE e.tracking_type + WHEN 'weight' THEN (COALESCE(cs.weight, 0) * CASE WHEN e.double_weight = 1 THEN 2 ELSE 1 END) * (1.0 + COALESCE(cs.reps, 0) / 30.0) + WHEN 'assisted' THEN (CAST((SELECT value FROM settings WHERE key = 'bodyWeight') AS REAL) - COALESCE(cs.weight, 0)) * (1.0 + COALESCE(cs.reps, 0) / 30.0) + WHEN 'reps' THEN CAST(COALESCE(cs.reps, 0) AS REAL) + WHEN 'time' THEN CAST(COALESCE(cs.time, 0) AS REAL) + WHEN 'distance' THEN CAST(COALESCE(cs.distance, 0) AS REAL) + ELSE (COALESCE(cs.weight, 0) * CASE WHEN e.double_weight = 1 THEN 2 ELSE 1 END) * (1.0 + COALESCE(cs.reps, 0) / 30.0) + END`; + + const rows = await db.getAllAsync<{ + exercise_id: number; + app_exercise_id: number | null; + exercise_name: string; + tracking_type: string; + weight: number | null; + reps: number | null; + time: number | null; + distance: number | null; + date_completed: string; + pm: number; + all_time_pr: number; + rn: number; + }>( + `SELECT * FROM ( + SELECT + e.exercise_id, e.app_exercise_id, e.name AS exercise_name, e.tracking_type, + cs.weight, cs.reps, cs.time, cs.distance, + DATE(cw.date_completed) AS date_completed, + ${pmExpr} AS pm, + MAX(${pmExpr}) OVER (PARTITION BY e.exercise_id) AS all_time_pr, + ROW_NUMBER() OVER (PARTITION BY e.exercise_id ORDER BY ${pmExpr} DESC) AS rn + FROM exercises e + JOIN completed_exercises ce ON ce.exercise_id = e.exercise_id AND ce.is_deleted = 0 + JOIN completed_sets cs ON cs.completed_exercise_id = ce.id + AND cs.is_warmup = 0 AND cs.is_deleted = 0 + JOIN completed_workouts cw ON cw.id = ce.completed_workout_id AND cw.is_deleted = 0 + WHERE e.exercise_id IN (${placeholders}) + ) + WHERE rn <= 5`, + exerciseIds, + ); + + const exerciseMap = new Map(); + for (const row of rows) { + if (!exerciseMap.has(row.exercise_id)) { + exerciseMap.set(row.exercise_id, { + exercise_id: row.exercise_id, + app_exercise_id: row.app_exercise_id, + exercise_name: row.exercise_name, + tracking_type: row.tracking_type, + all_time_pr: row.all_time_pr, + all_time_pr_date: row.date_completed, + top_sets: [], + }); + } + const entry = exerciseMap.get(row.exercise_id)!; + // Keep the earliest date where the all-time PR was achieved + if ( + row.pm >= row.all_time_pr && + row.date_completed < entry.all_time_pr_date + ) { + entry.all_time_pr_date = row.date_completed; + } + entry.top_sets.push({ + weight: row.weight, + reps: row.reps, + time: row.time, + distance: row.distance, + date_completed: row.date_completed, + }); + } + + return Array.from(exerciseMap.values()); +}; diff --git a/utils/friends.ts b/utils/friends.ts new file mode 100644 index 00000000..2b0c6cc9 --- /dev/null +++ b/utils/friends.ts @@ -0,0 +1,105 @@ +import firestore from "@react-native-firebase/firestore"; + +export interface UserSearchResult { + uid: string; + displayName: string; + email: string; + photoURL: string; +} + +// Always uses .set() (overwrite) so a re-request after decline replaces the +// existing document rather than failing or creating a duplicate. +export const sendFriendRequest = async ( + fromUid: string, + toUid: string, +): Promise => { + const requestId = `${fromUid}_${toUid}`; + await firestore().collection("friendRequests").doc(requestId).set({ + from: fromUid, + to: toUid, + status: "pending", + createdAt: firestore.FieldValue.serverTimestamp(), + }); +}; + +export const acceptFriendRequest = async ( + fromUid: string, + myUid: string, +): Promise => { + const requestId = `${fromUid}_${myUid}`; + const db = firestore(); + const now = firestore.FieldValue.serverTimestamp(); + const batch = db.batch(); + + batch.set( + db.collection("users").doc(myUid).collection("friends").doc(fromUid), + { since: now }, + ); + batch.set( + db.collection("users").doc(fromUid).collection("friends").doc(myUid), + { since: now }, + ); + batch.update(db.collection("friendRequests").doc(requestId), { + status: "accepted", + }); + + await batch.commit(); +}; + +export const declineFriendRequest = async ( + fromUid: string, + myUid: string, +): Promise => { + const requestId = `${fromUid}_${myUid}`; + await firestore() + .collection("friendRequests") + .doc(requestId) + .update({ status: "declined" }); +}; + +export const removeFriend = async ( + myUid: string, + friendUid: string, +): Promise => { + const db = firestore(); + const batch = db.batch(); + + batch.delete( + db.collection("users").doc(myUid).collection("friends").doc(friendUid), + ); + batch.delete( + db.collection("users").doc(friendUid).collection("friends").doc(myUid), + ); + + // Also clean up the friend request document in both possible directions. + // We don't know which user initiated the original request, so delete both. + batch.delete(db.collection("friendRequests").doc(`${myUid}_${friendUid}`)); + batch.delete(db.collection("friendRequests").doc(`${friendUid}_${myUid}`)); + + await batch.commit(); +}; + +// Returns null if no user found or if the result is the current user. +export const searchUserByEmail = async ( + email: string, + currentUid: string, +): Promise => { + const snapshot = await firestore() + .collection("users") + .where("email", "==", email.toLowerCase().trim()) + .limit(1) + .get(); + + if (snapshot.empty) return null; + + const doc = snapshot.docs[0]; + if (doc.id === currentUid) return null; + + const data = doc.data(); + return { + uid: doc.id, + displayName: data.displayName, + email: data.email, + photoURL: data.photoURL, + }; +}; diff --git a/utils/importUtils.ts b/utils/importUtils.ts new file mode 100644 index 00000000..fc7d7ecc --- /dev/null +++ b/utils/importUtils.ts @@ -0,0 +1,49 @@ +import { SQLiteDatabase } from "expo-sqlite"; +import { SharedExercise } from "@/types/firestore"; + +/** + * Resolves a SharedExercise to a local exercise_id in userData.db. + * For app exercises: looks up by app_exercise_id (must already exist — call + * ensureAppExercisesExist before starting the transaction). + * For custom exercises: matches by name (app_exercise_id IS NULL), inserting + * a new row if no match is found. + */ +export const resolveExerciseId = async ( + db: SQLiteDatabase, + exercise: SharedExercise, +): Promise => { + if (exercise.appExerciseId !== null) { + const row = await db.getFirstAsync<{ exercise_id: number }>( + "SELECT exercise_id FROM exercises WHERE app_exercise_id = ? LIMIT 1", + [exercise.appExerciseId], + ); + if (!row) + throw new Error( + `App exercise ${exercise.appExerciseId} not found in userData.db`, + ); + return row.exercise_id; + } + + const existing = await db.getFirstAsync<{ exercise_id: number }>( + "SELECT exercise_id FROM exercises WHERE app_exercise_id IS NULL AND name = ? LIMIT 1", + [exercise.name], + ); + if (existing) return existing.exercise_id; + + const result = await db.runAsync( + `INSERT INTO exercises (app_exercise_id, name, body_part, target_muscle, equipment, secondary_muscles, tracking_type, is_unilateral, double_weight, animated_url) + VALUES (NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, + [ + exercise.name, + exercise.bodyPart, + exercise.targetMuscle, + exercise.equipment, + JSON.stringify(exercise.secondaryMuscles), + exercise.trackingType, + exercise.isUnilateral ? 1 : 0, + exercise.doubleWeight ? 1 : 0, + exercise.animatedUrl, + ], + ); + return result.lastInsertRowId; +}; diff --git a/utils/loadPremadePlans.ts b/utils/loadPremadePlans.ts index 2d7380c4..930cf2c3 100644 --- a/utils/loadPremadePlans.ts +++ b/utils/loadPremadePlans.ts @@ -3,7 +3,7 @@ import { openDatabase } from "./database"; import { SQLiteDatabase } from "expo-sqlite"; import Bugsnag from "@bugsnag/expo"; -const ensureAppExercisesExist = async ( +export const ensureAppExercisesExist = async ( userDb: SQLiteDatabase, appExerciseIds: number[], ): Promise => { diff --git a/utils/sharing.ts b/utils/sharing.ts new file mode 100644 index 00000000..ee3ba91f --- /dev/null +++ b/utils/sharing.ts @@ -0,0 +1,378 @@ +import firestore from "@react-native-firebase/firestore"; +import Bugsnag from "@bugsnag/expo"; +import { + fetchFullPlanForSharing, + fetchStandaloneWorkoutForSharing, + fetchCompletedWorkoutForSharing, + fetchBodyMeasurementEntryForSharing, + fetchPRDataForExercises, +} from "./database"; +import type { Exercise } from "./database"; + +// ─── helpers ────────────────────────────────────────────────────────────────── + +const parseSecondaryMuscles = (raw: string | null): string[] => { + if (!raw) return []; + try { + return JSON.parse(raw); + } catch { + return []; + } +}; + +const parseSets = (raw: string | null): any[] => { + if (!raw) return []; + try { + return JSON.parse(raw); + } catch { + return []; + } +}; + +const buildSharedExercise = (row: { + exercise_id: number | null; + app_exercise_id: number | null; + exercise_name: string | null; + animated_url: string | null; + equipment: string | null; + body_part: string | null; + target_muscle: string | null; + secondary_muscles: string | null; + tracking_type: string | null; + is_unilateral: number; + double_weight: number; + tracking_type_override: string | null; + sets: string | null; + exercise_order: number; + superset_group_id: string | null; +}) => ({ + appExerciseId: row.app_exercise_id ?? null, + name: row.exercise_name ?? "", + equipment: row.equipment ?? "", + bodyPart: row.body_part ?? "", + targetMuscle: row.target_muscle ?? "", + secondaryMuscles: parseSecondaryMuscles(row.secondary_muscles), + trackingType: row.tracking_type ?? "weight", + isUnilateral: !!row.is_unilateral, + doubleWeight: !!row.double_weight, + animatedUrl: row.animated_url ?? null, + sets: parseSets(row.sets).map((s: any) => ({ + repsMin: s.repsMin ?? null, + repsMax: s.repsMax ?? null, + restMinutes: s.restMinutes ?? 0, + restSeconds: s.restSeconds ?? 0, + time: s.time ?? null, + distance: s.distance ?? null, + isWarmup: !!s.isWarmup, + isDropSet: !!s.isDropSet, + isToFailure: !!(s.isToFailure ?? s.toFailure), + })), + exerciseOrder: row.exercise_order, + supersetGroupId: row.superset_group_id ?? null, + trackingTypeOverride: row.tracking_type_override ?? null, +}); + +// ─── plans ──────────────────────────────────────────────────────────────────── + +export const publishPlan = async ( + uid: string, + planId: number, +): Promise => { + const data = await fetchFullPlanForSharing(planId); + if (!data) return; + + const now = firestore.FieldValue.serverTimestamp(); + const db = firestore(); + const ref = db + .collection("users") + .doc(uid) + .collection("sharedPlans") + .doc(String(planId)); + + const existing = await ref.get(); + const publishedAt = existing.exists() ? existing.data()?.publishedAt : now; + + await ref.set({ + localPlanId: planId, + name: data.plan.name, + imageUrl: data.plan.image_url ?? null, + publishedAt, + updatedAt: now, + workouts: data.workouts.map((w) => ({ + name: w.workout_name, + workoutOrder: w.workout_order, + exercises: w.exercises.map(buildSharedExercise), + })), + }); +}; + +export const unpublishPlan = async ( + uid: string, + planId: number, +): Promise => { + await firestore() + .collection("users") + .doc(uid) + .collection("sharedPlans") + .doc(String(planId)) + .delete(); +}; + +// ─── standalone workouts ────────────────────────────────────────────────────── + +export const publishStandaloneWorkout = async ( + uid: string, + workoutId: number, +): Promise => { + const data = await fetchStandaloneWorkoutForSharing(workoutId); + if (!data) return; + + const now = firestore.FieldValue.serverTimestamp(); + const db = firestore(); + const ref = db + .collection("users") + .doc(uid) + .collection("sharedStandaloneWorkouts") + .doc(String(workoutId)); + + const existing = await ref.get(); + const publishedAt = existing.exists() ? existing.data()?.publishedAt : now; + + await ref.set({ + localWorkoutId: workoutId, + name: data.workout_name, + imageUrl: data.image_url ?? null, + publishedAt, + updatedAt: now, + exercises: data.exercises.map(buildSharedExercise), + }); +}; + +export const unpublishStandaloneWorkout = async ( + uid: string, + workoutId: number, +): Promise => { + await firestore() + .collection("users") + .doc(uid) + .collection("sharedStandaloneWorkouts") + .doc(String(workoutId)) + .delete(); +}; + +// ─── custom exercises ───────────────────────────────────────────────────────── + +export const pushCustomExercise = async ( + uid: string, + exercise: Exercise, +): Promise => { + try { + const now = firestore.FieldValue.serverTimestamp(); + const db = firestore(); + const ref = db + .collection("users") + .doc(uid) + .collection("sharedCustomExercises") + .doc(String(exercise.exercise_id)); + + const existing = await ref.get(); + const publishedAt = existing.exists() ? existing.data()?.publishedAt : now; + + await ref.set({ + localExerciseId: exercise.exercise_id, + name: exercise.name, + equipment: exercise.equipment ?? "", + bodyPart: exercise.body_part ?? "", + targetMuscle: exercise.target_muscle ?? "", + secondaryMuscles: Array.isArray(exercise.secondary_muscles) + ? exercise.secondary_muscles + : parseSecondaryMuscles( + exercise.secondary_muscles as unknown as string, + ), + description: exercise.description ?? null, + trackingType: exercise.tracking_type ?? "weight", + isUnilateral: !!exercise.is_unilateral, + doubleWeight: !!exercise.double_weight, + animatedUrl: exercise.animated_url ?? null, + publishedAt, + updatedAt: now, + }); + } catch (error) { + Bugsnag.notify(error as Error); + } +}; + +export const removeCustomExercise = async ( + uid: string, + exerciseId: number, +): Promise => { + try { + await firestore() + .collection("users") + .doc(uid) + .collection("sharedCustomExercises") + .doc(String(exerciseId)) + .delete(); + } catch (error) { + Bugsnag.notify(error as Error); + } +}; + +// ─── completed workouts ─────────────────────────────────────────────────────── + +export const pushCompletedWorkout = async ( + uid: string, + completedWorkoutId: number, +): Promise => { + try { + const data = await fetchCompletedWorkoutForSharing(completedWorkoutId); + if (!data) return; + + await firestore() + .collection("users") + .doc(uid) + .collection("sharedWorkouts") + .doc(String(completedWorkoutId)) + .set({ + localWorkoutId: completedWorkoutId, + planName: data.plan_name ?? null, + workoutName: data.workout_name ?? null, + dateCompleted: firestore.Timestamp.fromDate( + new Date(data.date_completed), + ), + durationSeconds: data.duration, + totalSetsCompleted: data.total_sets_completed, + isDeload: !!data.is_deload, + exercises: data.exercises.map((ex) => ({ + name: ex.exercise_name, + sets: ex.sets.map((s) => ({ + setNumber: s.set_number, + weight: s.weight, + reps: s.reps, + time: s.time, + distance: s.distance, + isWarmup: !!s.is_warmup, + isDropSet: !!s.is_drop_set, + isToFailure: !!s.is_to_failure, + })), + })), + }); + } catch (error) { + Bugsnag.notify(error as Error); + } +}; + +// ─── body measurements ──────────────────────────────────────────────────────── + +export const pushBodyMeasurement = async ( + uid: string, + entryId: number, +): Promise => { + try { + const data = await fetchBodyMeasurementEntryForSharing(entryId); + if (!data) return; + + await firestore() + .collection("users") + .doc(uid) + .collection("sharedMeasurements") + .doc(String(entryId)) + .set({ + localEntryId: entryId, + recordedAt: firestore.Timestamp.fromDate(new Date(data.recorded_at)), + values: data.values, + }); + } catch (error) { + Bugsnag.notify(error as Error); + } +}; + +// ─── strength PRs ───────────────────────────────────────────────────────────── + +export const pushStrengthPRs = async ( + uid: string, + exerciseIds: number[], +): Promise => { + try { + const prData = await fetchPRDataForExercises(exerciseIds); + if (prData.length === 0) return; + + const db = firestore(); + const BATCH_LIMIT = 500; + + for (let i = 0; i < prData.length; i += BATCH_LIMIT) { + const chunk = prData.slice(i, i + BATCH_LIMIT); + const batch = db.batch(); + + for (const pr of chunk) { + const docId = + pr.app_exercise_id != null + ? `app_${pr.app_exercise_id}` + : `custom_${pr.exercise_id}`; + const ref = db + .collection("users") + .doc(uid) + .collection("sharedStrength") + .doc(docId); + + batch.set(ref, { + exerciseName: pr.exercise_name, + appExerciseId: pr.app_exercise_id, + trackingType: pr.tracking_type, + allTimePR: pr.all_time_pr, + allTimePRDate: firestore.Timestamp.fromDate( + new Date(pr.all_time_pr_date), + ), + topPRSets: pr.top_sets.map((s) => ({ + weight: s.weight, + reps: s.reps, + time: s.time, + distance: s.distance, + date: firestore.Timestamp.fromDate(new Date(s.date_completed)), + })), + }); + } + + await batch.commit(); + } + } catch (error) { + Bugsnag.notify(error as Error); + } +}; + +// ─── delete all shared data ─────────────────────────────────────────────────── + +const deleteSubcollection = async ( + uid: string, + subcollection: string, +): Promise => { + const db = firestore(); + const collRef = db.collection("users").doc(uid).collection(subcollection); + + let snapshot = await collRef.limit(500).get(); + while (!snapshot.empty) { + const batch = db.batch(); + for (const doc of snapshot.docs) { + batch.delete(doc.ref); + } + await batch.commit(); + if (snapshot.docs.length < 500) break; + snapshot = await collRef.limit(500).get(); + } +}; + +export const deleteAllSharedData = async (uid: string): Promise => { + try { + const subcollections = [ + "sharedPlans", + "sharedStandaloneWorkouts", + "sharedCustomExercises", + "sharedWorkouts", + "sharedMeasurements", + "sharedStrength", + ]; + await Promise.all(subcollections.map((c) => deleteSubcollection(uid, c))); + } catch (error) { + Bugsnag.notify(error as Error); + } +}; diff --git a/utils/userProfile.ts b/utils/userProfile.ts new file mode 100644 index 00000000..f5ac6796 --- /dev/null +++ b/utils/userProfile.ts @@ -0,0 +1,46 @@ +import { FirebaseAuthTypes } from "@react-native-firebase/auth"; +import firestore from "@react-native-firebase/firestore"; +import Bugsnag from "@bugsnag/expo"; +import { FirestorePrivateSettings } from "../types/firestore"; + +const DEFAULT_PRIVACY_SETTINGS: FirestorePrivateSettings = { + sharePlans: false, + shareStandaloneWorkouts: false, + shareCustomExercises: false, + shareCompletedWorkouts: false, + shareBodyMeasurements: false, + shareStrengthProgress: false, +}; + +export const upsertUserProfile = async ( + user: FirebaseAuthTypes.User, +): Promise => { + try { + const db = firestore(); + const userRef = db.collection("users").doc(user.uid); + const privateSettingsRef = userRef.collection("private").doc("settings"); + + const [userDoc, settingsDoc] = await Promise.all([ + userRef.get(), + privateSettingsRef.get(), + ]); + + const profileData: Record = { + displayName: user.displayName ?? "", + email: user.email ?? "", + photoURL: user.photoURL ?? "", + }; + if (!userDoc.exists()) { + profileData.createdAt = firestore.FieldValue.serverTimestamp(); + } + + const writes: Promise[] = [userRef.set(profileData, { merge: true })]; + if (!settingsDoc.exists()) { + writes.push(privateSettingsRef.set(DEFAULT_PRIVACY_SETTINGS)); + } + + await Promise.all(writes); + } catch (error) { + Bugsnag.notify(error as Error); + } +};