From 70fba34f0cc727457b196ad3e18d20d1ea98d46e Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Fri, 16 May 2025 22:15:12 +0200 Subject: [PATCH 01/89] Better handling of time zones We now send the current time zone to the server when serializing datetime objects. This was causing entries to be saved some hours wrong or depending on the time, on a different day. --- lib/helpers/date.dart | 40 ++++++++++++++++ lib/helpers/json.dart | 9 ++++ lib/helpers/misc.dart | 32 ------------- lib/models/nutrition/log.dart | 2 +- lib/models/nutrition/log.g.dart | 2 +- lib/models/nutrition/meal.dart | 2 +- lib/models/nutrition/nutritional_plan.dart | 2 +- lib/models/nutrition/nutritional_plan.g.dart | 2 +- lib/models/workouts/log.dart | 2 +- lib/models/workouts/log.g.dart | 2 +- lib/models/workouts/routine.dart | 4 +- lib/models/workouts/routine.g.dart | 2 +- lib/providers/nutrition.dart | 2 +- lib/screens/log_meal_screen.dart | 47 +++++++++++-------- lib/screens/nutritional_plan_screen.dart | 2 +- lib/widgets/dashboard/calendar.dart | 2 +- lib/widgets/dashboard/widgets/nutrition.dart | 2 +- lib/widgets/dashboard/widgets/routines.dart | 2 +- lib/widgets/nutrition/forms.dart | 18 +++---- lib/widgets/nutrition/meal.dart | 2 +- lib/widgets/routines/day.dart | 2 +- lib/widgets/routines/gym_mode/log_page.dart | 19 ++++---- .../routines/gym_mode/session_page.dart | 2 +- lib/widgets/routines/log.dart | 1 + test/exercises/exercise_provider_db_test.dart | 2 +- test/helpers/colors_test.dart | 18 +++++++ .../date_test.dart} | 23 ++++----- test/helpers/json_test.dart | 27 +++++++++++ .../nutritional_meal_item_form_test.dart | 2 +- 29 files changed, 169 insertions(+), 105 deletions(-) create mode 100644 lib/helpers/date.dart rename test/{other/extensions_test.dart => helpers/date_test.dart} (60%) diff --git a/lib/helpers/date.dart b/lib/helpers/date.dart new file mode 100644 index 00000000..9177b8fc --- /dev/null +++ b/lib/helpers/date.dart @@ -0,0 +1,40 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +/// Returns a timezone aware DateTime object from a date and time string. +DateTime getDateTimeFromDateAndTime(String date, String time) { + return DateTime.parse('$date $time'); +} + +/// Returns a list of [DateTime] objects from [first] to [last], inclusive. +List daysInRange(DateTime first, DateTime last) { + final dayCount = last.difference(first).inDays + 1; + return List.generate( + dayCount, + (index) => DateTime.utc(first.year, first.month, first.day + index), + ); +} + +extension DateTimeExtension on DateTime { + bool isSameDayAs(DateTime other) { + final thisDay = DateTime(year, month, day); + final otherDay = DateTime(other.year, other.month, other.day); + + return thisDay.isAtSameMomentAs(otherDay); + } +} diff --git a/lib/helpers/json.dart b/lib/helpers/json.dart index f10c1f80..31c9d396 100644 --- a/lib/helpers/json.dart +++ b/lib/helpers/json.dart @@ -53,6 +53,15 @@ String? dateToYYYYMMDD(DateTime? dateTime) { return DateFormat('yyyy-MM-dd').format(dateTime); } +/// Convert a date to UTC and then to an ISO8601 string. +/// +/// This makes sure that the serialized data has correct timezone information. +/// Otherwise the django backend will possible treat the date as local time, +/// which will not be correct in most cases. +String dateToUtcIso8601(DateTime dateTime) { + return dateTime.toUtc().toIso8601String(); +} + /* * Converts a time to a date object. * Needed e.g. when the wger api only sends a time but no date information. diff --git a/lib/helpers/misc.dart b/lib/helpers/misc.dart index 8db74a85..f99b2364 100644 --- a/lib/helpers/misc.dart +++ b/lib/helpers/misc.dart @@ -63,38 +63,6 @@ String repText( return out.join(' '); } -/// Returns a list of [DateTime] objects from [first] to [last], inclusive. -List daysInRange(DateTime first, DateTime last) { - final dayCount = last.difference(first).inDays + 1; - return List.generate( - dayCount, - (index) => DateTime.utc(first.year, first.month, first.day + index), - ); -} - -extension TimeOfDayExtension on TimeOfDay { - bool isAfter(TimeOfDay other) { - return toMinutes() > other.toMinutes(); - } - - bool isBefore(TimeOfDay other) { - return toMinutes() < other.toMinutes(); - } - - int toMinutes() { - return (hour * 60) + minute; - } -} - -extension DateTimeExtension on DateTime { - bool isSameDayAs(DateTime other) { - final thisDay = DateTime(year, month, day); - final otherDay = DateTime(other.year, other.month, other.day); - - return thisDay.isAtSameMomentAs(otherDay); - } -} - void launchURL(String url, BuildContext context) async { final scaffoldMessenger = ScaffoldMessenger.of(context); final launched = await launchUrl(Uri.parse(url)); diff --git a/lib/models/nutrition/log.dart b/lib/models/nutrition/log.dart index ac4aa845..d36e5a53 100644 --- a/lib/models/nutrition/log.dart +++ b/lib/models/nutrition/log.dart @@ -36,7 +36,7 @@ class Log { @JsonKey(required: true, name: 'plan') int planId; - @JsonKey(required: true) + @JsonKey(required: true, toJson: dateToUtcIso8601) late DateTime datetime; String? comment; diff --git a/lib/models/nutrition/log.g.dart b/lib/models/nutrition/log.g.dart index dcb1d721..8d8587d2 100644 --- a/lib/models/nutrition/log.g.dart +++ b/lib/models/nutrition/log.g.dart @@ -27,7 +27,7 @@ Map _$LogToJson(Log instance) => { 'id': instance.id, 'meal': instance.mealId, 'plan': instance.planId, - 'datetime': instance.datetime.toIso8601String(), + 'datetime': dateToUtcIso8601(instance.datetime), 'comment': instance.comment, 'ingredient': instance.ingredientId, 'weight_unit': instance.weightUnitId, diff --git a/lib/models/nutrition/meal.dart b/lib/models/nutrition/meal.dart index 3e98c9e8..b7c51e4d 100644 --- a/lib/models/nutrition/meal.dart +++ b/lib/models/nutrition/meal.dart @@ -19,8 +19,8 @@ import 'package:flutter/material.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:wger/helpers/consts.dart'; +import 'package:wger/helpers/date.dart'; import 'package:wger/helpers/json.dart'; -import 'package:wger/helpers/misc.dart'; import 'package:wger/models/nutrition/log.dart'; import 'package:wger/models/nutrition/meal_item.dart'; import 'package:wger/models/nutrition/nutritional_values.dart'; diff --git a/lib/models/nutrition/nutritional_plan.dart b/lib/models/nutrition/nutritional_plan.dart index 4318f07e..3605e220 100644 --- a/lib/models/nutrition/nutritional_plan.dart +++ b/lib/models/nutrition/nutritional_plan.dart @@ -38,7 +38,7 @@ class NutritionalPlan { @JsonKey(required: true) late String description; - @JsonKey(required: true, name: 'creation_date', toJson: dateToYYYYMMDD) + @JsonKey(required: true, name: 'creation_date', toJson: dateToUtcIso8601) late DateTime creationDate; @JsonKey(required: true, name: 'only_logging') diff --git a/lib/models/nutrition/nutritional_plan.g.dart b/lib/models/nutrition/nutritional_plan.g.dart index cabc3f30..731befbf 100644 --- a/lib/models/nutrition/nutritional_plan.g.dart +++ b/lib/models/nutrition/nutritional_plan.g.dart @@ -37,7 +37,7 @@ NutritionalPlan _$NutritionalPlanFromJson(Map json) { Map _$NutritionalPlanToJson(NutritionalPlan instance) => { 'id': instance.id, 'description': instance.description, - 'creation_date': dateToYYYYMMDD(instance.creationDate), + 'creation_date': dateToUtcIso8601(instance.creationDate), 'only_logging': instance.onlyLogging, 'goal_energy': instance.goalEnergy, 'goal_protein': instance.goalProtein, diff --git a/lib/models/workouts/log.dart b/lib/models/workouts/log.dart index 49a04923..3931d321 100644 --- a/lib/models/workouts/log.dart +++ b/lib/models/workouts/log.dart @@ -80,7 +80,7 @@ class Log { @JsonKey(includeFromJson: false, includeToJson: false) late WeightUnit? weightUnitObj; - @JsonKey(required: true, toJson: dateToYYYYMMDD) + @JsonKey(required: true, toJson: dateToUtcIso8601) late DateTime date; Log({ diff --git a/lib/models/workouts/log.g.dart b/lib/models/workouts/log.g.dart index 397df1b5..ec4b667c 100644 --- a/lib/models/workouts/log.g.dart +++ b/lib/models/workouts/log.g.dart @@ -58,5 +58,5 @@ Map _$LogToJson(Log instance) => { 'weight': numToString(instance.weight), 'weight_target': numToString(instance.weightTarget), 'weight_unit': instance.weightUnitId, - 'date': dateToYYYYMMDD(instance.date), + 'date': dateToUtcIso8601(instance.date), }; diff --git a/lib/models/workouts/routine.dart b/lib/models/workouts/routine.dart index d0f55dbb..bd90d6bb 100644 --- a/lib/models/workouts/routine.dart +++ b/lib/models/workouts/routine.dart @@ -17,8 +17,8 @@ */ import 'package:json_annotation/json_annotation.dart'; +import 'package:wger/helpers/date.dart'; import 'package:wger/helpers/json.dart'; -import 'package:wger/helpers/misc.dart'; import 'package:wger/models/workouts/day.dart'; import 'package:wger/models/workouts/day_data.dart'; import 'package:wger/models/workouts/log.dart'; @@ -42,7 +42,7 @@ class Routine { @JsonKey(required: true, includeToJson: false) int? id; - @JsonKey(required: true) + @JsonKey(required: true, toJson: dateToUtcIso8601) late DateTime created; @JsonKey(required: true, name: 'name') diff --git a/lib/models/workouts/routine.g.dart b/lib/models/workouts/routine.g.dart index fea9912f..44649f04 100644 --- a/lib/models/workouts/routine.g.dart +++ b/lib/models/workouts/routine.g.dart @@ -31,7 +31,7 @@ Routine _$RoutineFromJson(Map json) { } Map _$RoutineToJson(Routine instance) => { - 'created': instance.created.toIso8601String(), + 'created': dateToUtcIso8601(instance.created), 'name': instance.name, 'description': instance.description, 'fit_in_week': instance.fitInWeek, diff --git a/lib/providers/nutrition.dart b/lib/providers/nutrition.dart index b8089f9e..384890c9 100644 --- a/lib/providers/nutrition.dart +++ b/lib/providers/nutrition.dart @@ -421,7 +421,7 @@ class NutritionPlansProvider with ChangeNotifier { ]) async { final plan = findById(planId); mealItem.ingredient = await fetchIngredient(mealItem.ingredientId); - final Log log = Log.fromMealItem(mealItem, plan.id!, null, dateTime); + final log = Log.fromMealItem(mealItem, plan.id!, null, dateTime); final data = await baseProvider.post( log.toJson(), diff --git a/lib/screens/log_meal_screen.dart b/lib/screens/log_meal_screen.dart index 23354206..0f2566d2 100644 --- a/lib/screens/log_meal_screen.dart +++ b/lib/screens/log_meal_screen.dart @@ -18,6 +18,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:wger/helpers/date.dart'; import 'package:wger/helpers/json.dart'; import 'package:wger/l10n/generated/app_localizations.dart'; import 'package:wger/models/nutrition/meal.dart'; @@ -70,8 +71,10 @@ class _LogMealScreenState extends State { .toList(), ); + final i18n = AppLocalizations.of(context); + return Scaffold( - appBar: AppBar(title: Text(AppLocalizations.of(context).logMeal)), + appBar: AppBar(title: Text(i18n.logMeal)), body: Consumer( builder: (context, nutritionProvider, child) => SingleChildScrollView( child: Padding( @@ -83,7 +86,7 @@ class _LogMealScreenState extends State { style: Theme.of(context).textTheme.headlineSmall, ), if (meal.mealItems.isEmpty) - ListTile(title: Text(AppLocalizations.of(context).noIngredientsDefined)) + ListTile(title: Text(i18n.noIngredientsDefined)) else Column( children: [ @@ -113,7 +116,7 @@ class _LogMealScreenState extends State { child: TextFormField( key: const ValueKey('field-date'), readOnly: true, - decoration: InputDecoration(labelText: AppLocalizations.of(context).date), + decoration: InputDecoration(labelText: i18n.date), enableInteractiveSelection: false, controller: _dateController, onTap: () async { @@ -138,7 +141,7 @@ class _LogMealScreenState extends State { child: TextFormField( key: const ValueKey('field-time'), readOnly: true, - decoration: InputDecoration(labelText: AppLocalizations.of(context).time), + decoration: InputDecoration(labelText: i18n.time), controller: _timeController, onTap: () async { // Open time picker @@ -165,28 +168,32 @@ class _LogMealScreenState extends State { children: [ if (meal.mealItems.isNotEmpty) TextButton( - child: const Text('Log'), + child: Text(i18n.save), onPressed: () async { + final loggedTime = getDateTimeFromDateAndTime( + _dateController.text, + _timeController.text, + ); + await Provider.of( context, listen: false, - ).logMealToDiary( - meal, - DateTime.parse('${_dateController.text} ${_timeController.text}'), - ); - // ignore: use_build_context_synchronously - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text( - // ignore: use_build_context_synchronously - AppLocalizations.of(context).mealLogged, - textAlign: TextAlign.center, + ).logMealToDiary(meal, loggedTime); + + if (context.mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + i18n.mealLogged, + textAlign: TextAlign.center, + ), ), - ), - ); - Navigator.of(context).pop(); - if (args.popTwice) { + ); + Navigator.of(context).pop(); + if (args.popTwice) { + Navigator.of(context).pop(); + } } }, ), diff --git a/lib/screens/nutritional_plan_screen.dart b/lib/screens/nutritional_plan_screen.dart index c974b06d..1f8e2062 100644 --- a/lib/screens/nutritional_plan_screen.dart +++ b/lib/screens/nutritional_plan_screen.dart @@ -60,7 +60,7 @@ class NutritionalPlanScreen extends StatelessWidget { FormScreen.routeName, arguments: FormScreenArguments( AppLocalizations.of(context).logIngredient, - IngredientLogForm(nutritionalPlan), + getIngredientLogForm(nutritionalPlan), hasListView: true, ), ); diff --git a/lib/widgets/dashboard/calendar.dart b/lib/widgets/dashboard/calendar.dart index 2019aa64..ba8ac41c 100644 --- a/lib/widgets/dashboard/calendar.dart +++ b/lib/widgets/dashboard/calendar.dart @@ -20,8 +20,8 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:table_calendar/table_calendar.dart'; import 'package:wger/helpers/consts.dart'; +import 'package:wger/helpers/date.dart'; import 'package:wger/helpers/json.dart'; -import 'package:wger/helpers/misc.dart'; import 'package:wger/l10n/generated/app_localizations.dart'; import 'package:wger/providers/body_weight.dart'; import 'package:wger/providers/measurement.dart'; diff --git a/lib/widgets/dashboard/widgets/nutrition.dart b/lib/widgets/dashboard/widgets/nutrition.dart index ceb4d8bf..4f7c0281 100644 --- a/lib/widgets/dashboard/widgets/nutrition.dart +++ b/lib/widgets/dashboard/widgets/nutrition.dart @@ -108,7 +108,7 @@ class _DashboardNutritionWidgetState extends State { FormScreen.routeName, arguments: FormScreenArguments( AppLocalizations.of(context).logIngredient, - IngredientLogForm(_plan!), + getIngredientLogForm(_plan!), hasListView: true, ), ); diff --git a/lib/widgets/dashboard/widgets/routines.dart b/lib/widgets/dashboard/widgets/routines.dart index dd34773c..ae4c06e2 100644 --- a/lib/widgets/dashboard/widgets/routines.dart +++ b/lib/widgets/dashboard/widgets/routines.dart @@ -19,7 +19,7 @@ import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; -import 'package:wger/helpers/misc.dart'; +import 'package:wger/helpers/date.dart'; import 'package:wger/l10n/generated/app_localizations.dart'; import 'package:wger/models/workouts/day_data.dart'; import 'package:wger/models/workouts/routine.dart'; diff --git a/lib/widgets/nutrition/forms.dart b/lib/widgets/nutrition/forms.dart index ad5b7aa4..00298b29 100644 --- a/lib/widgets/nutrition/forms.dart +++ b/lib/widgets/nutrition/forms.dart @@ -19,6 +19,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:wger/helpers/consts.dart'; +import 'package:wger/helpers/date.dart'; import 'package:wger/helpers/json.dart'; import 'package:wger/l10n/generated/app_localizations.dart'; import 'package:wger/models/nutrition/ingredient.dart'; @@ -113,7 +114,7 @@ class MealForm extends StatelessWidget { } } -Widget MealItemForm( +Widget getMealItemForm( Meal meal, List recent, [ String? barcode, @@ -132,7 +133,7 @@ Widget MealItemForm( ); } -Widget IngredientLogForm(NutritionalPlan plan) { +Widget getIngredientLogForm(NutritionalPlan plan) { return IngredientForm( recent: plan.dedupDiaryEntries, onSave: (BuildContext context, MealItem mealItem, DateTime? dt) { @@ -394,16 +395,11 @@ class IngredientFormState extends State { _form.currentState!.save(); _mealItem.ingredientId = int.parse(_ingredientIdController.text); - var date = DateTime.parse(_dateController.text); - final tod = stringToTime(_timeController.text); - date = DateTime( - date.year, - date.month, - date.day, - tod.hour, - tod.minute, + final loggedDate = getDateTimeFromDateAndTime( + _dateController.text, + _timeController.text, ); - widget.onSave(context, _mealItem, date); + widget.onSave(context, _mealItem, loggedDate); Navigator.of(context).pop(); }, diff --git a/lib/widgets/nutrition/meal.dart b/lib/widgets/nutrition/meal.dart index 00296109..3aebb160 100644 --- a/lib/widgets/nutrition/meal.dart +++ b/lib/widgets/nutrition/meal.dart @@ -116,7 +116,7 @@ class _MealWidgetState extends State { FormScreen.routeName, arguments: FormScreenArguments( AppLocalizations.of(context).addIngredient, - MealItemForm(widget._meal, widget._recentMealItems), + getMealItemForm(widget._meal, widget._recentMealItems), hasListView: true, ), ); diff --git a/lib/widgets/routines/day.dart b/lib/widgets/routines/day.dart index 5c544708..46bc5e3c 100644 --- a/lib/widgets/routines/day.dart +++ b/lib/widgets/routines/day.dart @@ -17,7 +17,7 @@ */ import 'package:flutter/material.dart'; -import 'package:wger/helpers/misc.dart'; +import 'package:wger/helpers/date.dart'; import 'package:wger/l10n/generated/app_localizations.dart'; import 'package:wger/models/exercises/exercise.dart'; import 'package:wger/models/workouts/day_data.dart'; diff --git a/lib/widgets/routines/gym_mode/log_page.dart b/lib/widgets/routines/gym_mode/log_page.dart index 17ace6e7..48b486aa 100644 --- a/lib/widgets/routines/gym_mode/log_page.dart +++ b/lib/widgets/routines/gym_mode/log_page.dart @@ -298,15 +298,18 @@ class _LogPageState extends State { context, listen: false, ).addLog(widget._log); - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - duration: const Duration(seconds: 2), // default is 4 - content: Text( - AppLocalizations.of(context).successfullySaved, - textAlign: TextAlign.center, + + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + duration: const Duration(seconds: 2), // default is 4 + content: Text( + AppLocalizations.of(context).successfullySaved, + textAlign: TextAlign.center, + ), ), - ), - ); + ); + } widget._controller.nextPage( duration: DEFAULT_ANIMATION_DURATION, curve: DEFAULT_ANIMATION_CURVE, diff --git a/lib/widgets/routines/gym_mode/session_page.dart b/lib/widgets/routines/gym_mode/session_page.dart index ce9c0f90..0a22a8e6 100644 --- a/lib/widgets/routines/gym_mode/session_page.dart +++ b/lib/widgets/routines/gym_mode/session_page.dart @@ -18,7 +18,7 @@ import 'package:clock/clock.dart'; import 'package:flutter/material.dart'; import 'package:wger/helpers/consts.dart'; -import 'package:wger/helpers/misc.dart'; +import 'package:wger/helpers/date.dart'; import 'package:wger/l10n/generated/app_localizations.dart'; import 'package:wger/models/exercises/exercise.dart'; import 'package:wger/models/workouts/routine.dart'; diff --git a/lib/widgets/routines/log.dart b/lib/widgets/routines/log.dart index 3028341f..25ce8d24 100644 --- a/lib/widgets/routines/log.dart +++ b/lib/widgets/routines/log.dart @@ -19,6 +19,7 @@ import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:wger/helpers/colors.dart'; +import 'package:wger/helpers/date.dart'; import 'package:wger/helpers/errors.dart'; import 'package:wger/helpers/misc.dart'; import 'package:wger/l10n/generated/app_localizations.dart'; diff --git a/test/exercises/exercise_provider_db_test.dart b/test/exercises/exercise_provider_db_test.dart index 5723bab2..1b092bf8 100644 --- a/test/exercises/exercise_provider_db_test.dart +++ b/test/exercises/exercise_provider_db_test.dart @@ -8,7 +8,7 @@ import 'package:shared_preferences_platform_interface/in_memory_shared_preferenc import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart'; import 'package:wger/database/exercises/exercise_database.dart'; import 'package:wger/helpers/consts.dart'; -import 'package:wger/helpers/misc.dart'; +import 'package:wger/helpers/date.dart'; import 'package:wger/helpers/shared_preferences.dart'; import 'package:wger/models/exercises/exercise_api.dart'; import 'package:wger/models/exercises/muscle.dart'; diff --git a/test/helpers/colors_test.dart b/test/helpers/colors_test.dart index da451a78..6dc2e6c7 100644 --- a/test/helpers/colors_test.dart +++ b/test/helpers/colors_test.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:wger/helpers/colors.dart'; diff --git a/test/other/extensions_test.dart b/test/helpers/date_test.dart similarity index 60% rename from test/other/extensions_test.dart rename to test/helpers/date_test.dart index c3140fca..49eed706 100644 --- a/test/other/extensions_test.dart +++ b/test/helpers/date_test.dart @@ -1,6 +1,6 @@ /* * This file is part of wger Workout Manager . - * Copyright (C) 2020, 2021 wger Team + * Copyright (C) wger Team * * wger Workout Manager is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by @@ -16,21 +16,16 @@ * along with this program. If not, see . */ -import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:wger/helpers/misc.dart'; +import 'package:wger/helpers/date.dart'; void main() { - test('Test the TimeOfDayExtension', () { - const time1 = TimeOfDay(hour: 00, minute: 00); - const time2 = TimeOfDay(hour: 23, minute: 59); - - expect(time2.toMinutes(), 23 * 60 + 59); - expect(time1.isAfter(time2), false); - expect(time1.isBefore(time2), true); - expect(time2.isAfter(time1), true); - expect(time2.isBefore(time1), false); - expect(time1.isAfter(time1), false); - expect(time2.isBefore(time2), false); + group('getDateTimeFromDateAndTime', () { + test('should correctly generate a DateTime', () { + expect( + getDateTimeFromDateAndTime('2025-05-16', '17:02'), + DateTime(2025, 5, 16, 17, 2), + ); + }); }); } diff --git a/test/helpers/json_test.dart b/test/helpers/json_test.dart index c0ac1d8c..098d8e67 100644 --- a/test/helpers/json_test.dart +++ b/test/helpers/json_test.dart @@ -1,3 +1,21 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (C) wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wger Workout Manager is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:wger/helpers/json.dart'; @@ -39,6 +57,15 @@ void main() { }); }); + group('dateToIsoWithTimezone', () { + test('should format DateTime to a string with timezone', () { + expect( + dateToUtcIso8601(DateTime.parse('2025-05-16T18:15:00+02:00')), + '2025-05-16T16:15:00.000Z', + ); + }); + }); + group('stringToTime', () { test('should default to 00:00 for null input', () { expect(stringToTime(null), const TimeOfDay(hour: 0, minute: 0)); diff --git a/test/nutrition/nutritional_meal_item_form_test.dart b/test/nutrition/nutritional_meal_item_form_test.dart index 1dbd28b0..017d9a17 100644 --- a/test/nutrition/nutritional_meal_item_form_test.dart +++ b/test/nutrition/nutritional_meal_item_form_test.dart @@ -101,7 +101,7 @@ void main() { home: Scaffold( body: Scrollable( viewportBuilder: (BuildContext context, ViewportOffset position) => - MealItemForm(meal, const [], code, test), + getMealItemForm(meal, const [], code, test), ), ), routes: { From ab2480d4831a4946ae205ba555756f583fd658fe Mon Sep 17 00:00:00 2001 From: shravya Date: Mon, 9 Jun 2025 18:43:40 +0530 Subject: [PATCH 02/89] timer code is now updated and uses a better approach --- lib/widgets/routines/gym_mode/timer.dart | 89 +++++++++++------------- 1 file changed, 39 insertions(+), 50 deletions(-) diff --git a/lib/widgets/routines/gym_mode/timer.dart b/lib/widgets/routines/gym_mode/timer.dart index a60ab884..7c374451 100644 --- a/lib/widgets/routines/gym_mode/timer.dart +++ b/lib/widgets/routines/gym_mode/timer.dart @@ -40,42 +40,33 @@ class TimerWidget extends StatefulWidget { } class _TimerWidgetState extends State { - // See https://stackoverflow.com/questions/54610121/flutter-countdown-timer - - Timer? _timer; - int _seconds = 1; + late DateTime _startTime; final _maxSeconds = 600; - DateTime today = DateTime(2000, 1, 1, 0, 0, 0); + late Timer _uiTimer; - void startTimer() { - setState(() => _seconds = 0); + @override + void initState() { + super.initState(); + _startTime = DateTime.now(); - _timer?.cancel(); - - const oneSecond = Duration(seconds: 1); - _timer = Timer.periodic(oneSecond, (Timer timer) { - if (_seconds == _maxSeconds) { - setState(() => timer.cancel()); - } else { - setState(() => _seconds++); - } + _uiTimer = Timer.periodic(Duration(seconds: 1), (_) { + if (mounted) setState(() {}); }); } @override void dispose() { - _timer?.cancel(); + _uiTimer.cancel(); super.dispose(); } - @override - void initState() { - super.initState(); - startTimer(); - } - @override Widget build(BuildContext context) { + final elapsed = DateTime.now().difference(_startTime).inSeconds; + final displaySeconds = elapsed > _maxSeconds ? _maxSeconds : elapsed; + final displayTime = DateTime(2000, 1, 1, 0, 0, 0) + .add(Duration(seconds: displaySeconds)); + return Column( children: [ NavigationHeader( @@ -86,8 +77,11 @@ class _TimerWidgetState extends State { Expanded( child: Center( child: Text( - DateFormat('m:ss').format(today.add(Duration(seconds: _seconds))), - style: Theme.of(context).textTheme.displayLarge!.copyWith(color: wgerPrimaryColor), + DateFormat('m:ss').format(displayTime), + style: Theme.of(context) + .textTheme + .displayLarge! + .copyWith(color: wgerPrimaryColor), ), ), ), @@ -115,40 +109,32 @@ class TimerCountdownWidget extends StatefulWidget { } class _TimerCountdownWidgetState extends State { - // See https://stackoverflow.com/questions/54610121/flutter-countdown-timer + late DateTime _endTime; + late Timer _uiTimer; - Timer? _timer; - late int _seconds; - DateTime today = DateTime(2000, 1, 1, 0, 0, 0); + @override + void initState() { + super.initState(); + _endTime = DateTime.now().add(Duration(seconds: widget._seconds)); - void startTimer() { - _timer?.cancel(); - - const oneSecond = Duration(seconds: 1); - _timer = Timer.periodic(oneSecond, (Timer timer) { - if (_seconds == 0) { - setState(() => timer.cancel()); - } else { - setState(() => _seconds--); - } + _uiTimer = Timer.periodic(Duration(seconds: 1), (_) { + if (mounted) setState(() {}); }); } @override void dispose() { - _timer?.cancel(); + _uiTimer.cancel(); super.dispose(); } - @override - void initState() { - super.initState(); - _seconds = widget._seconds; - startTimer(); - } - @override Widget build(BuildContext context) { + final remaining = _endTime.difference(DateTime.now()); + final remainingSeconds = remaining.inSeconds <= 0 ? 0 : remaining.inSeconds; + final displayTime = DateTime(2000, 1, 1, 0, 0, 0) + .add(Duration(seconds: remainingSeconds)); + return Column( children: [ NavigationHeader( @@ -159,8 +145,11 @@ class _TimerCountdownWidgetState extends State { Expanded( child: Center( child: Text( - DateFormat('m:ss').format(today.add(Duration(seconds: _seconds))), - style: Theme.of(context).textTheme.displayLarge!.copyWith(color: wgerPrimaryColor), + DateFormat('m:ss').format(displayTime), + style: Theme.of(context) + .textTheme + .displayLarge! + .copyWith(color: wgerPrimaryColor), ), ), ), @@ -168,4 +157,4 @@ class _TimerCountdownWidgetState extends State { ], ); } -} +} \ No newline at end of file From ed46fd6cf0ad232fbba5a5e0d42b9b2d53a82eb4 Mon Sep 17 00:00:00 2001 From: Dieter Plaetinck Date: Sat, 28 Jun 2025 00:04:11 +0200 Subject: [PATCH 03/89] add dart formatter (for 3.7 and up), cleanup dcm formatter --- analysis_options.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index 15127111..68c186a1 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -19,6 +19,9 @@ analyzer: # Please see https://github.com/flutter/flutter/pull/24528 for details. sdk_version_async_exported_from_core: ignore +formatter: + page_width: 100 + linter: rules: # These rules are documented on and in the same order as @@ -165,8 +168,6 @@ dart_code_metrics: - avoid-passing-self-as-argument: false # fairly harmless. and e.g. drift calls are like this - avoid-passing-async-when-sync-expected: false # we really like to do this in onTap() etc, and it seems harmless - prefer-match-file-name: false # dieter wants to enable this. but requires a lot of renames. what does roland think? - formatter: indent: 0 - line-length: 100 cascading-widget-extensions: false From f9e0ba5d179dfbb1cf3d8bd046161c51c6afbb0d Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Fri, 27 Jun 2025 16:05:34 +0200 Subject: [PATCH 04/89] Replace missing TextInputType --- lib/widgets/routines/gym_mode/log_page.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/widgets/routines/gym_mode/log_page.dart b/lib/widgets/routines/gym_mode/log_page.dart index 10fff593..f6d3763c 100644 --- a/lib/widgets/routines/gym_mode/log_page.dart +++ b/lib/widgets/routines/gym_mode/log_page.dart @@ -185,7 +185,7 @@ class _LogPageState extends ConsumerState { labelText: AppLocalizations.of(context).weight, ), controller: _weightController, - keyboardType: TextInputType.number, + keyboardType: textInputTypeDecimal, onFieldSubmitted: (_) { // Placeholder for potential future logic }, From 8248f25865308f4672ef2337067b95fa3faf5b6d Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Fri, 27 Jun 2025 16:15:58 +0200 Subject: [PATCH 05/89] Refactor log_page.dart The different help functions are now proper widgets, which allows flutter to optimize them better. --- lib/widgets/routines/gym_mode/log_page.dart | 612 ++++++++++++-------- 1 file changed, 359 insertions(+), 253 deletions(-) diff --git a/lib/widgets/routines/gym_mode/log_page.dart b/lib/widgets/routines/gym_mode/log_page.dart index f6d3763c..7a6c38bd 100644 --- a/lib/widgets/routines/gym_mode/log_page.dart +++ b/lib/widgets/routines/gym_mode/log_page.dart @@ -18,6 +18,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:intl/intl.dart'; +import 'package:logging/logging.dart'; import 'package:provider/provider.dart' as provider; import 'package:wger/exceptions/http_exception.dart'; import 'package:wger/helpers/consts.dart'; @@ -77,16 +78,20 @@ class _LogPageState extends ConsumerState { @override void initState() { super.initState(); - focusNode = FocusNode(); - if (widget._configData.repetitions != null) { - _repetitionsController.text = widget._configData.repetitions!.toString(); - } + WidgetsBinding.instance.addPostFrameCallback((_) { + final locale = Localizations.localeOf(context).toString(); + final numberFormat = NumberFormat.decimalPattern(locale); - if (widget._configData.weight != null) { - _weightController.text = widget._configData.weight!.toString(); - } + if (widget._configData.repetitions != null) { + _repetitionsController.text = numberFormat.format(widget._configData.repetitions); + } + + if (widget._configData.weight != null) { + _weightController.text = numberFormat.format(widget._configData.weight); + } + }); } @override @@ -97,144 +102,6 @@ class _LogPageState extends ConsumerState { super.dispose(); } - Widget getRepsWidget() { - final repsValueChange = widget._configData.repetitionsRounding ?? 1; - final numberFormat = NumberFormat.decimalPattern(Localizations.localeOf(context).toString()); - - return Row( - children: [ - IconButton( - icon: const Icon(Icons.remove, color: Colors.black), - onPressed: () { - try { - final num newValue = - numberFormat.parse(_repetitionsController.text) - repsValueChange; - if (newValue > 0) { - _repetitionsController.text = newValue.toString(); - } - } on FormatException {} - }, - ), - Expanded( - child: TextFormField( - decoration: InputDecoration( - labelText: AppLocalizations.of(context).repetitions, - ), - enabled: true, - controller: _repetitionsController, - keyboardType: textInputTypeDecimal, - focusNode: focusNode, - onFieldSubmitted: (_) { - // Placeholder for potential future logic - }, - onSaved: (newValue) { - widget._log.repetitions = numberFormat.parse(newValue!); - focusNode.unfocus(); - }, - validator: (value) { - if (numberFormat.tryParse(value ?? '') == null) { - return AppLocalizations.of(context).enterValidNumber; - } - return null; - }, - ), - ), - IconButton( - icon: const Icon(Icons.add, color: Colors.black), - onPressed: () { - try { - final num newValue = - numberFormat.parse(_repetitionsController.text) + repsValueChange; - _repetitionsController.text = newValue.toString(); - } on FormatException {} - }, - ), - ], - ); - } - - Widget getWeightWidget() { - final weightValueChange = widget._configData.weightRounding ?? 1.25; - final numberFormat = NumberFormat.decimalPattern(Localizations.localeOf(context).toString()); - - return Row( - children: [ - IconButton( - icon: const Icon(Icons.remove, color: Colors.black), - onPressed: () { - try { - final num newValue = - numberFormat.parse(_weightController.text) - (2 * weightValueChange); - if (newValue > 0) { - setState(() { - widget._log.weight = newValue; - _weightController.text = newValue.toString(); - ref.read(plateCalculatorProvider.notifier).setWeight( - _weightController.text == '' - ? 0 - : numberFormat.parse(_weightController.text), - ); - }); - } - } on FormatException {} - }, - ), - Expanded( - child: TextFormField( - decoration: InputDecoration( - labelText: AppLocalizations.of(context).weight, - ), - controller: _weightController, - keyboardType: textInputTypeDecimal, - onFieldSubmitted: (_) { - // Placeholder for potential future logic - }, - onChanged: (value) { - try { - numberFormat.parse(value); - setState(() { - widget._log.weight = numberFormat.parse(value); - ref.read(plateCalculatorProvider.notifier).setWeight( - _weightController.text == '' - ? 0 - : numberFormat.parse(_weightController.text), - ); - }); - } on FormatException {} - }, - onSaved: (newValue) { - setState(() { - widget._log.weight = numberFormat.parse(newValue!); - }); - }, - validator: (value) { - if (numberFormat.tryParse(value ?? '') == null) { - return AppLocalizations.of(context).enterValidNumber; - } - return null; - }, - ), - ), - IconButton( - icon: const Icon(Icons.add, color: Colors.black), - onPressed: () { - try { - final num newValue = - numberFormat.parse(_weightController.text) + (2 * weightValueChange); - setState(() { - widget._log.weight = newValue; - _weightController.text = newValue.toString(); - ref.read(plateCalculatorProvider.notifier).setWeight( - _weightController.text == '' ? 0 : numberFormat.parse(_weightController.text), - ); - }); - } on FormatException {} - }, - ), - ], - ); - } - Widget getForm() { return Form( key: _form, @@ -249,16 +116,46 @@ class _LogPageState extends ConsumerState { if (!_detailed) Row( children: [ - Flexible(child: getRepsWidget()), + Flexible( + child: LogsRepsWidget( + controller: _repetitionsController, + configData: widget._configData, + focusNode: focusNode, + log: widget._log, + setStateCallback: (fn) { + setState(fn); + }, + ), + ), const SizedBox(width: 8), - Flexible(child: getWeightWidget()), + Flexible( + child: LogsWeightWidget( + controller: _weightController, + configData: widget._configData, + focusNode: focusNode, + log: widget._log, + setStateCallback: (fn) { + setState(fn); + }, + ), + ), ], ), if (_detailed) Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ - Flexible(child: getRepsWidget()), + Flexible( + child: LogsRepsWidget( + controller: _repetitionsController, + configData: widget._configData, + focusNode: focusNode, + log: widget._log, + setStateCallback: (fn) { + setState(fn); + }, + ), + ), const SizedBox(width: 8), Flexible( child: RepetitionUnitInputWidget( @@ -273,7 +170,17 @@ class _LogPageState extends ConsumerState { Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ - Flexible(child: getWeightWidget()), + Flexible( + child: LogsWeightWidget( + controller: _weightController, + configData: widget._configData, + focusNode: focusNode, + log: widget._log, + setStateCallback: (fn) { + setState(fn); + }, + ), + ), const SizedBox(width: 8), Flexible( child: WeightUnitInputWidget(widget._log.weightUnitId, onChanged: (v) => {}), @@ -348,80 +255,78 @@ class _LogPageState extends ConsumerState { ); } - Widget getPastLogs() { - return Container( - padding: const EdgeInsets.symmetric(vertical: 8), - decoration: BoxDecoration( - // color: Theme.of(context).secondaryHeaderColor, - // color: Theme.of(context).splashColor, - // color: Theme.of(context).colorScheme.onInverseSurface, - // border: Border.all(color: Colors.black, width: 1), + @override + Widget build(BuildContext context) { + return Column( + children: [ + NavigationHeader( + widget._exercise.getTranslation(Localizations.localeOf(context).languageCode).name, + widget._controller, + exercisePages: widget._exercisePages, + ), + + Container( + color: Theme.of(context).colorScheme.onInverseSurface, + padding: const EdgeInsets.symmetric(vertical: 10), + child: Center( + child: Text( + widget._configData.textRepr, + style: Theme.of(context) + .textTheme + .headlineMedium + ?.copyWith(color: Theme.of(context).colorScheme.primary), + textAlign: TextAlign.center, + ), ), - child: ListView( - children: [ - Text( - AppLocalizations.of(context).labelWorkoutLogs, - style: Theme.of(context).textTheme.titleMedium, - textAlign: TextAlign.center, + ), + if (widget._slotData.comment.isNotEmpty) + Text(widget._slotData.comment, textAlign: TextAlign.center), + // Only show calculator for barbell + if (widget._log.exercise.equipment.map((e) => e.id).contains(ID_EQUIPMENT_BARBELL)) + const LogsPlatesWidget(), + const SizedBox(height: 10), + Expanded( + child: (widget._workoutPlan.filterLogsByExercise(widget._exercise.id!).isNotEmpty) + ? LogsPastLogsWidget( + weightController: _weightController, + repetitionsController: _repetitionsController, + log: widget._log, + pastLogs: widget._workoutPlan.filterLogsByExercise(widget._exercise.id!), + setStateCallback: (fn) { + setState(fn); + }, + ) + : Container(), + ), + + Padding( + padding: const EdgeInsets.all(10), + child: Card( + color: Theme.of(context).colorScheme.inversePrimary, + // color: Theme.of(context).secondaryHeaderColor, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 5), + child: getForm(), + ), ), - ...widget._workoutPlan - .filterLogsByExercise(widget._exercise.id!, unique: true) - .map((log) { - return ListTile( - title: Text(log.singleLogRepTextNoNl), - subtitle: Text( - DateFormat.yMd(Localizations.localeOf(context).languageCode).format(log.date), - ), - trailing: const Icon(Icons.copy), - onTap: () { - setState(() { - // Text field - _repetitionsController.text = log.repetitions?.toString() ?? ''; - _weightController.text = log.weight?.toString() ?? ''; - - // Drop downs - - widget._log.rir = log.rir; - widget._log.repetitionUnit = log.repetitionsUnitObj; - widget._log.weightUnit = log.weightUnitObj; - - ScaffoldMessenger.of(context).hideCurrentSnackBar(); - ScaffoldMessenger.of(context).showSnackBar(SnackBar( - content: Text(AppLocalizations.of(context).dataCopied), - )); - }); - }, - contentPadding: const EdgeInsets.symmetric(horizontal: 40), - ); - }), - ], - ), + ), + NavigationFooter(widget._controller, widget._ratioCompleted), + ], ); } +} - Widget getPlates() { +class LogsPlatesWidget extends ConsumerWidget { + const LogsPlatesWidget({super.key}); + + @override + Widget build(BuildContext context, WidgetRef ref) { final plateWeightsState = ref.watch(plateCalculatorProvider); return Container( color: Theme.of(context).colorScheme.onInverseSurface, child: Column( children: [ - // Row( - // mainAxisAlignment: MainAxisAlignment.center, - // children: [ - // Text( - // AppLocalizations.of(context).plateCalculator, - // style: Theme.of(context).textTheme.titleMedium, - // ), - // IconButton( - // onPressed: () { - // Navigator.of(context) - // .push(MaterialPageRoute(builder: (context) => const AddPlateWeights())); - // }, - // icon: const Icon(Icons.settings, size: 16), - // ), - // ], - // ), GestureDetector( onTap: () { Navigator.of(context).pushNamed(ConfigurePlatesScreen.routeName); @@ -463,56 +368,257 @@ class _LogPageState extends ConsumerState { ), ); } +} + +class LogsRepsWidget extends StatelessWidget { + final TextEditingController controller; + final SetConfigData configData; + final FocusNode focusNode; + final Log log; + final void Function(VoidCallback fn) setStateCallback; + + final _logger = Logger('LogsRepsWidget'); + + LogsRepsWidget({ + super.key, + required this.controller, + required this.configData, + required this.focusNode, + required this.log, + required this.setStateCallback, + }); @override Widget build(BuildContext context) { - return Column( + final repsValueChange = configData.repetitionsRounding ?? 1; + final numberFormat = NumberFormat.decimalPattern(Localizations.localeOf(context).toString()); + + final i18n = AppLocalizations.of(context); + + return Row( children: [ - NavigationHeader( - widget._exercise.getTranslation(Localizations.localeOf(context).languageCode).name, - widget._controller, - exercisePages: widget._exercisePages, + IconButton( + icon: const Icon(Icons.remove, color: Colors.black), + onPressed: () { + final currentValue = numberFormat.tryParse(controller.text) ?? 0; + final newValue = currentValue - repsValueChange; + if (newValue >= 0) { + setStateCallback(() { + log.repetitions = newValue; + controller.text = numberFormat.format(newValue); + }); + } + }, ), - - Container( - color: Theme.of(context).colorScheme.onInverseSurface, - padding: const EdgeInsets.symmetric(vertical: 10), - child: Center( - child: Text( - widget._configData.textRepr, - style: Theme.of(context) - .textTheme - .headlineMedium - ?.copyWith(color: Theme.of(context).colorScheme.primary), - textAlign: TextAlign.center, - ), - ), - ), - if (widget._slotData.comment.isNotEmpty) - Text(widget._slotData.comment, textAlign: TextAlign.center), - // Only show calculator for barbell - if (widget._log.exercise.equipment.map((e) => e.id).contains(ID_EQUIPMENT_BARBELL)) - getPlates(), - const SizedBox(height: 10), Expanded( - child: (widget._workoutPlan.filterLogsByExercise(widget._exercise.id!).isNotEmpty) - ? getPastLogs() - : Container(), - ), - - Padding( - padding: const EdgeInsets.all(10), - child: Card( - color: Theme.of(context).colorScheme.inversePrimary, - // color: Theme.of(context).secondaryHeaderColor, - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 5), - child: getForm(), - ), + child: TextFormField( + decoration: InputDecoration(labelText: i18n.repetitions), + enabled: true, + controller: controller, + keyboardType: textInputTypeDecimal, + focusNode: focusNode, + onChanged: (value) { + try { + final newValue = numberFormat.parse(value); + setStateCallback(() { + log.repetitions = newValue; + }); + } on FormatException catch (error) { + _logger.fine('Error parsing repetitions: $error'); + } + }, + onSaved: (newValue) { + _logger.info('Saving new reps value: $newValue'); + setStateCallback(() { + log.repetitions = numberFormat.parse(newValue!); + // focusNode.unfocus(); + }); + }, + validator: (value) { + if (numberFormat.tryParse(value ?? '') == null) { + return i18n.enterValidNumber; + } + return null; + }, ), ), - NavigationFooter(widget._controller, widget._ratioCompleted), + IconButton( + icon: const Icon(Icons.add, color: Colors.black), + onPressed: () { + try { + final newValue = numberFormat.parse(controller.text) + repsValueChange; + setStateCallback(() { + log.repetitions = newValue; + controller.text = numberFormat.format(newValue); + }); + } on FormatException catch (error) { + _logger.fine('Error parsing reps during quick-add: $error'); + } + }, + ), ], ); } } + +class LogsWeightWidget extends ConsumerWidget { + final TextEditingController controller; + final SetConfigData configData; + final FocusNode focusNode; + final Log log; + final void Function(VoidCallback fn) setStateCallback; + + final _logger = Logger('LogsWeightWidget'); + + LogsWeightWidget({ + super.key, + required this.controller, + required this.configData, + required this.focusNode, + required this.log, + required this.setStateCallback, + }); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final weightValueChange = configData.weightRounding ?? 1.25; + final numberFormat = NumberFormat.decimalPattern(Localizations.localeOf(context).toString()); + final i18n = AppLocalizations.of(context); + + return Row( + children: [ + IconButton( + icon: const Icon(Icons.remove, color: Colors.black), + onPressed: () { + try { + final newValue = numberFormat.parse(controller.text) - weightValueChange; + if (newValue > 0) { + setStateCallback(() { + log.weight = newValue; + controller.text = numberFormat.format(newValue); + ref.read(plateCalculatorProvider.notifier).setWeight( + controller.text == '' ? 0 : newValue, + ); + }); + } + } on FormatException catch (error) { + _logger.fine('Error parsing weight during quick-remove: $error'); + } + }, + ), + Expanded( + child: TextFormField( + decoration: InputDecoration(labelText: i18n.weight), + controller: controller, + keyboardType: textInputTypeDecimal, + onChanged: (value) { + try { + final newValue = numberFormat.parse(value); + setStateCallback(() { + log.weight = newValue; + ref.read(plateCalculatorProvider.notifier).setWeight( + controller.text == '' ? 0 : numberFormat.parse(controller.text), + ); + }); + } on FormatException catch (error) { + _logger.fine('Error parsing weight: $error'); + } + }, + onSaved: (newValue) { + setStateCallback(() { + log.weight = numberFormat.parse(newValue!); + }); + }, + validator: (value) { + if (numberFormat.tryParse(value ?? '') == null) { + return i18n.enterValidNumber; + } + return null; + }, + ), + ), + IconButton( + icon: const Icon(Icons.add, color: Colors.black), + onPressed: () { + try { + final newValue = numberFormat.parse(controller.text) + weightValueChange; + setStateCallback(() { + log.weight = newValue; + controller.text = numberFormat.format(newValue); + ref.read(plateCalculatorProvider.notifier).setWeight( + controller.text == '' ? 0 : newValue, + ); + }); + } on FormatException catch (error) { + _logger.fine('Error parsing weight during quick-add: $error'); + } + }, + ), + ], + ); + } +} + +class LogsPastLogsWidget extends StatelessWidget { + final TextEditingController weightController; + final TextEditingController repetitionsController; + final Log log; + final List pastLogs; + final void Function(VoidCallback fn) setStateCallback; + + const LogsPastLogsWidget({ + super.key, + required this.weightController, + required this.repetitionsController, + required this.log, + required this.pastLogs, + required this.setStateCallback, + }); + + @override + Widget build(BuildContext context) { + final numberFormat = NumberFormat.decimalPattern(Localizations.localeOf(context).toString()); + + return Container( + padding: const EdgeInsets.symmetric(vertical: 8), + child: ListView( + children: [ + Text( + AppLocalizations.of(context).labelWorkoutLogs, + style: Theme.of(context).textTheme.titleMedium, + textAlign: TextAlign.center, + ), + ...pastLogs.map((pastLog) { + return ListTile( + title: Text(pastLog.singleLogRepTextNoNl), + subtitle: Text( + DateFormat.yMd(Localizations.localeOf(context).languageCode).format(pastLog.date), + ), + trailing: const Icon(Icons.copy), + onTap: () { + setStateCallback(() { + // Text field + repetitionsController.text = + pastLog.repetitions != null ? numberFormat.format(pastLog.repetitions) : ''; + weightController.text = + pastLog.weight != null ? numberFormat.format(pastLog.weight) : ''; + + // Drop downs + log.rir = pastLog.rir; + log.repetitionUnit = pastLog.repetitionsUnitObj; + log.weightUnit = pastLog.weightUnitObj; + + ScaffoldMessenger.of(context).hideCurrentSnackBar(); + ScaffoldMessenger.of(context).showSnackBar(SnackBar( + content: Text(AppLocalizations.of(context).dataCopied), + )); + }); + }, + contentPadding: const EdgeInsets.symmetric(horizontal: 40), + ); + }), + ], + ), + ); + } +} From e64170bfc3f98fb46808e76a55991b3a6056c77e Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Sat, 28 Jun 2025 10:02:13 +0200 Subject: [PATCH 06/89] Add link to app store --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index cb728a73..a64ef7b2 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,9 @@ height="80">](https://play.google.com/store/apps/details?id=de.wger.flutter) [Get it on F-Droid](https://f-droid.org/packages/de.wger.flutter/) +[](https://apps.apple.com/us/app/wger-workout-manager/id6502226792) ## Developing and contributing From 0df9b62f0b7e89cec6e60ddc41fd3fb89b8c276f Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Sat, 28 Jun 2025 10:12:12 +0200 Subject: [PATCH 07/89] Try using badge without padding --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a64ef7b2..4cb0c049 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ height="80">](https://play.google.com/store/apps/details?id=de.wger.flutter) [Get it on F-Droid](https://f-droid.org/packages/de.wger.flutter/) -[Download on the App Store](https://apps.apple.com/us/app/wger-workout-manager/id6502226792) From 4f45999e4ba87b0a64102fb2836bcefdfb4e4e0f Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Sat, 28 Jun 2025 10:15:45 +0200 Subject: [PATCH 08/89] Also replace the other badged for (hopefully) more consistency --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4cb0c049..6ec5c459 100644 --- a/README.md +++ b/README.md @@ -17,10 +17,10 @@ If you want to contribute, hop on the Discord server and say hi! ## Installation -[Get it on Google Play](https://play.google.com/store/apps/details?id=de.wger.flutter) -[Get it on F-Droid](https://f-droid.org/packages/de.wger.flutter/) [ Date: Sat, 28 Jun 2025 10:33:54 +0200 Subject: [PATCH 09/89] Use badges without padding for all badges and add flathub --- README.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6ec5c459..7f14390b 100644 --- a/README.md +++ b/README.md @@ -19,13 +19,16 @@ If you want to contribute, hop on the Discord server and say hi! [Get it on Google Play](https://play.google.com/store/apps/details?id=de.wger.flutter) -[](https://play.google.com/store/apps/details?id=de.wger.flutter) +[Get it on F-Droid](https://f-droid.org/packages/de.wger.flutter/) +height="55">](https://f-droid.org/packages/de.wger.flutter/) [Download on the App Store](https://apps.apple.com/us/app/wger-workout-manager/id6502226792) +height="55">](https://apps.apple.com/us/app/wger-workout-manager/id6502226792) +[](https://flathub.org/apps/de.wger.flutter) ## Developing and contributing From 837023a8389704aecda5a7687b43feaad6d043a3 Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Sat, 28 Jun 2025 10:50:53 +0200 Subject: [PATCH 10/89] Use github links to the files --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7f14390b..cf31f6d3 100644 --- a/README.md +++ b/README.md @@ -17,16 +17,16 @@ If you want to contribute, hop on the Discord server and say hi! ## Installation -[Get it on Google Play](https://play.google.com/store/apps/details?id=de.wger.flutter) -[Get it on F-Droid](https://f-droid.org/packages/de.wger.flutter/) -[Download on the App Store](https://apps.apple.com/us/app/wger-workout-manager/id6502226792) -[Get it on Flathub](https://flathub.org/apps/de.wger.flutter) From c7c47cdc495f9cfc4ef6fa1180f763de35111200 Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Sat, 28 Jun 2025 17:49:59 +0200 Subject: [PATCH 11/89] Make the linter happy --- lib/widgets/routines/gym_mode/timer.dart | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/lib/widgets/routines/gym_mode/timer.dart b/lib/widgets/routines/gym_mode/timer.dart index 7c374451..55fa8c54 100644 --- a/lib/widgets/routines/gym_mode/timer.dart +++ b/lib/widgets/routines/gym_mode/timer.dart @@ -49,7 +49,8 @@ class _TimerWidgetState extends State { super.initState(); _startTime = DateTime.now(); - _uiTimer = Timer.periodic(Duration(seconds: 1), (_) { + _uiTimer = Timer.periodic(const Duration(seconds: 1), (_) { + // ignore: no-empty-block, avoid-empty-setstate if (mounted) setState(() {}); }); } @@ -64,8 +65,7 @@ class _TimerWidgetState extends State { Widget build(BuildContext context) { final elapsed = DateTime.now().difference(_startTime).inSeconds; final displaySeconds = elapsed > _maxSeconds ? _maxSeconds : elapsed; - final displayTime = DateTime(2000, 1, 1, 0, 0, 0) - .add(Duration(seconds: displaySeconds)); + final displayTime = DateTime(2000, 1, 1, 0, 0, 0).add(Duration(seconds: displaySeconds)); return Column( children: [ @@ -78,10 +78,7 @@ class _TimerWidgetState extends State { child: Center( child: Text( DateFormat('m:ss').format(displayTime), - style: Theme.of(context) - .textTheme - .displayLarge! - .copyWith(color: wgerPrimaryColor), + style: Theme.of(context).textTheme.displayLarge!.copyWith(color: wgerPrimaryColor), ), ), ), @@ -117,7 +114,8 @@ class _TimerCountdownWidgetState extends State { super.initState(); _endTime = DateTime.now().add(Duration(seconds: widget._seconds)); - _uiTimer = Timer.periodic(Duration(seconds: 1), (_) { + _uiTimer = Timer.periodic(const Duration(seconds: 1), (_) { + // ignore: no-empty-block, avoid-empty-setstate if (mounted) setState(() {}); }); } @@ -132,8 +130,7 @@ class _TimerCountdownWidgetState extends State { Widget build(BuildContext context) { final remaining = _endTime.difference(DateTime.now()); final remainingSeconds = remaining.inSeconds <= 0 ? 0 : remaining.inSeconds; - final displayTime = DateTime(2000, 1, 1, 0, 0, 0) - .add(Duration(seconds: remainingSeconds)); + final displayTime = DateTime(2000, 1, 1, 0, 0, 0).add(Duration(seconds: remainingSeconds)); return Column( children: [ @@ -146,10 +143,7 @@ class _TimerCountdownWidgetState extends State { child: Center( child: Text( DateFormat('m:ss').format(displayTime), - style: Theme.of(context) - .textTheme - .displayLarge! - .copyWith(color: wgerPrimaryColor), + style: Theme.of(context).textTheme.displayLarge!.copyWith(color: wgerPrimaryColor), ), ), ), @@ -157,4 +151,4 @@ class _TimerCountdownWidgetState extends State { ], ); } -} \ No newline at end of file +} From bf344479589963bb9e6b89bded8ff3827314347f Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Wed, 2 Jul 2025 19:29:24 +0200 Subject: [PATCH 12/89] Remove the explicit line length, this is not needed anymore --- .github/pull_request_template.md | 2 +- .github/workflows/linter.yml.bak | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 073681dc..5d11748c 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -12,6 +12,6 @@ If applicable, please link to any related issues (`Closes #123`, - [ ] Tests for the changes have been added (for bug fixes / features) - [ ] Set a 100 character limit in your editor/IDE to avoid white space diffs in the PR - (run `dart format --line-length=100 .`) + (run `dart format .`) - [ ] Updated/added relevant documentation (doc comments with `///`). - [ ] Added relevant reviewers. diff --git a/.github/workflows/linter.yml.bak b/.github/workflows/linter.yml.bak index 6339805d..e3665a58 100644 --- a/.github/workflows/linter.yml.bak +++ b/.github/workflows/linter.yml.bak @@ -26,7 +26,7 @@ jobs: run: flutter pub get - name: Check for formatting issues (run "dart format . ") - run: dart format --line-length=100 . + run: dart format . - name: Push a commit with the changed files continue-on-error: true From 4cca613c727190c4aa9fad540df7758d5296a78d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ningu=C3=A9m=20Mesmo?= Date: Sun, 22 Jun 2025 23:13:43 +0200 Subject: [PATCH 13/89] Translated using Weblate (Portuguese) Currently translated at 98.3% (307 of 312 strings) Translation: wger Workout Manager/Mobile App Translate-URL: https://hosted.weblate.org/projects/wger/mobile/pt/ --- lib/l10n/app_pt.arb | 110 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 105 insertions(+), 5 deletions(-) diff --git a/lib/l10n/app_pt.arb b/lib/l10n/app_pt.arb index 3e5c59bf..0cdf97cd 100644 --- a/lib/l10n/app_pt.arb +++ b/lib/l10n/app_pt.arb @@ -113,7 +113,7 @@ "@addMeal": {}, "addIngredient": "Adicionar ingrediente", "@addIngredient": {}, - "logIngredient": "Salvar no gráfico de nutrição", + "logIngredient": "Registar ingrediente no diário de nutrição", "@logIngredient": {}, "nutritionalDiary": "Gráfico nutricional", "@nutritionalDiary": {}, @@ -357,7 +357,7 @@ "@jumpTo": { "description": "Imperative. Label used in popup allowing the user to jump to a specific exercise while in the gym mode" }, - "logMeal": "Registrar esta refeição", + "logMeal": "Registar esta refeição no diário de nutrição", "@logMeal": {}, "measurementCategoriesHelpText": "Categoria de medição, como 'bíceps' ou 'gordura corporal'", "@measurementCategoriesHelpText": {}, @@ -742,9 +742,9 @@ }, "aboutMastodonTitle": "Mastodon", "@aboutMastodonTitle": {}, - "aboutDonateTitle": "Doar", + "aboutDonateTitle": "Faz uma doação", "@aboutDonateTitle": {}, - "aboutDonateText": "Nos compre um café para ajudar o projeto, pagar os custos do servidor e nos manter energizados", + "aboutDonateText": "Embora o projeto seja, e será sempre, gratuito, manter o servidor não o é! O desenvolvimento também leva bastante do tempo dos voluntários. O teu contributo suporta diretamente estes custos ajudando a manter o serviço constante.", "@aboutDonateText": {}, "onlyLogging": "Só controlar calorias", "@onlyLogging": {}, @@ -908,5 +908,105 @@ "restTime": "Tempo de descanso", "@restTime": {}, "isRestDayHelp": "Favor notar que todos os sets e exercícios serão removidos quando você marcar um dia como dia de descanso.", - "@isRestDayHelp": {} + "@isRestDayHelp": {}, + "apiToken": "Códibo API", + "@apiToken": {}, + "errorInfoDescription": "Lamentamos, mas algo correu mal. Podes ajudar a corrigir isto reportando o erro no GitHub.", + "@errorInfoDescription": {}, + "supersetNr": "Superset {nr}", + "@supersetNr": { + "description": "Header in form indicating the number of the current exercise. Can also be translated as something like 'Superset Nr. xy'.", + "type": "text", + "placeholders": { + "nr": { + "type": "String" + } + } + }, + "needsLogsToAdvance": "Precisa de dados para avançar", + "@needsLogsToAdvance": {}, + "needsLogsToAdvanceHelp": "Seleciona se queres que a rotina progrida para o dia seguinte agendado apenas se registaste um treino no dia", + "@needsLogsToAdvanceHelp": {}, + "min": "Min", + "@min": {}, + "max": "Máximo", + "@max": {}, + "resultingRoutine": "Rotina resultante", + "@resultingRoutine": {}, + "fitInWeekHelp": "Se selecionado, os dias repetir-se-ão num ciclo semanal, caso contrário, os dias seguir-se-ão sequencialmente independentemente do início de nova semana.", + "@fitInWeekHelp": {}, + "fitInWeek": "Encaixa na semana", + "@fitInWeek": {}, + "simpleModeHelp": "Esconde alguns dos parâmetros mais avançados quando editando exercícios", + "@simpleModeHelp": {}, + "addSuperset": "Adiciona um superset", + "@addSuperset": {}, + "setHasNoExercises": "Esta série ainda não tem exercícios!", + "@setHasNoExercises": {}, + "resistance_band": "Banda elástica", + "@resistance_band": { + "description": "Generated entry for translation for server strings" + }, + "yourCurrentNutritionPlanHasNoMealsDefinedYet": "O teu plano nutricional atual não tem refeições definidas", + "@yourCurrentNutritionPlanHasNoMealsDefinedYet": { + "description": "Message shown when a nutrition plan doesn't have any meals" + }, + "toAddMealsToThePlanGoToNutritionalPlanDetails": "Para adicionar refeições ao plano, vai aos detalhes do plano nutricional", + "@toAddMealsToThePlanGoToNutritionalPlanDetails": { + "description": "Message shown to guide users to the nutritional plan details page to add meals" + }, + "errorInfoDescription2": "Podes continuar a usar a aplicação, mas algumas funções podem não funcionar.", + "@errorInfoDescription2": {}, + "errorCouldNotConnectToServer": "Não foi possível ligar ao servidor", + "@errorCouldNotConnectToServer": {}, + "aboutBugsListTitle": "Relata um problema ou sugere uma funcionalidade", + "@aboutBugsListTitle": {}, + "aboutTranslationListTitle": "Traduz a aplicação", + "@aboutTranslationListTitle": {}, + "aboutSourceListTitle": "Vê o código fonte", + "@aboutSourceListTitle": {}, + "aboutWhySupportTitle": "Código aberto & livre para usar ❤️", + "@aboutWhySupportTitle": {}, + "aboutContributeTitle": "Contribui", + "@aboutContributeTitle": {}, + "aboutContributeText": "Todos os tipos de contribuição são bem-vindos. Quer sejas um desenvolvedor, um tradutor ou apenas um apaixonado pelo exercício, todas as migalhas de suporte são apreciadas!", + "@aboutContributeText": {}, + "aboutJoinCommunityTitle": "Junta-te à comunidade", + "@aboutJoinCommunityTitle": {}, + "aboutDiscordTitle": "Discord", + "@aboutDiscordTitle": {}, + "others": "Outros", + "@others": {}, + "setHasProgression": "A série tem progressão", + "@setHasProgression": {}, + "simpleMode": "Modo simples", + "@simpleMode": {}, + "progressionRules": "Este exercíco tem regras de progressão e não pode ser editado na aplicação móvel. Por favor, usa a aplicação web para editar este exercício.", + "@progressionRules": {}, + "selectAvailablePlates": "Seleciona anilhas disponíveis", + "@selectAvailablePlates": {}, + "useApiToken": "Usa código API", + "@useApiToken": {}, + "barWeight": "Peso da barra", + "@barWeight": {}, + "invalidApiToken": "Por favor, introduz uma chave API válida", + "@invalidApiToken": { + "description": "Error message when the user enters an invalid API key" + }, + "useColors": "Usa cores", + "@useColors": {}, + "useUsernameAndPassword": "Usa nome de utilizador e palavra passe", + "@useUsernameAndPassword": {}, + "apiTokenValidChars": "Uma chave API pode apenas conter letras a-f, números 0-9 e ter exatamente 40 caracteres", + "@apiTokenValidChars": { + "description": "Error message when the user tries to input a API key with forbidden characters" + }, + "errorViewDetails": "Detalhes técnicos", + "@errorViewDetails": {}, + "errorCouldNotConnectToServerDetails": "A aplicação não conseguiu ligar-se ao servidor. Por favor, verifica a ligação à rede ou o URL do servidor e tenta novamente. Se o problema persistir, contacta o administrador do servidor.", + "@errorCouldNotConnectToServerDetails": {}, + "copyToClipboard": "Copia para a memória", + "@copyToClipboard": {}, + "setHasProgressionWarning": "Por favor, nota que, de momento, não é possível editar todos os valores para uma série na aplicação móvel ou configurar a progressão automática. Por agora, por favor, usa a aplicação web.", + "@setHasProgressionWarning": {} } From d5db761016b438c6e16ffddc14a1fd9288e3e32b Mon Sep 17 00:00:00 2001 From: Arga Pandika Date: Sun, 22 Jun 2025 19:30:14 +0200 Subject: [PATCH 14/89] Translated using Weblate (Indonesian) Currently translated at 99.3% (310 of 312 strings) Translation: wger Workout Manager/Mobile App Translate-URL: https://hosted.weblate.org/projects/wger/mobile/id/ --- lib/l10n/app_id.arb | 638 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 569 insertions(+), 69 deletions(-) diff --git a/lib/l10n/app_id.arb b/lib/l10n/app_id.arb index 96bcc922..fdea90b6 100644 --- a/lib/l10n/app_id.arb +++ b/lib/l10n/app_id.arb @@ -46,7 +46,7 @@ }, "email": "Alamat E-mail", "@email": {}, - "username": "Username", + "username": "Nama pengguna", "@username": {}, "invalidUsername": "Mohon masukkan username yang valid", "@invalidUsername": { @@ -124,11 +124,11 @@ "@repetitions": { "description": "Repetitions for an exercise set" }, - "reps": "Reps", + "reps": "Repetisi", "@reps": { "description": "Shorthand for repetitions, used when space constraints are tighter" }, - "rir": "RiR", + "rir": "Repetisi tersisa", "@rir": { "description": "Shorthand for Repetitions In Reserve" }, @@ -186,7 +186,7 @@ "@gymMode": { "description": "Label when starting the gym mode" }, - "plateCalculator": "Plates", + "plateCalculator": "Lempeng Beban", "@plateCalculator": { "description": "Label used for the plate calculator in the gym mode" }, @@ -204,9 +204,9 @@ }, "todaysWorkout": "Latihanmu hari ini", "@todaysWorkout": {}, - "logHelpEntries": "If on a single day there is more than one entry with the same number of repetitions, but different weights, only the entry with the higher weight is shown in the diagram.", + "logHelpEntries": "Jika dalam satu hari terdapat lebih dari satu entri dengan jumlah repetisi yang sama namun beban berbeda, hanya entri dengan beban tertinggi yang akan ditampilkan di diagram.", "@logHelpEntries": {}, - "logHelpEntriesUnits": "Note that only entries with a weight unit (kg or lb) and repetitions are charted, other combinations such as time or until failure are ignored here.", + "logHelpEntriesUnits": "Perlu dicatat bahwa hanya entri dengan satuan beban (kg atau lb) dan repetisi yang akan ditampilkan di grafik. Kombinasi lain seperti waktu atau hingga gagal tidak diperhitungkan di sini.", "@logHelpEntriesUnits": {}, "description": "Description", "@description": {}, @@ -222,49 +222,49 @@ }, "addMeal": "Tambah makanan", "@addMeal": {}, - "mealLogged": "Meal logged to diary", + "mealLogged": "Makanan ditambahkan ke buku harian", "@mealLogged": {}, - "logMeal": "Catat makanan ini", + "logMeal": "Catat makanan ke buku harian nutrisi", "@logMeal": {}, "addIngredient": "Tambah komposisi", "@addIngredient": {}, - "logIngredient": "Simpan di diari nutrisi", + "logIngredient": "Catat bahan ke buku harian nutrisi", "@logIngredient": {}, "searchIngredient": "Cari komposisi", "@searchIngredient": { "description": "Label on ingredient search form" }, - "nutritionalPlan": "Nutritional plan", + "nutritionalPlan": "Rencana Nutrisi", "@nutritionalPlan": {}, - "nutritionalDiary": "Nutritional diary", + "nutritionalDiary": "Buku Harian Nutrisi", "@nutritionalDiary": {}, - "nutritionalPlans": "Nutritional plans", + "nutritionalPlans": "Rencana Nutrisi", "@nutritionalPlans": {}, - "noNutritionalPlans": "You have no nutritional plans", + "noNutritionalPlans": "Anda belum memiliki rencana nutrisi", "@noNutritionalPlans": { "description": "Message shown when the user has no nutritional plans" }, - "anErrorOccurred": "An Error Occurred!", + "anErrorOccurred": "Terjadi kesalahan!", "@anErrorOccurred": {}, - "weight": "Weight", + "weight": "Berat", "@weight": { "description": "The weight of a workout log or body weight entry" }, "measurement": "Ukuran", "@measurement": {}, - "measurements": "Measurements", + "measurements": "Pengukuran", "@measurements": { "description": "Categories for the measurements such as biceps size, body fat, etc." }, - "measurementCategoriesHelpText": "Measurement category, such as 'biceps' or 'body fat'", + "measurementCategoriesHelpText": "Kategori pengukuran, seperti 'bisep' atau 'lemak tubuh'", "@measurementCategoriesHelpText": {}, - "measurementEntriesHelpText": "The unit used to measure the category such as 'cm' or '%'", + "measurementEntriesHelpText": "Satuan yang digunakan untuk mengukur kategori, seperti 'cm' atau '%'", "@measurementEntriesHelpText": {}, "date": "Date", "@date": { "description": "The date of a workout log or body weight entry" }, - "value": "Value", + "value": "Nilai", "@value": { "description": "The value of a measurement entry" }, @@ -272,23 +272,23 @@ "@start": { "description": "Label on button to start the gym mode (i.e., an imperative)" }, - "time": "Time", + "time": "Waktu", "@time": { "description": "The time of a meal or workout" }, - "timeStart": "Start time", + "timeStart": "Waktu mulai", "@timeStart": { "description": "The starting time of a workout" }, - "timeEnd": "End time", + "timeEnd": "Waktu selesai", "@timeEnd": { "description": "The end time of a workout" }, - "timeStartAhead": "Start time cannot be ahead of end time", + "timeStartAhead": "Waktu mulai tidak boleh melebihi waktu selesai", "@timeStartAhead": {}, - "ingredient": "Ingredient", + "ingredient": "Komposisi", "@ingredient": {}, - "energy": "Energy", + "energy": "Energi", "@energy": { "description": "Energy in a meal, ingredient etc. e.g. in kJ" }, @@ -296,29 +296,29 @@ "@energyShort": { "description": "The first letter or short name of the word 'Energy', used in overviews" }, - "kcal": "kcal", + "kcal": "kkal", "@kcal": { "description": "Energy in a meal in kilocalories, kcal" }, - "macronutrients": "Macronutrients", + "macronutrients": "Makronutrien", "@macronutrients": {}, - "planned": "Planned", + "planned": "Direncanakan", "@planned": { "description": "Header for the column of 'planned' nutritional values, i.e. what should be eaten" }, - "logged": "Logged", + "logged": "Dicatat", "@logged": { "description": "Header for the column of 'logged' nutritional values, i.e. what was eaten" }, - "weekAverage": "7 day average", + "weekAverage": "Rata-rata 7 hari", "@weekAverage": { "description": "Header for the column of '7 day average' nutritional values, i.e. what was logged last week" }, - "difference": "Difference", + "difference": "Perbedaan", "@difference": {}, "percentEnergy": "Persenan Energi", "@percentEnergy": {}, - "gPerBodyKg": "g per body kg", + "gPerBodyKg": "g per kg tubuh", "@gPerBodyKg": { "description": "Label used for total sums of e.g. calories or similar in grams per Kg of body weight" }, @@ -340,27 +340,27 @@ "@proteinShort": { "description": "The first letter or short name of the word 'Protein', used in overviews" }, - "carbohydrates": "Carbohydrates", + "carbohydrates": "Karbohidrat", "@carbohydrates": {}, "carbohydratesShort": "C", "@carbohydratesShort": { "description": "The first letter or short name of the word 'Carbohydrates', used in overviews" }, - "sugars": "Sugars", + "sugars": "Gula", "@sugars": {}, - "fat": "Fat", + "fat": "Lemak", "@fat": {}, "fatShort": "F", "@fatShort": { "description": "The first letter or short name of the word 'Fat', used in overviews" }, - "saturatedFat": "Saturated fat", + "saturatedFat": "Lemak jenuh", "@saturatedFat": {}, "fiber": "Fibre", "@fiber": {}, "sodium": "Sodium", "@sodium": {}, - "amount": "Amount", + "amount": "Jumlah", "@amount": { "description": "The amount (e.g. in grams) of an ingredient in a meal" }, @@ -368,11 +368,11 @@ "@unit": { "description": "The unit used for a repetition (kg, time, etc.)" }, - "newEntry": "New entry", + "newEntry": "Entri baru", "@newEntry": { "description": "Title when adding a new entry such as a weight or log entry" }, - "noWeightEntries": "You have no weight entries", + "noWeightEntries": "Anda belum memiliki entri berat badan", "@noWeightEntries": { "description": "Message shown when the user has no logged weight entries" }, @@ -384,7 +384,7 @@ }, "delete": "Delete", "@delete": {}, - "confirmDelete": "Are you sure you want to delete '{toDelete}'?", + "confirmDelete": "Apakah anda yakin ingin menghapus '{toDelete}'?", "@confirmDelete": { "description": "Confirmation text before the user deletes an object", "type": "text", @@ -394,33 +394,33 @@ } } }, - "newNutritionalPlan": "New nutritional plan", + "newNutritionalPlan": "Rencana nutrisi baru", "@newNutritionalPlan": {}, - "toggleDetails": "Toggle details", + "toggleDetails": "Toggle rincian", "@toggleDetails": { "description": "Switch to toggle detail / overview" }, "goToDetailPage": "Go to detail page", "@goToDetailPage": {}, - "aboutDescription": "Thank you for using wger! wger is a collaborative open source project, made by fitness enthusiasts from around the world.", + "aboutDescription": "Terima kasih telah menggunakan wger! wger proyek open source kolaboratif, dibuat oleh para penggemar kebugaran dari seluruh dunia.", "@aboutDescription": { "description": "Text in the about dialog" }, - "calendar": "Calendar", + "calendar": "Kalender", "@calendar": {}, - "goToToday": "Go to today", + "goToToday": "Pergi ke hari ini", "@goToToday": { "description": "Label on button to jump back to 'today' in the calendar widget" }, - "enterValue": "Please enter a value", + "enterValue": "Silakan masukan nilai", "@enterValue": { "description": "Error message when the user hasn't entered a value on a required field" }, - "selectExercise": "Please select an exercise", + "selectExercise": "Silakan pilih latihan", "@selectExercise": { "description": "Error message when the user hasn't selected an exercise in the form" }, - "enterCharacters": "Please enter between {min} and {max} characters", + "enterCharacters": "Silakan masukan antara {min} dan {max} karakter", "@enterCharacters": { "description": "Error message when the user hasn't entered the correct number of characters in a form", "type": "text", @@ -433,7 +433,7 @@ } } }, - "nrOfSets": "Sets per exercise: {nrOfSets}", + "nrOfSets": "Sets per latihan: {nrOfSets}", "@nrOfSets": { "description": "Label shown on the slider where the user selects the nr of sets", "type": "text", @@ -443,24 +443,24 @@ } } }, - "setUnitsAndRir": "Set units and RiR", + "setUnitsAndRir": "Unit Set and RiR", "@setUnitsAndRir": { "description": "Label shown on the slider where the user can toggle showing units and RiR", "type": "text" }, - "enterValidNumber": "Please enter a valid number", + "enterValidNumber": "Silakan masukan angka yang valid", "@enterValidNumber": { "description": "Error message when the user has submitted an invalid number (e.g. '3,.,.,.')" }, - "selectIngredient": "Please select an ingredient", + "selectIngredient": "Silakan pilih komposisi", "@selectIngredient": { "description": "Error message when the user hasn't selected an ingredient from the autocompleter" }, - "recentlyUsedIngredients": "Recently added ingredients", + "recentlyUsedIngredients": "Komposisi yang baru ditambahkan", "@recentlyUsedIngredients": { "description": "A message when a user adds a new ingredient to a meal." }, - "selectImage": "Please select an image", + "selectImage": "Silakan pilih gambar", "@selectImage": { "description": "Label and error message when the user hasn't selected an image to save" }, @@ -468,27 +468,27 @@ "@optionsLabel": { "description": "Label for the popup with general app options" }, - "takePicture": "Take a picture", + "takePicture": "Ambil gambar", "@takePicture": {}, - "chooseFromLibrary": "Choose from photo library", + "chooseFromLibrary": "Pilih foto dari library", "@chooseFromLibrary": {}, - "gallery": "Gallery", + "gallery": "Galeri", "@gallery": {}, "addImage": "Add image", "@addImage": {}, - "dataCopied": "Data copied to new entry", + "dataCopied": "Data disalin ke entri baru", "@dataCopied": { "description": "Snackbar message to show on copying data to a new log entry" }, - "appUpdateTitle": "Update needed", + "appUpdateTitle": "Pembaruan diperlukan", "@appUpdateTitle": {}, - "appUpdateContent": "This version of the app is not compatible with the server, please update your application.", + "appUpdateContent": "Versi aplikasi ini tidak kompatibel dengan server, silakan perbarui aplikasi Anda.", "@appUpdateContent": {}, - "productFound": "Product found", + "productFound": "Produk ditemukan", "@productFound": { "description": "Header label for dialog when product is found with barcode" }, - "productFoundDescription": "The barcode corresponds to this product: {productName}. Do you want to continue?", + "productFoundDescription": "Kode batang ini sesuai dengan produk: {productName}. Apakah Anda ingin melanjutkan?", "@productFoundDescription": { "description": "Dialog info when product is found with barcode", "type": "text", @@ -498,11 +498,11 @@ } } }, - "productNotFound": "Product not found", + "productNotFound": "Produk tidak ditemukan", "@productNotFound": { "description": "Header label for dialog when product is not found with barcode" }, - "productNotFoundDescription": "The product with the scanned barcode {barcode} was not found in the wger database", + "productNotFoundDescription": "Produk dengan kode batang {barcode} tidak ditemukan dalam database wger", "@productNotFoundDescription": { "description": "Dialog info when product is not found with barcode", "type": "text", @@ -512,11 +512,11 @@ } } }, - "scanBarcode": "Scan barcode", + "scanBarcode": "Pindai kode batang", "@scanBarcode": { "description": "Label for scan barcode button" }, - "close": "Close", + "close": "Tutup", "@close": { "description": "Translation for close" }, @@ -558,10 +558,510 @@ "@searchNamesInEnglish": {}, "noIngredientsDefined": "Belum ada bahan yang ditetapkan", "@noIngredientsDefined": {}, - "ingredientLogged": "Bahan telah dicatat", + "ingredientLogged": "Komposisi telah dicatat", "@ingredientLogged": {}, "triceps": "Trisep", "@triceps": { "description": "Generated entry for translation for server strings" - } -} \ No newline at end of file + }, + "goalFiber": "Target serat", + "@goalFiber": {}, + "abs": "Otot perut", + "@abs": { + "description": "Generated entry for translation for server strings" + }, + "selectAvailablePlates": "Pilih lempeng beban yang tersedia", + "@selectAvailablePlates": {}, + "useColors": "Gunakan warna", + "@useColors": {}, + "barWeight": "Berat Batang", + "@barWeight": {}, + "routineDays": "Hari dalam rutinitas", + "@routineDays": {}, + "resultingRoutine": "Rutinitas yang dihasilkan", + "@resultingRoutine": {}, + "goalCarbohydrates": "Target karbohidrat", + "@goalCarbohydrates": {}, + "alternativeNames": "Nama lain", + "@alternativeNames": {}, + "back": "Punggung", + "@back": { + "description": "Generated entry for translation for server strings" + }, + "routines": "Rutinitas", + "@routines": {}, + "newRoutine": "Rutinitas baru", + "@newRoutine": {}, + "sets": "Set", + "@sets": { + "description": "The number of sets to be done for one exercise" + }, + "isRestDayHelp": "Harap diperhatikan bahwa semua set dan latihan akan dihapus ketika Anda menandai suatu hari sebagai hari istirahat.", + "@isRestDayHelp": {}, + "max": "Maksimal", + "@max": {}, + "today": "Hari ini", + "@today": {}, + "noMeasurementEntries": "Anda belum memiliki entri pengukuran apa pun", + "@noMeasurementEntries": {}, + "log": "Catat", + "@log": { + "description": "Log a specific meal (imperative form)" + }, + "settingsTitle": "Pengaturan", + "@settingsTitle": {}, + "biceps": "Bisep", + "@biceps": { + "description": "Generated entry for translation for server strings" + }, + "miles_per_hour": "Mil Per Jam", + "@miles_per_hour": { + "description": "Generated entry for translation for server strings" + }, + "selectEntry": "Silakan pilih entri", + "@selectEntry": {}, + "next": "Selanjutnya", + "@next": {}, + "simpleMode": "Mode sederhana", + "@simpleMode": {}, + "body_weight": "Berat Badan", + "@body_weight": { + "description": "Generated entry for translation for server strings" + }, + "incline_bench": "Bangku Incline", + "@incline_bench": { + "description": "Generated entry for translation for server strings" + }, + "legs": "Kaki", + "@legs": { + "description": "Generated entry for translation for server strings" + }, + "aboutDonateTitle": "Beri donasi", + "@aboutDonateTitle": {}, + "bench": "Bangku", + "@bench": { + "description": "Generated entry for translation for server strings" + }, + "useUsernameAndPassword": "Gunakan nama pengguna dan kata sandi", + "@useUsernameAndPassword": {}, + "useApiToken": "Gunakan Token API", + "@useApiToken": {}, + "restTime": "Waktu istirahat", + "@restTime": {}, + "restDay": "Hari istirahat", + "@restDay": {}, + "exerciseNr": "Latihan ke-{nr}", + "@exerciseNr": { + "description": "Header in form indicating the number of the current exercise. Can also be translated as something like 'Set Nr. xy'.", + "type": "text", + "placeholders": { + "nr": { + "type": "String" + } + } + }, + "errorCouldNotConnectToServer": "Tidak dapat terhubung ke server", + "@errorCouldNotConnectToServer": {}, + "errorInfoDescription": "Maaf, terjadi kesalahan. Anda dapat membantu kami memperbaikinya dengan melaporkan masalah ini di GitHub.", + "@errorInfoDescription": {}, + "min": "Minimal", + "@min": {}, + "chartAllTimeTitle": "{name}Sepanjang waktu", + "@chartAllTimeTitle": { + "description": "All-time chart of 'name' (e.g. 'weight', 'body fat' etc.)", + "type": "text", + "placeholders": { + "name": { + "type": "String" + } + } + }, + "chart30DaysTitle": "{name} 30 hari terakhir", + "@chart30DaysTitle": { + "description": "last 30 days chart of 'name' (e.g. 'weight', 'body fat' etc.)", + "type": "text", + "placeholders": { + "name": { + "type": "String" + } + } + }, + "chartDuringPlanTitle": "{chartName} selama rencana nutrisi {planName}", + "@chartDuringPlanTitle": { + "description": "chart of 'chartName' (e.g. 'weight', 'body fat' etc.) logged during plan", + "type": "text", + "placeholders": { + "chartName": { + "type": "String" + }, + "planName": { + "type": "String" + } + } + }, + "aboutWhySupportTitle": "Bersifat open source & gratis ❤️", + "@aboutWhySupportTitle": {}, + "aboutSourceListTitle": "Lihat kode sumber", + "@aboutSourceListTitle": {}, + "aboutJoinCommunityTitle": "Gabung komunitas", + "@aboutJoinCommunityTitle": {}, + "previous": "Sebelumnya", + "@previous": {}, + "setHasProgressionWarning": "Perlu diketahui, saat ini pengaturan lengkap untuk set dan konfigurasi progresi otomatis belum bisa dilakukan di aplikasi mobile. Silakan gunakan aplikasi web untuk fitur tersebut.", + "@setHasProgressionWarning": {}, + "settingsExerciseCacheDescription": "Cache latihan", + "@settingsExerciseCacheDescription": {}, + "settingsIngredientCacheDescription": "Cache komposisi", + "@settingsIngredientCacheDescription": {}, + "settingsCacheDeletedSnackbar": "Cache berhasil dibersihkan", + "@settingsCacheDeletedSnackbar": {}, + "aboutPageTitle": "Tentang kami dan dukungan", + "@aboutPageTitle": {}, + "simpleModeHelp": "Sembunyikan beberapa pengaturan lanjutan saat mengedit latihan", + "@simpleModeHelp": {}, + "kilometers": "Kilometer", + "@kilometers": { + "description": "Generated entry for translation for server strings" + }, + "lats": "Otot Punggung Samping", + "@lats": { + "description": "Generated entry for translation for server strings" + }, + "lower_back": "Punggung Bawah", + "@lower_back": { + "description": "Generated entry for translation for server strings" + }, + "minutes": "Menit", + "@minutes": { + "description": "Generated entry for translation for server strings" + }, + "until_failure": "Sampai tidak mampu lagi", + "@until_failure": { + "description": "Generated entry for translation for server strings" + }, + "kg": "kg", + "@kg": { + "description": "Generated entry for translation for server strings" + }, + "done": "Selesai", + "@done": {}, + "overallChangeWeight": "Perubahan keseluruhan", + "@overallChangeWeight": { + "description": "Overall change in weight, added for localization" + }, + "goalTypeMeals": "Dari makanan", + "@goalTypeMeals": { + "description": "added for localization of Class GoalType's filed meals" + }, + "goalTypeBasic": "Dasar", + "@goalTypeBasic": { + "description": "added for localization of Class GoalType's filed basic" + }, + "goalTypeAdvanced": "Lanjutan", + "@goalTypeAdvanced": { + "description": "added for localization of Class GoalType's filed advanced" + }, + "indicatorRaw": "Mentah", + "@indicatorRaw": { + "description": "added for localization of Class Indicator's field text" + }, + "indicatorAvg": "rata-rata", + "@indicatorAvg": { + "description": "added for localization of Class Indicator's field text" + }, + "themeMode": "mode Tema", + "@themeMode": {}, + "systemMode": "Pengaturan sitem", + "@systemMode": {}, + "pull_up_bar": "Palang Pull-up", + "@pull_up_bar": { + "description": "Generated entry for translation for server strings" + }, + "onlyLoggingHelpText": "Centang kotak ini jika Anda hanya ingin mencatat kalori dan tidak ingin menyusun rencana nutrisi secara rinci dengan menu khusus", + "@onlyLoggingHelpText": {}, + "goalEnergy": "Target energi", + "@goalEnergy": {}, + "moreMeasurementEntries": "Tambah pengukuran baru", + "@moreMeasurementEntries": { + "description": "Message shown when the user wants to add new measurement" + }, + "baseNameEnglish": "Semua latihan memerlukan nama dasar dalam Bahasa Inggris", + "@baseNameEnglish": {}, + "add_exercise_image_license": "Gambar harus kompatibel dengan lisensi CC BY SA. Jika ragu, unggah hanya foto yang anda ambil sendiri.", + "@add_exercise_image_license": {}, + "verifiedEmail": "Email terverifikasi", + "@verifiedEmail": {}, + "max_reps": "Repetisi Maksimal", + "@max_reps": { + "description": "Generated entry for translation for server strings" + }, + "miles": "Mil", + "@miles": { + "description": "Generated entry for translation for server strings" + }, + "lb": "lb", + "@lb": { + "description": "Generated entry for translation for server strings" + }, + "verifiedEmailReason": "Anda perlu memverifikasi email untuk dapat menambahkan latihan", + "@verifiedEmailReason": {}, + "baseData": "Dasar dalam Bahasa Inggris", + "@baseData": { + "description": "The base data for an exercise such as category, trained muscles, etc." + }, + "textPromptSubheading": "Tekan tombol untuk mulai", + "@textPromptSubheading": {}, + "cacheWarning": "Karena sistem cache, perubahan mungkin membutuhkan waktu sebelum terlihat di seluruh aplikasi.", + "@cacheWarning": {}, + "textPromptTitle": "Siap memulai?", + "@textPromptTitle": {}, + "yourCurrentNutritionPlanHasNoMealsDefinedYet": "Rencana nutrisi Anda saat ini belum memiliki menu yang ditentukan", + "@yourCurrentNutritionPlanHasNoMealsDefinedYet": { + "description": "Message shown when a nutrition plan doesn't have any meals" + }, + "toAddMealsToThePlanGoToNutritionalPlanDetails": "Untuk menambahkan menu ke dalam rencana, buka detail rencana nutrisi", + "@toAddMealsToThePlanGoToNutritionalPlanDetails": { + "description": "Message shown to guide users to the nutritional plan details page to add meals" + }, + "goalFat": "Target lemak", + "@goalFat": {}, + "errorInfoDescription2": "Anda masih dapat menggunakan aplikasi, namun beberapa fitur mungkin tidak berfungsi.", + "@errorInfoDescription2": {}, + "errorViewDetails": "Rincian teknis", + "@errorViewDetails": {}, + "copyToClipboard": "Salin ke papan klip", + "@copyToClipboard": {}, + "loggedToday": "Dicatat hari ini", + "@loggedToday": {}, + "aboutDonateText": "Meskipun proyek ini gratis dan akan selalu begitu, menjalankan server tetap memerlukan biaya! Pengembangan juga membutuhkan waktu dan tenaga yang tidak sedikit dari para relawan. Kontribusi Anda secara langsung membantu menutup biaya-biaya ini dan menjaga layanan tetap andal.", + "@aboutDonateText": {}, + "aboutContributeText": "Semua jenis kontribusi sangat kami hargai. Baik Anda seorang pengembang, penerjemah, atau sekadar memiliki semangat di bidang kebugaran, setiap bentuk dukungan sangat berarti!", + "@aboutContributeText": {}, + "aboutTranslationListTitle": "Terjemahkan aplikasi", + "@aboutTranslationListTitle": {}, + "others": "Lainnya", + "@others": {}, + "verifiedEmailInfo": "Email verifikasi telah dikirim ke {email}", + "@verifiedEmailInfo": { + "placeholders": { + "email": { + "type": "String" + } + } + }, + "oneNamePerLine": "Satu nama per baris", + "@oneNamePerLine": {}, + "whatVariationsExist": "Apakah ada variasi dari latihan ini? Jika ada, apa saja?", + "@whatVariationsExist": {}, + "images": "Gambar", + "@images": {}, + "fitInWeek": "Bugar dalam seminggu", + "@fitInWeek": {}, + "fitInWeekHelp": "Jika diaktifkan, hari-hari akan berulang dalam siklus mingguan. Jika tidak, hari-hari akan berjalan secara berurutan tanpa memperhatikan awal minggu baru.", + "@fitInWeekHelp": {}, + "calves": "Betis", + "@calves": { + "description": "Generated entry for translation for server strings" + }, + "cardio": "Kardio", + "@cardio": { + "description": "Generated entry for translation for server strings" + }, + "dumbbell": "Dumbel", + "@dumbbell": { + "description": "Generated entry for translation for server strings" + }, + "gym_mat": "Matras Gym", + "@gym_mat": { + "description": "Generated entry for translation for server strings" + }, + "hamstrings": "Paha Belakang", + "@hamstrings": { + "description": "Generated entry for translation for server strings" + }, + "kettlebell": "Kettlebell", + "@kettlebell": { + "description": "Generated entry for translation for server strings" + }, + "kilometers_per_hour": "Kilometer Per Jam", + "@kilometers_per_hour": { + "description": "Generated entry for translation for server strings" + }, + "darkMode": "Selalu mode gelap", + "@darkMode": {}, + "goalMacro": "Target makronutrien", + "@goalMacro": { + "description": "The goal for macronutrients" + }, + "selectMealToLog": "Pilih makanan untuk dicatat ke dalam buku harian", + "@selectMealToLog": {}, + "surplus": "Surplus", + "@surplus": { + "description": "Caloric surplus (either planned or unplanned)" + }, + "kcalValue": "{value} kkal", + "@kcalValue": { + "description": "A value in kcal, e.g. 500 kcal", + "type": "text", + "placeholders": { + "value": { + "type": "String" + } + } + }, + "gValue": "{value} g", + "@gValue": { + "description": "A value in grams, e.g. 5 g", + "type": "text", + "placeholders": { + "value": { + "type": "String" + } + } + }, + "percentValue": "{value} %", + "@percentValue": { + "description": "A value in percent, e.g. 10 %", + "type": "text", + "placeholders": { + "value": { + "type": "String" + } + } + }, + "aboutMastodonTitle": "Mastodon", + "@aboutMastodonTitle": {}, + "variations": "Variasi", + "@variations": { + "description": "Variations of one exercise (e.g. benchpress and benchpress narrow)" + }, + "alsoKnownAs": "Juga dikenal sebagai: {aliases}", + "@alsoKnownAs": { + "placeholders": { + "aliases": { + "type": "String" + } + }, + "description": "List of alternative names for an exercise" + }, + "language": "Bahasa", + "@language": {}, + "contributeExercise": "Tambahkan latihan", + "@contributeExercise": {}, + "addExercise": "Tambah latihan", + "@addExercise": {}, + "translation": "Terjemahan", + "@translation": {}, + "settingsCacheTitle": "Cache", + "@settingsCacheTitle": {}, + "contributeExerciseWarning": "Anda hanya dapat menambahkan latihan jika akun Anda berusia lebih dari {days} hari dan email Anda telah terverifikasi", + "@contributeExerciseWarning": { + "description": "Number of days before which a person can add exercise", + "placeholders": { + "days": { + "type": "String", + "example": "14" + } + } + }, + "arms": "Lengan", + "@arms": { + "description": "Generated entry for translation for server strings" + }, + "chest": "Dada", + "@chest": { + "description": "Generated entry for translation for server strings" + }, + "plates": "Lempeng Beban", + "@plates": { + "description": "Generated entry for translation for server strings" + }, + "quads": "Paha Depan", + "@quads": { + "description": "Generated entry for translation for server strings" + }, + "none__bodyweight_exercise_": "Tanpa alat (Latihan Berat Badan Sendiri)", + "@none__bodyweight_exercise_": { + "description": "Generated entry for translation for server strings" + }, + "deficit": "defisit", + "@deficit": { + "description": "Caloric deficit (either planned or unplanned)" + }, + "addSuperset": "Tambah superset", + "@addSuperset": {}, + "isRestDay": "Hari ini adalah hari istirahat", + "@isRestDay": {}, + "apiTokenValidChars": "Kunci API hanya boleh berisi huruf a-f, angka 0-9 dan harus berjumlah 40 karakter", + "@apiTokenValidChars": { + "description": "Error message when the user tries to input a API key with forbidden characters" + }, + "needsLogsToAdvance": "Perlu log untuk melanjutkan", + "@needsLogsToAdvance": {}, + "invalidApiToken": "Mohon masukan kunci API yang valid", + "@invalidApiToken": { + "description": "Error message when the user enters an invalid API key" + }, + "goalProtein": "Target protein", + "@goalProtein": {}, + "noRoutines": "Kamu tidak memiliki rutinitas", + "@noRoutines": {}, + "apiToken": "Token API", + "@apiToken": {}, + "supersetNr": "Superset ke-{nr}", + "@supersetNr": { + "description": "Header in form indicating the number of the current exercise. Can also be translated as something like 'Superset Nr. xy'.", + "type": "text", + "placeholders": { + "nr": { + "type": "String" + } + } + }, + "aboutContributeTitle": "Kontribusi", + "@aboutContributeTitle": {}, + "translateExercise": "Terjemahkan latihan ini sekarang", + "@translateExercise": {}, + "enterMinCharacters": "Silakan masukan minimal {min} karakter", + "@enterMinCharacters": { + "description": "Error message when the user hasn't entered the minimum amount characters in a form", + "type": "text", + "placeholders": { + "min": { + "type": "String" + } + } + }, + "swiss_ball": "Bola Gym", + "@swiss_ball": { + "description": "Generated entry for translation for server strings" + }, + "needsLogsToAdvanceHelp": "Pilih opsi ini jika Anda ingin rutinitas berlanjut ke hari berikutnya hanya setelah Anda mencatat latihan pada hari tersebut", + "@needsLogsToAdvanceHelp": {}, + "setHasNoExercises": "Set ini belum memiliki latihan apa pun!", + "@setHasNoExercises": {}, + "aboutBugsListTitle": "Laporkan masalah atau usulkan fitur", + "@aboutBugsListTitle": {}, + "errorCouldNotConnectToServerDetails": "Aplikasi tidak dapat terhubung ke server. Silakan periksa koneksi internet atau URL server anda, lalu coba lagi. Jika masalah terus berlanjut, hubungi administrator server.", + "@errorCouldNotConnectToServerDetails": {}, + "unVerifiedEmail": "Email belum diverifikasi", + "@unVerifiedEmail": {}, + "progressionRules": "Latihan ini memiliki aturan peningkatan dan tidak dapat diedit melalui aplikasi mobile. Silakan gunakan aplikasi web untuk mengedit latihan ini.", + "@progressionRules": {}, + "setHasProgression": "Set memiliki peningkatan", + "@setHasProgression": {}, + "barbell": "Barbel", + "@barbell": { + "description": "Generated entry for translation for server strings" + }, + "glutes": "Bokong", + "@glutes": { + "description": "Generated entry for translation for server strings" + }, + "resistance_band": "Karet Latihan", + "@resistance_band": { + "description": "Generated entry for translation for server strings" + }, + "lightMode": "Selalu mode terang", + "@lightMode": {} +} From 62089ba4581bfb3368a10669235691b6881e2c7f Mon Sep 17 00:00:00 2001 From: Nurfitra Pujo Santiko Date: Tue, 24 Jun 2025 04:05:09 +0200 Subject: [PATCH 15/89] Translated using Weblate (Indonesian) Currently translated at 99.3% (310 of 312 strings) Translation: wger Workout Manager/Mobile App Translate-URL: https://hosted.weblate.org/projects/wger/mobile/id/ --- lib/l10n/app_id.arb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/l10n/app_id.arb b/lib/l10n/app_id.arb index fdea90b6..398849e8 100644 --- a/lib/l10n/app_id.arb +++ b/lib/l10n/app_id.arb @@ -36,9 +36,9 @@ "@passwordTooShort": { "description": "Error message when the user a password that is too short" }, - "password": "Password", + "password": "Kata sandi", "@password": {}, - "confirmPassword": "Konfirmasi Password", + "confirmPassword": "Konfirmasi Kata Sandi", "@confirmPassword": {}, "invalidEmail": "Mohon masukkan E-mail yang valid", "@invalidEmail": { @@ -520,7 +520,7 @@ "@close": { "description": "Translation for close" }, - "userProfile": "Profilmu", + "userProfile": "Profil Kamu", "@userProfile": {}, "verify": "Verifikasi", "@verify": {}, @@ -574,7 +574,7 @@ "@selectAvailablePlates": {}, "useColors": "Gunakan warna", "@useColors": {}, - "barWeight": "Berat Batang", + "barWeight": "Berat batang", "@barWeight": {}, "routineDays": "Hari dalam rutinitas", "@routineDays": {}, From bfc7b8cf7d3b879d2c7c970411a0eb94ad5b6e57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ningu=C3=A9m=20Mesmo?= Date: Tue, 24 Jun 2025 23:45:50 +0200 Subject: [PATCH 16/89] Translated using Weblate (Portuguese (Portugal)) Currently translated at 100.0% (3 of 3 strings) Translation: wger Workout Manager/Play Store Translate-URL: https://hosted.weblate.org/projects/wger/play-store/pt_PT/ --- .../android/pt-PT/full_description.txt | 52 +++++++++---------- .../android/pt-PT/short_description.txt | 2 +- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/fastlane/metadata/android/pt-PT/full_description.txt b/fastlane/metadata/android/pt-PT/full_description.txt index 60e8c3d9..abb82544 100644 --- a/fastlane/metadata/android/pt-PT/full_description.txt +++ b/fastlane/metadata/android/pt-PT/full_description.txt @@ -1,39 +1,39 @@ -Feito por amantes da vida fitness - organize sua saúde com o WGER, seu Gerenciador de Treinos! +De amantes do exercício para amantes do exercício - Organiza a tua saúde com WGER, o gestor de treinos! -Você já encontrou o seu aplicativo de fitness nº1? Você adora criar suas próprias rotinas de treino? Não importa que tipo de fera esportiva você seja - todos nós temos algo em comum: adoramos acompanhar nossos dados de saúde <3 +Já encontraste a tua aplicação fitness n.º 1 e adoras criar as tuas próprias rotinas desportivas? Independentemente do animal desportivo que sejas, todos temos algo em comum: adoramos dominar os nossos dados biométricos <3 -Nós não te julgamos por ainda gerenciar sua jornada fitness em um caderno, mas bem-vindo(a) ao século 21! +Por isso não te julgamos se ainda fazes os teus registos no teu lindo caderninho de treino, mas bem-vindo a 2025! -Desenvolvemos um aplicativo de acompanhemento de saúde e fitness 100% gratuito para você, reduzido aos recursos mais relevantes para facilitar sua vida. Comece, treine e comemore seu progresso! +Desenvolvemos uma aplicação digital de controle de treino e saúde 100% livre para ti, simplificada às funções mais importantes para simplificar a tua vida. Começa, continua a treinar e celebra os teus progressos! -O wger é um projeto open-source que é sobre: -* Seu Corpo -* Seus Treinos -* Seu Progresso -* Seus Dados +wger é um projeto open source e comprometido com: +* O teu corpo +* Os teus treinos +* O teu progresso +* Os teus dados -Seu Corpo: -Não precisa pesquisar no Google os ingredientes de suas receitas favoritas - escolha suas refeições diárias entre mais de 78.000 itens e veja os valores nutricionais. Adicione as refeições ao plano nutricional e mantenha uma visão geral de sua dieta no calendário. +O teu corpo +Não é preciso googlar os ingredientes dos teus petiscos favoritos - escolhe as tuas refeições diárias de mais de 78000 produtos e verifica os valores nutricionais. Adiciona refeições ao plano nutricional e tem uma visão de conjunto da tua dieta no calendário. -Seus Treinos: -Você sabe o que é melhor para o seu corpo. Crie seus próprios treinos a partir de uma variedade de mais de 200 exercícios. Em seguida, use o Modo Academia para orientá-lo durante o treino, enquanto registra suas cargas com um clique. +Os teus treinos +Tu sabes o que é melhor para o teu corpo. Cria os teus treinos a partir duma grande variedade de 200 exercícios diferentes. Depois, usa o modo ginásio para te guiar no treino enquanto registas os pesos com um toque. -Seu Progresso: -Nunca perca de vista seus objetivos. Acompanhe seu peso e mantenha suas estatísticas. +O teu progresso +Nunca percas os teus objetivos de vista. Regista o teu peso e guarda as tuas estatísticas. -Seus Dados: -O wger é o seu diário fitness personalizado - mas você é dono(a) dos seus dados. Use a REST API para acessá-los e fazer coisas incríveis com eles. +Os teus dados +wger é o teu diário de treino personalizado - mas tu possuis os teus dados. Usa a API REST para aceder e fazer coisas espantosas com eles. -Obs.: Este aplicativo gratuito não é baseado em financiamentos adicionais e não pedimos que você doe dinheiro. Mais do que isso, é um projeto comunitário em constante crescimento. Portanto, esteja preparado(a) para novos recursos a qualquer momento! +Por favor nota: Esta app gratuita não está baseada em fundos adicionais e não pedimos que dês dinheiro. Mais do que isso, é um projeto comunitário que tem evoluído constantemente. Por isso, espera novas funcionalidades a qualquer momento! -#CódigoAberto - o que isso significa? +#Código aberto - O que quer isso dizer? -Código aberto significa que todo o código-fonte deste aplicativo e do servidor ao qual ele se conecta é gratuito e está disponível para qualquer pessoa: -* Você quer executar o wger em seu próprio servidor, para você ou para sua academia? Sinta-se à vontade! -* Está sentindo falta de um recurso e quer implementá-lo? Comece agora! -* Quer verificar se nenhum dado está sendo compartilhado? Você pode! +Código aberto quer dizer que todo o código fonte desta aplicação e do servidor com que comunica é livre e disponível para toda a gente: +* Queres correr o wger no teu servidor para ti e para o teu ginásio? Força! +* Sentes falta duma funcionalidade e queres implementá-la? Começa já! +* Queres verificar que nada está a ser enviado para lado nenhum? Podes! -Junte-se à nossa comunidade e faça parte dos entusiastas do esporte e geeks de TI de todo o mundo. Continuamos trabalhando para ajustar e otimizar o aplicativo de acordo com nossas necessidades. Amamos suas contribuições, então sinta-se à vontade para participar a qualquer momento e contribuir com seus desejos e ideias! +Junta-te à nossa comunidade e torna-te parte de entusiastas do exercício e geeks das TI de todo o mundo. Nós continuamos a ajustar e otimizar a app talhada para as nossas necessidades. Adoramos o teu contributo, por isso sente-te à vontade para aparecer com sugestões e ideias! --> encontre o código-fonte em https://github.com/wger-project --> faça suas perguntas ou apenas diga Olá no nosso servidor do Discord https://discord.gg/rPWFv6W +-> encontra o código fonte em https://github.com/wger-project +-> faz as tuas perguntas ou simplesmente diz olá no nosso servidor discord https://discord.gg/rPWFv6W diff --git a/fastlane/metadata/android/pt-PT/short_description.txt b/fastlane/metadata/android/pt-PT/short_description.txt index 064060fe..3b018c2c 100644 --- a/fastlane/metadata/android/pt-PT/short_description.txt +++ b/fastlane/metadata/android/pt-PT/short_description.txt @@ -1 +1 @@ -Monitore seus treinos e dieta +Gestor de treinos, nutrição e peso From 3a6e494f00173a64d85da77f7c06c04c9aaed6b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ningu=C3=A9m=20Mesmo?= Date: Tue, 24 Jun 2025 23:50:21 +0200 Subject: [PATCH 17/89] Added translation using Weblate (Portuguese (Portugal)) --- lib/l10n/app_pt_PT.arb | 1 + 1 file changed, 1 insertion(+) create mode 100644 lib/l10n/app_pt_PT.arb diff --git a/lib/l10n/app_pt_PT.arb b/lib/l10n/app_pt_PT.arb new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/lib/l10n/app_pt_PT.arb @@ -0,0 +1 @@ +{} From a39b1f1c3310b8d81593db12419397d19cf17b10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ningu=C3=A9m=20Mesmo?= Date: Tue, 24 Jun 2025 23:52:04 +0200 Subject: [PATCH 18/89] Translated using Weblate (Portuguese (Portugal)) Currently translated at 35.2% (110 of 312 strings) Translation: wger Workout Manager/Mobile App Translate-URL: https://hosted.weblate.org/projects/wger/mobile/pt_PT/ --- lib/l10n/app_pt_PT.arb | 544 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 543 insertions(+), 1 deletion(-) diff --git a/lib/l10n/app_pt_PT.arb b/lib/l10n/app_pt_PT.arb index 0967ef42..4ad8e2bc 100644 --- a/lib/l10n/app_pt_PT.arb +++ b/lib/l10n/app_pt_PT.arb @@ -1 +1,543 @@ -{} +{ + "login": "Entrar", + "@login": { + "description": "Text for login button" + }, + "success": "Sucesso", + "@success": { + "description": "Message when an action completed successfully, usually used as a heading" + }, + "noMatchingExerciseFound": "Nenhum exercício correspondente encontrado", + "@noMatchingExerciseFound": { + "description": "Message returned if no exercises match the searched string" + }, + "labelDashboard": "Painel", + "@labelDashboard": { + "description": "Title for screen dashboard" + }, + "exercise": "Exercício", + "@exercise": { + "description": "An exercise for a workout" + }, + "usernameValidChars": "O nome de utilizador só pode conter letras, dígitos e os caracteres @, +, ., -, e _", + "@usernameValidChars": { + "description": "Error message when the user tries to register a username with forbidden characters" + }, + "searchNamesInEnglish": "Pesquisa também por nomes em inglês", + "@searchNamesInEnglish": {}, + "useCustomServer": "Usa um servidor próprio", + "@useCustomServer": { + "description": "Toggle button allowing users to switch between the default and a custom wger server" + }, + "equipment": "Equipamento", + "@equipment": { + "description": "Equipment needed to perform an exercise" + }, + "userProfile": "O teu perfil", + "@userProfile": {}, + "register": "Registar", + "@register": { + "description": "Text for registration button" + }, + "comment": "Comentário", + "@comment": { + "description": "Comment, additional information" + }, + "customServerHint": "Introduza o endereço do seu próprio servidor, caso contrário o servidor padrão será usado", + "@customServerHint": { + "description": "Hint text for the form where the users can enter their own wger instance" + }, + "useDefaultServer": "Usa o servidor padrão", + "@useDefaultServer": { + "description": "Toggle button allowing users to switch between the default and a custom wger server" + }, + "invalidUrl": "Por favor, introduz um URL válido", + "@invalidUrl": { + "description": "Error message when the user enters an invalid URL, e.g. in the login form" + }, + "passwordsDontMatch": "As palavras passe não coincidem", + "@passwordsDontMatch": { + "description": "Error message when the user enters two different passwords during registration" + }, + "passwordTooShort": "A palavra passe é muito pequena", + "@passwordTooShort": { + "description": "Error message when the user a password that is too short" + }, + "selectAvailablePlates": "Seleciona as anilhas disponíveis", + "@selectAvailablePlates": {}, + "barWeight": "Peso da barra", + "@barWeight": {}, + "useColors": "Usa cores", + "@useColors": {}, + "password": "Palavra passe", + "@password": {}, + "confirmPassword": "Confirma a palavra passe", + "@confirmPassword": {}, + "invalidEmail": "Por favor, insere um endereço de email válido", + "@invalidEmail": { + "description": "Error message when the user enters an invalid email" + }, + "email": "Endereço de email", + "@email": {}, + "username": "Utilizador", + "@username": {}, + "invalidUsername": "Por favor, insere um nome de utilizador válido", + "@invalidUsername": { + "description": "Error message when the user enters an invalid username" + }, + "useApiToken": "Usa um código API", + "@useApiToken": {}, + "useUsernameAndPassword": "Usa nome de utilizador e palavra passe", + "@useUsernameAndPassword": {}, + "apiToken": "Código API", + "@apiToken": {}, + "invalidApiToken": "Por favor, insere um código API válido", + "@invalidApiToken": { + "description": "Error message when the user enters an invalid API key" + }, + "apiTokenValidChars": "Uma chave API pode apenas conter as letras a-f, os números 0-9 e ter exatamente 40 caracteres", + "@apiTokenValidChars": { + "description": "Error message when the user tries to input a API key with forbidden characters" + }, + "customServerUrl": "URL da instância wger", + "@customServerUrl": { + "description": "Label in the form where the users can enter their own wger instance" + }, + "reset": "Redefinir", + "@reset": { + "description": "Button text allowing the user to reset the entered values to the default" + }, + "registerInstead": "Não tens uma conta? Regista-te agora", + "@registerInstead": {}, + "loginInstead": "Já tens uma conta? Entra", + "@loginInstead": {}, + "labelBottomNavWorkout": "Treino", + "@labelBottomNavWorkout": { + "description": "Label used in bottom navigation, use a short word" + }, + "labelBottomNavNutrition": "Nutrição", + "@labelBottomNavNutrition": { + "description": "Label used in bottom navigation, use a short word" + }, + "labelWorkoutLogs": "Registos de treino", + "@labelWorkoutLogs": { + "description": "(Workout) logs" + }, + "labelWorkoutPlan": "Plano de treino", + "@labelWorkoutPlan": { + "description": "Title for screen workout plan" + }, + "successfullyDeleted": "Excluído", + "@successfullyDeleted": { + "description": "Message when an item was successfully deleted" + }, + "successfullySaved": "Guardado", + "@successfullySaved": { + "description": "Message when an item was successfully saved" + }, + "exerciseList": "Lista de exercícios", + "@exerciseList": {}, + "exercises": "Exercícios", + "@exercises": { + "description": "Multiple exercises for a workout" + }, + "exerciseName": "Nome do exercício", + "@exerciseName": { + "description": "Label for the name of a workout exercise" + }, + "searchExercise": "Pesquisar exercício para adicionar", + "@searchExercise": { + "description": "Label on set form. Selected exercises are added to the set" + }, + "muscles": "Músculos", + "@muscles": { + "description": "(main) muscles trained by an exercise" + }, + "musclesSecondary": "Músculos secundários", + "@musclesSecondary": { + "description": "secondary muscles trained by an exercise" + }, + "category": "Categoria", + "@category": { + "description": "Category for an exercise, ingredient, etc." + }, + "routines": "Rotinas", + "@routines": {}, + "newRoutine": "Nova rotina", + "@newRoutine": {}, + "noRoutines": "Não tens rotinas", + "@noRoutines": {}, + "reps": "Repetições", + "@reps": { + "description": "Shorthand for repetitions, used when space constraints are tighter" + }, + "sets": "Séries", + "@sets": { + "description": "The number of sets to be done for one exercise" + }, + "rir": "ReR", + "@rir": { + "description": "Shorthand for Repetitions In Reserve" + }, + "restTime": "Tempo de descanso", + "@restTime": {}, + "rirNotUsed": "ReR não usado", + "@rirNotUsed": { + "description": "Label used in RiR slider when the RiR value is not used/saved for the current setting or log" + }, + "useMetric": "Usa as unidades métricas para o peso corporal", + "@useMetric": {}, + "weightUnit": "Unidade de peso", + "@weightUnit": {}, + "set": "Série", + "@set": { + "description": "A set in a workout plan" + }, + "needsLogsToAdvance": "Precisa de registos para avançar", + "@needsLogsToAdvance": {}, + "repetitionUnit": "Unidade de repetição", + "@repetitionUnit": {}, + "dayDescriptionHelp": "Uma descrição do que é feito neste dia (por exemplo: 'dia de puxar') ou que partes do corpo são treinadas (por exemplo: 'peito e ombros')", + "@dayDescriptionHelp": {}, + "exerciseNr": "Exercício {nr}", + "@exerciseNr": { + "description": "Header in form indicating the number of the current exercise. Can also be translated as something like 'Set Nr. xy'.", + "type": "text", + "placeholders": { + "nr": { + "type": "String" + } + } + }, + "supersetNr": "Superset {nr}", + "@supersetNr": { + "description": "Header in form indicating the number of the current exercise. Can also be translated as something like 'Superset Nr. xy'.", + "type": "text", + "placeholders": { + "nr": { + "type": "String" + } + } + }, + "sameRepetitions": "Se fizeres as mesmas repetições e peso para todas as séries, poderás preencher apenas uma linha. Por exemplo: para 4 séries basta inserir 10 para as repetições, isso automaticamente se tornará \"4 x 10\".", + "@sameRepetitions": {}, + "impression": "Impressão", + "@impression": { + "description": "General impression (e.g. for a workout session) such as good, bad, etc." + }, + "notes": "Notas", + "@notes": { + "description": "Personal notes, e.g. for a workout session" + }, + "workoutSession": "Sessão de treino", + "@workoutSession": { + "description": "A (logged) workout session" + }, + "isRestDayHelp": "Repara que todas as séries e exercícios serão removidos quando marcas um dia como dia de descanso.", + "@isRestDayHelp": {}, + "restDay": "Dia de descanso", + "@restDay": {}, + "isRestDay": "É dia de descanso", + "@isRestDay": {}, + "selectExercises": "Se quiseres fazer um superset podes procurar por vários exercícios, eles serão agrupados", + "@selectExercises": {}, + "gymMode": "Modo ginásio", + "@gymMode": { + "description": "Label when starting the gym mode" + }, + "plateCalculator": "Anilhas", + "@plateCalculator": { + "description": "Label used for the plate calculator in the gym mode" + }, + "plateCalculatorNotDivisible": "Não é possível compor o peso com as anilhas disponíveis", + "@plateCalculatorNotDivisible": { + "description": "Error message when the current weight is not reachable with plates (e.g. 33.1 kg)" + }, + "pause": "Pausa", + "@pause": { + "description": "Noun, not an imperative! Label used for the pause when using the gym mode" + }, + "jumpTo": "Salta para", + "@jumpTo": { + "description": "Imperative. Label used in popup allowing the user to jump to a specific exercise while in the gym mode" + }, + "todaysWorkout": "O teu treino, hoje", + "@todaysWorkout": {}, + "logHelpEntries": "Se, no mesmo dia, houver mais do que uma entrada com o mesmo número de repetições e pesos diferentes, apenas a entrada com mais peso será mostrada no gráfico.", + "@logHelpEntries": {}, + "logHelpEntriesUnits": "Nota que apenas entradas com uma unidade de peso (kg ou lb) e repetições são mostradas no gráfico. Outras combinações, como por tempo ou até à falha, são ignoradas aqui.", + "@logHelpEntriesUnits": {}, + "description": "Descrição", + "@description": {}, + "name": "Nome", + "@name": { + "description": "Name for a workout or nutritional plan" + }, + "save": "Guardar", + "@save": {}, + "verify": "Verificar", + "@verify": {}, + "addSet": "Adicionar série", + "@addSet": { + "description": "Label for the button that adds a set (to a workout day)" + }, + "addMeal": "Adicional refeição", + "@addMeal": {}, + "mealLogged": "Refeição registada no diário", + "@mealLogged": {}, + "ingredientLogged": "Ingrediente registado no diário", + "@ingredientLogged": {}, + "logMeal": "Registar refeição no diário de nutrição", + "@logMeal": {}, + "addIngredient": "Adicionar ingrediente", + "@addIngredient": {}, + "logIngredient": "Registar ingrediente no diário nutricional", + "@logIngredient": {}, + "searchIngredient": "Pesquisar Ingrediente", + "@searchIngredient": { + "description": "Label on ingredient search form" + }, + "nutritionalPlan": "Plano nutricional", + "@nutritionalPlan": {}, + "nutritionalDiary": "Diário nutricional", + "@nutritionalDiary": {}, + "nutritionalPlans": "Planos nutricionais", + "@nutritionalPlans": {}, + "noNutritionalPlans": "Não tens planos nutricionais", + "@noNutritionalPlans": { + "description": "Message shown when the user has no nutritional plans" + }, + "onlyLogging": "Acompanha apenas as calorias", + "@onlyLogging": {}, + "onlyLoggingHelpText": "Seleciona se apenas pretendes registar as calorias e não queres configurar um plano nutricional detalhado com refeições específicas", + "@onlyLoggingHelpText": {}, + "goalMacro": "Objetivo macro", + "@goalMacro": { + "description": "The goal for macronutrients" + }, + "selectMealToLog": "Seleciona uma refeição para registar no diário", + "@selectMealToLog": {}, + "yourCurrentNutritionPlanHasNoMealsDefinedYet": "O teu plano nutricional corrente não tem refeições defiinidas", + "@yourCurrentNutritionPlanHasNoMealsDefinedYet": { + "description": "Message shown when a nutrition plan doesn't have any meals" + }, + "toAddMealsToThePlanGoToNutritionalPlanDetails": "Para adicionar refeições ao plano, vai aos detalhes do plano nutricional", + "@toAddMealsToThePlanGoToNutritionalPlanDetails": { + "description": "Message shown to guide users to the nutritional plan details page to add meals" + }, + "goalEnergy": "Meta energética", + "@goalEnergy": {}, + "goalProtein": "Meta proteica", + "@goalProtein": {}, + "goalCarbohydrates": "Meta de hidratos de carbono", + "@goalCarbohydrates": {}, + "goalFat": "Meta de gorduras", + "@goalFat": {}, + "goalFiber": "Meta de fibras", + "@goalFiber": {}, + "anErrorOccurred": "Ocorreu um erro!", + "@anErrorOccurred": {}, + "errorInfoDescription": "Perdão, mas algo correu mal. Podes ajudar a corrigir isto relatando o problema no GitHub.", + "@errorInfoDescription": {}, + "errorInfoDescription2": "Podes continuar a usar a app, mas algumas funções podem não funcionar.", + "@errorInfoDescription2": {}, + "errorViewDetails": "Detalhes técnicos", + "@errorViewDetails": {}, + "errorCouldNotConnectToServer": "Erro ao ligar ao servidor", + "@errorCouldNotConnectToServer": {}, + "copyToClipboard": "Copia para a memória", + "@copyToClipboard": {}, + "weight": "Peso", + "@weight": { + "description": "The weight of a workout log or body weight entry" + }, + "min": "Min", + "@min": {}, + "max": "Máximo", + "@max": {}, + "chartAllTimeTitle": "{name} de sempre", + "@chartAllTimeTitle": { + "description": "All-time chart of 'name' (e.g. 'weight', 'body fat' etc.)", + "type": "text", + "placeholders": { + "name": { + "type": "String" + } + } + }, + "chart30DaysTitle": "{name} dos últimos 30 dias", + "@chart30DaysTitle": { + "description": "last 30 days chart of 'name' (e.g. 'weight', 'body fat' etc.)", + "type": "text", + "placeholders": { + "name": { + "type": "String" + } + } + }, + "chartDuringPlanTitle": "{chartName} durante plano nutricional {planName}", + "@chartDuringPlanTitle": { + "description": "chart of 'chartName' (e.g. 'weight', 'body fat' etc.) logged during plan", + "type": "text", + "placeholders": { + "chartName": { + "type": "String" + }, + "planName": { + "type": "String" + } + } + }, + "measurement": "Medição", + "@measurement": {}, + "measurementCategoriesHelpText": "Categoria de valores, como 'biceps' ou 'gordura corporal'", + "@measurementCategoriesHelpText": {}, + "measurementEntriesHelpText": "A unidade usada para medir a categoria, como 'cm' ou '%'", + "@measurementEntriesHelpText": {}, + "date": "Data", + "@date": { + "description": "The date of a workout log or body weight entry" + }, + "value": "Valor", + "@value": { + "description": "The value of a measurement entry" + }, + "time": "Tempo", + "@time": { + "description": "The time of a meal or workout" + }, + "timeStart": "Hora de início", + "@timeStart": { + "description": "The starting time of a workout" + }, + "timeEnd": "Tempo final", + "@timeEnd": { + "description": "The end time of a workout" + }, + "timeStartAhead": "O horário de início não pode ser anterior ao horário de término", + "@timeStartAhead": {}, + "ingredient": "Ingrediente", + "@ingredient": {}, + "energy": "Energia", + "@energy": { + "description": "Energy in a meal, ingredient etc. e.g. in kJ" + }, + "planned": "Planeado", + "@planned": { + "description": "Header for the column of 'planned' nutritional values, i.e. what should be eaten" + }, + "logged": "Registado", + "@logged": { + "description": "Header for the column of 'logged' nutritional values, i.e. what was eaten" + }, + "today": "Hoje", + "@today": {}, + "loggedToday": "Registado hoje", + "@loggedToday": {}, + "weekAverage": "Média de 7 dias", + "@weekAverage": { + "description": "Header for the column of '7 day average' nutritional values, i.e. what was logged last week" + }, + "surplus": "excedente", + "@surplus": { + "description": "Caloric surplus (either planned or unplanned)" + }, + "deficit": "déficit", + "@deficit": { + "description": "Caloric deficit (either planned or unplanned)" + }, + "difference": "Diferença", + "@difference": {}, + "percentEnergy": "Percentagem de energia", + "@percentEnergy": {}, + "gPerBodyKg": "g por kg corporal", + "@gPerBodyKg": { + "description": "Label used for total sums of e.g. calories or similar in grams per Kg of body weight" + }, + "total": "Total", + "@total": { + "description": "Label used for total sums of e.g. calories or similar" + }, + "kcal": "kcal", + "@kcal": { + "description": "Energy in a meal in kilocalories, kcal" + }, + "kJ": "kJ", + "@kJ": { + "description": "Energy in a meal in kilo joules, kJ" + }, + "g": "g", + "@g": { + "description": "Abbreviation for gram" + }, + "gValue": "{value} g", + "@gValue": { + "description": "A value in grams, e.g. 5 g", + "type": "text", + "placeholders": { + "value": { + "type": "String" + } + } + }, + "logout": "Sair", + "@logout": { + "description": "Text for logout button" + }, + "noIngredientsDefined": "Nenhum ingrediente definido, ainda", + "@noIngredientsDefined": {}, + "routineDays": "Dias na rotina", + "@routineDays": {}, + "newDay": "Novo dia", + "@newDay": {}, + "newSet": "Nova série", + "@newSet": { + "description": "Header when adding a new set to a workout day" + }, + "kcalValue": "{value} kcal", + "@kcalValue": { + "description": "A value in kcal, e.g. 500 kcal", + "type": "text", + "placeholders": { + "value": { + "type": "String" + } + } + }, + "protein": "Proteína", + "@protein": {}, + "resultingRoutine": "Rotina resultante", + "@resultingRoutine": {}, + "errorCouldNotConnectToServerDetails": "A aplicação não conseguiu ligar-se ao servidor. Por favor, verifica a ligação à Internet ou o URL do servidor e tenta novamente. Se o problema persistir, contacta o administrador do servidor.", + "@errorCouldNotConnectToServerDetails": {}, + "needsLogsToAdvanceHelp": "Seleciona se queres que a rotina progrida para o próximo dia agendado apenas se registaste um treino para o dia", + "@needsLogsToAdvanceHelp": {}, + "start": "Começar", + "@start": { + "description": "Label on button to start the gym mode (i.e., an imperative)" + }, + "energyShort": "E", + "@energyShort": { + "description": "The first letter or short name of the word 'Energy', used in overviews" + }, + "macronutrients": "Macronutrientes", + "@macronutrients": {}, + "proteinShort": "P", + "@proteinShort": { + "description": "The first letter or short name of the word 'Protein', used in overviews" + }, + "measurements": "Medidas", + "@measurements": { + "description": "Categories for the measurements such as biceps size, body fat, etc." + }, + "percentValue": "{value} %", + "@percentValue": { + "description": "A value in percent, e.g. 10 %", + "type": "text", + "placeholders": { + "value": { + "type": "String" + } + } + } +} From 1df4039fca270a070cbb0081a6babd8265c0dca7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ningu=C3=A9m=20Mesmo?= Date: Thu, 26 Jun 2025 00:13:19 +0200 Subject: [PATCH 19/89] Translated using Weblate (Portuguese (Portugal)) Currently translated at 49.0% (153 of 312 strings) Translation: wger Workout Manager/Mobile App Translate-URL: https://hosted.weblate.org/projects/wger/mobile/pt_PT/ --- lib/l10n/app_pt_PT.arb | 271 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 271 insertions(+) diff --git a/lib/l10n/app_pt_PT.arb b/lib/l10n/app_pt_PT.arb index 4ad8e2bc..af9c75ac 100644 --- a/lib/l10n/app_pt_PT.arb +++ b/lib/l10n/app_pt_PT.arb @@ -539,5 +539,276 @@ "type": "String" } } + }, + "carbohydrates": "Hidratos de carbono", + "@carbohydrates": {}, + "carbohydratesShort": "HC", + "@carbohydratesShort": { + "description": "The first letter or short name of the word 'Carbohydrates', used in overviews" + }, + "sugars": "Açúcares", + "@sugars": {}, + "fat": "Gordura", + "@fat": {}, + "fatShort": "G", + "@fatShort": { + "description": "The first letter or short name of the word 'Fat', used in overviews" + }, + "fiber": "Fibra", + "@fiber": {}, + "sodium": "Sódio", + "@sodium": {}, + "amount": "Quantidade", + "@amount": { + "description": "The amount (e.g. in grams) of an ingredient in a meal" + }, + "unit": "Unidade", + "@unit": { + "description": "The unit used for a repetition (kg, time, etc.)" + }, + "newEntry": "Nova entrada", + "@newEntry": { + "description": "Title when adding a new entry such as a weight or log entry" + }, + "noMeasurementEntries": "Não tens registos de medidas", + "@noMeasurementEntries": {}, + "aboutDescription": "Obrigado por usar o Wger! Wger é um projeto colaborativo de código aberto, feito por entusiastas do exercício de todo o mundo.", + "@aboutDescription": { + "description": "Text in the about dialog" + }, + "aboutDonateTitle": "Faz uma doação", + "@aboutDonateTitle": {}, + "aboutDonateText": "Embora o projeto seja gratuito, e sê-lo-á sempre, manter o servidor não o é! O desenvolvimento também leva um tempo e esforço significativo dos voluntários. O teu contributo suporta diretamente estes custos ajudando a garantir o serviço.", + "@aboutDonateText": {}, + "aboutContributeTitle": "Contribui", + "@aboutContributeTitle": {}, + "aboutContributeText": "Todos os tipos de contribuição são encorajados. Sejas um desenvolvedor, tradutor ou apenas um apaixonado pelo exercício, todas as migalhas de ajuda são apreciadas!", + "@aboutContributeText": {}, + "aboutBugsListTitle": "Relata um problema ou sugere uma funcionalidade", + "@aboutBugsListTitle": {}, + "aboutTranslationListTitle": "Traduz a aplicação", + "@aboutTranslationListTitle": {}, + "aboutSourceListTitle": "Vê o código fonte", + "@aboutSourceListTitle": {}, + "aboutJoinCommunityTitle": "Junta-te à comunidade", + "@aboutJoinCommunityTitle": {}, + "aboutMastodonTitle": "Mastodon", + "@aboutMastodonTitle": {}, + "aboutDiscordTitle": "Discord", + "@aboutDiscordTitle": {}, + "others": "Outros", + "@others": {}, + "calendar": "Calendário", + "@calendar": {}, + "goToToday": "Vai para hoje", + "@goToToday": { + "description": "Label on button to jump back to 'today' in the calendar widget" + }, + "enterValue": "Por favor, insere um valor", + "@enterValue": { + "description": "Error message when the user hasn't entered a value on a required field" + }, + "selectEntry": "Por favor, selecione uma entrada", + "@selectEntry": {}, + "selectExercise": "Por favor, selecione um exercício", + "@selectExercise": { + "description": "Error message when the user hasn't selected an exercise in the form" + }, + "enterCharacters": "Por favor, utiliza entre {min} e {max} caracteres", + "@enterCharacters": { + "description": "Error message when the user hasn't entered the correct number of characters in a form", + "type": "text", + "placeholders": { + "min": { + "type": "String" + }, + "max": { + "type": "String" + } + } + }, + "enterMinCharacters": "Por favor, utiliza pelo menos {min} caracteres", + "@enterMinCharacters": { + "description": "Error message when the user hasn't entered the minimum amount characters in a form", + "type": "text", + "placeholders": { + "min": { + "type": "String" + } + } + }, + "baseNameEnglish": "Todos os exercícios necessitam de um nome base em inglês", + "@baseNameEnglish": {}, + "nrOfSets": "Séries por exercício: {nrOfSets}", + "@nrOfSets": { + "description": "Label shown on the slider where the user selects the nr of sets", + "type": "text", + "placeholders": { + "nrOfSets": { + "type": "String" + } + } + }, + "optionsLabel": "Opções", + "@optionsLabel": { + "description": "Label for the popup with general app options" + }, + "takePicture": "Tira uma fotografia", + "@takePicture": {}, + "chooseFromLibrary": "Escolher da galeria de fotos", + "@chooseFromLibrary": {}, + "gallery": "Galeria", + "@gallery": {}, + "addImage": "Adicionar imagem", + "@addImage": {}, + "appUpdateContent": "Esta versão da aplicação não é compatível com o servidor. Por favor, atualiza a aplicação.", + "@appUpdateContent": {}, + "productNotFoundDescription": "O produto com o código de barras digitalizado {barcode} não foi encontrado na base de dados do wger", + "@productNotFoundDescription": { + "description": "Dialog info when product is not found with barcode", + "type": "text", + "placeholders": { + "barcode": { + "type": "String" + } + } + }, + "scanBarcode": "Digitaliza o código de barras", + "@scanBarcode": { + "description": "Label for scan barcode button" + }, + "close": "Fechar", + "@close": { + "description": "Translation for close" + }, + "add_exercise_image_license": "As imagens devem ser compatíveis com a licença CC BY SA. Em caso de dúvida, carrega apenas fotos que tenhas tirado tu.", + "@add_exercise_image_license": {}, + "variations": "Variações", + "@variations": { + "description": "Variations of one exercise (e.g. benchpress and benchpress narrow)" + }, + "verifiedEmail": "Email verificado", + "@verifiedEmail": {}, + "verifiedEmailReason": "Tens de verificar o teu email para contribuir com exercícios", + "@verifiedEmailReason": {}, + "verifiedEmailInfo": "Um email de verificação foi enviado para {email}", + "@verifiedEmailInfo": { + "placeholders": { + "email": { + "type": "String" + } + } + }, + "alternativeNames": "Nomes alternativos", + "@alternativeNames": {}, + "oneNamePerLine": "Um nome por linha", + "@oneNamePerLine": {}, + "whatVariationsExist": "Que variações deste exercício existem, se houver?", + "@whatVariationsExist": {}, + "previous": "Anterior", + "@previous": {}, + "next": "Próximo", + "@next": {}, + "images": "Imagens", + "@images": {}, + "language": "Linguagem", + "@language": {}, + "addExercise": "Adicionar exercício", + "@addExercise": {}, + "fitInWeek": "Encaixa na semana", + "@fitInWeek": {}, + "toggleDetails": "Alternar detalhes", + "@toggleDetails": { + "description": "Switch to toggle detail / overview" + }, + "edit": "Editar", + "@edit": {}, + "aboutWhySupportTitle": "Código aberto & livre para usar ❤️", + "@aboutWhySupportTitle": {}, + "goToDetailPage": "Ir para a página de detalhes", + "@goToDetailPage": {}, + "productFound": "Produto encontrado", + "@productFound": { + "description": "Header label for dialog when product is found with barcode" + }, + "unVerifiedEmail": "Email não verificado", + "@unVerifiedEmail": {}, + "moreMeasurementEntries": "Adiciona nova medição", + "@moreMeasurementEntries": { + "description": "Message shown when the user wants to add new measurement" + }, + "selectIngredient": "Por favor, seleciona um ingrediente", + "@selectIngredient": { + "description": "Error message when the user hasn't selected an ingredient from the autocompleter" + }, + "newNutritionalPlan": "Novo plano nutricional", + "@newNutritionalPlan": {}, + "setUnitsAndRir": "Configura unidades e ReR", + "@setUnitsAndRir": { + "description": "Label shown on the slider where the user can toggle showing units and RiR", + "type": "text" + }, + "saturatedFat": "Gordura saturada", + "@saturatedFat": {}, + "selectImage": "Por favor, seleciona uma imagem", + "@selectImage": { + "description": "Label and error message when the user hasn't selected an image to save" + }, + "appUpdateTitle": "Atualização necessária", + "@appUpdateTitle": {}, + "noWeightEntries": "Não tens registos de peso", + "@noWeightEntries": { + "description": "Message shown when the user has no logged weight entries" + }, + "confirmDelete": "Tens certeza de que desejas excluir '{toDelete}'?", + "@confirmDelete": { + "description": "Confirmation text before the user deletes an object", + "type": "text", + "placeholders": { + "toDelete": { + "type": "String" + } + } + }, + "recentlyUsedIngredients": "Ingredientes adicionados recentemente", + "@recentlyUsedIngredients": { + "description": "A message when a user adds a new ingredient to a meal." + }, + "loadingText": "A carregar...", + "@loadingText": { + "description": "Text to show when entries are being loaded in the background: Loading..." + }, + "delete": "Excluir", + "@delete": {}, + "productNotFound": "Produto não encontrado", + "@productNotFound": { + "description": "Header label for dialog when product is not found with barcode" + }, + "enterValidNumber": "Por favor, insere um número válido", + "@enterValidNumber": { + "description": "Error message when the user has submitted an invalid number (e.g. '3,.,.,.')" + }, + "dataCopied": "Dados copiados para a nova entrada", + "@dataCopied": { + "description": "Snackbar message to show on copying data to a new log entry" + }, + "productFoundDescription": "O código de barras corresponde a este produto: {productName}. Queres continuar?", + "@productFoundDescription": { + "description": "Dialog info when product is found with barcode", + "type": "text", + "placeholders": { + "productName": { + "type": "String" + } + } + }, + "alsoKnownAs": "Também conhecido como:{aliases}", + "@alsoKnownAs": { + "placeholders": { + "aliases": { + "type": "String" + } + }, + "description": "List of alternative names for an exercise" } } From 957c0f136690f290da3d4ede13035771abdc2c41 Mon Sep 17 00:00:00 2001 From: Paulkit Date: Sun, 29 Jun 2025 07:45:37 +0200 Subject: [PATCH 20/89] Translated using Weblate (Chinese (Traditional Han script)) Currently translated at 83.6% (261 of 312 strings) Translation: wger Workout Manager/Mobile App Translate-URL: https://hosted.weblate.org/projects/wger/mobile/zh_Hant/ --- lib/l10n/app_zh_Hant.arb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/l10n/app_zh_Hant.arb b/lib/l10n/app_zh_Hant.arb index 03a2b3fe..4281fb2d 100644 --- a/lib/l10n/app_zh_Hant.arb +++ b/lib/l10n/app_zh_Hant.arb @@ -938,5 +938,11 @@ "ingredientLogged": "食材已紀錄到日記", "@ingredientLogged": {}, "selectMealToLog": "選擇要紀錄到日記的餐點", - "@selectMealToLog": {} + "@selectMealToLog": {}, + "errorCouldNotConnectToServerDetails": "無法連接到伺服器", + "@errorCouldNotConnectToServerDetails": {}, + "copyToClipboard": "複製到剪貼簿", + "@copyToClipboard": {}, + "aboutWhySupportTitle": "開源且免費使用❤️", + "@aboutWhySupportTitle": {} } From 6afbb2f320564274052aa07a47119feb1a0c1b8e Mon Sep 17 00:00:00 2001 From: "Omer I.S" Date: Sat, 5 Jul 2025 23:12:55 +0200 Subject: [PATCH 21/89] Translated using Weblate (Hebrew) Currently translated at 79.4% (248 of 312 strings) Translation: wger Workout Manager/Mobile App Translate-URL: https://hosted.weblate.org/projects/wger/mobile/he/ --- lib/l10n/app_he.arb | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/lib/l10n/app_he.arb b/lib/l10n/app_he.arb index 5c4ca82c..45d46d19 100644 --- a/lib/l10n/app_he.arb +++ b/lib/l10n/app_he.arb @@ -326,7 +326,7 @@ "@reset": { "description": "Button text allowing the user to reset the entered values to the default" }, - "loginInstead": "הכנס במקום", + "loginInstead": "כבר יש לך חשבון? ניתן להיכנס", "@loginInstead": {}, "selectExercise": "אנא בחר/י אימון", "@selectExercise": { @@ -447,7 +447,7 @@ "@logHelpEntries": {}, "searchNamesInEnglish": "חפש גם לפי שמות באנגלית", "@searchNamesInEnglish": {}, - "success": "מוצלח", + "success": "הפעולה צלחה", "@success": { "description": "Message when an action completed successfully, usually used as a heading" }, @@ -466,5 +466,35 @@ "noMatchingExerciseFound": "לא נמצאו תרגילים תואמים", "@noMatchingExerciseFound": { "description": "Message returned if no exercises match the searched string" + }, + "useColors": "שימוש בצבעים", + "@useColors": {}, + "useApiToken": "שימוש באסימון API", + "@useApiToken": {}, + "useUsernameAndPassword": "שימוש בשם משתמש וסיסמה", + "@useUsernameAndPassword": {}, + "apiToken": "אסימון API", + "@apiToken": {}, + "invalidApiToken": "נא להקליד אסימון API תקין", + "@invalidApiToken": { + "description": "Error message when the user enters an invalid API key" + }, + "routines": "שגרות", + "@routines": {}, + "newRoutine": "שגרה חדשה", + "@newRoutine": {}, + "noRoutines": "אין לך שגרות", + "@noRoutines": {}, + "restDay": "יום מנוחה", + "@restDay": {}, + "isRestDay": "הוא יום מנוחה", + "@isRestDay": {}, + "routineDays": "ימים בשגרה", + "@routineDays": {}, + "verify": "אימות", + "@verify": {}, + "searchIngredient": "חיפוש רכיב", + "@searchIngredient": { + "description": "Label on ingredient search form" } -} \ No newline at end of file +} From 5510efa4999a2bcb5229046b2b6f505f57c55337 Mon Sep 17 00:00:00 2001 From: "Omer I.S" Date: Sat, 5 Jul 2025 23:15:21 +0200 Subject: [PATCH 22/89] Translated using Weblate (Hebrew) Currently translated at 79.4% (248 of 312 strings) Translation: wger Workout Manager/Mobile App Translate-URL: https://hosted.weblate.org/projects/wger/mobile/he/ --- lib/l10n/app_he.arb | 64 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/lib/l10n/app_he.arb b/lib/l10n/app_he.arb index 45d46d19..e082de32 100644 --- a/lib/l10n/app_he.arb +++ b/lib/l10n/app_he.arb @@ -493,8 +493,68 @@ "@routineDays": {}, "verify": "אימות", "@verify": {}, - "searchIngredient": "חיפוש רכיב", + "searchIngredient": "חיפוש מרכיב", "@searchIngredient": { "description": "Label on ingredient search form" - } + }, + "onlyLogging": "מעקב אחר קלוריות בלבד", + "@onlyLogging": {}, + "goalMacro": "מטרות מזעריות", + "@goalMacro": { + "description": "The goal for macronutrients" + }, + "goalEnergy": "יעד אנרגיה", + "@goalEnergy": {}, + "goalProtein": "יעד חלבונים", + "@goalProtein": {}, + "goalFat": "יעד שומנים", + "@goalFat": {}, + "goalFiber": "יעד סיבים תזונתיים", + "@goalFiber": {}, + "errorViewDetails": "פרטים טכניים", + "@errorViewDetails": {}, + "errorCouldNotConnectToServer": "לא היה ניתן להתחבר לשרת", + "@errorCouldNotConnectToServer": {}, + "min": "מינ׳", + "@min": {}, + "max": "מקס׳", + "@max": {}, + "today": "היום", + "@today": {}, + "weekAverage": "ממוצע שבועי", + "@weekAverage": { + "description": "Header for the column of '7 day average' nutritional values, i.e. what was logged last week" + }, + "kcalValue": "{value} ק׳ קלוריות", + "@kcalValue": { + "description": "A value in kcal, e.g. 500 kcal", + "type": "text", + "placeholders": { + "value": { + "type": "String" + } + } + }, + "gValue": "{value} גר׳", + "@gValue": { + "description": "A value in grams, e.g. 5 g", + "type": "text", + "placeholders": { + "value": { + "type": "String" + } + } + }, + "percentValue": "{value}%", + "@percentValue": { + "description": "A value in percent, e.g. 10 %", + "type": "text", + "placeholders": { + "value": { + "type": "String" + } + } + }, + "aboutWhySupportTitle": "תוכנה בקוד פתוח, וחופשית לשימוש", + "@aboutWhySupportTitle": {} } From ad3067d69c7b2685bb454c3375560e4c00eabec6 Mon Sep 17 00:00:00 2001 From: "Omer I.S" Date: Sat, 5 Jul 2025 23:19:31 +0200 Subject: [PATCH 23/89] Translated using Weblate (Hebrew) Currently translated at 79.4% (248 of 312 strings) Translation: wger Workout Manager/Mobile App Translate-URL: https://hosted.weblate.org/projects/wger/mobile/he/ --- lib/l10n/app_he.arb | 89 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 87 insertions(+), 2 deletions(-) diff --git a/lib/l10n/app_he.arb b/lib/l10n/app_he.arb index e082de32..e686174c 100644 --- a/lib/l10n/app_he.arb +++ b/lib/l10n/app_he.arb @@ -555,6 +555,91 @@ } } }, - "aboutWhySupportTitle": "תוכנה בקוד פתוח, וחופשית לשימוש", - "@aboutWhySupportTitle": {} + "aboutWhySupportTitle": "תוכנה בקוד פתוח, וחופשית לשימוש ❤️", + "@aboutWhySupportTitle": {}, + "aboutDonateTitle": "תרומה כספית", + "@aboutDonateTitle": {}, + "aboutContributeTitle": "התנדבות", + "@aboutContributeTitle": {}, + "aboutTranslationListTitle": "עזרה בתרגום היישום", + "@aboutTranslationListTitle": {}, + "aboutSourceListTitle": "צפייה בקוד המקור", + "@aboutSourceListTitle": {}, + "aboutJoinCommunityTitle": "הצטרפות לקהילה", + "@aboutJoinCommunityTitle": {}, + "others": "אחרים", + "@others": {}, + "selectEntry": "נא לבחור ערך", + "@selectEntry": {}, + "recentlyUsedIngredients": "מרכיבים שנוספו לאחרונה", + "@recentlyUsedIngredients": { + "description": "A message when a user adds a new ingredient to a meal." + }, + "appUpdateTitle": "צריך לעדכן", + "@appUpdateTitle": {}, + "appUpdateContent": "גרסה זו של היישום אינה מסוגלת להתחבר לשרת, נא לעדכן את היישום.", + "@appUpdateContent": {}, + "productFound": "המוצר נמצא", + "@productFound": { + "description": "Header label for dialog when product is found with barcode" + }, + "productNotFound": "המוצר לא נמצא", + "@productNotFound": { + "description": "Header label for dialog when product is not found with barcode" + }, + "scanBarcode": "סריקת ברקוד", + "@scanBarcode": { + "description": "Label for scan barcode button" + }, + "close": "סגירה", + "@close": { + "description": "Translation for close" + }, + "alsoKnownAs": "מוכר גם בתור: {aliases}", + "@alsoKnownAs": { + "placeholders": { + "aliases": { + "type": "String" + } + }, + "description": "List of alternative names for an exercise" + }, + "alternativeNames": "שמות חלופיים", + "@alternativeNames": {}, + "previous": "הקודם", + "@previous": {}, + "next": "הבא", + "@next": {}, + "images": "תמונות", + "@images": {}, + "language": "שפה", + "@language": {}, + "addExercise": "הוספת תרגיל", + "@addExercise": {}, + "translation": "תרגום", + "@translation": {}, + "translateExercise": "לתרגם את התרגיל הזה כעת", + "@translateExercise": {}, + "settingsTitle": "הגדרות", + "@settingsTitle": {}, + "settingsCacheTitle": "מטמון", + "@settingsCacheTitle": {}, + "settingsExerciseCacheDescription": "מטמון תרגילים", + "@settingsExerciseCacheDescription": {}, + "aboutPageTitle": "מידע כללי ותמיכה", + "@aboutPageTitle": {}, + "simpleMode": "מצב פשוט", + "@simpleMode": {}, + "arms": "זרועות", + "@arms": { + "description": "Generated entry for translation for server strings" + }, + "back": "גב", + "@back": { + "description": "Generated entry for translation for server strings" + }, + "biceps": "שרירי הקיבורת", + "@biceps": { + "description": "Generated entry for translation for server strings" + } } From 91a30704f35c4109975cdf3ac88b52b35066cd2c Mon Sep 17 00:00:00 2001 From: "Omer I.S" Date: Sat, 5 Jul 2025 23:20:53 +0200 Subject: [PATCH 24/89] Translated using Weblate (Hebrew) Currently translated at 79.4% (248 of 312 strings) Translation: wger Workout Manager/Mobile App Translate-URL: https://hosted.weblate.org/projects/wger/mobile/he/ --- lib/l10n/app_he.arb | 54 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/lib/l10n/app_he.arb b/lib/l10n/app_he.arb index e686174c..599f9e1e 100644 --- a/lib/l10n/app_he.arb +++ b/lib/l10n/app_he.arb @@ -638,8 +638,60 @@ "@back": { "description": "Generated entry for translation for server strings" }, - "biceps": "שרירי הקיבורת", + "biceps": "שרירי הקיבורת (דו־ראשיים)", "@biceps": { "description": "Generated entry for translation for server strings" + }, + "body_weight": "משקל הגוף", + "@body_weight": { + "description": "Generated entry for translation for server strings" + }, + "cardio": "סיבולת", + "@cardio": { + "description": "Generated entry for translation for server strings" + }, + "chest": "חזה", + "@chest": { + "description": "Generated entry for translation for server strings" + }, + "gym_mat": "שטיח אימונים", + "@gym_mat": { + "description": "Generated entry for translation for server strings" + }, + "kilometers": "קילומטרים", + "@kilometers": { + "description": "Generated entry for translation for server strings" + }, + "kilometers_per_hour": "קילומטרים לשעה", + "@kilometers_per_hour": { + "description": "Generated entry for translation for server strings" + }, + "miles": "מילים", + "@miles": { + "description": "Generated entry for translation for server strings" + }, + "miles_per_hour": "מילים לשעה", + "@miles_per_hour": { + "description": "Generated entry for translation for server strings" + }, + "minutes": "דקות", + "@minutes": { + "description": "Generated entry for translation for server strings" + }, + "resistance_band": "רצועת התנגדות", + "@resistance_band": { + "description": "Generated entry for translation for server strings" + }, + "seconds": "שניות", + "@seconds": { + "description": "Generated entry for translation for server strings" + }, + "shoulders": "כתפיים", + "@shoulders": { + "description": "Generated entry for translation for server strings" + }, + "triceps": "שרירים תלת־ראשיים", + "@triceps": { + "description": "Generated entry for translation for server strings" } } From 441dcd7a760342d50628910e8bba969ca2e0a67e Mon Sep 17 00:00:00 2001 From: "Omer I.S" Date: Sat, 5 Jul 2025 23:41:23 +0200 Subject: [PATCH 25/89] Translated using Weblate (Hebrew) Currently translated at 79.4% (248 of 312 strings) Translation: wger Workout Manager/Mobile App Translate-URL: https://hosted.weblate.org/projects/wger/mobile/he/ --- lib/l10n/app_he.arb | 52 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/lib/l10n/app_he.arb b/lib/l10n/app_he.arb index 599f9e1e..d973db60 100644 --- a/lib/l10n/app_he.arb +++ b/lib/l10n/app_he.arb @@ -45,7 +45,7 @@ "@customServerHint": { "description": "Hint text for the form where the users can enter their own wger instance" }, - "labelWorkoutLogs": "יומני אימון", + "labelWorkoutLogs": "אימונים מתועדים", "@labelWorkoutLogs": { "description": "(Workout) logs" }, @@ -57,7 +57,7 @@ "@labelDashboard": { "description": "Title for screen dashboard" }, - "successfullyDeleted": "נמחק", + "successfullyDeleted": "המחיקה בוצעה", "@successfullyDeleted": { "description": "Message when an item was successfully deleted" }, @@ -69,7 +69,7 @@ "@exercise": { "description": "An exercise for a workout" }, - "searchExercise": "חיפוש תרגיל כושר להוספה", + "searchExercise": "חיפוש תרגילים להוספה", "@searchExercise": { "description": "Label on set form. Selected exercises are added to the set" }, @@ -165,7 +165,7 @@ "@mealLogged": {}, "addIngredient": "הוספת מרכיב", "@addIngredient": {}, - "nutritionalPlan": "תוכנית תזונה", + "nutritionalPlan": "תכנון תזונתי", "@nutritionalPlan": {}, "nutritionalDiary": "יומן תזונה", "@nutritionalDiary": {}, @@ -199,7 +199,7 @@ "@value": { "description": "The value of a measurement entry" }, - "start": "התחל", + "start": "התחלה", "@start": { "description": "Label on button to start the gym mode (i.e., an imperative)" }, @@ -223,7 +223,7 @@ "@energy": { "description": "Energy in a meal, ingredient etc. e.g. in kJ" }, - "logMeal": "רשום את הארוחה הזאת", + "logMeal": "תיעוד הארוחה ביומן התזונתי", "@logMeal": {}, "logHelpEntriesUnits": "שים לב שרק רשומות עם יחידת משקל (ק\"ג או ליברות) וחזרות הן ממופות, ישנה התעלמות משילובים אחרים כגון זמן או עד כשלון.", "@logHelpEntriesUnits": {}, @@ -243,7 +243,7 @@ "@difference": {}, "percentEnergy": "אחוז של אנרגיה", "@percentEnergy": {}, - "total": "סה\"כ", + "total": "סה״כ", "@total": { "description": "Label used for total sums of e.g. calories or similar" }, @@ -273,7 +273,7 @@ "@amount": { "description": "The amount (e.g. in grams) of an ingredient in a meal" }, - "unit": "יחידה", + "unit": "יחידת מידה", "@unit": { "description": "The unit used for a repetition (kg, time, etc.)" }, @@ -690,8 +690,40 @@ "@shoulders": { "description": "Generated entry for translation for server strings" }, - "triceps": "שרירים תלת־ראשיים", + "triceps": "השרירים התלת־ראשיים", "@triceps": { "description": "Generated entry for translation for server strings" - } + }, + "kg": "ק״ג", + "@kg": { + "description": "Generated entry for translation for server strings" + }, + "goalTypeBasic": "בסיסי", + "@goalTypeBasic": { + "description": "added for localization of Class GoalType's filed basic" + }, + "goalTypeAdvanced": "מתקדם", + "@goalTypeAdvanced": { + "description": "added for localization of Class GoalType's filed advanced" + }, + "indicatorAvg": "ממוצע", + "@indicatorAvg": { + "description": "added for localization of Class Indicator's field text" + }, + "systemMode": "הגדרות מערכת", + "@systemMode": {}, + "copyToClipboard": "העתקה ללוח", + "@copyToClipboard": {}, + "noIngredientsDefined": "עדיין לא הוגדרו מרכיבים", + "@noIngredientsDefined": {}, + "restTime": "זמן מנוחה", + "@restTime": {}, + "sets": "סטים", + "@sets": { + "description": "The number of sets to be done for one exercise" + }, + "ingredientLogged": "המרכיב תועד ביומן", + "@ingredientLogged": {}, + "logIngredient": "תיעוד המרכיב ביומן התזונתי", + "@logIngredient": {} } From b2156ae0a7302848e1e5c6e02fd81e79995e5522 Mon Sep 17 00:00:00 2001 From: "Omer I.S" Date: Sat, 5 Jul 2025 23:43:29 +0200 Subject: [PATCH 26/89] Translated using Weblate (Hebrew) Currently translated at 79.4% (248 of 312 strings) Translation: wger Workout Manager/Mobile App Translate-URL: https://hosted.weblate.org/projects/wger/mobile/he/ --- lib/l10n/app_he.arb | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/lib/l10n/app_he.arb b/lib/l10n/app_he.arb index d973db60..67cde28a 100644 --- a/lib/l10n/app_he.arb +++ b/lib/l10n/app_he.arb @@ -223,7 +223,7 @@ "@energy": { "description": "Energy in a meal, ingredient etc. e.g. in kJ" }, - "logMeal": "תיעוד הארוחה ביומן התזונתי", + "logMeal": "תיעוד המנה ביומן התזונתי", "@logMeal": {}, "logHelpEntriesUnits": "שים לב שרק רשומות עם יחידת משקל (ק\"ג או ליברות) וחזרות הן ממופות, ישנה התעלמות משילובים אחרים כגון זמן או עד כשלון.", "@logHelpEntriesUnits": {}, @@ -725,5 +725,23 @@ "ingredientLogged": "המרכיב תועד ביומן", "@ingredientLogged": {}, "logIngredient": "תיעוד המרכיב ביומן התזונתי", - "@logIngredient": {} + "@logIngredient": {}, + "errorInfoDescription": "משהו השתבש, עמך הסליחה. ניתן לעזור לנו בתיקון התקלה בעזרת דיווח על הבעיה ב־GitHub.", + "@errorInfoDescription": {}, + "errorInfoDescription2": "אפשר להמשיך להשתמש ביישום, אבל ייתכן כי תכונות מסוימות לא יעבדו.", + "@errorInfoDescription2": {}, + "proteinShort": "חל׳", + "@proteinShort": { + "description": "The first letter or short name of the word 'Protein', used in overviews" + }, + "fatShort": "שומנ׳", + "@fatShort": { + "description": "The first letter or short name of the word 'Fat', used in overviews" + }, + "moreMeasurementEntries": "הוספת מדד חדש", + "@moreMeasurementEntries": { + "description": "Message shown when the user wants to add new measurement" + }, + "aboutBugsListTitle": "דיווח על בעיה או הצגת תכונה", + "@aboutBugsListTitle": {} } From 8e877e8d91cbf84e41069c5288ab3f95f2128b82 Mon Sep 17 00:00:00 2001 From: "Omer I.S" Date: Sat, 5 Jul 2025 23:43:40 +0200 Subject: [PATCH 27/89] Translated using Weblate (Hebrew) Currently translated at 79.4% (248 of 312 strings) Translation: wger Workout Manager/Mobile App Translate-URL: https://hosted.weblate.org/projects/wger/mobile/he/ --- lib/l10n/app_he.arb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/l10n/app_he.arb b/lib/l10n/app_he.arb index 67cde28a..0928bbf5 100644 --- a/lib/l10n/app_he.arb +++ b/lib/l10n/app_he.arb @@ -742,6 +742,6 @@ "@moreMeasurementEntries": { "description": "Message shown when the user wants to add new measurement" }, - "aboutBugsListTitle": "דיווח על בעיה או הצגת תכונה", + "aboutBugsListTitle": "דיווח על בעיה או הצעת תכונה", "@aboutBugsListTitle": {} } From 59c9f5f411b2020e7c712e136cb45989d1160391 Mon Sep 17 00:00:00 2001 From: "Omer I.S" Date: Sun, 6 Jul 2025 00:07:29 +0200 Subject: [PATCH 28/89] Translated using Weblate (Hebrew) Currently translated at 79.4% (248 of 312 strings) Translation: wger Workout Manager/Mobile App Translate-URL: https://hosted.weblate.org/projects/wger/mobile/he/ --- lib/l10n/app_he.arb | 88 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 85 insertions(+), 3 deletions(-) diff --git a/lib/l10n/app_he.arb b/lib/l10n/app_he.arb index 0928bbf5..df2e81f9 100644 --- a/lib/l10n/app_he.arb +++ b/lib/l10n/app_he.arb @@ -129,7 +129,7 @@ "@notes": { "description": "Personal notes, e.g. for a workout session" }, - "workoutSession": "אימון", + "workoutSession": "סשן אימונים", "@workoutSession": { "description": "A (logged) workout session" }, @@ -742,6 +742,88 @@ "@moreMeasurementEntries": { "description": "Message shown when the user wants to add new measurement" }, - "aboutBugsListTitle": "דיווח על בעיה או הצעת תכונה", - "@aboutBugsListTitle": {} + "aboutBugsListTitle": "דיווח על בעיה או הצעת תכונה חדשה", + "@aboutBugsListTitle": {}, + "aboutDiscordTitle": "Discord", + "@aboutDiscordTitle": {}, + "dataCopied": "הנתונים הועתקו לערך החדש", + "@dataCopied": { + "description": "Snackbar message to show on copying data to a new log entry" + }, + "useMetric": "שימוש בשיטה המטרית למדידת משקל הגוף", + "@useMetric": {}, + "selectMealToLog": "בחירת מנה לתיעוד ביומן", + "@selectMealToLog": {}, + "energyShort": "אנרגיה", + "@energyShort": { + "description": "The first letter or short name of the word 'Energy', used in overviews" + }, + "loggedToday": "תועדו היום", + "@loggedToday": {}, + "enterMinCharacters": "נא להקליד לפחות {min} תווים", + "@enterMinCharacters": { + "description": "Error message when the user hasn't entered the minimum amount characters in a form", + "type": "text", + "placeholders": { + "min": { + "type": "String" + } + } + }, + "productFoundDescription": "הברקוד תואם למוצר: {productName}. להמשיך?", + "@productFoundDescription": { + "description": "Dialog info when product is found with barcode", + "type": "text", + "placeholders": { + "productName": { + "type": "String" + } + } + }, + "productNotFoundDescription": "לא נמצא המוצר עם הברקוד שנסרק {barcode} במאגר של wger", + "@productNotFoundDescription": { + "description": "Dialog info when product is not found with barcode", + "type": "text", + "placeholders": { + "barcode": { + "type": "String" + } + } + }, + "verifiedEmail": "דוא״ל מאומת", + "@verifiedEmail": {}, + "unVerifiedEmail": "דוא״ל לא מאומת", + "@unVerifiedEmail": {}, + "verifiedEmailInfo": "נשלחה הודעת אימות לכתובת {email}", + "@verifiedEmailInfo": { + "placeholders": { + "email": { + "type": "String" + } + } + }, + "setHasNoExercises": "עדיין אין אימונים בסט זה!", + "@setHasNoExercises": {}, + "settingsIngredientCacheDescription": "מטמון מרכיב", + "@settingsIngredientCacheDescription": {}, + "settingsCacheDeletedSnackbar": "המטמון נוקה בהצלחה", + "@settingsCacheDeletedSnackbar": {}, + "textPromptTitle": "מוכנים להתחיל?", + "@textPromptTitle": {}, + "abs": "שרירי בטן", + "@abs": { + "description": "Generated entry for translation for server strings" + }, + "lb": "פאונד", + "@lb": { + "description": "Generated entry for translation for server strings" + }, + "log": "תיעוד", + "@log": { + "description": "Log a specific meal (imperative form)" + }, + "done": "סיום", + "@done": {}, + "themeMode": "ערכת נושא", + "@themeMode": {} } From 3eeb530d4472109078912654aab5159868fc19a2 Mon Sep 17 00:00:00 2001 From: "Omer I.S" Date: Sun, 6 Jul 2025 00:07:56 +0200 Subject: [PATCH 29/89] Translated using Weblate (Hebrew) Currently translated at 79.4% (248 of 312 strings) Translation: wger Workout Manager/Mobile App Translate-URL: https://hosted.weblate.org/projects/wger/mobile/he/ --- lib/l10n/app_he.arb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/l10n/app_he.arb b/lib/l10n/app_he.arb index df2e81f9..e31ac2b7 100644 --- a/lib/l10n/app_he.arb +++ b/lib/l10n/app_he.arb @@ -824,6 +824,10 @@ }, "done": "סיום", "@done": {}, - "themeMode": "ערכת נושא", - "@themeMode": {} + "themeMode": "ערכת מצב", + "@themeMode": {}, + "darkMode": "מצב כהה תמיד", + "@darkMode": {}, + "lightMode": "מצב בהיר תמיד", + "@lightMode": {} } From ffb46f608196dffbc613d1ec06f6bb6db1dcb47e Mon Sep 17 00:00:00 2001 From: "n,rdo" Date: Sat, 5 Jul 2025 23:35:03 +0200 Subject: [PATCH 30/89] Translated using Weblate (Hebrew) Currently translated at 79.4% (248 of 312 strings) Translation: wger Workout Manager/Mobile App Translate-URL: https://hosted.weblate.org/projects/wger/mobile/he/ --- lib/l10n/app_he.arb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/l10n/app_he.arb b/lib/l10n/app_he.arb index e31ac2b7..e5e34520 100644 --- a/lib/l10n/app_he.arb +++ b/lib/l10n/app_he.arb @@ -49,11 +49,11 @@ "@labelWorkoutLogs": { "description": "(Workout) logs" }, - "labelWorkoutPlan": "תוכנית כושר", + "labelWorkoutPlan": "תוכנית אימונים", "@labelWorkoutPlan": { "description": "Title for screen workout plan" }, - "labelDashboard": "לוח פעולות", + "labelDashboard": "לוח בקרה", "@labelDashboard": { "description": "Title for screen dashboard" }, @@ -65,7 +65,7 @@ "@successfullySaved": { "description": "Message when an item was successfully saved" }, - "exercise": "תרגיל כושר", + "exercise": "תרגיל", "@exercise": { "description": "An exercise for a workout" }, @@ -322,7 +322,7 @@ "description": "Label shown on the slider where the user can toggle showing units and RiR", "type": "text" }, - "reset": "אתחול", + "reset": "איפוס", "@reset": { "description": "Button text allowing the user to reset the entered values to the default" }, @@ -405,7 +405,7 @@ }, "registerInstead": "אין לך חשבון? הירשם עכשיו", "@registerInstead": {}, - "labelBottomNavWorkout": "כושר", + "labelBottomNavWorkout": "אימון", "@labelBottomNavWorkout": { "description": "Label used in bottom navigation, use a short word" }, From 22492d7d10165c2b48c56042afabeec19eccf4b4 Mon Sep 17 00:00:00 2001 From: "Omer I.S" Date: Sun, 6 Jul 2025 00:08:12 +0200 Subject: [PATCH 31/89] Translated using Weblate (Hebrew) Currently translated at 79.4% (248 of 312 strings) Translation: wger Workout Manager/Mobile App Translate-URL: https://hosted.weblate.org/projects/wger/mobile/he/ --- lib/l10n/app_he.arb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/l10n/app_he.arb b/lib/l10n/app_he.arb index e5e34520..f5ec951b 100644 --- a/lib/l10n/app_he.arb +++ b/lib/l10n/app_he.arb @@ -824,10 +824,10 @@ }, "done": "סיום", "@done": {}, - "themeMode": "ערכת מצב", + "themeMode": "ערכת עיצוב", "@themeMode": {}, - "darkMode": "מצב כהה תמיד", + "darkMode": "עיצוב כהה תמיד", "@darkMode": {}, - "lightMode": "מצב בהיר תמיד", + "lightMode": "עיצוב בהיר תמיד", "@lightMode": {} } From e37d8976ceb80689c84fd17bfcb34b043181ea8b Mon Sep 17 00:00:00 2001 From: "Omer I.S" Date: Sat, 5 Jul 2025 23:39:01 +0200 Subject: [PATCH 32/89] Translated using Weblate (Hebrew) Currently translated at 66.6% (2 of 3 strings) Translation: wger Workout Manager/Play Store Translate-URL: https://hosted.weblate.org/projects/wger/play-store/he/ --- fastlane/metadata/android/iw-IL/short_description.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 fastlane/metadata/android/iw-IL/short_description.txt diff --git a/fastlane/metadata/android/iw-IL/short_description.txt b/fastlane/metadata/android/iw-IL/short_description.txt new file mode 100644 index 00000000..bdcc931c --- /dev/null +++ b/fastlane/metadata/android/iw-IL/short_description.txt @@ -0,0 +1 @@ +מעקב אחר כושר גופני, תזונה ומשקל From 0dbcb7518f0121ec36cb34c226f37a0ef1138abd Mon Sep 17 00:00:00 2001 From: "Omer I.S" Date: Wed, 9 Jul 2025 12:14:28 +0200 Subject: [PATCH 33/89] Translated using Weblate (Hebrew) Currently translated at 89.4% (279 of 312 strings) Translation: wger Workout Manager/Mobile App Translate-URL: https://hosted.weblate.org/projects/wger/mobile/he/ --- lib/l10n/app_he.arb | 99 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 98 insertions(+), 1 deletion(-) diff --git a/lib/l10n/app_he.arb b/lib/l10n/app_he.arb index f5ec951b..815fdfec 100644 --- a/lib/l10n/app_he.arb +++ b/lib/l10n/app_he.arb @@ -829,5 +829,102 @@ "darkMode": "עיצוב כהה תמיד", "@darkMode": {}, "lightMode": "עיצוב בהיר תמיד", - "@lightMode": {} + "@lightMode": {}, + "barWeight": "משקל Bar", + "@barWeight": {}, + "apiTokenValidChars": "מפתח API יכול להכיל רק את האותיות a-f, את הספרות 0-9, ועליו להיות באורך 40 תווים בדיוק", + "@apiTokenValidChars": { + "description": "Error message when the user tries to input a API key with forbidden characters" + }, + "exerciseNr": "תרגיל {nr}", + "@exerciseNr": { + "description": "Header in form indicating the number of the current exercise. Can also be translated as something like 'Set Nr. xy'.", + "type": "text", + "placeholders": { + "nr": { + "type": "String" + } + } + }, + "isRestDayHelp": "לתשומת לבך, כל הסטים והתרגילים יוסרו מימים שהגדרת בתור ימי מנוחה.", + "@isRestDayHelp": {}, + "onlyLoggingHelpText": "נא לסמן תיבה זו אך ורק אם ברצונך לתעד את כמות הקלוריות מבלי להגדיר תוכנית תזונתית עם מנות ספציפיות", + "@onlyLoggingHelpText": {}, + "yourCurrentNutritionPlanHasNoMealsDefinedYet": "לא הוגדרו מנות בתוכניות התזונתית הנוכחית שלך", + "@yourCurrentNutritionPlanHasNoMealsDefinedYet": { + "description": "Message shown when a nutrition plan doesn't have any meals" + }, + "toAddMealsToThePlanGoToNutritionalPlanDetails": "לצורך הוספת מנות לתוכנית, יש לגשת לפרטי התוכנית התזונתית", + "@toAddMealsToThePlanGoToNutritionalPlanDetails": { + "description": "Message shown to guide users to the nutritional plan details page to add meals" + }, + "errorCouldNotConnectToServerDetails": "אין באפשרות היישום להתחבר לשרת. נא לבדוק את החיבור לאינטרנט או לכתובת השרת ולנסות שוב. אם הבעיה ממשיכה להתקיים, נא לפנות למנהל השרת.", + "@errorCouldNotConnectToServerDetails": {}, + "chartAllTimeTitle": "{name} בכל הזמנים", + "@chartAllTimeTitle": { + "description": "All-time chart of 'name' (e.g. 'weight', 'body fat' etc.)", + "type": "text", + "placeholders": { + "name": { + "type": "String" + } + } + }, + "chart30DaysTitle": "{name} ב־30 הימים האחרונים", + "@chart30DaysTitle": { + "description": "last 30 days chart of 'name' (e.g. 'weight', 'body fat' etc.)", + "type": "text", + "placeholders": { + "name": { + "type": "String" + } + } + }, + "chartDuringPlanTitle": "{chartName} במסגרת התוכנית התזונתית {planName}", + "@chartDuringPlanTitle": { + "description": "chart of 'chartName' (e.g. 'weight', 'body fat' etc.) logged during plan", + "type": "text", + "placeholders": { + "chartName": { + "type": "String" + }, + "planName": { + "type": "String" + } + } + }, + "aboutDonateText": "בעוד המיזם הזה חופשי ותמיד יישאר כך, תפעול השרת כן עולה לנו כסף! גם הפיתוח דורש השקעה משמעותית של זמן ומאמץ של מתנדבים. התרומה שלך תלך ישירות לכיסוי העלויות האלה, המאפשרות לספק את השירות שלנו נאמנה.", + "@aboutDonateText": {}, + "aboutContributeText": "אנחנו מעודדים את כל סוגי התרומה. בין אם היא מתבטאת בפיתוח קוד, תרגום, או אפילו רק תשוקה לכושר, אנו מעריכים כל סוג של תמיכה!", + "@aboutContributeText": {}, + "aboutMastodonTitle": "Mastodon", + "@aboutMastodonTitle": {}, + "baseNameEnglish": "לכל התרגילים נחוץ שם מקור באנגלית", + "@baseNameEnglish": {}, + "add_exercise_image_license": "על התמונות להיות תואמות לרישיון CC BY SA. אם יש ספק כלשהו, יש להעלות רק תמונות שצילמת בעצמך.", + "@add_exercise_image_license": {}, + "variations": "וריאציות", + "@variations": { + "description": "Variations of one exercise (e.g. benchpress and benchpress narrow)" + }, + "verifiedEmailReason": "עליך לאמת את הדואר האלקטרוני שלך כדי לתרום תרגילים", + "@verifiedEmailReason": {}, + "oneNamePerLine": "שם אחד בכל שורה", + "@oneNamePerLine": {}, + "whatVariationsExist": "מהן הווריאציות שיש לתרגיל זה, אם קיימות?", + "@whatVariationsExist": {}, + "contributeExercise": "לתרום תרגיל", + "@contributeExercise": {}, + "contributeExerciseWarning": "אפשר לתרום תרגילים אך ורק אם החשבון שלך בן יותר מ־{days} ימים וכתובת הדואר האלקטרוני שלך מאומתת", + "@contributeExerciseWarning": { + "description": "Number of days before which a person can add exercise", + "placeholders": { + "days": { + "type": "String", + "example": "14" + } + } + }, + "textPromptSubheading": "לחץ על כפתור הפעולה כדי להתחיל", + "@textPromptSubheading": {} } From 12d26556e2540441fa9ddc17cb63d1d0cb55aaed Mon Sep 17 00:00:00 2001 From: "Omer I.S" Date: Wed, 9 Jul 2025 12:14:50 +0200 Subject: [PATCH 34/89] Translated using Weblate (Hebrew) Currently translated at 89.4% (279 of 312 strings) Translation: wger Workout Manager/Mobile App Translate-URL: https://hosted.weblate.org/projects/wger/mobile/he/ --- lib/l10n/app_he.arb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/l10n/app_he.arb b/lib/l10n/app_he.arb index 815fdfec..d423a117 100644 --- a/lib/l10n/app_he.arb +++ b/lib/l10n/app_he.arb @@ -925,6 +925,10 @@ } } }, - "textPromptSubheading": "לחץ על כפתור הפעולה כדי להתחיל", - "@textPromptSubheading": {} + "textPromptSubheading": "נא ללחוץ על כפתור הפעולה כדי להתחיל", + "@textPromptSubheading": {}, + "bench": "ספסל", + "@bench": { + "description": "Generated entry for translation for server strings" + } } From a5ff90d400c1a07ffe380474c1d480b5f7eecfbe Mon Sep 17 00:00:00 2001 From: "Omer I.S" Date: Wed, 9 Jul 2025 12:17:37 +0200 Subject: [PATCH 35/89] Translated using Weblate (Hebrew) Currently translated at 89.4% (279 of 312 strings) Translation: wger Workout Manager/Mobile App Translate-URL: https://hosted.weblate.org/projects/wger/mobile/he/ --- lib/l10n/app_he.arb | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/lib/l10n/app_he.arb b/lib/l10n/app_he.arb index d423a117..280f8cbe 100644 --- a/lib/l10n/app_he.arb +++ b/lib/l10n/app_he.arb @@ -927,8 +927,36 @@ }, "textPromptSubheading": "נא ללחוץ על כפתור הפעולה כדי להתחיל", "@textPromptSubheading": {}, - "bench": "ספסל", + "bench": "", "@bench": { "description": "Generated entry for translation for server strings" + }, + "dumbbell": "משקולות", + "@dumbbell": { + "description": "Generated entry for translation for server strings" + }, + "kettlebell": "משקולות קטלבל", + "@kettlebell": { + "description": "Generated entry for translation for server strings" + }, + "legs": "רגליים", + "@legs": { + "description": "Generated entry for translation for server strings" + }, + "lower_back": "גב תחתון", + "@lower_back": { + "description": "Generated entry for translation for server strings" + }, + "max_reps": "מספר מרבי של חזרות", + "@max_reps": { + "description": "Generated entry for translation for server strings" + }, + "swiss_ball": "כדור התעמלות", + "@swiss_ball": { + "description": "Generated entry for translation for server strings" + }, + "none__bodyweight_exercise_": "ללא (התרגיל מסתמך על משקל הגוף)", + "@none__bodyweight_exercise_": { + "description": "Generated entry for translation for server strings" } } From 75569700cfb6d622abd14e1c79312b4273816366 Mon Sep 17 00:00:00 2001 From: "Omer I.S" Date: Wed, 9 Jul 2025 12:29:17 +0200 Subject: [PATCH 36/89] Translated using Weblate (Hebrew) Currently translated at 89.4% (279 of 312 strings) Translation: wger Workout Manager/Mobile App Translate-URL: https://hosted.weblate.org/projects/wger/mobile/he/ --- lib/l10n/app_he.arb | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/l10n/app_he.arb b/lib/l10n/app_he.arb index 280f8cbe..84233651 100644 --- a/lib/l10n/app_he.arb +++ b/lib/l10n/app_he.arb @@ -379,7 +379,7 @@ "@gallery": {}, "addImage": "הוסף תמונה", "@addImage": {}, - "email": "כתובת מייל", + "email": "כתובת דואר אלקטרוני", "@email": {}, "username": "שם משתמש", "@username": {}, @@ -399,7 +399,7 @@ "@passwordsDontMatch": { "description": "Error message when the user enters two different passwords during registration" }, - "invalidEmail": "אנא הכנס/י כתובת מייל תקינה", + "invalidEmail": "נא להקליד כתובת דואר אלקטרוני תקינה", "@invalidEmail": { "description": "Error message when the user enters an invalid email" }, @@ -445,7 +445,7 @@ "@selectExercises": {}, "logHelpEntries": "אם ביום אחד ישנה יותר מרשומה אחת עם אותה כמות חזרות, אבל משקל שונה, רק הרשומה עם המשקל הגבוה יותר תופיע בדיאגרמה.", "@logHelpEntries": {}, - "searchNamesInEnglish": "חפש גם לפי שמות באנגלית", + "searchNamesInEnglish": "לחפש גם לפי השמות באנגלית", "@searchNamesInEnglish": {}, "success": "הפעולה צלחה", "@success": { @@ -955,8 +955,12 @@ "@swiss_ball": { "description": "Generated entry for translation for server strings" }, - "none__bodyweight_exercise_": "ללא (התרגיל מסתמך על משקל הגוף)", + "none__bodyweight_exercise_": "ללא (התרגיל מסתמך על משקל גוף)", "@none__bodyweight_exercise_": { "description": "Generated entry for translation for server strings" + }, + "overallChangeWeight": "שינוי כללי", + "@overallChangeWeight": { + "description": "Overall change in weight, added for localization" } } From a914468140b13ce1daa2981e0ba3cb6c37f1c654 Mon Sep 17 00:00:00 2001 From: Chia Wen Tsai Date: Sat, 12 Jul 2025 12:09:20 +0200 Subject: [PATCH 37/89] Translated using Weblate (Chinese (Traditional Han script)) Currently translated at 83.6% (261 of 312 strings) Translation: wger Workout Manager/Mobile App Translate-URL: https://hosted.weblate.org/projects/wger/mobile/zh_Hant/ --- lib/l10n/app_zh_Hant.arb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/l10n/app_zh_Hant.arb b/lib/l10n/app_zh_Hant.arb index 4281fb2d..4f3c985b 100644 --- a/lib/l10n/app_zh_Hant.arb +++ b/lib/l10n/app_zh_Hant.arb @@ -155,7 +155,7 @@ "@repetitionUnit": {}, "dayDescriptionHelp": "描述這一天做了什麼(例如:拉力日)或訓練了哪些部位(例如:胸部和肩膀)", "@dayDescriptionHelp": {}, - "comment": "註釋", + "comment": "註解", "@comment": { "description": "Comment, additional information" }, From 92a3e99448a16f6e3cbe2c4a3e732f7bd211f4af Mon Sep 17 00:00:00 2001 From: FilipeAb Date: Mon, 14 Jul 2025 16:06:54 +0200 Subject: [PATCH 38/89] Translated using Weblate (Portuguese (Portugal)) Currently translated at 100.0% (312 of 312 strings) Translation: wger Workout Manager/Mobile App Translate-URL: https://hosted.weblate.org/projects/wger/mobile/pt_PT/ --- lib/l10n/app_pt_PT.arb | 494 +++++++++++++++++++++++++++++++---------- 1 file changed, 371 insertions(+), 123 deletions(-) diff --git a/lib/l10n/app_pt_PT.arb b/lib/l10n/app_pt_PT.arb index af9c75ac..9b44b776 100644 --- a/lib/l10n/app_pt_PT.arb +++ b/lib/l10n/app_pt_PT.arb @@ -1,5 +1,5 @@ { - "login": "Entrar", + "login": "Iniciar sessão", "@login": { "description": "Text for login button" }, @@ -7,7 +7,7 @@ "@success": { "description": "Message when an action completed successfully, usually used as a heading" }, - "noMatchingExerciseFound": "Nenhum exercício correspondente encontrado", + "noMatchingExerciseFound": "Não foram encontrados exercícios", "@noMatchingExerciseFound": { "description": "Message returned if no exercises match the searched string" }, @@ -19,13 +19,13 @@ "@exercise": { "description": "An exercise for a workout" }, - "usernameValidChars": "O nome de utilizador só pode conter letras, dígitos e os caracteres @, +, ., -, e _", + "usernameValidChars": "O nome de utilizador só pode conter letras, números e os caracteres @, +, ., - e _", "@usernameValidChars": { "description": "Error message when the user tries to register a username with forbidden characters" }, - "searchNamesInEnglish": "Pesquisa também por nomes em inglês", + "searchNamesInEnglish": "Também procurar nomes em inglês", "@searchNamesInEnglish": {}, - "useCustomServer": "Usa um servidor próprio", + "useCustomServer": "Usar servidor personalizado", "@useCustomServer": { "description": "Toggle button allowing users to switch between the default and a custom wger server" }, @@ -43,59 +43,59 @@ "@comment": { "description": "Comment, additional information" }, - "customServerHint": "Introduza o endereço do seu próprio servidor, caso contrário o servidor padrão será usado", + "customServerHint": "Introduz o endereço do teu próprio servidor, senão será usado o predefinido", "@customServerHint": { "description": "Hint text for the form where the users can enter their own wger instance" }, - "useDefaultServer": "Usa o servidor padrão", + "useDefaultServer": "Usar servidor predefinido", "@useDefaultServer": { "description": "Toggle button allowing users to switch between the default and a custom wger server" }, - "invalidUrl": "Por favor, introduz um URL válido", + "invalidUrl": "Introduz um URL válido", "@invalidUrl": { "description": "Error message when the user enters an invalid URL, e.g. in the login form" }, - "passwordsDontMatch": "As palavras passe não coincidem", + "passwordsDontMatch": "As palavras-passe não coincidem", "@passwordsDontMatch": { "description": "Error message when the user enters two different passwords during registration" }, - "passwordTooShort": "A palavra passe é muito pequena", + "passwordTooShort": "A palavra-passe é demasiado curta", "@passwordTooShort": { "description": "Error message when the user a password that is too short" }, - "selectAvailablePlates": "Seleciona as anilhas disponíveis", + "selectAvailablePlates": "Selecionar discos disponíveis", "@selectAvailablePlates": {}, "barWeight": "Peso da barra", "@barWeight": {}, - "useColors": "Usa cores", + "useColors": "Usar cores", "@useColors": {}, - "password": "Palavra passe", + "password": "Palavra-passe", "@password": {}, - "confirmPassword": "Confirma a palavra passe", + "confirmPassword": "Confirmar palavra-passe", "@confirmPassword": {}, - "invalidEmail": "Por favor, insere um endereço de email válido", + "invalidEmail": "Introduz um e-mail válido", "@invalidEmail": { "description": "Error message when the user enters an invalid email" }, - "email": "Endereço de email", + "email": "Endereço de e-mail", "@email": {}, - "username": "Utilizador", + "username": "Nome de utilizador", "@username": {}, - "invalidUsername": "Por favor, insere um nome de utilizador válido", + "invalidUsername": "Introduz um nome de utilizador válido", "@invalidUsername": { "description": "Error message when the user enters an invalid username" }, - "useApiToken": "Usa um código API", + "useApiToken": "Usar Token da API", "@useApiToken": {}, - "useUsernameAndPassword": "Usa nome de utilizador e palavra passe", + "useUsernameAndPassword": "Usar nome de utilizador e palavra-passe", "@useUsernameAndPassword": {}, - "apiToken": "Código API", + "apiToken": "Token da API", "@apiToken": {}, - "invalidApiToken": "Por favor, insere um código API válido", + "invalidApiToken": "Introduz uma chave API válida", "@invalidApiToken": { "description": "Error message when the user enters an invalid API key" }, - "apiTokenValidChars": "Uma chave API pode apenas conter as letras a-f, os números 0-9 e ter exatamente 40 caracteres", + "apiTokenValidChars": "Uma chave API só pode conter letras de a-f, números de 0-9 e ter exatamente 40 caracteres", "@apiTokenValidChars": { "description": "Error message when the user tries to input a API key with forbidden characters" }, @@ -103,13 +103,13 @@ "@customServerUrl": { "description": "Label in the form where the users can enter their own wger instance" }, - "reset": "Redefinir", + "reset": "Repor", "@reset": { "description": "Button text allowing the user to reset the entered values to the default" }, - "registerInstead": "Não tens uma conta? Regista-te agora", + "registerInstead": "Ainda não tens conta? Regista-te agora", "@registerInstead": {}, - "loginInstead": "Já tens uma conta? Entra", + "loginInstead": "Já tens conta? Inicia sessão", "@loginInstead": {}, "labelBottomNavWorkout": "Treino", "@labelBottomNavWorkout": { @@ -127,7 +127,7 @@ "@labelWorkoutPlan": { "description": "Title for screen workout plan" }, - "successfullyDeleted": "Excluído", + "successfullyDeleted": "Eliminado", "@successfullyDeleted": { "description": "Message when an item was successfully deleted" }, @@ -145,7 +145,7 @@ "@exerciseName": { "description": "Label for the name of a workout exercise" }, - "searchExercise": "Pesquisar exercício para adicionar", + "searchExercise": "Procura um exercício para adicionar", "@searchExercise": { "description": "Label on set form. Selected exercises are added to the set" }, @@ -165,7 +165,7 @@ "@routines": {}, "newRoutine": "Nova rotina", "@newRoutine": {}, - "noRoutines": "Não tens rotinas", + "noRoutines": "Ainda não tens rotinas", "@noRoutines": {}, "reps": "Repetições", "@reps": { @@ -175,17 +175,17 @@ "@sets": { "description": "The number of sets to be done for one exercise" }, - "rir": "ReR", + "rir": "Repetições em Reserva", "@rir": { "description": "Shorthand for Repetitions In Reserve" }, "restTime": "Tempo de descanso", "@restTime": {}, - "rirNotUsed": "ReR não usado", + "rirNotUsed": "ReR não utilizado", "@rirNotUsed": { "description": "Label used in RiR slider when the RiR value is not used/saved for the current setting or log" }, - "useMetric": "Usa as unidades métricas para o peso corporal", + "useMetric": "Usar unidades métricas para peso corporal", "@useMetric": {}, "weightUnit": "Unidade de peso", "@weightUnit": {}, @@ -197,7 +197,7 @@ "@needsLogsToAdvance": {}, "repetitionUnit": "Unidade de repetição", "@repetitionUnit": {}, - "dayDescriptionHelp": "Uma descrição do que é feito neste dia (por exemplo: 'dia de puxar') ou que partes do corpo são treinadas (por exemplo: 'peito e ombros')", + "dayDescriptionHelp": "Descrição do que é feito neste dia (ex.: \"dia de puxar\") ou que músculos são treinados (ex.: \"peito e ombros\")", "@dayDescriptionHelp": {}, "exerciseNr": "Exercício {nr}", "@exerciseNr": { @@ -219,7 +219,7 @@ } } }, - "sameRepetitions": "Se fizeres as mesmas repetições e peso para todas as séries, poderás preencher apenas uma linha. Por exemplo: para 4 séries basta inserir 10 para as repetições, isso automaticamente se tornará \"4 x 10\".", + "sameRepetitions": "Se fizeres o mesmo número de repetições e peso em todas as séries, basta preencher uma linha. Por exemplo: para 4 séries de 10, escreve \"10\" e fica automaticamente \"4 x 10\".", "@sameRepetitions": {}, "impression": "Impressão", "@impression": { @@ -233,23 +233,23 @@ "@workoutSession": { "description": "A (logged) workout session" }, - "isRestDayHelp": "Repara que todas as séries e exercícios serão removidos quando marcas um dia como dia de descanso.", + "isRestDayHelp": "Nota que todas as séries e exercícios serão removidos se marcares o dia como descanso", "@isRestDayHelp": {}, "restDay": "Dia de descanso", "@restDay": {}, "isRestDay": "É dia de descanso", "@isRestDay": {}, - "selectExercises": "Se quiseres fazer um superset podes procurar por vários exercícios, eles serão agrupados", + "selectExercises": "Se quiseres fazer um superset, podes procurar vários exercícios - eles serão agrupados", "@selectExercises": {}, "gymMode": "Modo ginásio", "@gymMode": { "description": "Label when starting the gym mode" }, - "plateCalculator": "Anilhas", + "plateCalculator": "Discos", "@plateCalculator": { "description": "Label used for the plate calculator in the gym mode" }, - "plateCalculatorNotDivisible": "Não é possível compor o peso com as anilhas disponíveis", + "plateCalculatorNotDivisible": "Não é possível atingir o peso com os discos disponíveis", "@plateCalculatorNotDivisible": { "description": "Error message when the current weight is not reachable with plates (e.g. 33.1 kg)" }, @@ -257,15 +257,15 @@ "@pause": { "description": "Noun, not an imperative! Label used for the pause when using the gym mode" }, - "jumpTo": "Salta para", + "jumpTo": "Ir para", "@jumpTo": { "description": "Imperative. Label used in popup allowing the user to jump to a specific exercise while in the gym mode" }, - "todaysWorkout": "O teu treino, hoje", + "todaysWorkout": "O teu treino de hoje", "@todaysWorkout": {}, - "logHelpEntries": "Se, no mesmo dia, houver mais do que uma entrada com o mesmo número de repetições e pesos diferentes, apenas a entrada com mais peso será mostrada no gráfico.", + "logHelpEntries": "Se houver várias entradas no mesmo dia com o mesmo número de repetições mas pesos diferentes, só aparece no gráfico a de maior peso", "@logHelpEntries": {}, - "logHelpEntriesUnits": "Nota que apenas entradas com uma unidade de peso (kg ou lb) e repetições são mostradas no gráfico. Outras combinações, como por tempo ou até à falha, são ignoradas aqui.", + "logHelpEntriesUnits": "Apenas são mostradas entradas com unidade de peso (kg ou lb) e repetições, outras como tempo ou até falhar são ignoradas", "@logHelpEntriesUnits": {}, "description": "Descrição", "@description": {}, @@ -281,19 +281,19 @@ "@addSet": { "description": "Label for the button that adds a set (to a workout day)" }, - "addMeal": "Adicional refeição", + "addMeal": "Adicionar refeição", "@addMeal": {}, "mealLogged": "Refeição registada no diário", "@mealLogged": {}, "ingredientLogged": "Ingrediente registado no diário", "@ingredientLogged": {}, - "logMeal": "Registar refeição no diário de nutrição", + "logMeal": "Registar refeição no diário nutricional", "@logMeal": {}, "addIngredient": "Adicionar ingrediente", "@addIngredient": {}, "logIngredient": "Registar ingrediente no diário nutricional", "@logIngredient": {}, - "searchIngredient": "Pesquisar Ingrediente", + "searchIngredient": "Procurar ingrediente", "@searchIngredient": { "description": "Label on ingredient search form" }, @@ -303,21 +303,21 @@ "@nutritionalDiary": {}, "nutritionalPlans": "Planos nutricionais", "@nutritionalPlans": {}, - "noNutritionalPlans": "Não tens planos nutricionais", + "noNutritionalPlans": "Ainda não tens planos nutricionais", "@noNutritionalPlans": { "description": "Message shown when the user has no nutritional plans" }, - "onlyLogging": "Acompanha apenas as calorias", + "onlyLogging": "Registar apenas calorias", "@onlyLogging": {}, - "onlyLoggingHelpText": "Seleciona se apenas pretendes registar as calorias e não queres configurar um plano nutricional detalhado com refeições específicas", + "onlyLoggingHelpText": "Marca esta opção se quiseres registar só as calorias, sem plano nutricional detalhado", "@onlyLoggingHelpText": {}, - "goalMacro": "Objetivo macro", + "goalMacro": "Objetivos de macronutrientes", "@goalMacro": { "description": "The goal for macronutrients" }, "selectMealToLog": "Seleciona uma refeição para registar no diário", "@selectMealToLog": {}, - "yourCurrentNutritionPlanHasNoMealsDefinedYet": "O teu plano nutricional corrente não tem refeições defiinidas", + "yourCurrentNutritionPlanHasNoMealsDefinedYet": "O teu plano nutricional atual não tem refeições definidas", "@yourCurrentNutritionPlanHasNoMealsDefinedYet": { "description": "Message shown when a nutrition plan doesn't have any meals" }, @@ -325,37 +325,37 @@ "@toAddMealsToThePlanGoToNutritionalPlanDetails": { "description": "Message shown to guide users to the nutritional plan details page to add meals" }, - "goalEnergy": "Meta energética", + "goalEnergy": "Objetivo energético", "@goalEnergy": {}, - "goalProtein": "Meta proteica", + "goalProtein": "Objetivo de proteína", "@goalProtein": {}, - "goalCarbohydrates": "Meta de hidratos de carbono", + "goalCarbohydrates": "Objetivo de hidratos de carbono", "@goalCarbohydrates": {}, - "goalFat": "Meta de gorduras", + "goalFat": "Objetivo de gordura", "@goalFat": {}, - "goalFiber": "Meta de fibras", + "goalFiber": "Objetivo de fibra", "@goalFiber": {}, "anErrorOccurred": "Ocorreu um erro!", "@anErrorOccurred": {}, - "errorInfoDescription": "Perdão, mas algo correu mal. Podes ajudar a corrigir isto relatando o problema no GitHub.", + "errorInfoDescription": "Lamentamos, algo correu mal. Podes ajudar a corrigir isto ao reportar o problema no GitHub.", "@errorInfoDescription": {}, - "errorInfoDescription2": "Podes continuar a usar a app, mas algumas funções podem não funcionar.", + "errorInfoDescription2": "Podes continuar a usar a app, mas algumas funcionalidades podem não funcionar.", "@errorInfoDescription2": {}, "errorViewDetails": "Detalhes técnicos", "@errorViewDetails": {}, - "errorCouldNotConnectToServer": "Erro ao ligar ao servidor", + "errorCouldNotConnectToServer": "Não foi possível ligar ao servidor", "@errorCouldNotConnectToServer": {}, - "copyToClipboard": "Copia para a memória", + "copyToClipboard": "Copiar para a área de transferência", "@copyToClipboard": {}, "weight": "Peso", "@weight": { "description": "The weight of a workout log or body weight entry" }, - "min": "Min", + "min": "Mín", "@min": {}, - "max": "Máximo", + "max": "Máx", "@max": {}, - "chartAllTimeTitle": "{name} de sempre", + "chartAllTimeTitle": "{name} total", "@chartAllTimeTitle": { "description": "All-time chart of 'name' (e.g. 'weight', 'body fat' etc.)", "type": "text", @@ -365,7 +365,7 @@ } } }, - "chart30DaysTitle": "{name} dos últimos 30 dias", + "chart30DaysTitle": "{name} últimos 30 dias", "@chart30DaysTitle": { "description": "last 30 days chart of 'name' (e.g. 'weight', 'body fat' etc.)", "type": "text", @@ -375,7 +375,7 @@ } } }, - "chartDuringPlanTitle": "{chartName} durante plano nutricional {planName}", + "chartDuringPlanTitle": "{chartName} durante o plano nutricional {planName}", "@chartDuringPlanTitle": { "description": "chart of 'chartName' (e.g. 'weight', 'body fat' etc.) logged during plan", "type": "text", @@ -390,9 +390,9 @@ }, "measurement": "Medição", "@measurement": {}, - "measurementCategoriesHelpText": "Categoria de valores, como 'biceps' ou 'gordura corporal'", + "measurementCategoriesHelpText": "Categoria de medição, como 'bíceps' ou 'gordura corporal'", "@measurementCategoriesHelpText": {}, - "measurementEntriesHelpText": "A unidade usada para medir a categoria, como 'cm' ou '%'", + "measurementEntriesHelpText": "Unidade usada para medir, como 'cm' ou '%'", "@measurementEntriesHelpText": {}, "date": "Data", "@date": { @@ -402,7 +402,7 @@ "@value": { "description": "The value of a measurement entry" }, - "time": "Tempo", + "time": "Hora", "@time": { "description": "The time of a meal or workout" }, @@ -410,11 +410,11 @@ "@timeStart": { "description": "The starting time of a workout" }, - "timeEnd": "Tempo final", + "timeEnd": "Hora de fim", "@timeEnd": { "description": "The end time of a workout" }, - "timeStartAhead": "O horário de início não pode ser anterior ao horário de término", + "timeStartAhead": "Hora de início não pode ser depois da hora de fim", "@timeStartAhead": {}, "ingredient": "Ingrediente", "@ingredient": {}, @@ -442,15 +442,15 @@ "@surplus": { "description": "Caloric surplus (either planned or unplanned)" }, - "deficit": "déficit", + "deficit": "défice", "@deficit": { "description": "Caloric deficit (either planned or unplanned)" }, "difference": "Diferença", "@difference": {}, - "percentEnergy": "Percentagem de energia", + "percentEnergy": "Percentagem da energia", "@percentEnergy": {}, - "gPerBodyKg": "g por kg corporal", + "gPerBodyKg": "g por kg de corpo", "@gPerBodyKg": { "description": "Label used for total sums of e.g. calories or similar in grams per Kg of body weight" }, @@ -480,11 +480,11 @@ } } }, - "logout": "Sair", + "logout": "Terminar sessão", "@logout": { "description": "Text for logout button" }, - "noIngredientsDefined": "Nenhum ingrediente definido, ainda", + "noIngredientsDefined": "Ainda não há ingredientes definidos", "@noIngredientsDefined": {}, "routineDays": "Dias na rotina", "@routineDays": {}, @@ -508,11 +508,11 @@ "@protein": {}, "resultingRoutine": "Rotina resultante", "@resultingRoutine": {}, - "errorCouldNotConnectToServerDetails": "A aplicação não conseguiu ligar-se ao servidor. Por favor, verifica a ligação à Internet ou o URL do servidor e tenta novamente. Se o problema persistir, contacta o administrador do servidor.", + "errorCouldNotConnectToServerDetails": "A aplicação não conseguiu ligar ao servidor. Verifica a ligação à internet ou o URL do servidor e tenta outra vez. Se continuar, contacta o administrador do servidor.", "@errorCouldNotConnectToServerDetails": {}, - "needsLogsToAdvanceHelp": "Seleciona se queres que a rotina progrida para o próximo dia agendado apenas se registaste um treino para o dia", + "needsLogsToAdvanceHelp": "Seleciona se queres que a rotina avance para o próximo dia apenas se registares um treino", "@needsLogsToAdvanceHelp": {}, - "start": "Começar", + "start": "Início", "@start": { "description": "Label on button to start the gym mode (i.e., an imperative)" }, @@ -526,7 +526,7 @@ "@proteinShort": { "description": "The first letter or short name of the word 'Protein', used in overviews" }, - "measurements": "Medidas", + "measurements": "Medições", "@measurements": { "description": "Categories for the measurements such as biceps size, body fat, etc." }, @@ -542,7 +542,7 @@ }, "carbohydrates": "Hidratos de carbono", "@carbohydrates": {}, - "carbohydratesShort": "HC", + "carbohydratesShort": "C", "@carbohydratesShort": { "description": "The first letter or short name of the word 'Carbohydrates', used in overviews" }, @@ -550,11 +550,11 @@ "@sugars": {}, "fat": "Gordura", "@fat": {}, - "fatShort": "G", + "fatShort": "F", "@fatShort": { "description": "The first letter or short name of the word 'Fat', used in overviews" }, - "fiber": "Fibra", + "fiber": "Fibras", "@fiber": {}, "sodium": "Sódio", "@sodium": {}, @@ -570,25 +570,25 @@ "@newEntry": { "description": "Title when adding a new entry such as a weight or log entry" }, - "noMeasurementEntries": "Não tens registos de medidas", + "noMeasurementEntries": "Ainda não tens registos de medições", "@noMeasurementEntries": {}, - "aboutDescription": "Obrigado por usar o Wger! Wger é um projeto colaborativo de código aberto, feito por entusiastas do exercício de todo o mundo.", + "aboutDescription": "Obrigado por usares o wger! O wger é um projeto colaborativo de código aberto, feito por fãs de fitness de todo o mundo.", "@aboutDescription": { "description": "Text in the about dialog" }, - "aboutDonateTitle": "Faz uma doação", + "aboutDonateTitle": "Fazer um donativo", "@aboutDonateTitle": {}, - "aboutDonateText": "Embora o projeto seja gratuito, e sê-lo-á sempre, manter o servidor não o é! O desenvolvimento também leva um tempo e esforço significativo dos voluntários. O teu contributo suporta diretamente estes custos ajudando a garantir o serviço.", + "aboutDonateText": "Apesar de gratuito e assim continuará, manter o servidor tem custos! O desenvolvimento também exige muito tempo dos voluntários. A tua ajuda apoia diretamente estes custos.", "@aboutDonateText": {}, - "aboutContributeTitle": "Contribui", + "aboutContributeTitle": "Contribuir", "@aboutContributeTitle": {}, - "aboutContributeText": "Todos os tipos de contribuição são encorajados. Sejas um desenvolvedor, tradutor ou apenas um apaixonado pelo exercício, todas as migalhas de ajuda são apreciadas!", + "aboutContributeText": "Todos os tipos de contribuição são bem-vindos. Sejas programador, tradutor ou apenas apaixonado por fitness, toda a ajuda conta!", "@aboutContributeText": {}, - "aboutBugsListTitle": "Relata um problema ou sugere uma funcionalidade", + "aboutBugsListTitle": "Reportar um problema ou sugerir uma funcionalidade", "@aboutBugsListTitle": {}, - "aboutTranslationListTitle": "Traduz a aplicação", + "aboutTranslationListTitle": "Traduzir a aplicação", "@aboutTranslationListTitle": {}, - "aboutSourceListTitle": "Vê o código fonte", + "aboutSourceListTitle": "Ver código-fonte", "@aboutSourceListTitle": {}, "aboutJoinCommunityTitle": "Junta-te à comunidade", "@aboutJoinCommunityTitle": {}, @@ -600,21 +600,21 @@ "@others": {}, "calendar": "Calendário", "@calendar": {}, - "goToToday": "Vai para hoje", + "goToToday": "Ir para hoje", "@goToToday": { "description": "Label on button to jump back to 'today' in the calendar widget" }, - "enterValue": "Por favor, insere um valor", + "enterValue": "Introduz um valor", "@enterValue": { "description": "Error message when the user hasn't entered a value on a required field" }, - "selectEntry": "Por favor, selecione uma entrada", + "selectEntry": "Seleciona uma entrada", "@selectEntry": {}, - "selectExercise": "Por favor, selecione um exercício", + "selectExercise": "Seleciona um exercício", "@selectExercise": { "description": "Error message when the user hasn't selected an exercise in the form" }, - "enterCharacters": "Por favor, utiliza entre {min} e {max} caracteres", + "enterCharacters": "Escreve entre {min} e {max} caracteres", "@enterCharacters": { "description": "Error message when the user hasn't entered the correct number of characters in a form", "type": "text", @@ -627,7 +627,7 @@ } } }, - "enterMinCharacters": "Por favor, utiliza pelo menos {min} caracteres", + "enterMinCharacters": "Escreve pelo menos {min} caracteres", "@enterMinCharacters": { "description": "Error message when the user hasn't entered the minimum amount characters in a form", "type": "text", @@ -637,7 +637,7 @@ } } }, - "baseNameEnglish": "Todos os exercícios necessitam de um nome base em inglês", + "baseNameEnglish": "Todos os exercícios precisam de nome base em inglês", "@baseNameEnglish": {}, "nrOfSets": "Séries por exercício: {nrOfSets}", "@nrOfSets": { @@ -653,9 +653,9 @@ "@optionsLabel": { "description": "Label for the popup with general app options" }, - "takePicture": "Tira uma fotografia", + "takePicture": "Tirar foto", "@takePicture": {}, - "chooseFromLibrary": "Escolher da galeria de fotos", + "chooseFromLibrary": "Escolher da galeria", "@chooseFromLibrary": {}, "gallery": "Galeria", "@gallery": {}, @@ -663,7 +663,7 @@ "@addImage": {}, "appUpdateContent": "Esta versão da aplicação não é compatível com o servidor. Por favor, atualiza a aplicação.", "@appUpdateContent": {}, - "productNotFoundDescription": "O produto com o código de barras digitalizado {barcode} não foi encontrado na base de dados do wger", + "productNotFoundDescription": "O produto com o código {barcode} não foi encontrado na base de dados wger", "@productNotFoundDescription": { "description": "Dialog info when product is not found with barcode", "type": "text", @@ -673,7 +673,7 @@ } } }, - "scanBarcode": "Digitaliza o código de barras", + "scanBarcode": "Ler código de barras", "@scanBarcode": { "description": "Label for scan barcode button" }, @@ -681,17 +681,17 @@ "@close": { "description": "Translation for close" }, - "add_exercise_image_license": "As imagens devem ser compatíveis com a licença CC BY SA. Em caso de dúvida, carrega apenas fotos que tenhas tirado tu.", + "add_exercise_image_license": "Imagens têm de ser compatíveis com a licença CC BY SA. Se tiveres dúvidas, usa apenas fotos tiradas por ti", "@add_exercise_image_license": {}, "variations": "Variações", "@variations": { "description": "Variations of one exercise (e.g. benchpress and benchpress narrow)" }, - "verifiedEmail": "Email verificado", + "verifiedEmail": "E-mail verificado", "@verifiedEmail": {}, - "verifiedEmailReason": "Tens de verificar o teu email para contribuir com exercícios", + "verifiedEmailReason": "Tens de verificar o e-mail para poderes contribuir com exercícios", "@verifiedEmailReason": {}, - "verifiedEmailInfo": "Um email de verificação foi enviado para {email}", + "verifiedEmailInfo": "Foi enviado um e-mail de verificação para {email}", "@verifiedEmailInfo": { "placeholders": { "email": { @@ -703,27 +703,27 @@ "@alternativeNames": {}, "oneNamePerLine": "Um nome por linha", "@oneNamePerLine": {}, - "whatVariationsExist": "Que variações deste exercício existem, se houver?", + "whatVariationsExist": "Que variações deste exercício existem (se houver)?", "@whatVariationsExist": {}, "previous": "Anterior", "@previous": {}, - "next": "Próximo", + "next": "Seguinte", "@next": {}, "images": "Imagens", "@images": {}, - "language": "Linguagem", + "language": "Idioma", "@language": {}, "addExercise": "Adicionar exercício", "@addExercise": {}, - "fitInWeek": "Encaixa na semana", + "fitInWeek": "Ajustar à semana", "@fitInWeek": {}, - "toggleDetails": "Alternar detalhes", + "toggleDetails": "Mostrar detalhes", "@toggleDetails": { "description": "Switch to toggle detail / overview" }, "edit": "Editar", "@edit": {}, - "aboutWhySupportTitle": "Código aberto & livre para usar ❤️", + "aboutWhySupportTitle": "Código aberto e gratuito ❤️", "@aboutWhySupportTitle": {}, "goToDetailPage": "Ir para a página de detalhes", "@goToDetailPage": {}, @@ -731,36 +731,36 @@ "@productFound": { "description": "Header label for dialog when product is found with barcode" }, - "unVerifiedEmail": "Email não verificado", + "unVerifiedEmail": "E-mail não verificado", "@unVerifiedEmail": {}, - "moreMeasurementEntries": "Adiciona nova medição", + "moreMeasurementEntries": "Adicionar nova medição", "@moreMeasurementEntries": { "description": "Message shown when the user wants to add new measurement" }, - "selectIngredient": "Por favor, seleciona um ingrediente", + "selectIngredient": "Seleciona um ingrediente", "@selectIngredient": { "description": "Error message when the user hasn't selected an ingredient from the autocompleter" }, "newNutritionalPlan": "Novo plano nutricional", "@newNutritionalPlan": {}, - "setUnitsAndRir": "Configura unidades e ReR", + "setUnitsAndRir": "Unidades de série e ReR", "@setUnitsAndRir": { "description": "Label shown on the slider where the user can toggle showing units and RiR", "type": "text" }, "saturatedFat": "Gordura saturada", "@saturatedFat": {}, - "selectImage": "Por favor, seleciona uma imagem", + "selectImage": "Seleciona uma imagem", "@selectImage": { "description": "Label and error message when the user hasn't selected an image to save" }, "appUpdateTitle": "Atualização necessária", "@appUpdateTitle": {}, - "noWeightEntries": "Não tens registos de peso", + "noWeightEntries": "Ainda não tens registos de peso", "@noWeightEntries": { "description": "Message shown when the user has no logged weight entries" }, - "confirmDelete": "Tens certeza de que desejas excluir '{toDelete}'?", + "confirmDelete": "Tens a certeza que queres eliminar '{toDelete}'?", "@confirmDelete": { "description": "Confirmation text before the user deletes an object", "type": "text", @@ -778,17 +778,17 @@ "@loadingText": { "description": "Text to show when entries are being loaded in the background: Loading..." }, - "delete": "Excluir", + "delete": "Eliminar", "@delete": {}, "productNotFound": "Produto não encontrado", "@productNotFound": { "description": "Header label for dialog when product is not found with barcode" }, - "enterValidNumber": "Por favor, insere um número válido", + "enterValidNumber": "Introduz um número válido", "@enterValidNumber": { "description": "Error message when the user has submitted an invalid number (e.g. '3,.,.,.')" }, - "dataCopied": "Dados copiados para a nova entrada", + "dataCopied": "Dados copiados para nova entrada", "@dataCopied": { "description": "Snackbar message to show on copying data to a new log entry" }, @@ -802,7 +802,7 @@ } } }, - "alsoKnownAs": "Também conhecido como:{aliases}", + "alsoKnownAs": "Também conhecido como: {aliases}", "@alsoKnownAs": { "placeholders": { "aliases": { @@ -810,5 +810,253 @@ } }, "description": "List of alternative names for an exercise" - } + }, + "fitInWeekHelp": "Se ativado, os dias repetem-se semanalmente. Caso contrário, seguem-se em sequência sem respeitar o início da semana.", + "@fitInWeekHelp": {}, + "addSuperset": "Adicionar superset", + "@addSuperset": {}, + "setHasProgression": "Série com progressão", + "@setHasProgression": {}, + "setHasProgressionWarning": "De momento não é possível editar todas as definições de uma série na app móvel ou configurar progressões automáticas. Usa a versão web", + "@setHasProgressionWarning": {}, + "setHasNoExercises": "Esta série ainda não tem exercícios!", + "@setHasNoExercises": {}, + "contributeExercise": "Contribuir com um exercício", + "@contributeExercise": {}, + "translation": "Tradução", + "@translation": {}, + "translateExercise": "Traduz este exercício agora", + "@translateExercise": {}, + "baseData": "Básico em inglês", + "@baseData": { + "description": "The base data for an exercise such as category, trained muscles, etc." + }, + "settingsTitle": "Definições", + "@settingsTitle": {}, + "settingsCacheTitle": "Cache", + "@settingsCacheTitle": {}, + "settingsExerciseCacheDescription": "Cache de exercícios", + "@settingsExerciseCacheDescription": {}, + "settingsIngredientCacheDescription": "Cache de ingredientes", + "@settingsIngredientCacheDescription": {}, + "settingsCacheDeletedSnackbar": "Cache limpo com sucesso", + "@settingsCacheDeletedSnackbar": {}, + "aboutPageTitle": "Sobre nós & Apoio", + "@aboutPageTitle": {}, + "contributeExerciseWarning": "Só podes contribuir com exercícios se a tua conta tiver mais de {days} dias e e-mail verificado", + "@contributeExerciseWarning": { + "description": "Number of days before which a person can add exercise", + "placeholders": { + "days": { + "type": "String", + "example": "14" + } + } + }, + "simpleMode": "Modo simples", + "@simpleMode": {}, + "simpleModeHelp": "Esconder opções mais avançadas ao editar exercícios", + "@simpleModeHelp": {}, + "progressionRules": "Este exercício tem regras de progressão e não pode ser editado na app. Usa a versão web para o editar", + "@progressionRules": {}, + "cacheWarning": "Por causa da cache, pode demorar um pouco até veres as alterações na app", + "@cacheWarning": {}, + "textPromptTitle": "Pronto para começar?", + "@textPromptTitle": {}, + "textPromptSubheading": "Clica no botão de ação para começar", + "@textPromptSubheading": {}, + "abs": "Abdominais", + "@abs": { + "description": "Generated entry for translation for server strings" + }, + "arms": "Braços", + "@arms": { + "description": "Generated entry for translation for server strings" + }, + "back": "Costas", + "@back": { + "description": "Generated entry for translation for server strings" + }, + "barbell": "Barra olímpica", + "@barbell": { + "description": "Generated entry for translation for server strings" + }, + "bench": "Banco", + "@bench": { + "description": "Generated entry for translation for server strings" + }, + "biceps": "Bíceps", + "@biceps": { + "description": "Generated entry for translation for server strings" + }, + "body_weight": "Peso corporal", + "@body_weight": { + "description": "Generated entry for translation for server strings" + }, + "calves": "Gémeos", + "@calves": { + "description": "Generated entry for translation for server strings" + }, + "cardio": "Cardio", + "@cardio": { + "description": "Generated entry for translation for server strings" + }, + "chest": "Peito", + "@chest": { + "description": "Generated entry for translation for server strings" + }, + "dumbbell": "Halteres", + "@dumbbell": { + "description": "Generated entry for translation for server strings" + }, + "glutes": "Glúteos", + "@glutes": { + "description": "Generated entry for translation for server strings" + }, + "gym_mat": "Tapete de ginásio", + "@gym_mat": { + "description": "Generated entry for translation for server strings" + }, + "hamstrings": "Isquiotibiais", + "@hamstrings": { + "description": "Generated entry for translation for server strings" + }, + "incline_bench": "Banco inclinado", + "@incline_bench": { + "description": "Generated entry for translation for server strings" + }, + "kettlebell": "Kettlebell", + "@kettlebell": { + "description": "Generated entry for translation for server strings" + }, + "kilometers": "Quilómetros", + "@kilometers": { + "description": "Generated entry for translation for server strings" + }, + "kilometers_per_hour": "Km/h", + "@kilometers_per_hour": { + "description": "Generated entry for translation for server strings" + }, + "lats": "Dorsais", + "@lats": { + "description": "Generated entry for translation for server strings" + }, + "legs": "Pernas", + "@legs": { + "description": "Generated entry for translation for server strings" + }, + "lower_back": "Zona lombar", + "@lower_back": { + "description": "Generated entry for translation for server strings" + }, + "max_reps": "Repetições máximas", + "@max_reps": { + "description": "Generated entry for translation for server strings" + }, + "miles": "Milhas", + "@miles": { + "description": "Generated entry for translation for server strings" + }, + "miles_per_hour": "Mi/h", + "@miles_per_hour": { + "description": "Generated entry for translation for server strings" + }, + "minutes": "Minutos", + "@minutes": { + "description": "Generated entry for translation for server strings" + }, + "plates": "Discos", + "@plates": { + "description": "Generated entry for translation for server strings" + }, + "pull_up_bar": "Barra de Pull-up", + "@pull_up_bar": { + "description": "Generated entry for translation for server strings" + }, + "quads": "Quadríceps", + "@quads": { + "description": "Generated entry for translation for server strings" + }, + "repetitions": "Repetições", + "@repetitions": { + "description": "Generated entry for translation for server strings" + }, + "resistance_band": "Banda de resistência", + "@resistance_band": { + "description": "Generated entry for translation for server strings" + }, + "sz_bar": "Barra SZ", + "@sz_bar": { + "description": "Generated entry for translation for server strings" + }, + "seconds": "Segundos", + "@seconds": { + "description": "Generated entry for translation for server strings" + }, + "shoulders": "Ombros", + "@shoulders": { + "description": "Generated entry for translation for server strings" + }, + "swiss_ball": "Bola suíça", + "@swiss_ball": { + "description": "Generated entry for translation for server strings" + }, + "triceps": "Tríceps", + "@triceps": { + "description": "Generated entry for translation for server strings" + }, + "until_failure": "Até falhar", + "@until_failure": { + "description": "Generated entry for translation for server strings" + }, + "kg": "kg", + "@kg": { + "description": "Generated entry for translation for server strings" + }, + "lb": "lb", + "@lb": { + "description": "Generated entry for translation for server strings" + }, + "none__bodyweight_exercise_": "nenhum (exercício com peso corporal)", + "@none__bodyweight_exercise_": { + "description": "Generated entry for translation for server strings" + }, + "log": "Registar", + "@log": { + "description": "Log a specific meal (imperative form)" + }, + "done": "Concluído", + "@done": {}, + "overallChangeWeight": "Alteração total", + "@overallChangeWeight": { + "description": "Overall change in weight, added for localization" + }, + "goalTypeMeals": "Das refeições", + "@goalTypeMeals": { + "description": "added for localization of Class GoalType's filed meals" + }, + "goalTypeBasic": "Básico", + "@goalTypeBasic": { + "description": "added for localization of Class GoalType's filed basic" + }, + "goalTypeAdvanced": "Avançado", + "@goalTypeAdvanced": { + "description": "added for localization of Class GoalType's filed advanced" + }, + "indicatorRaw": "cru", + "@indicatorRaw": { + "description": "added for localization of Class Indicator's field text" + }, + "indicatorAvg": "média", + "@indicatorAvg": { + "description": "added for localization of Class Indicator's field text" + }, + "themeMode": "Modo de tema", + "@themeMode": {}, + "darkMode": "Modo escuro sempre", + "@darkMode": {}, + "lightMode": "Modo claro sempre", + "@lightMode": {}, + "systemMode": "Usar definições do sistema", + "@systemMode": {} } From 069c9c30589426d22746b19e8dcf940666ba3461 Mon Sep 17 00:00:00 2001 From: FilipeAb Date: Mon, 14 Jul 2025 16:32:25 +0200 Subject: [PATCH 39/89] Translated using Weblate (Portuguese (Portugal)) Currently translated at 100.0% (312 of 312 strings) Translation: wger Workout Manager/Mobile App Translate-URL: https://hosted.weblate.org/projects/wger/mobile/pt_PT/ --- lib/l10n/app_pt_PT.arb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/l10n/app_pt_PT.arb b/lib/l10n/app_pt_PT.arb index 9b44b776..7a86a046 100644 --- a/lib/l10n/app_pt_PT.arb +++ b/lib/l10n/app_pt_PT.arb @@ -297,7 +297,7 @@ "@searchIngredient": { "description": "Label on ingredient search form" }, - "nutritionalPlan": "Plano nutricional", + "nutritionalPlan": "Plano alimentar", "@nutritionalPlan": {}, "nutritionalDiary": "Diário nutricional", "@nutritionalDiary": {}, @@ -351,9 +351,9 @@ "@weight": { "description": "The weight of a workout log or body weight entry" }, - "min": "Mín", + "min": "Mínimo", "@min": {}, - "max": "Máx", + "max": "Máximo", "@max": {}, "chartAllTimeTitle": "{name} total", "@chartAllTimeTitle": { @@ -778,7 +778,7 @@ "@loadingText": { "description": "Text to show when entries are being loaded in the background: Loading..." }, - "delete": "Eliminar", + "delete": "Apagar", "@delete": {}, "productNotFound": "Produto não encontrado", "@productNotFound": { From de8182a6b9b78aa6df01c77951621aeecff672fa Mon Sep 17 00:00:00 2001 From: FilipeAb Date: Mon, 14 Jul 2025 16:38:27 +0200 Subject: [PATCH 40/89] Translated using Weblate (Portuguese (Portugal)) Currently translated at 100.0% (312 of 312 strings) Translation: wger Workout Manager/Mobile App Translate-URL: https://hosted.weblate.org/projects/wger/mobile/pt_PT/ --- lib/l10n/app_pt_PT.arb | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/l10n/app_pt_PT.arb b/lib/l10n/app_pt_PT.arb index 7a86a046..a5a7c90e 100644 --- a/lib/l10n/app_pt_PT.arb +++ b/lib/l10n/app_pt_PT.arb @@ -233,7 +233,7 @@ "@workoutSession": { "description": "A (logged) workout session" }, - "isRestDayHelp": "Nota que todas as séries e exercícios serão removidos se marcares o dia como descanso", + "isRestDayHelp": "Nota que todas as séries e exercícios serão removidos se marcares o dia como descanso.", "@isRestDayHelp": {}, "restDay": "Dia de descanso", "@restDay": {}, @@ -263,9 +263,9 @@ }, "todaysWorkout": "O teu treino de hoje", "@todaysWorkout": {}, - "logHelpEntries": "Se houver várias entradas no mesmo dia com o mesmo número de repetições mas pesos diferentes, só aparece no gráfico a de maior peso", + "logHelpEntries": "Se houver várias entradas no mesmo dia com o mesmo número de repetições mas pesos diferentes, só aparece no gráfico a de maior peso.", "@logHelpEntries": {}, - "logHelpEntriesUnits": "Apenas são mostradas entradas com unidade de peso (kg ou lb) e repetições, outras como tempo ou até falhar são ignoradas", + "logHelpEntriesUnits": "Apenas são mostradas entradas com unidade de peso (kg ou lb) e repetições, outras como tempo ou até falhar são ignoradas.", "@logHelpEntriesUnits": {}, "description": "Descrição", "@description": {}, @@ -297,7 +297,7 @@ "@searchIngredient": { "description": "Label on ingredient search form" }, - "nutritionalPlan": "Plano alimentar", + "nutritionalPlan": "Plano nutricional", "@nutritionalPlan": {}, "nutritionalDiary": "Diário nutricional", "@nutritionalDiary": {}, @@ -351,9 +351,9 @@ "@weight": { "description": "The weight of a workout log or body weight entry" }, - "min": "Mínimo", + "min": "Mín", "@min": {}, - "max": "Máximo", + "max": "Máx", "@max": {}, "chartAllTimeTitle": "{name} total", "@chartAllTimeTitle": { @@ -681,7 +681,7 @@ "@close": { "description": "Translation for close" }, - "add_exercise_image_license": "Imagens têm de ser compatíveis com a licença CC BY SA. Se tiveres dúvidas, usa apenas fotos tiradas por ti", + "add_exercise_image_license": "Imagens têm de ser compatíveis com a licença CC BY SA. Se tiveres dúvidas, usa apenas fotos tiradas por ti.", "@add_exercise_image_license": {}, "variations": "Variações", "@variations": { @@ -778,7 +778,7 @@ "@loadingText": { "description": "Text to show when entries are being loaded in the background: Loading..." }, - "delete": "Apagar", + "delete": "Eliminar", "@delete": {}, "productNotFound": "Produto não encontrado", "@productNotFound": { @@ -813,11 +813,11 @@ }, "fitInWeekHelp": "Se ativado, os dias repetem-se semanalmente. Caso contrário, seguem-se em sequência sem respeitar o início da semana.", "@fitInWeekHelp": {}, - "addSuperset": "Adicionar superset", + "addSuperset": "Adicionar Superset", "@addSuperset": {}, "setHasProgression": "Série com progressão", "@setHasProgression": {}, - "setHasProgressionWarning": "De momento não é possível editar todas as definições de uma série na app móvel ou configurar progressões automáticas. Usa a versão web", + "setHasProgressionWarning": "De momento não é possível editar todas as definições de uma série na app móvel ou configurar progressões automáticas. Usa a versão web.", "@setHasProgressionWarning": {}, "setHasNoExercises": "Esta série ainda não tem exercícios!", "@setHasNoExercises": {}, @@ -857,9 +857,9 @@ "@simpleMode": {}, "simpleModeHelp": "Esconder opções mais avançadas ao editar exercícios", "@simpleModeHelp": {}, - "progressionRules": "Este exercício tem regras de progressão e não pode ser editado na app. Usa a versão web para o editar", + "progressionRules": "Este exercício tem regras de progressão e não pode ser editado na app. Usa a versão web para o editar.", "@progressionRules": {}, - "cacheWarning": "Por causa da cache, pode demorar um pouco até veres as alterações na app", + "cacheWarning": "Por causa da cache, pode demorar um pouco até veres as alterações na app.", "@cacheWarning": {}, "textPromptTitle": "Pronto para começar?", "@textPromptTitle": {}, @@ -969,7 +969,7 @@ "@plates": { "description": "Generated entry for translation for server strings" }, - "pull_up_bar": "Barra de Pull-up", + "pull_up_bar": "Barra de elevações", "@pull_up_bar": { "description": "Generated entry for translation for server strings" }, From a78da55464dc2e039ae06317132c3ba8b1053a5b Mon Sep 17 00:00:00 2001 From: Afzal Momin Date: Wed, 23 Jul 2025 21:32:15 +0530 Subject: [PATCH 41/89] changed calender settings to allow to choose future days upto 112 days. --- lib/widgets/dashboard/calendar.dart | 2 +- lib/widgets/routines/forms/routine.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/widgets/dashboard/calendar.dart b/lib/widgets/dashboard/calendar.dart index 2069d243..049b0d78 100644 --- a/lib/widgets/dashboard/calendar.dart +++ b/lib/widgets/dashboard/calendar.dart @@ -225,7 +225,7 @@ class _DashboardCalendarWidgetState extends State TableCalendar( locale: Localizations.localeOf(context).languageCode, firstDay: DateTime.now().subtract(const Duration(days: 1000)), - lastDay: DateTime.now(), + lastDay: DateTime.now().add(const Duration(days: 112)), focusedDay: _focusedDay, selectedDayPredicate: (day) => isSameDay(_selectedDay, day), rangeStartDay: _rangeStart, diff --git a/lib/widgets/routines/forms/routine.dart b/lib/widgets/routines/forms/routine.dart index d8bb5bd1..cb1f9ad8 100644 --- a/lib/widgets/routines/forms/routine.dart +++ b/lib/widgets/routines/forms/routine.dart @@ -163,7 +163,7 @@ class _RoutineFormState extends State { context: context, initialDate: endDate, firstDate: DateTime(DateTime.now().year - 10), - lastDate: DateTime.now(), + lastDate: DateTime.now().add(const Duration(days: 112)), ); if (picked == null) { From 24b1a687ab9cb1266b10fccac5b9525d19375ab2 Mon Sep 17 00:00:00 2001 From: KW Lam Date: Thu, 24 Jul 2025 05:41:03 +0200 Subject: [PATCH 42/89] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (312 of 312 strings) Translation: wger Workout Manager/Mobile App Translate-URL: https://hosted.weblate.org/projects/wger/mobile/zh_Hans/ --- lib/l10n/app_zh.arb | 60 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 54 insertions(+), 6 deletions(-) diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index 27b5141d..fd2cda5c 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -91,7 +91,7 @@ "@notes": { "description": "Personal notes, e.g. for a workout session" }, - "comment": "备注", + "comment": "评论", "@comment": { "description": "Comment, additional information" }, @@ -519,7 +519,7 @@ "@logged": { "description": "Header for the column of 'logged' nutritional values, i.e. what was eaten" }, - "userProfile": "账户", + "userProfile": "个人资料", "@userProfile": {}, "exerciseName": "锻炼名", "@exerciseName": { @@ -706,7 +706,7 @@ "@biceps": { "description": "Generated entry for translation for server strings" }, - "aboutPageTitle": "关于 Wger", + "aboutPageTitle": "关于我们&支持", "@aboutPageTitle": {}, "selectEntry": "请选择一项", "@selectEntry": {}, @@ -734,9 +734,9 @@ "@sz_bar": { "description": "Generated entry for translation for server strings" }, - "aboutDonateTitle": "捐赠", + "aboutDonateTitle": "进行捐赠", "@aboutDonateTitle": {}, - "aboutDonateText": "向我们打赏来支持此项目,给服务器买单,及激励我们", + "aboutDonateText": "尽管该项目是免费的,且将始终保持免费,但服务器的运营并非如此!开发工作也需要志愿者投入大量的时间和精力。您的捐赠将直接用于支付这些成本,助力维持服务的稳定可靠。", "@aboutDonateText": {}, "none__bodyweight_exercise_": "无(自重动作)", "@none__bodyweight_exercise_": { @@ -1014,5 +1014,53 @@ "apiTokenValidChars": "API 密钥只能包含字母 a-f、数字 0-9,长度为 40 个字符", "@apiTokenValidChars": { "description": "Error message when the user tries to input a API key with forbidden characters" - } + }, + "selectAvailablePlates": "选择可用的杠片", + "@selectAvailablePlates": {}, + "yourCurrentNutritionPlanHasNoMealsDefinedYet": "你当前的营养计划中没有设定任何餐食", + "@yourCurrentNutritionPlanHasNoMealsDefinedYet": { + "description": "Message shown when a nutrition plan doesn't have any meals" + }, + "toAddMealsToThePlanGoToNutritionalPlanDetails": "若要为营养计划添加餐食,请前往营养计划详情页面", + "@toAddMealsToThePlanGoToNutritionalPlanDetails": { + "description": "Message shown to guide users to the nutritional plan details page to add meals" + }, + "errorInfoDescription": "很抱歉,出现了一些问题。您可以通过在 GitHub 上报告此问题来帮助我们修复它。", + "@errorInfoDescription": {}, + "errorInfoDescription2": "您可以继续使用这款应用,但部分功能可能无法正常运行。", + "@errorInfoDescription2": {}, + "errorViewDetails": "错误技术详情", + "@errorViewDetails": {}, + "errorCouldNotConnectToServer": "无法连接到服务器", + "@errorCouldNotConnectToServer": {}, + "errorCouldNotConnectToServerDetails": "应用程序无法连接到服务器。请检查您的网络连接或服务器网址,然后重试。如果问题持续存在,请联系服务器管理员。", + "@errorCouldNotConnectToServerDetails": {}, + "copyToClipboard": "复制", + "@copyToClipboard": {}, + "aboutWhySupportTitle": "开源 & 免费使用", + "@aboutWhySupportTitle": {}, + "aboutContributeTitle": "贡献", + "@aboutContributeTitle": {}, + "aboutContributeText": "我们鼓励各种形式的贡献。无论您是开发者、翻译人员,还是单纯热爱健身的人士,每一份支持都值得我们由衷感谢!", + "@aboutContributeText": {}, + "aboutBugsListTitle": "报告问题或提出功能建议", + "@aboutBugsListTitle": {}, + "aboutTranslationListTitle": "翻译此软件", + "@aboutTranslationListTitle": {}, + "aboutSourceListTitle": "查看源代码", + "@aboutSourceListTitle": {}, + "aboutJoinCommunityTitle": "加入社区", + "@aboutJoinCommunityTitle": {}, + "aboutDiscordTitle": "Discord", + "@aboutDiscordTitle": {}, + "others": "其他", + "@others": {}, + "fitInWeek": "一周健身计划", + "@fitInWeek": {}, + "resistance_band": "弹力带", + "@resistance_band": { + "description": "Generated entry for translation for server strings" + }, + "resultingRoutine": "最终生成的训练计划", + "@resultingRoutine": {} } From 4a4e7e6abe2f8bf1da4177b107618d028f8cba17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D0=BA=D1=81=D0=B8=D0=BC=20=D0=93=D0=BE=D1=80?= =?UTF-8?q?=D0=BF=D0=B8=D0=BD=D1=96=D1=87?= Date: Thu, 24 Jul 2025 16:49:38 +0200 Subject: [PATCH 43/89] Translated using Weblate (Ukrainian) Currently translated at 100.0% (312 of 312 strings) Translation: wger Workout Manager/Mobile App Translate-URL: https://hosted.weblate.org/projects/wger/mobile/uk/ --- lib/l10n/app_uk.arb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/l10n/app_uk.arb b/lib/l10n/app_uk.arb index 5426836d..3db56005 100644 --- a/lib/l10n/app_uk.arb +++ b/lib/l10n/app_uk.arb @@ -385,7 +385,7 @@ }, "saturatedFat": "Насичені жири", "@saturatedFat": {}, - "fiber": "Волокна", + "fiber": "Волокон", "@fiber": {}, "sodium": "Натрій", "@sodium": {}, From a63fb64ef29f3c3ee80b1e7b50e3ba15c708d4bd Mon Sep 17 00:00:00 2001 From: caue Antunes Siqueira Date: Mon, 28 Jul 2025 05:02:54 +0200 Subject: [PATCH 44/89] Translated using Weblate (Portuguese) Currently translated at 99.3% (310 of 312 strings) Translation: wger Workout Manager/Mobile App Translate-URL: https://hosted.weblate.org/projects/wger/mobile/pt/ --- lib/l10n/app_pt.arb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/l10n/app_pt.arb b/lib/l10n/app_pt.arb index 0cdf97cd..54fb5a6a 100644 --- a/lib/l10n/app_pt.arb +++ b/lib/l10n/app_pt.arb @@ -618,7 +618,7 @@ "@kettlebell": {}, "none__bodyweight_exercise_": "nenhum (somente peso do corpo)", "@none__bodyweight_exercise_": {}, - "aboutPageTitle": "Sobre Wger", + "aboutPageTitle": "Sobre nós & suporte", "@aboutPageTitle": {}, "enterMinCharacters": "Por favor, selecione ao menos {min} de caracteres", "@enterMinCharacters": { @@ -873,7 +873,7 @@ "@lightMode": {}, "systemMode": "Configurações do sistema", "@systemMode": {}, - "themeMode": "Modo temático", + "themeMode": "Tema", "@themeMode": {}, "darkMode": "Modo sempre escuro", "@darkMode": {}, From 66589c4c4fc020b604a36a15ed39011a72f83399 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=AAnisson=20Alves=20de=20Andrade?= Date: Mon, 4 Aug 2025 09:50:40 +0200 Subject: [PATCH 45/89] Translated using Weblate (Portuguese (Brazil)) Currently translated at 84.9% (265 of 312 strings) Translation: wger Workout Manager/Mobile App Translate-URL: https://hosted.weblate.org/projects/wger/mobile/pt_BR/ --- lib/l10n/app_pt_BR.arb | 66 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 6 deletions(-) diff --git a/lib/l10n/app_pt_BR.arb b/lib/l10n/app_pt_BR.arb index bacc9a10..97bfa4f9 100644 --- a/lib/l10n/app_pt_BR.arb +++ b/lib/l10n/app_pt_BR.arb @@ -31,7 +31,7 @@ "@logout": { "description": "Text for logout button" }, - "notes": "Notas", + "notes": "Comentários", "@notes": { "description": "Personal notes, e.g. for a workout session" }, @@ -95,7 +95,7 @@ }, "confirmPassword": "Confirme sua senha", "@confirmPassword": {}, - "comment": "Comente", + "comment": "Comentário", "@comment": { "description": "Comment, additional information" }, @@ -227,7 +227,7 @@ }, "percentEnergy": "Porcentagem de energia", "@percentEnergy": {}, - "searchNamesInEnglish": "Pesquise também por nomes em inglês", + "searchNamesInEnglish": "Procure também nomes em inglês", "@searchNamesInEnglish": {}, "exercise": "Exercício", "@exercise": { @@ -451,7 +451,7 @@ "@aboutMastodonTitle": {}, "selectEntry": "Por favor, selecione uma entrada", "@selectEntry": {}, - "noMatchingExerciseFound": "Nenhum exercício correspondente encontrado", + "noMatchingExerciseFound": "Sem exercícios correspondentes encontrados", "@noMatchingExerciseFound": { "description": "Message returned if no exercises match the searched string" }, @@ -469,7 +469,7 @@ "@labelBottomNavWorkout": { "description": "Label used in bottom navigation, use a short word" }, - "reps": "Reps", + "reps": "Repetições", "@reps": { "description": "Shorthand for repetitions, used when space constraints are tighter" }, @@ -930,5 +930,59 @@ "biceps": "Bíceps", "@biceps": { "description": "Generated entry for translation for server strings" - } + }, + "useApiToken": "Usar API Token", + "@useApiToken": {}, + "useUsernameAndPassword": "Usar usuário e senha", + "@useUsernameAndPassword": {}, + "apiToken": "API Token", + "@apiToken": {}, + "invalidApiToken": "Por favor, entre com a API key válida", + "@invalidApiToken": { + "description": "Error message when the user enters an invalid API key" + }, + "apiTokenValidChars": "A chave API deve ter apenas letras a-f, números 0-9 e ter exatamente 40 caracteres", + "@apiTokenValidChars": { + "description": "Error message when the user tries to input a API key with forbidden characters" + }, + "routines": "Rotinas", + "@routines": {}, + "newRoutine": "Nova rotina", + "@newRoutine": {}, + "noRoutines": "Não tens rotinas", + "@noRoutines": {}, + "restTime": "Tempo de descanso", + "@restTime": {}, + "sets": "Conjuntos", + "@sets": { + "description": "The number of sets to be done for one exercise" + }, + "exerciseNr": "Exercício {nr}", + "@exerciseNr": { + "description": "Header in form indicating the number of the current exercise. Can also be translated as something like 'Set Nr. xy'.", + "type": "text", + "placeholders": { + "nr": { + "type": "String" + } + } + }, + "supersetNr": "Superset {nr}", + "@supersetNr": { + "description": "Header in form indicating the number of the current exercise. Can also be translated as something like 'Superset Nr. xy'.", + "type": "text", + "placeholders": { + "nr": { + "type": "String" + } + } + }, + "restDay": "Dia de descanso", + "@restDay": {}, + "isRestDay": "É dia de descanso", + "@isRestDay": {}, + "isRestDayHelp": "Por favor, note que todos os conjuntos e exercícios serão removidos quando marcar um dia como um dia de descanso.", + "@isRestDayHelp": {}, + "needsLogsToAdvance": "Precisa de logs para avançar", + "@needsLogsToAdvance": {} } From 173d177c7d0033ab07305af5bd752c05c1e5c1f6 Mon Sep 17 00:00:00 2001 From: Jaafer Mahfoud Date: Tue, 5 Aug 2025 21:40:33 +0200 Subject: [PATCH 46/89] Translated using Weblate (Arabic) Currently translated at 72.1% (225 of 312 strings) Translation: wger Workout Manager/Mobile App Translate-URL: https://hosted.weblate.org/projects/wger/mobile/ar/ --- lib/l10n/app_ar.arb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/l10n/app_ar.arb b/lib/l10n/app_ar.arb index f6b4f004..5cd7da9d 100644 --- a/lib/l10n/app_ar.arb +++ b/lib/l10n/app_ar.arb @@ -795,5 +795,15 @@ "description": "Error message when the user enters an invalid API key" }, "useUsernameAndPassword": "استخدم اسم المستخدم وكلمة المرور", - "@useUsernameAndPassword": {} + "@useUsernameAndPassword": {}, + "selectAvailablePlates": "اختر من الاطباق المتوفرة", + "@selectAvailablePlates": {}, + "barWeight": "وزن القضيب الحديدي", + "@barWeight": {}, + "useColors": "استخدم الالوان", + "@useColors": {}, + "apiTokenValidChars": "إن مفتاح ال API لا يمكن أن يحتوي غير الأحرف من a-f، أرقام من 0-9، ويحب أن تكون 40 محرف تماما", + "@apiTokenValidChars": { + "description": "Error message when the user tries to input a API key with forbidden characters" + } } From 1aaa7e7e929429376c4d9ced864309e085e17016 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Jul 2025 00:41:58 +0000 Subject: [PATCH 47/89] Bump freezed from 3.0.6 to 3.2.0 Bumps [freezed](https://github.com/rrousselGit/freezed) from 3.0.6 to 3.2.0. - [Commits](https://github.com/rrousselGit/freezed/compare/freezed-v3.0.6...freezed-v3.2.0) --- updated-dependencies: - dependency-name: freezed dependency-version: 3.2.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pubspec.lock | 68 +++++++++++++++++++++++----------------------------- pubspec.yaml | 2 +- 2 files changed, 31 insertions(+), 39 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index a398dbf8..a3c579fc 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,18 +5,18 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: e55636ed79578b9abca5fecf9437947798f5ef7456308b5cb85720b793eac92f + sha256: da0d9209ca76bde579f2da330aeb9df62b6319c834fa7baae052021b0462401f url: "https://pub.dev" source: hosted - version: "82.0.0" + version: "85.0.0" analyzer: dependency: transitive description: name: analyzer - sha256: "904ae5bb474d32c38fb9482e2d925d5454cda04ddd0e55d2e6826bc72f6ba8c0" + sha256: "974859dc0ff5f37bc4313244b3218c791810d03ab3470a579580279ba971a48d" url: "https://pub.dev" source: hosted - version: "7.4.5" + version: "7.7.1" archive: dependency: transitive description: @@ -53,10 +53,10 @@ packages: dependency: transitive description: name: build - sha256: "74273591bd8b7f82eeb1f191c1b65a6576535bbfd5ca3722778b07d5702d33cc" + sha256: "7d95cbbb1526ab5ae977df9b4cc660963b9b27f6d1075c0b34653868911385e4" url: "https://pub.dev" source: hosted - version: "2.5.3" + version: "3.0.0" build_config: dependency: transitive description: @@ -77,26 +77,26 @@ packages: dependency: transitive description: name: build_resolvers - sha256: badce70566085f2e87434531c4a6bc8e833672f755fc51146d612245947e91c9 + sha256: "38c9c339333a09b090a638849a4c56e70a404c6bdd3b511493addfbc113b60c2" url: "https://pub.dev" source: hosted - version: "2.5.3" + version: "3.0.0" build_runner: dependency: "direct dev" description: name: build_runner - sha256: b9070a4127033777c0e63195f6f117ed16a351ed676f6313b095cf4f328c0b82 + sha256: b971d4a1c789eba7be3e6fe6ce5e5b50fd3719e3cb485b3fad6d04358304351d url: "https://pub.dev" source: hosted - version: "2.5.3" + version: "2.6.0" build_runner_core: dependency: transitive description: name: build_runner_core - sha256: "1cdfece3eeb3f1263f7dbf5bcc0cba697bd0c22d2c866cb4b578c954dbb09bcf" + sha256: c04e612ca801cd0928ccdb891c263a2b1391cb27940a5ea5afcf9ba894de5d62 url: "https://pub.dev" source: hosted - version: "9.1.1" + version: "9.2.0" built_collection: dependency: transitive description: @@ -285,18 +285,18 @@ packages: dependency: "direct main" description: name: drift - sha256: e60c715f045dd33624fc533efb0075e057debec9f39e83843e518f488a0e21fb + sha256: dce2723fb0dd03563af21f305f8f96514c27f870efba934b4fe84d4fedb4eff7 url: "https://pub.dev" source: hosted - version: "2.27.0" + version: "2.28.0" drift_dev: dependency: "direct dev" description: name: drift_dev - sha256: "7ad88b8982e753eadcdbc0ea7c7d30500598af733601428b5c9d264baf5106d6" + sha256: dce092d556aa11ee808537ab32e0657f235dc20ccfc300320e916461ae88abcc url: "https://pub.dev" source: hosted - version: "2.27.0" + version: "2.28.1-dev.0" equatable: dependency: "direct main" description: @@ -550,18 +550,18 @@ packages: dependency: "direct dev" description: name: freezed - sha256: "6022db4c7bfa626841b2a10f34dd1e1b68e8f8f9650db6112dcdeeca45ca793c" + sha256: da32f8ba8cfcd4ec71d9decc8cbf28bd2c31b5283d9887eb51eb4a0659d8110c url: "https://pub.dev" source: hosted - version: "3.0.6" + version: "3.2.0" freezed_annotation: dependency: "direct main" description: name: freezed_annotation - sha256: c87ff004c8aa6af2d531668b46a4ea379f7191dc6dfa066acd53d506da6e044b + sha256: "7294967ff0a6d98638e7acb774aac3af2550777accd8149c90af5b014e6d44d8" url: "https://pub.dev" source: hosted - version: "3.0.0" + version: "3.1.0" frontend_server_client: dependency: transitive description: @@ -724,14 +724,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.5" - js: - dependency: transitive - description: - name: js - sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc" - url: "https://pub.dev" - source: hosted - version: "0.7.2" json_annotation: dependency: "direct main" description: @@ -744,10 +736,10 @@ packages: dependency: "direct dev" description: name: json_serializable - sha256: c50ef5fc083d5b5e12eef489503ba3bf5ccc899e487d691584699b4bdefeea8c + sha256: ce2cf974ccdee13be2a510832d7fba0b94b364e0b0395dee42abaa51b855be27 url: "https://pub.dev" source: hosted - version: "6.9.5" + version: "6.10.0" leak_tracker: dependency: transitive description: @@ -848,10 +840,10 @@ packages: dependency: "direct dev" description: name: mockito - sha256: "4546eac99e8967ea91bae633d2ca7698181d008e95fa4627330cf903d573277a" + sha256: "2314cbe9165bcd16106513df9cf3c3224713087f09723b128928dc11a4379f99" url: "https://pub.dev" source: hosted - version: "5.4.6" + version: "5.5.0" multi_select_flutter: dependency: "direct main" description: @@ -1197,18 +1189,18 @@ packages: dependency: transitive description: name: source_gen - sha256: "35c8150ece9e8c8d263337a265153c3329667640850b9304861faea59fc98f6b" + sha256: fc787b1f89ceac9580c3616f899c9a447413cbdac1df071302127764c023a134 url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "3.0.0" source_helper: dependency: transitive description: name: source_helper - sha256: "86d247119aedce8e63f4751bd9626fc9613255935558447569ad42f9f5b48b3c" + sha256: "4f81479fe5194a622cdd1713fe1ecb683a6e6c85cd8cec8e2e35ee5ab3fdf2a1" url: "https://pub.dev" source: hosted - version: "1.3.5" + version: "1.3.6" source_span: dependency: transitive description: @@ -1237,10 +1229,10 @@ packages: dependency: transitive description: name: sqlparser - sha256: "27dd0a9f0c02e22ac0eb42a23df9ea079ce69b52bb4a3b478d64e0ef34a263ee" + sha256: "7c859c803cf7e9a84d6db918bac824545045692bbe94a6386bd3a45132235d09" url: "https://pub.dev" source: hosted - version: "0.41.0" + version: "0.41.1" stack_trace: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 5fab4d40..13dc4b5c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -78,7 +78,7 @@ dev_dependencies: cider: ^0.2.7 drift_dev: ^2.27.0 flutter_lints: ^6.0.0 - freezed: ^3.0.6 + freezed: ^3.2.0 json_serializable: ^6.9.5 mockito: ^5.4.6 network_image_mock: ^2.1.1 From 1d2d0b3e8cf0c10b8e0247a16a80c37e6d757cdc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Jul 2025 00:41:34 +0000 Subject: [PATCH 48/89] Bump build_runner from 2.5.3 to 2.6.0 Bumps [build_runner](https://github.com/dart-lang/build) from 2.5.3 to 2.6.0. - [Release notes](https://github.com/dart-lang/build/releases) - [Commits](https://github.com/dart-lang/build/compare/build_runner-v2.5.3...build_runner-v2.6.0) --- updated-dependencies: - dependency-name: build_runner dependency-version: 2.6.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 13dc4b5c..be877e8b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -74,7 +74,7 @@ dev_dependencies: sdk: flutter integration_test: sdk: flutter - build_runner: ^2.5.3 + build_runner: ^2.6.0 cider: ^0.2.7 drift_dev: ^2.27.0 flutter_lints: ^6.0.0 From 2eef0603eee303575a72a7353f48526e2699c91b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Aug 2025 17:56:59 +0000 Subject: [PATCH 49/89] Bump drift_dev from 2.27.0 to 2.28.1 Bumps [drift_dev](https://github.com/simolus3/drift) from 2.27.0 to 2.28.1. - [Release notes](https://github.com/simolus3/drift/releases) - [Commits](https://github.com/simolus3/drift/compare/drift_dev-2.27.0...drift_dev-2.28.1) --- updated-dependencies: - dependency-name: drift_dev dependency-version: 2.28.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pubspec.lock | 4 ++-- pubspec.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index a3c579fc..485e1e54 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -293,10 +293,10 @@ packages: dependency: "direct dev" description: name: drift_dev - sha256: dce092d556aa11ee808537ab32e0657f235dc20ccfc300320e916461ae88abcc + sha256: "2fc05ad458a7c562755bf0cae11178dfc58387a416829b78d4da5155a61465fd" url: "https://pub.dev" source: hosted - version: "2.28.1-dev.0" + version: "2.28.1" equatable: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index be877e8b..df3fb621 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -76,7 +76,7 @@ dev_dependencies: sdk: flutter build_runner: ^2.6.0 cider: ^0.2.7 - drift_dev: ^2.27.0 + drift_dev: ^2.28.1 flutter_lints: ^6.0.0 freezed: ^3.2.0 json_serializable: ^6.9.5 From ce588f5ebcea2c0c2d781d1c1f298c6df551572c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Aug 2025 18:02:00 +0000 Subject: [PATCH 50/89] Bump url_launcher from 6.3.1 to 6.3.2 Bumps [url_launcher](https://github.com/flutter/packages/tree/main/packages/url_launcher) from 6.3.1 to 6.3.2. - [Release notes](https://github.com/flutter/packages/releases) - [Commits](https://github.com/flutter/packages/commits/url_launcher-v6.3.2/packages/url_launcher) --- updated-dependencies: - dependency-name: url_launcher dependency-version: 6.3.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pubspec.lock | 4 ++-- pubspec.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index 485e1e54..ff8e66f8 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1325,10 +1325,10 @@ packages: dependency: "direct main" description: name: url_launcher - sha256: "9d06212b1362abc2f0f0d78e6f09f726608c74e3b9462e8368bb03314aa8d603" + sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8 url: "https://pub.dev" source: hosted - version: "6.3.1" + version: "6.3.2" url_launcher_android: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index df3fb621..58f9c9ab 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -63,7 +63,7 @@ dependencies: shared_preferences: ^2.5.3 sqlite3_flutter_libs: ^0.5.34 table_calendar: ^3.0.8 - url_launcher: ^6.3.1 + url_launcher: ^6.3.2 version: ^3.0.2 video_player: ^2.10.0 logging: ^1.3.0 From 13e39bd958740fec1ae9027ffe4c53813d0a27eb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Aug 2025 08:41:13 +0000 Subject: [PATCH 51/89] Bump actions/checkout from 4 to 5 Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build-android.yml | 4 ++-- .github/workflows/build-apple.yml | 6 +++--- .github/workflows/build-linux.yml | 4 ++-- .github/workflows/build-windows.yml | 2 +- .github/workflows/bump-version.yml | 2 +- .github/workflows/ci.yml | 2 +- .github/workflows/make-release.yml | 4 ++-- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build-android.yml b/.github/workflows/build-android.yml index ff044875..f07a7066 100644 --- a/.github/workflows/build-android.yml +++ b/.github/workflows/build-android.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout application - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: ref: ${{ inputs.ref }} @@ -46,7 +46,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout application - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: ref: ${{ inputs.ref }} diff --git a/.github/workflows/build-apple.yml b/.github/workflows/build-apple.yml index 64456188..43df683a 100644 --- a/.github/workflows/build-apple.yml +++ b/.github/workflows/build-apple.yml @@ -11,7 +11,7 @@ jobs: runs-on: macos-latest steps: - name: Checkout application - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: ref: ${{ inputs.ref }} @@ -34,7 +34,7 @@ jobs: runs-on: macos-latest steps: - name: Checkout application - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: ref: ${{ inputs.ref }} @@ -57,7 +57,7 @@ jobs: runs-on: macos-latest steps: - name: Checkout application - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: ref: ${{ inputs.ref }} diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml index a69e3dff..ebb76376 100644 --- a/.github/workflows/build-linux.yml +++ b/.github/workflows/build-linux.yml @@ -25,7 +25,7 @@ jobs: # runner: ubuntu-24.04-arm steps: - name: Checkout application - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: ref: ${{ inputs.ref }} @@ -56,7 +56,7 @@ jobs: steps: - name: Checkout flatpak-flathub repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: wger-project/de.wger.flutter diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index 8c1208b7..adc64f80 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -15,7 +15,7 @@ jobs: runs-on: windows-latest steps: - name: Checkout application - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: ref: ${{ inputs.ref }} diff --git a/.github/workflows/bump-version.yml b/.github/workflows/bump-version.yml index 483b0c3e..951ab4db 100644 --- a/.github/workflows/bump-version.yml +++ b/.github/workflows/bump-version.yml @@ -13,7 +13,7 @@ jobs: steps: - name: Checkout application - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: fetch-depth: 0 # needed to push changes token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9bc20e31..1fe851a3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,7 +17,7 @@ jobs: name: Run tests runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Common flutter setup uses: ./.github/actions/flutter-common diff --git a/.github/workflows/make-release.yml b/.github/workflows/make-release.yml index ad371196..97d83d8f 100644 --- a/.github/workflows/make-release.yml +++ b/.github/workflows/make-release.yml @@ -61,7 +61,7 @@ jobs: - build_linux steps: - name: Checkout application - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: ref: ${{ github.event.inputs.version }} @@ -105,7 +105,7 @@ jobs: # - build_apple # steps: # - name: Checkout application - # uses: actions/checkout@v4 + # uses: actions/checkout@v5 # with: # ref: feature/build-process # # ref: ${{ github.event.inputs.version }} From 3426810ba6b5f9a03598a09d71412e85c9c880d5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Aug 2025 00:55:44 +0000 Subject: [PATCH 52/89] Bump actions/download-artifact from 4 to 5 Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4 to 5. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/make-release.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/make-release.yml b/.github/workflows/make-release.yml index 97d83d8f..1b5b5f9a 100644 --- a/.github/workflows/make-release.yml +++ b/.github/workflows/make-release.yml @@ -66,7 +66,7 @@ jobs: ref: ${{ github.event.inputs.version }} - name: Download builds - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v5 with: path: /tmp/ @@ -114,7 +114,7 @@ jobs: # uses: ./.github/actions/flutter-common # # - name: Download builds - # uses: actions/download-artifact@v4 + # uses: actions/download-artifact@v5 # with: # path: /tmp/ # @@ -133,7 +133,7 @@ jobs: steps: - name: Download builds - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v5 - name: Make Github release uses: softprops/action-gh-release@v2 From e44d5718f3f8150db546af2d4335afee582df0ae Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Tue, 12 Aug 2025 22:03:20 +0200 Subject: [PATCH 53/89] Bump some dependencies --- pubspec.lock | 32 ++++++++++++++++---------------- pubspec.yaml | 12 ++++++------ 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index ff8e66f8..e3dde89d 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -285,10 +285,10 @@ packages: dependency: "direct main" description: name: drift - sha256: dce2723fb0dd03563af21f305f8f96514c27f870efba934b4fe84d4fedb4eff7 + sha256: "6aaea757f53bb035e8a3baedf3d1d53a79d6549a6c13d84f7546509da9372c7c" url: "https://pub.dev" source: hosted - version: "2.28.0" + version: "2.28.1" drift_dev: dependency: "direct dev" description: @@ -534,18 +534,18 @@ packages: dependency: "direct main" description: name: flutter_zxing - sha256: "90de8b25947111e090214c0409a3363561b444d395cb3feab9207ac4ee247c94" + sha256: dbcd89da2c9aa84f48d7d7e1ba436825f8656a69b142abb7bcdb7c2d9c22d48c url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.2.1" font_awesome_flutter: dependency: "direct main" description: name: font_awesome_flutter - sha256: d3a89184101baec7f4600d58840a764d2ef760fe1c5a20ef9e6b0e9b24a07a3a + sha256: f50ce90dbe26d977415b9540400d6778bef00894aced6358ae578abd92b14b10 url: "https://pub.dev" source: hosted - version: "10.8.0" + version: "10.9.0" freezed: dependency: "direct dev" description: @@ -579,10 +579,10 @@ packages: dependency: "direct main" description: name: get_it - sha256: f126a3e286b7f5b578bf436d5592968706c4c1de28a228b870ce375d9f743103 + sha256: a4292e7cf67193f8e7c1258203104eb2a51ec8b3a04baa14695f4064c144297b url: "https://pub.dev" source: hosted - version: "8.0.3" + version: "8.2.0" glob: dependency: transitive description: @@ -611,10 +611,10 @@ packages: dependency: "direct main" description: name: http - sha256: "2c11f3f94c687ee9bad77c171151672986360b2b001d109814ee7140b2cf261b" + sha256: bb2ce4590bc2667c96f318d68cac1b5a7987ec819351d32b1c987239a815e007 url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.5.0" http_multi_server: dependency: transitive description: @@ -880,18 +880,18 @@ packages: dependency: "direct main" description: name: package_info_plus - sha256: "7976bfe4c583170d6cdc7077e3237560b364149fcd268b5f53d95a991963b191" + sha256: "16eee997588c60225bda0488b6dcfac69280a6b7a3cf02c741895dd370a02968" url: "https://pub.dev" source: hosted - version: "8.3.0" + version: "8.3.1" package_info_plus_platform_interface: dependency: transitive description: name: package_info_plus_platform_interface - sha256: "6c935fb612dff8e3cc9632c2b301720c77450a126114126ffaafe28d2e87956c" + sha256: "202a487f08836a592a6bd4f901ac69b3a8f146af552bbd14407b6b41e1c3f086" url: "https://pub.dev" source: hosted - version: "3.2.0" + version: "3.2.1" path: dependency: "direct main" description: @@ -1221,10 +1221,10 @@ packages: dependency: "direct main" description: name: sqlite3_flutter_libs - sha256: e07232b998755fe795655c56d1f5426e0190c9c435e1752d39e7b1cd33699c71 + sha256: "2b03273e71867a8a4d030861fc21706200debe5c5858a4b9e58f4a1c129586a4" url: "https://pub.dev" source: hosted - version: "0.5.34" + version: "0.5.39" sqlparser: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 58f9c9ab..683b6a71 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -36,7 +36,7 @@ dependencies: clock: ^1.1.2 collection: ^1.18.0 cupertino_icons: ^1.0.8 - drift: ^2.27.0 + drift: ^2.28.1 equatable: ^2.0.7 fl_chart: ^1.0.0 flex_color_scheme: ^8.1.1 @@ -46,16 +46,16 @@ dependencies: flutter_svg: ^2.2.0 flutter_svg_icons: ^0.0.1 flutter_typeahead: ^5.2.0 - flutter_zxing: ^2.1.0 - font_awesome_flutter: ^10.8.0 + flutter_zxing: ^2.2.1 + font_awesome_flutter: ^10.9.0 freezed_annotation: ^3.0.0 - get_it: ^8.0.3 - http: ^1.4.0 + get_it: ^8.2.0 + http: ^1.5.0 image_picker: ^1.1.0 intl: ^0.20.0 json_annotation: ^4.8.1 multi_select_flutter: ^4.1.3 - package_info_plus: ^8.3.0 + package_info_plus: ^8.3.1 path: ^1.9.0 path_provider: ^2.1.5 provider: ^6.1.5 From 63373af8841c7d864e5f113ec76b3f2fa3e785e5 Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Wed, 13 Aug 2025 19:52:28 +0200 Subject: [PATCH 54/89] Update Podfile.lock --- ios/Podfile.lock | 27 +++++++++++++++------------ macos/Podfile.lock | 25 ++++++++++++++----------- 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 10721381..e515168f 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -22,28 +22,31 @@ PODS: - shared_preferences_foundation (0.0.1): - Flutter - FlutterMacOS - - sqlite3 (3.50.1): - - sqlite3/common (= 3.50.1) - - sqlite3/common (3.50.1) - - sqlite3/dbstatvtab (3.50.1): + - sqlite3 (3.50.4): + - sqlite3/common (= 3.50.4) + - sqlite3/common (3.50.4) + - sqlite3/dbstatvtab (3.50.4): - sqlite3/common - - sqlite3/fts5 (3.50.1): + - sqlite3/fts5 (3.50.4): - sqlite3/common - - sqlite3/math (3.50.1): + - sqlite3/math (3.50.4): - sqlite3/common - - sqlite3/perf-threadsafe (3.50.1): + - sqlite3/perf-threadsafe (3.50.4): - sqlite3/common - - sqlite3/rtree (3.50.1): + - sqlite3/rtree (3.50.4): + - sqlite3/common + - sqlite3/session (3.50.4): - sqlite3/common - sqlite3_flutter_libs (0.0.1): - Flutter - FlutterMacOS - - sqlite3 (~> 3.50.1) + - sqlite3 (~> 3.50.4) - sqlite3/dbstatvtab - sqlite3/fts5 - sqlite3/math - sqlite3/perf-threadsafe - sqlite3/rtree + - sqlite3/session - url_launcher_ios (0.0.1): - Flutter - video_player_avfoundation (0.0.1): @@ -112,11 +115,11 @@ SPEC CHECKSUMS: pointer_interceptor_ios: ec847ef8b0915778bed2b2cef636f4d177fa8eed rive_common: dd421daaf9ae69f0125aa761dd96abd278399952 shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7 - sqlite3: 1d85290c3321153511f6e900ede7a1608718bbd5 - sqlite3_flutter_libs: e7fc8c9ea2200ff3271f08f127842131746b70e2 + sqlite3: 73513155ec6979715d3904ef53a8d68892d4032b + sqlite3_flutter_libs: 83f8e9f5b6554077f1d93119fe20ebaa5f3a9ef1 url_launcher_ios: 694010445543906933d732453a59da0a173ae33d video_player_avfoundation: 2cef49524dd1f16c5300b9cd6efd9611ce03639b -PODFILE CHECKSUM: 5a367937f10bf0c459576e5e472a1159ee029c13 +PODFILE CHECKSUM: 0940a686eb3f7747ff575b8c89d61b33faac475a COCOAPODS: 1.16.2 diff --git a/macos/Podfile.lock b/macos/Podfile.lock index 09aeee16..13c443e9 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -14,28 +14,31 @@ PODS: - shared_preferences_foundation (0.0.1): - Flutter - FlutterMacOS - - sqlite3 (3.50.1): - - sqlite3/common (= 3.50.1) - - sqlite3/common (3.50.1) - - sqlite3/dbstatvtab (3.50.1): + - sqlite3 (3.50.4): + - sqlite3/common (= 3.50.4) + - sqlite3/common (3.50.4) + - sqlite3/dbstatvtab (3.50.4): - sqlite3/common - - sqlite3/fts5 (3.50.1): + - sqlite3/fts5 (3.50.4): - sqlite3/common - - sqlite3/math (3.50.1): + - sqlite3/math (3.50.4): - sqlite3/common - - sqlite3/perf-threadsafe (3.50.1): + - sqlite3/perf-threadsafe (3.50.4): - sqlite3/common - - sqlite3/rtree (3.50.1): + - sqlite3/rtree (3.50.4): + - sqlite3/common + - sqlite3/session (3.50.4): - sqlite3/common - sqlite3_flutter_libs (0.0.1): - Flutter - FlutterMacOS - - sqlite3 (~> 3.50.1) + - sqlite3 (~> 3.50.4) - sqlite3/dbstatvtab - sqlite3/fts5 - sqlite3/math - sqlite3/perf-threadsafe - sqlite3/rtree + - sqlite3/session - url_launcher_macos (0.0.1): - FlutterMacOS - video_player_avfoundation (0.0.1): @@ -88,8 +91,8 @@ SPEC CHECKSUMS: path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564 rive_common: ea79040f86acf053a2d5a75a2506175ee39796a5 shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7 - sqlite3: 1d85290c3321153511f6e900ede7a1608718bbd5 - sqlite3_flutter_libs: e7fc8c9ea2200ff3271f08f127842131746b70e2 + sqlite3: 73513155ec6979715d3904ef53a8d68892d4032b + sqlite3_flutter_libs: 83f8e9f5b6554077f1d93119fe20ebaa5f3a9ef1 url_launcher_macos: 0fba8ddabfc33ce0a9afe7c5fef5aab3d8d2d673 video_player_avfoundation: 2cef49524dd1f16c5300b9cd6efd9611ce03639b From bea40c9a3c794c8f5ea62efe21b67a38e27fb39d Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Wed, 13 Aug 2025 19:54:32 +0200 Subject: [PATCH 55/89] Correctly parse the localized weight values in the form --- lib/widgets/weight/forms.dart | 25 +++++++++++++++---------- test/weight/weight_form_test.dart | 2 +- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/lib/widgets/weight/forms.dart b/lib/widgets/weight/forms.dart index 7ab3b2ba..5b309e3f 100644 --- a/lib/widgets/weight/forms.dart +++ b/lib/widgets/weight/forms.dart @@ -22,6 +22,7 @@ import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; import 'package:wger/helpers/consts.dart'; import 'package:wger/helpers/json.dart'; +import 'package:wger/helpers/misc.dart'; import 'package:wger/l10n/generated/app_localizations.dart'; import 'package:wger/models/body_weight/weight_entry.dart'; import 'package:wger/providers/body_weight.dart'; @@ -35,7 +36,7 @@ class WeightForm extends StatelessWidget { WeightForm([WeightEntry? weightEntry]) { _weightEntry = weightEntry ?? WeightEntry(date: DateTime.now()); - weightController.text = _weightEntry.weight == 0 ? '' : _weightEntry.weight.toString(); + weightController.text = ''; dateController.text = dateToYYYYMMDD(_weightEntry.date)!; } @@ -43,6 +44,10 @@ class WeightForm extends StatelessWidget { Widget build(BuildContext context) { final numberFormat = NumberFormat.decimalPattern(Localizations.localeOf(context).toString()); + if (weightController.text.isEmpty && _weightEntry.weight != 0) { + weightController.text = numberFormat.format(_weightEntry.weight); + } + return Form( key: _form, child: Column( @@ -69,7 +74,7 @@ class WeightForm extends StatelessWidget { lastDate: DateTime.now(), selectableDayPredicate: (day) { // Always allow the current initial date - if (day == _weightEntry.date) { + if (day.isSameDayAs(_weightEntry.date)) { return true; } @@ -101,8 +106,8 @@ class WeightForm extends StatelessWidget { icon: const FaIcon(FontAwesomeIcons.circleMinus), onPressed: () { try { - final num newValue = num.parse(weightController.text) - 1; - weightController.text = newValue.toString(); + final newValue = numberFormat.parse(weightController.text) - 1; + weightController.text = numberFormat.format(newValue); } on FormatException {} }, ), @@ -111,8 +116,8 @@ class WeightForm extends StatelessWidget { icon: const FaIcon(FontAwesomeIcons.minus), onPressed: () { try { - final num newValue = num.parse(weightController.text) - 0.1; - weightController.text = newValue.toStringAsFixed(1); + final newValue = numberFormat.parse(weightController.text) - 0.1; + weightController.text = numberFormat.format(newValue); } on FormatException {} }, ), @@ -126,8 +131,8 @@ class WeightForm extends StatelessWidget { icon: const FaIcon(FontAwesomeIcons.plus), onPressed: () { try { - final num newValue = num.parse(weightController.text) + 0.1; - weightController.text = newValue.toStringAsFixed(1); + final newValue = numberFormat.parse(weightController.text) + 0.1; + weightController.text = numberFormat.format(newValue); } on FormatException {} }, ), @@ -136,8 +141,8 @@ class WeightForm extends StatelessWidget { icon: const FaIcon(FontAwesomeIcons.circlePlus), onPressed: () { try { - final num newValue = num.parse(weightController.text) + 1; - weightController.text = newValue.toString(); + final newValue = numberFormat.parse(weightController.text) + 1; + weightController.text = numberFormat.format(newValue); } on FormatException {} }, ), diff --git a/test/weight/weight_form_test.dart b/test/weight/weight_form_test.dart index 443f07f5..9a1bfaa2 100644 --- a/test/weight/weight_form_test.dart +++ b/test/weight/weight_form_test.dart @@ -56,7 +56,7 @@ void main() { expect(find.text('79.9'), findsOneWidget); await tester.tap(find.byKey(const Key('quickPlusSmall'))); - expect(find.text('80.0'), findsOneWidget); + expect(find.text('80'), findsOneWidget); }); testWidgets("Entering garbage doesn't break the quick-change", (WidgetTester tester) async { From d2f38228fb6229b7e64f8e03b42c7b459738bdd1 Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Wed, 13 Aug 2025 20:45:58 +0200 Subject: [PATCH 56/89] Improvements in handling localized values in the UI --- lib/widgets/dashboard/calendar.dart | 13 +++++++------ lib/widgets/measurements/charts.dart | 9 +++++++-- lib/widgets/measurements/entries.dart | 5 +++-- lib/widgets/measurements/forms.dart | 17 ++++++++++++++--- lib/widgets/weight/weight_overview.dart | 4 +++- .../measurement_entries_screen_test.dart | 2 +- 6 files changed, 35 insertions(+), 15 deletions(-) diff --git a/lib/widgets/dashboard/calendar.dart b/lib/widgets/dashboard/calendar.dart index 2069d243..76621fad 100644 --- a/lib/widgets/dashboard/calendar.dart +++ b/lib/widgets/dashboard/calendar.dart @@ -17,6 +17,7 @@ */ import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; import 'package:table_calendar/table_calendar.dart'; import 'package:wger/helpers/consts.dart'; @@ -85,9 +86,10 @@ class _DashboardCalendarWidgetState extends State } void loadEvents() async { + final numberFormat = NumberFormat.decimalPattern(Localizations.localeOf(context).toString()); + // Process weight entries - final BodyWeightProvider weightProvider = - Provider.of(context, listen: false); + final weightProvider = context.read(); for (final entry in weightProvider.items) { final date = DateFormatLists.format(entry.date); @@ -96,12 +98,11 @@ class _DashboardCalendarWidgetState extends State } // Add events to lists - _events[date]!.add(Event(EventType.weight, '${entry.weight} kg')); + _events[date]!.add(Event(EventType.weight, '${numberFormat.format(entry.weight)} kg')); } // Process measurements - final MeasurementProvider measurementProvider = - Provider.of(context, listen: false); + final measurementProvider = context.read(); for (final category in measurementProvider.categories) { for (final entry in category.entries) { final date = DateFormatLists.format(entry.date); @@ -112,7 +113,7 @@ class _DashboardCalendarWidgetState extends State _events[date]!.add(Event( EventType.measurement, - '${category.name}: ${entry.value} ${category.unit}', + '${category.name}: ${numberFormat.format(entry.value)} ${category.unit}', )); } } diff --git a/lib/widgets/measurements/charts.dart b/lib/widgets/measurements/charts.dart index 62ee1d4a..704c3da6 100644 --- a/lib/widgets/measurements/charts.dart +++ b/lib/widgets/measurements/charts.dart @@ -78,13 +78,16 @@ class _MeasurementChartWidgetFlState extends State { touchTooltipData: LineTouchTooltipData( getTooltipColor: (touchedSpot) => Theme.of(context).colorScheme.primaryContainer, getTooltipItems: (touchedSpots) { + final numberFormat = + NumberFormat.decimalPattern(Localizations.localeOf(context).toString()); + return touchedSpots.map((touchedSpot) { final DateTime date = DateTime.fromMillisecondsSinceEpoch(touchedSpot.x.toInt()); final dateStr = DateFormat.Md(Localizations.localeOf(context).languageCode).format(date); return LineTooltipItem( - '$dateStr: ${touchedSpot.y.toStringAsFixed(1)} ${widget._unit}', + '$dateStr: ${numberFormat.format(touchedSpot.y)} ${widget._unit}', TextStyle(color: touchedSpot.bar.color), ); }).toList(); @@ -94,6 +97,8 @@ class _MeasurementChartWidgetFlState extends State { } LineChartData mainData() { + final numberFormat = NumberFormat.decimalPattern(Localizations.localeOf(context).toString()); + return LineChartData( lineTouchData: tooltipData(), gridData: FlGridData( @@ -158,7 +163,7 @@ class _MeasurementChartWidgetFlState extends State { return const Text(''); } - return Text('${value.toStringAsFixed(1)} ${widget._unit}'); + return Text('${numberFormat.format(value)} ${widget._unit}'); }, ), ), diff --git a/lib/widgets/measurements/entries.dart b/lib/widgets/measurements/entries.dart index 2efa8858..8fe2e3a8 100644 --- a/lib/widgets/measurements/entries.dart +++ b/lib/widgets/measurements/entries.dart @@ -37,6 +37,8 @@ class EntriesList extends StatelessWidget { @override Widget build(BuildContext context) { final plan = Provider.of(context, listen: false).currentPlan; + final numberFormat = NumberFormat.decimalPattern(Localizations.localeOf(context).toString()); + final provider = Provider.of(context, listen: false); final entriesAll = _category.entries.map((e) => MeasurementChartEntry(e.value, e.date)).toList(); @@ -58,11 +60,10 @@ class EntriesList extends StatelessWidget { itemCount: _category.entries.length, itemBuilder: (context, index) { final currentEntry = _category.entries[index]; - final provider = Provider.of(context, listen: false); return Card( child: ListTile( - title: Text('${currentEntry.value} ${_category.unit}'), + title: Text('${numberFormat.format(currentEntry.value)} ${_category.unit}'), subtitle: Text( DateFormat.yMd(Localizations.localeOf(context).languageCode) .format(currentEntry.date), diff --git a/lib/widgets/measurements/forms.dart b/lib/widgets/measurements/forms.dart index d82759fa..e547dc2d 100644 --- a/lib/widgets/measurements/forms.dart +++ b/lib/widgets/measurements/forms.dart @@ -159,7 +159,7 @@ class MeasurementEntryForm extends StatelessWidget { } _dateController.text = dateToYYYYMMDD(_entryData['date'])!; - _valueController.text = _entryData['value']!.toString(); + _valueController.text = ''; _notesController.text = _entryData['notes']!; } @@ -172,12 +172,23 @@ class MeasurementEntryForm extends StatelessWidget { final numberFormat = NumberFormat.decimalPattern(Localizations.localeOf(context).toString()); + // If the value is not empty, format it + if (_valueController.text.isEmpty && _entryData['value'] != null && _entryData['value'] != '') { + _valueController.text = numberFormat.format(_entryData['value']); + } + return Form( key: _form, child: Column( children: [ TextFormField( - decoration: InputDecoration(labelText: AppLocalizations.of(context).date), + decoration: InputDecoration( + labelText: AppLocalizations.of(context).date, + suffixIcon: const Icon( + Icons.calendar_today, + key: Key('calendarIcon'), + ), + ), readOnly: true, // Hide text cursor controller: _dateController, @@ -202,7 +213,7 @@ class MeasurementEntryForm extends StatelessWidget { }, ); - _dateController.text = dateToYYYYMMDD(pickedDate)!; + _dateController.text = pickedDate == null ? '' : dateToYYYYMMDD(pickedDate)!; }, onSaved: (newValue) { _entryData['date'] = DateTime.parse(newValue!); diff --git a/lib/widgets/weight/weight_overview.dart b/lib/widgets/weight/weight_overview.dart index 9d47d9ae..a60e04b5 100644 --- a/lib/widgets/weight/weight_overview.dart +++ b/lib/widgets/weight/weight_overview.dart @@ -37,6 +37,7 @@ class WeightOverview extends StatelessWidget { @override Widget build(BuildContext context) { final profile = context.read().profile; + final numberFormat = NumberFormat.decimalPattern(Localizations.localeOf(context).toString()); final plan = Provider.of(context, listen: false).currentPlan; final entriesAll = _provider.items.map((e) => MeasurementChartEntry(e.weight, e.date)).toList(); @@ -78,7 +79,8 @@ class WeightOverview extends StatelessWidget { final currentEntry = _provider.items[index]; return Card( child: ListTile( - title: Text('${currentEntry.weight} ${weightUnit(profile.isMetric, context)}'), + title: Text( + '${numberFormat.format(currentEntry.weight)} ${weightUnit(profile.isMetric, context)}'), subtitle: Text( DateFormat.yMd( Localizations.localeOf(context).languageCode, diff --git a/test/measurements/measurement_entries_screen_test.dart b/test/measurements/measurement_entries_screen_test.dart index 85862dd5..5a1cb3ae 100644 --- a/test/measurements/measurement_entries_screen_test.dart +++ b/test/measurements/measurement_entries_screen_test.dart @@ -82,7 +82,7 @@ void main() { expect(find.text('body fat'), findsOneWidget); // Entries - expect(find.text('15.0 %'), findsNWidgets(1)); + expect(find.text('15 %'), findsNWidgets(1)); }); testWidgets('Tests the localization of dates - EN', (WidgetTester tester) async { From 94fc1573333e73dc56a6655068dabfd7a80971b9 Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Wed, 13 Aug 2025 21:20:48 +0200 Subject: [PATCH 57/89] Remove dead code and uncomment the dumpErrorToConsole message This can be useful e.g. for the flatpak versions --- lib/main.dart | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 9c3a2ab6..e63e7485 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -82,7 +82,6 @@ void main() async { _setupLogging(); final logger = Logger('main'); - //zx.setLogEnabled(kDebugMode); // Locator to initialize exerciseDB await ServiceLocator().configure(); @@ -97,9 +96,7 @@ void main() async { if (kReleaseMode) { FlutterError.onError = (FlutterErrorDetails details) { final stack = details.stack ?? StackTrace.empty; - // if (kDebugMode) { - // FlutterError.dumpErrorToConsole(details); - // } + FlutterError.dumpErrorToConsole(details); // Don't show the full error dialog for network image loading errors. if (details.exception is NetworkImageLoadException) { From 5cb3b080dbbb9c46a57d320ad039b4d9c9338349 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Aug 2025 00:26:18 +0000 Subject: [PATCH 58/89] Bump build_runner from 2.6.0 to 2.7.0 Bumps [build_runner](https://github.com/dart-lang/build) from 2.6.0 to 2.7.0. - [Release notes](https://github.com/dart-lang/build/releases) - [Commits](https://github.com/dart-lang/build/compare/build_runner-v2.6.0...build_runner-v2.7.0) --- updated-dependencies: - dependency-name: build_runner dependency-version: 2.7.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pubspec.lock | 40 ++++++++++++++++++++-------------------- pubspec.yaml | 2 +- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index e3dde89d..810bd522 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -53,18 +53,18 @@ packages: dependency: transitive description: name: build - sha256: "7d95cbbb1526ab5ae977df9b4cc660963b9b27f6d1075c0b34653868911385e4" + sha256: "6439a9c71a4e6eca8d9490c1b380a25b02675aa688137dfbe66d2062884a23ac" url: "https://pub.dev" source: hosted - version: "3.0.0" + version: "3.0.2" build_config: dependency: transitive description: name: build_config - sha256: "4ae2de3e1e67ea270081eaee972e1bd8f027d459f249e0f1186730784c2e7e33" + sha256: "4f64382b97504dc2fcdf487d5aae33418e08b4703fc21249e4db6d804a4d0187" url: "https://pub.dev" source: hosted - version: "1.1.2" + version: "1.2.0" build_daemon: dependency: transitive description: @@ -77,26 +77,26 @@ packages: dependency: transitive description: name: build_resolvers - sha256: "38c9c339333a09b090a638849a4c56e70a404c6bdd3b511493addfbc113b60c2" + sha256: "2b21a125d66a86b9511cc3fb6c668c42e9a1185083922bf60e46d483a81a9712" url: "https://pub.dev" source: hosted - version: "3.0.0" + version: "3.0.2" build_runner: dependency: "direct dev" description: name: build_runner - sha256: b971d4a1c789eba7be3e6fe6ce5e5b50fd3719e3cb485b3fad6d04358304351d + sha256: fd3c09f4bbff7fa6e8d8ef688a0b2e8a6384e6483a25af0dac75fef362bcfe6f url: "https://pub.dev" source: hosted - version: "2.6.0" + version: "2.7.0" build_runner_core: dependency: transitive description: name: build_runner_core - sha256: c04e612ca801cd0928ccdb891c263a2b1391cb27940a5ea5afcf9ba894de5d62 + sha256: ab27e46c8aa233e610cf6084ee6d8a22c6f873a0a9929241d8855b7a72978ae7 url: "https://pub.dev" source: hosted - version: "9.2.0" + version: "9.3.0" built_collection: dependency: transitive description: @@ -744,26 +744,26 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0" + sha256: "8dcda04c3fc16c14f48a7bb586d4be1f0d1572731b6d81d51772ef47c02081e0" url: "https://pub.dev" source: hosted - version: "10.0.9" + version: "11.0.1" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 + sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" url: "https://pub.dev" source: hosted - version: "3.0.9" + version: "3.0.10" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.2" lints: dependency: transitive description: @@ -1301,10 +1301,10 @@ packages: dependency: transitive description: name: test_api - sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd + sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" url: "https://pub.dev" source: hosted - version: "0.7.4" + version: "0.7.6" timing: dependency: transitive description: @@ -1413,10 +1413,10 @@ packages: dependency: transitive description: name: vector_math - sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.2.0" version: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 683b6a71..9d98335e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -74,7 +74,7 @@ dev_dependencies: sdk: flutter integration_test: sdk: flutter - build_runner: ^2.6.0 + build_runner: ^2.7.0 cider: ^0.2.7 drift_dev: ^2.28.1 flutter_lints: ^6.0.0 From a067dea56c0630368366bf0e6912699969499503 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Aug 2025 00:26:41 +0000 Subject: [PATCH 59/89] Bump image_picker from 1.1.2 to 1.2.0 Bumps [image_picker](https://github.com/flutter/packages/tree/main/packages/image_picker) from 1.1.2 to 1.2.0. - [Release notes](https://github.com/flutter/packages/releases) - [Commits](https://github.com/flutter/packages/commits/image_picker-v1.2.0/packages/image_picker) --- updated-dependencies: - dependency-name: image_picker dependency-version: 1.2.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pubspec.lock | 32 ++++++++++++++++---------------- pubspec.yaml | 2 +- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index 810bd522..81ccee78 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -643,66 +643,66 @@ packages: dependency: "direct main" description: name: image_picker - sha256: "021834d9c0c3de46bf0fe40341fa07168407f694d9b2bb18d532dc1261867f7a" + sha256: "736eb56a911cf24d1859315ad09ddec0b66104bc41a7f8c5b96b4e2620cf5041" url: "https://pub.dev" source: hosted - version: "1.1.2" + version: "1.2.0" image_picker_android: dependency: transitive description: name: image_picker_android - sha256: "317a5d961cec5b34e777b9252393f2afbd23084aa6e60fcf601dcf6341b9ebeb" + sha256: e83b2b05141469c5e19d77e1dfa11096b6b1567d09065b2265d7c6904560050c url: "https://pub.dev" source: hosted - version: "0.8.12+23" + version: "0.8.13" image_picker_for_web: dependency: transitive description: name: image_picker_for_web - sha256: "717eb042ab08c40767684327be06a5d8dbb341fe791d514e4b92c7bbe1b7bb83" + sha256: "40c2a6a0da15556dc0f8e38a3246064a971a9f512386c3339b89f76db87269b6" url: "https://pub.dev" source: hosted - version: "3.0.6" + version: "3.1.0" image_picker_ios: dependency: transitive description: name: image_picker_ios - sha256: "05da758e67bc7839e886b3959848aa6b44ff123ab4b28f67891008afe8ef9100" + sha256: eb06fe30bab4c4497bad449b66448f50edcc695f1c59408e78aa3a8059eb8f0e url: "https://pub.dev" source: hosted - version: "0.8.12+2" + version: "0.8.13" image_picker_linux: dependency: transitive description: name: image_picker_linux - sha256: "34a65f6740df08bbbeb0a1abd8e6d32107941fd4868f67a507b25601651022c9" + sha256: "1f81c5f2046b9ab724f85523e4af65be1d47b038160a8c8deed909762c308ed4" url: "https://pub.dev" source: hosted - version: "0.2.1+2" + version: "0.2.2" image_picker_macos: dependency: transitive description: name: image_picker_macos - sha256: "1b90ebbd9dcf98fb6c1d01427e49a55bd96b5d67b8c67cf955d60a5de74207c1" + sha256: d58cd9d67793d52beefd6585b12050af0a7663c0c2a6ece0fb110a35d6955e04 url: "https://pub.dev" source: hosted - version: "0.2.1+2" + version: "0.2.2" image_picker_platform_interface: dependency: transitive description: name: image_picker_platform_interface - sha256: "886d57f0be73c4b140004e78b9f28a8914a09e50c2d816bdd0520051a71236a0" + sha256: "9f143b0dba3e459553209e20cc425c9801af48e6dfa4f01a0fcf927be3f41665" url: "https://pub.dev" source: hosted - version: "2.10.1" + version: "2.11.0" image_picker_windows: dependency: transitive description: name: image_picker_windows - sha256: "6ad07afc4eb1bc25f3a01084d28520496c4a3bb0cb13685435838167c9dcedeb" + sha256: d248c86554a72b5495a31c56f060cf73a41c7ff541689327b1a7dbccc33adfae url: "https://pub.dev" source: hosted - version: "0.2.1+1" + version: "0.2.2" integration_test: dependency: "direct dev" description: flutter diff --git a/pubspec.yaml b/pubspec.yaml index 9d98335e..d8f47b74 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -51,7 +51,7 @@ dependencies: freezed_annotation: ^3.0.0 get_it: ^8.2.0 http: ^1.5.0 - image_picker: ^1.1.0 + image_picker: ^1.2.0 intl: ^0.20.0 json_annotation: ^4.8.1 multi_select_flutter: ^4.1.3 From bb1d9361396922e904c51b37ab53a480d2237436 Mon Sep 17 00:00:00 2001 From: Neno Horvat Date: Sat, 16 Aug 2025 14:11:59 +0200 Subject: [PATCH 60/89] Translated using Weblate (Croatian) Currently translated at 86.8% (271 of 312 strings) Translation: wger Workout Manager/Mobile App Translate-URL: https://hosted.weblate.org/projects/wger/mobile/hr/ --- lib/l10n/app_hr.arb | 1908 ++++++++++++++++++++++--------------------- 1 file changed, 970 insertions(+), 938 deletions(-) diff --git a/lib/l10n/app_hr.arb b/lib/l10n/app_hr.arb index 408a1c29..117cd7b0 100644 --- a/lib/l10n/app_hr.arb +++ b/lib/l10n/app_hr.arb @@ -1,942 +1,974 @@ { - "todaysWorkout": "Tvoj današnji trening", - "@todaysWorkout": {}, - "mealLogged": "Obrok prijavljen u dnevnik", - "@mealLogged": {}, - "time": "Vrijeme", - "@time": { - "description": "The time of a meal or workout" - }, - "timeEnd": "Vrijeme završetka", - "@timeEnd": { - "description": "The end time of a workout" - }, - "username": "Korisničko ime", - "@username": {}, - "passwordsDontMatch": "Lozinke se ne podudaraju", - "@passwordsDontMatch": { - "description": "Error message when the user enters two different passwords during registration" - }, - "passwordTooShort": "Lozinka je prekratka", - "@passwordTooShort": { - "description": "Error message when the user a password that is too short" - }, - "password": "Lozinka", - "@password": {}, - "confirmPassword": "Potvrdi lozinku", - "@confirmPassword": {}, - "invalidEmail": "Upiši valjanu e-mail adresu", - "@invalidEmail": { - "description": "Error message when the user enters an invalid email" - }, - "email": "E-mail adresa", - "@email": {}, - "invalidUrl": "Upiši važeći URL", - "@invalidUrl": { - "description": "Error message when the user enters an invalid URL, e.g. in the login form" - }, - "useCustomServer": "Koristi prilagođeni poslužitelj", - "@useCustomServer": { - "description": "Toggle button allowing users to switch between the default and a custom wger server" - }, - "invalidUsername": "Upiši važeće korisničko ime", - "@invalidUsername": { - "description": "Error message when the user enters an invalid username" - }, - "customServerUrl": "URL wger instance", - "@customServerUrl": { - "description": "Label in the form where the users can enter their own wger instance" - }, - "customServerHint": "Upiši adresu tvog poslužitelja, inače će se koristiti zadani", - "@customServerHint": { - "description": "Hint text for the form where the users can enter their own wger instance" - }, - "registerInstead": "Nemaš račun? Registriraj se", - "@registerInstead": {}, - "loginInstead": "Već imaš račun? Prijavi se", - "@loginInstead": {}, - "labelBottomNavWorkout": "Trening", - "@labelBottomNavWorkout": { - "description": "Label used in bottom navigation, use a short word" - }, - "labelBottomNavNutrition": "Prehrana", - "@labelBottomNavNutrition": { - "description": "Label used in bottom navigation, use a short word" - }, - "labelWorkoutLogs": "Dnevnici treninga", - "@labelWorkoutLogs": { - "description": "(Workout) logs" - }, - "labelWorkoutPlan": "Plan treninga", - "@labelWorkoutPlan": { - "description": "Title for screen workout plan" - }, - "labelDashboard": "Kontrolna ploča", - "@labelDashboard": { - "description": "Title for screen dashboard" - }, - "successfullyDeleted": "Izbrisano", - "@successfullyDeleted": { - "description": "Message when an item was successfully deleted" - }, - "successfullySaved": "Spremljeno", - "@successfullySaved": { - "description": "Message when an item was successfully saved" - }, - "exercise": "Vježba", - "@exercise": { - "description": "An exercise for a workout" - }, - "logHelpEntriesUnits": "Napomena: prikazuju se samo unosi s jedinicom težine (kg ili lb) i ponavljanja, druge kombinacije kao što su vrijeme ili do neuspjeha se ovdje zanemaruju.", - "@logHelpEntriesUnits": {}, - "description": "Opis", - "@description": {}, - "name": "Ime", - "@name": { - "description": "Name for a workout or nutritional plan" - }, - "nutritionalDiary": "Dnevnik prehrane", - "@nutritionalDiary": {}, - "nutritionalPlans": "Planovi prehrane", - "@nutritionalPlans": {}, - "noNutritionalPlans": "Nemaš planove prehrane", - "@noNutritionalPlans": { - "description": "Message shown when the user has no nutritional plans" - }, - "anErrorOccurred": "Dogodila se greška!", - "@anErrorOccurred": {}, - "weight": "Težina", - "@weight": { - "description": "The weight of a workout log or body weight entry" - }, - "measurement": "Mjerenje", - "@measurement": {}, - "measurements": "Mjerenja", - "@measurements": { - "description": "Categories for the measurements such as biceps size, body fat, etc." - }, - "measurementCategoriesHelpText": "Kategorija mjerenja, kao što su „bicepsi” ili „tjelesna mast”", - "@measurementCategoriesHelpText": {}, - "measurementEntriesHelpText": "Jedinica koja se koristi za mjerenje kategorije kao što su „cm” ili „%”", - "@measurementEntriesHelpText": {}, - "date": "Datum", - "@date": { - "description": "The date of a workout log or body weight entry" - }, - "repetitions": "Ponavljanja", - "@repetitions": { - "description": "Repetitions for an exercise set" - }, - "reps": "Ponavljanja", - "@reps": { - "description": "Shorthand for repetitions, used when space constraints are tighter" - }, - "rir": "PUR", - "@rir": { - "description": "Shorthand for Repetitions In Reserve" - }, - "rirNotUsed": "PUR se ne koristi", - "@rirNotUsed": { - "description": "Label used in RiR slider when the RiR value is not used/saved for the current setting or log" - }, - "macronutrients": "Makronutrijenti", - "@macronutrients": {}, - "planned": "Planirano", - "@planned": { - "description": "Header for the column of 'planned' nutritional values, i.e. what should be eaten" - }, - "logged": "Zabilježeno", - "@logged": { - "description": "Header for the column of 'logged' nutritional values, i.e. what was eaten" - }, - "difference": "Razlika", - "@difference": {}, - "percentEnergy": "Postotak energije", - "@percentEnergy": {}, - "gPerBodyKg": "g po tjelesnom kg", - "@gPerBodyKg": { - "description": "Label used for total sums of e.g. calories or similar in grams per Kg of body weight" - }, - "total": "Ukupno", - "@total": { - "description": "Label used for total sums of e.g. calories or similar" - }, - "kJ": "kJ", - "@kJ": { - "description": "Energy in a meal in kilo joules, kJ" - }, - "g": "g", - "@g": { - "description": "Abbreviation for gram" - }, - "proteinShort": "P", - "@proteinShort": { - "description": "The first letter or short name of the word 'Protein', used in overviews" - }, - "carbohydrates": "Ugljikohidrati", - "@carbohydrates": {}, - "carbohydratesShort": "U", - "@carbohydratesShort": { - "description": "The first letter or short name of the word 'Carbohydrates', used in overviews" - }, - "sugars": "Šećeri", - "@sugars": {}, - "fat": "Masti", - "@fat": {}, - "fatShort": "M", - "@fatShort": { - "description": "The first letter or short name of the word 'Fat', used in overviews" - }, - "saturatedFat": "Zasićene masti", - "@saturatedFat": {}, - "fiber": "Vlakna", - "@fiber": {}, - "sodium": "Natrij", - "@sodium": {}, - "toggleDetails": "Prikaži detalje", - "@toggleDetails": { - "description": "Switch to toggle detail / overview" - }, - "enterValue": "Upiši vrijednost", - "@enterValue": { - "description": "Error message when the user hasn't entered a value on a required field" - }, - "selectExercise": "Odaberi vježbu", - "@selectExercise": { - "description": "Error message when the user hasn't selected an exercise in the form" - }, - "enterCharacters": "Upiši {min} do {max} znakova", - "@enterCharacters": { - "description": "Error message when the user hasn't entered the correct number of characters in a form", - "type": "text", - "placeholders": { - "min": { - "type": "String" - }, - "max": { - "type": "String" - } - } - }, - "nrOfSets": "Broj serija po vježbi: {nrOfSets}", - "@nrOfSets": { - "description": "Label shown on the slider where the user selects the nr of sets", - "type": "text", - "placeholders": { - "nrOfSets": { - "type": "String" - } - } - }, - "setUnitsAndRir": "Postavi jedinice i PUR", - "@setUnitsAndRir": { - "description": "Label shown on the slider where the user can toggle showing units and RiR", - "type": "text" - }, - "enterValidNumber": "Upiši važeći broj", - "@enterValidNumber": { - "description": "Error message when the user has submitted an invalid number (e.g. '3,.,.,.')" - }, - "selectIngredient": "Odaberi sastojak", - "@selectIngredient": { - "description": "Error message when the user hasn't selected an ingredient from the autocompleter" - }, - "selectImage": "Odaberi sliku", - "@selectImage": { - "description": "Label and error message when the user hasn't selected an image to save" - }, - "optionsLabel": "Opcije", - "@optionsLabel": { - "description": "Label for the popup with general app options" - }, - "takePicture": "Snimi sliku", - "@takePicture": {}, - "chooseFromLibrary": "Odaberi iz biblioteke slika", - "@chooseFromLibrary": {}, - "gallery": "Galerija", - "@gallery": {}, - "addImage": "Dodaj sliku", - "@addImage": {}, - "dataCopied": "Podaci kopirani u novi unos", - "@dataCopied": { - "description": "Snackbar message to show on copying data to a new log entry" - }, - "usernameValidChars": "Korisničko ime može sadržavati samo slova, brojeve i sljedeće znakove: @, +, ., -, _", - "@usernameValidChars": { - "description": "Error message when the user tries to register a username with forbidden characters" - }, - "logHelpEntries": "Ako u jednom danu postoji više od jednog unosa s istim brojem ponavljanja, ali različitim težinama, na dijagramu je prikazan samo unos s većom težinom.", - "@logHelpEntries": {}, - "addSet": "Dodaj seriju", - "@addSet": { - "description": "Label for the button that adds a set (to a workout day)" - }, - "addMeal": "Dodaj obrok", - "@addMeal": {}, - "nutritionalPlan": "Plan prehrane", - "@nutritionalPlan": {}, - "useDefaultServer": "Koristi zadani poslužitelj", - "@useDefaultServer": { - "description": "Toggle button allowing users to switch between the default and a custom wger server" - }, - "logout": "Odjavi se", - "@logout": { - "description": "Text for logout button" - }, - "login": "Prijavi se", - "@login": { - "description": "Text for login button" - }, - "register": "Registracija", - "@register": { - "description": "Text for registration button" - }, - "reset": "Resetiraj", - "@reset": { - "description": "Button text allowing the user to reset the entered values to the default" - }, - "jumpTo": "Prijeđi na", - "@jumpTo": { - "description": "Imperative. Label used in popup allowing the user to jump to a specific exercise while in the gym mode" - }, - "save": "Spremi", - "@save": {}, - "energyShort": "E", - "@energyShort": { - "description": "The first letter or short name of the word 'Energy', used in overviews" - }, - "addIngredient": "Dodaj sastojak", - "@addIngredient": {}, - "logMeal": "Zapiši obrok u dnevnik prehrane", - "@logMeal": {}, - "value": "Vrijednost", - "@value": { - "description": "The value of a measurement entry" - }, - "start": "Početak", - "@start": { - "description": "Label on button to start the gym mode (i.e., an imperative)" - }, - "timeStart": "Vrijeme početka", - "@timeStart": { - "description": "The starting time of a workout" - }, - "timeStartAhead": "Vrijeme početka ne može biti prije vremena završetka", - "@timeStartAhead": {}, - "ingredient": "Sastojak", - "@ingredient": {}, - "energy": "Energija", - "@energy": { - "description": "Energy in a meal, ingredient etc. e.g. in kJ" - }, - "protein": "Proteini", - "@protein": {}, - "goToToday": "Idi na danas", - "@goToToday": { - "description": "Label on button to jump back to 'today' in the calendar widget" - }, - "kcal": "kcal", - "@kcal": { - "description": "Energy in a meal in kilocalories, kcal" - }, - "unit": "Jedinica", - "@unit": { - "description": "The unit used for a repetition (kg, time, etc.)" - }, - "edit": "Uredi", - "@edit": {}, - "confirmDelete": "Stvarno želiš izbrisati „{toDelete}”?", - "@confirmDelete": { - "description": "Confirmation text before the user deletes an object", - "type": "text", - "placeholders": { - "toDelete": { - "type": "String" - } - } - }, - "newNutritionalPlan": "Novi plan prehrane", - "@newNutritionalPlan": {}, - "amount": "Količina", - "@amount": { - "description": "The amount (e.g. in grams) of an ingredient in a meal" - }, - "newEntry": "Novi unos", - "@newEntry": { - "description": "Title when adding a new entry such as a weight or log entry" - }, - "noWeightEntries": "Nemaš unose težine", - "@noWeightEntries": { - "description": "Message shown when the user has no logged weight entries" - }, - "loadingText": "Učitavanje …", - "@loadingText": { - "description": "Text to show when entries are being loaded in the background: Loading..." - }, - "delete": "Izbriši", - "@delete": {}, - "goToDetailPage": "Idi na stranicu s detaljima", - "@goToDetailPage": {}, - "aboutDescription": "Hvala što koristiš wger! wger je suradnički projekt otvorenog koda koji su izradili ljubitelji fitnesa iz cijelog svijeta.", - "@aboutDescription": { - "description": "Text in the about dialog" - }, - "calendar": "Kalendar", - "@calendar": {}, - "musclesSecondary": "Sekundarni mišići", - "@musclesSecondary": { - "description": "secondary muscles trained by an exercise" - }, - "equipment": "Oprema", - "@equipment": { - "description": "Equipment needed to perform an exercise" - }, - "category": "Kategorija", - "@category": { - "description": "Category for an exercise, ingredient, etc." - }, - "searchExercise": "Traži vježbe koje želiš dodati", - "@searchExercise": { - "description": "Label on set form. Selected exercises are added to the set" - }, - "muscles": "Mišići", - "@muscles": { - "description": "(main) muscles trained by an exercise" - }, - "dayDescriptionHelp": "Opis onoga što se radi na današnji dan (npr. „dan povlačenja”) ili koji su dijelovi tijela trenirani (npr. „prsa i ramena”)", - "@dayDescriptionHelp": {}, - "setNr": "Serija br. {nr}", - "@setNr": { - "description": "Header in form indicating the number of the current set. Can also be translated as something like 'Set Nr. xy'.", - "type": "text", - "placeholders": { - "nr": { - "type": "String" - } - } - }, - "sameRepetitions": "Ako radiš ista ponavljanja i težinu za sve serije, ispuni jedan redak. Na primjer, za 4 serije jednostavno upiši 10 za ponavljanja, to automatski postaje „4 × 10”.", - "@sameRepetitions": {}, - "comment": "Komentar", - "@comment": { - "description": "Comment, additional information" - }, - "impression": "Dojam", - "@impression": { - "description": "General impression (e.g. for a workout session) such as good, bad, etc." - }, - "notes": "Bilješke", - "@notes": { - "description": "Personal notes, e.g. for a workout session" - }, - "workoutSession": "Sesija treninga", - "@workoutSession": { - "description": "A (logged) workout session" - }, - "newDay": "Novi dan", - "@newDay": {}, - "newSet": "Nova serija", - "@newSet": { - "description": "Header when adding a new set to a workout day" - }, - "selectExercises": "Ako želiš izraditi nasdkup, traži i odaberi vježbe koje će se grupirati u jednu grupu", - "@selectExercises": {}, - "gymMode": "Modus teretane", - "@gymMode": { - "description": "Label when starting the gym mode" - }, - "plateCalculator": "Ploče", - "@plateCalculator": { - "description": "Label used for the plate calculator in the gym mode" - }, - "plateCalculatorNotDivisible": "Nije moguće postići težinu s dostupnim pločastim utezima", - "@plateCalculatorNotDivisible": { - "description": "Error message when the current weight is not reachable with plates (e.g. 33.1 kg)" - }, - "pause": "Pauza", - "@pause": { - "description": "Noun, not an imperative! Label used for the pause when using the gym mode" - }, - "weightUnit": "Jedinica težine", - "@weightUnit": {}, - "appUpdateTitle": "Potrebna je nova verzija", - "@appUpdateTitle": {}, - "appUpdateContent": "Ova verzija aplikacije nije kompatibilna s poslužiteljem. Aktualiziraj svoju aplikaciju.", - "@appUpdateContent": {}, - "set": "Serija", - "@set": { - "description": "A set in a workout plan" - }, - "repetitionUnit": "Jedinica ponavljanja", - "@repetitionUnit": {}, - "recentlyUsedIngredients": "Nedavno dodani sastojci", - "@recentlyUsedIngredients": { - "description": "A message when a user adds a new ingredient to a meal." - }, - "logIngredient": "Zapiši sastojak u dnevnik prehrane", - "@logIngredient": {}, - "searchIngredient": "Traži sastojak", - "@searchIngredient": { - "description": "Label on ingredient search form" - }, - "weekAverage": "Sedmodnevni prosjek", - "@weekAverage": { - "description": "Header for the column of '7 day average' nutritional values, i.e. what was logged last week" - }, - "productFound": "Pronađeni proizvod", - "@productFound": { - "description": "Header label for dialog when product is found with barcode" - }, - "productFoundDescription": "Barkod odgovara ovom proizvodu: {productName}. Želiš li nastaviti?", - "@productFoundDescription": { - "description": "Dialog info when product is found with barcode", - "type": "text", - "placeholders": { - "productName": { - "type": "String" - } - } - }, - "productNotFound": "Proizvod nije pronađen", - "@productNotFound": { - "description": "Header label for dialog when product is not found with barcode" - }, - "productNotFoundDescription": "Proizvod sa skeniranim barkodom {barcode} nije pronađen u wger bazi podataka", - "@productNotFoundDescription": { - "description": "Dialog info when product is not found with barcode", - "type": "text", - "placeholders": { - "barcode": { - "type": "String" - } - } - }, - "scanBarcode": "Skeniraj barkod", - "@scanBarcode": { - "description": "Label for scan barcode button" - }, - "close": "Zatvori", - "@close": { - "description": "Translation for close" - }, - "enterMinCharacters": "Upiši barem {min} znakova", - "@enterMinCharacters": { - "description": "Error message when the user hasn't entered the minimum amount characters in a form", - "type": "text", - "placeholders": { - "min": { - "type": "String" - } - } - }, - "add_exercise_image_license": "Slike moraju biti kompatibilne s licencom CC BY SA. Ako si u nedoumici, prenesi samo svoje vlastite fotografije.", - "@add_exercise_image_license": {}, - "whatVariationsExist": "Koje varijante ove vježbe postoje?", - "@whatVariationsExist": {}, - "images": "Slike", - "@images": {}, - "alternativeNames": "Alternativna imena", - "@alternativeNames": {}, - "previous": "Prethodna", - "@previous": {}, - "oneNamePerLine": "Jedno ime po retku", - "@oneNamePerLine": {}, - "translation": "Prijevod", - "@translation": {}, - "addExercise": "Dodaj vježbu", - "@addExercise": {}, - "translateExercise": "Prevedi ovu vježbu", - "@translateExercise": {}, - "baseData": "Osnovni podaci na engleskom jeziku", - "@baseData": { - "description": "The base data for an exercise such as category, trained muscles, etc." - }, - "arms": "Ruke", - "@arms": { - "description": "Generated entry for translation for server strings" - }, - "back": "Leđa", - "@back": { - "description": "Generated entry for translation for server strings" - }, - "chest": "Prsa", - "@chest": { - "description": "Generated entry for translation for server strings" - }, - "sz_bar": "Zaobljena šipka", - "@sz_bar": { - "description": "Generated entry for translation for server strings" - }, - "userProfile": "Tvoj profil", - "@userProfile": {}, - "exerciseList": "Popis vježbi", - "@exerciseList": {}, - "exercises": "Vježbe", - "@exercises": { - "description": "Multiple exercises for a workout" - }, - "exerciseName": "Ime vježbe", - "@exerciseName": { - "description": "Label for the name of a workout exercise" - }, - "selectEntry": "Odaberi unos", - "@selectEntry": {}, - "success": "Uspjeh", - "@success": { - "description": "Message when an action completed successfully, usually used as a heading" - }, - "noMeasurementEntries": "Nemaš unose mjerenja", - "@noMeasurementEntries": {}, - "moreMeasurementEntries": "Dodaj novo mjerenje", - "@moreMeasurementEntries": { - "description": "Message shown when the user wants to add new measurement" - }, - "variations": "Varijante", - "@variations": { - "description": "Variations of one exercise (e.g. benchpress and benchpress narrow)" - }, - "alsoKnownAs": "Poznato i kao: {aliases}", - "@alsoKnownAs": { - "placeholders": { - "aliases": { - "type": "String" - } + "todaysWorkout": "Tvoj današnji trening", + "@todaysWorkout": {}, + "mealLogged": "Obrok prijavljen u dnevnik", + "@mealLogged": {}, + "time": "Vrijeme", + "@time": { + "description": "The time of a meal or workout" }, - "description": "List of alternative names for an exercise" - }, - "verifiedEmail": "Potvrđena e-mail adresa", - "@verifiedEmail": {}, - "unVerifiedEmail": "Nepotvrđena e-mail adresa", - "@unVerifiedEmail": {}, - "verifiedEmailInfo": "E-mail poruka za potvrdu je poslana na {email}", - "@verifiedEmailInfo": { - "placeholders": { - "email": { - "type": "String" - } + "timeEnd": "Vrijeme završetka", + "@timeEnd": { + "description": "The end time of a workout" + }, + "username": "Korisničko ime", + "@username": {}, + "passwordsDontMatch": "Lozinke se ne podudaraju", + "@passwordsDontMatch": { + "description": "Error message when the user enters two different passwords during registration" + }, + "passwordTooShort": "Lozinka je prekratka", + "@passwordTooShort": { + "description": "Error message when the user a password that is too short" + }, + "password": "Lozinka", + "@password": {}, + "confirmPassword": "Potvrdi lozinku", + "@confirmPassword": {}, + "invalidEmail": "Upiši valjanu e-mail adresu", + "@invalidEmail": { + "description": "Error message when the user enters an invalid email" + }, + "email": "E-mail adresa", + "@email": {}, + "invalidUrl": "Upiši važeći URL", + "@invalidUrl": { + "description": "Error message when the user enters an invalid URL, e.g. in the login form" + }, + "useCustomServer": "Koristi prilagođeni poslužitelj", + "@useCustomServer": { + "description": "Toggle button allowing users to switch between the default and a custom wger server" + }, + "invalidUsername": "Upiši važeće korisničko ime", + "@invalidUsername": { + "description": "Error message when the user enters an invalid username" + }, + "customServerUrl": "URL wger instance", + "@customServerUrl": { + "description": "Label in the form where the users can enter their own wger instance" + }, + "customServerHint": "Upiši adresu tvog poslužitelja, inače će se koristiti zadani", + "@customServerHint": { + "description": "Hint text for the form where the users can enter their own wger instance" + }, + "registerInstead": "Nemaš račun? Registriraj se", + "@registerInstead": {}, + "loginInstead": "Već imaš račun? Prijavi se", + "@loginInstead": {}, + "labelBottomNavWorkout": "Trening", + "@labelBottomNavWorkout": { + "description": "Label used in bottom navigation, use a short word" + }, + "labelBottomNavNutrition": "Prehrana", + "@labelBottomNavNutrition": { + "description": "Label used in bottom navigation, use a short word" + }, + "labelWorkoutLogs": "Dnevnici treninga", + "@labelWorkoutLogs": { + "description": "(Workout) logs" + }, + "labelWorkoutPlan": "Plan treninga", + "@labelWorkoutPlan": { + "description": "Title for screen workout plan" + }, + "labelDashboard": "Kontrolna ploča", + "@labelDashboard": { + "description": "Title for screen dashboard" + }, + "successfullyDeleted": "Izbrisano", + "@successfullyDeleted": { + "description": "Message when an item was successfully deleted" + }, + "successfullySaved": "Spremljeno", + "@successfullySaved": { + "description": "Message when an item was successfully saved" + }, + "exercise": "Vježba", + "@exercise": { + "description": "An exercise for a workout" + }, + "logHelpEntriesUnits": "Napomena: prikazuju se samo unosi s jedinicom težine (kg ili lb) i ponavljanja, druge kombinacije kao što su vrijeme ili do neuspjeha se ovdje zanemaruju.", + "@logHelpEntriesUnits": {}, + "description": "Opis", + "@description": {}, + "name": "Ime", + "@name": { + "description": "Name for a workout or nutritional plan" + }, + "nutritionalDiary": "Dnevnik prehrane", + "@nutritionalDiary": {}, + "nutritionalPlans": "Planovi prehrane", + "@nutritionalPlans": {}, + "noNutritionalPlans": "Nemaš planove prehrane", + "@noNutritionalPlans": { + "description": "Message shown when the user has no nutritional plans" + }, + "anErrorOccurred": "Dogodila se greška!", + "@anErrorOccurred": {}, + "weight": "Težina", + "@weight": { + "description": "The weight of a workout log or body weight entry" + }, + "measurement": "Mjerenje", + "@measurement": {}, + "measurements": "Mjerenja", + "@measurements": { + "description": "Categories for the measurements such as biceps size, body fat, etc." + }, + "measurementCategoriesHelpText": "Kategorija mjerenja, kao što su „bicepsi” ili „tjelesna mast”", + "@measurementCategoriesHelpText": {}, + "measurementEntriesHelpText": "Jedinica koja se koristi za mjerenje kategorije kao što su „cm” ili „%”", + "@measurementEntriesHelpText": {}, + "date": "Datum", + "@date": { + "description": "The date of a workout log or body weight entry" + }, + "repetitions": "Ponavljanja", + "@repetitions": { + "description": "Repetitions for an exercise set" + }, + "reps": "Ponavljanja", + "@reps": { + "description": "Shorthand for repetitions, used when space constraints are tighter" + }, + "rir": "PUR", + "@rir": { + "description": "Shorthand for Repetitions In Reserve" + }, + "rirNotUsed": "PUR se ne koristi", + "@rirNotUsed": { + "description": "Label used in RiR slider when the RiR value is not used/saved for the current setting or log" + }, + "macronutrients": "Makronutrijenti", + "@macronutrients": {}, + "planned": "Planirano", + "@planned": { + "description": "Header for the column of 'planned' nutritional values, i.e. what should be eaten" + }, + "logged": "Zabilježeno", + "@logged": { + "description": "Header for the column of 'logged' nutritional values, i.e. what was eaten" + }, + "difference": "Razlika", + "@difference": {}, + "percentEnergy": "Postotak energije", + "@percentEnergy": {}, + "gPerBodyKg": "g po tjelesnom kg", + "@gPerBodyKg": { + "description": "Label used for total sums of e.g. calories or similar in grams per Kg of body weight" + }, + "total": "Ukupno", + "@total": { + "description": "Label used for total sums of e.g. calories or similar" + }, + "kJ": "kJ", + "@kJ": { + "description": "Energy in a meal in kilo joules, kJ" + }, + "g": "g", + "@g": { + "description": "Abbreviation for gram" + }, + "proteinShort": "P", + "@proteinShort": { + "description": "The first letter or short name of the word 'Protein', used in overviews" + }, + "carbohydrates": "Ugljikohidrati", + "@carbohydrates": {}, + "carbohydratesShort": "U", + "@carbohydratesShort": { + "description": "The first letter or short name of the word 'Carbohydrates', used in overviews" + }, + "sugars": "Šećeri", + "@sugars": {}, + "fat": "Masti", + "@fat": {}, + "fatShort": "M", + "@fatShort": { + "description": "The first letter or short name of the word 'Fat', used in overviews" + }, + "saturatedFat": "Zasićene masti", + "@saturatedFat": {}, + "fiber": "Vlakna", + "@fiber": {}, + "sodium": "Natrij", + "@sodium": {}, + "toggleDetails": "Prikaži detalje", + "@toggleDetails": { + "description": "Switch to toggle detail / overview" + }, + "enterValue": "Upiši vrijednost", + "@enterValue": { + "description": "Error message when the user hasn't entered a value on a required field" + }, + "selectExercise": "Odaberi vježbu", + "@selectExercise": { + "description": "Error message when the user hasn't selected an exercise in the form" + }, + "enterCharacters": "Upiši {min} do {max} znakova", + "@enterCharacters": { + "description": "Error message when the user hasn't entered the correct number of characters in a form", + "type": "text", + "placeholders": { + "min": { + "type": "String" + }, + "max": { + "type": "String" + } + } + }, + "nrOfSets": "Broj serija po vježbi: {nrOfSets}", + "@nrOfSets": { + "description": "Label shown on the slider where the user selects the nr of sets", + "type": "text", + "placeholders": { + "nrOfSets": { + "type": "String" + } + } + }, + "setUnitsAndRir": "Postavi jedinice i PUR", + "@setUnitsAndRir": { + "description": "Label shown on the slider where the user can toggle showing units and RiR", + "type": "text" + }, + "enterValidNumber": "Upiši važeći broj", + "@enterValidNumber": { + "description": "Error message when the user has submitted an invalid number (e.g. '3,.,.,.')" + }, + "selectIngredient": "Odaberi sastojak", + "@selectIngredient": { + "description": "Error message when the user hasn't selected an ingredient from the autocompleter" + }, + "selectImage": "Odaberi sliku", + "@selectImage": { + "description": "Label and error message when the user hasn't selected an image to save" + }, + "optionsLabel": "Opcije", + "@optionsLabel": { + "description": "Label for the popup with general app options" + }, + "takePicture": "Snimi sliku", + "@takePicture": {}, + "chooseFromLibrary": "Odaberi iz biblioteke slika", + "@chooseFromLibrary": {}, + "gallery": "Galerija", + "@gallery": {}, + "addImage": "Dodaj sliku", + "@addImage": {}, + "dataCopied": "Podaci kopirani u novi unos", + "@dataCopied": { + "description": "Snackbar message to show on copying data to a new log entry" + }, + "usernameValidChars": "Korisničko ime može sadržavati samo slova, brojeve i sljedeće znakove: @, +, ., -, _", + "@usernameValidChars": { + "description": "Error message when the user tries to register a username with forbidden characters" + }, + "logHelpEntries": "Ako u jednom danu postoji više od jednog unosa s istim brojem ponavljanja, ali različitim težinama, na dijagramu je prikazan samo unos s većom težinom.", + "@logHelpEntries": {}, + "addSet": "Dodaj seriju", + "@addSet": { + "description": "Label for the button that adds a set (to a workout day)" + }, + "addMeal": "Dodaj obrok", + "@addMeal": {}, + "nutritionalPlan": "Plan prehrane", + "@nutritionalPlan": {}, + "useDefaultServer": "Koristi zadani poslužitelj", + "@useDefaultServer": { + "description": "Toggle button allowing users to switch between the default and a custom wger server" + }, + "logout": "Odjavi se", + "@logout": { + "description": "Text for logout button" + }, + "login": "Prijavi se", + "@login": { + "description": "Text for login button" + }, + "register": "Registracija", + "@register": { + "description": "Text for registration button" + }, + "reset": "Resetiraj", + "@reset": { + "description": "Button text allowing the user to reset the entered values to the default" + }, + "jumpTo": "Prijeđi na", + "@jumpTo": { + "description": "Imperative. Label used in popup allowing the user to jump to a specific exercise while in the gym mode" + }, + "save": "Spremi", + "@save": {}, + "energyShort": "E", + "@energyShort": { + "description": "The first letter or short name of the word 'Energy', used in overviews" + }, + "addIngredient": "Dodaj sastojak", + "@addIngredient": {}, + "logMeal": "Zapiši obrok u dnevnik prehrane", + "@logMeal": {}, + "value": "Vrijednost", + "@value": { + "description": "The value of a measurement entry" + }, + "start": "Početak", + "@start": { + "description": "Label on button to start the gym mode (i.e., an imperative)" + }, + "timeStart": "Vrijeme početka", + "@timeStart": { + "description": "The starting time of a workout" + }, + "timeStartAhead": "Vrijeme početka ne može biti prije vremena završetka", + "@timeStartAhead": {}, + "ingredient": "Sastojak", + "@ingredient": {}, + "energy": "Energija", + "@energy": { + "description": "Energy in a meal, ingredient etc. e.g. in kJ" + }, + "protein": "Proteini", + "@protein": {}, + "goToToday": "Idi na danas", + "@goToToday": { + "description": "Label on button to jump back to 'today' in the calendar widget" + }, + "kcal": "kcal", + "@kcal": { + "description": "Energy in a meal in kilocalories, kcal" + }, + "unit": "Jedinica", + "@unit": { + "description": "The unit used for a repetition (kg, time, etc.)" + }, + "edit": "Uredi", + "@edit": {}, + "confirmDelete": "Stvarno želiš izbrisati „{toDelete}”?", + "@confirmDelete": { + "description": "Confirmation text before the user deletes an object", + "type": "text", + "placeholders": { + "toDelete": { + "type": "String" + } + } + }, + "newNutritionalPlan": "Novi plan prehrane", + "@newNutritionalPlan": {}, + "amount": "Količina", + "@amount": { + "description": "The amount (e.g. in grams) of an ingredient in a meal" + }, + "newEntry": "Novi unos", + "@newEntry": { + "description": "Title when adding a new entry such as a weight or log entry" + }, + "noWeightEntries": "Nemaš unose težine", + "@noWeightEntries": { + "description": "Message shown when the user has no logged weight entries" + }, + "loadingText": "Učitavanje …", + "@loadingText": { + "description": "Text to show when entries are being loaded in the background: Loading..." + }, + "delete": "Izbriši", + "@delete": {}, + "goToDetailPage": "Idi na stranicu s detaljima", + "@goToDetailPage": {}, + "aboutDescription": "Hvala što koristiš wger! wger je suradnički projekt otvorenog koda koji su izradili ljubitelji fitnesa iz cijelog svijeta.", + "@aboutDescription": { + "description": "Text in the about dialog" + }, + "calendar": "Kalendar", + "@calendar": {}, + "musclesSecondary": "Sekundarni mišići", + "@musclesSecondary": { + "description": "secondary muscles trained by an exercise" + }, + "equipment": "Oprema", + "@equipment": { + "description": "Equipment needed to perform an exercise" + }, + "category": "Kategorija", + "@category": { + "description": "Category for an exercise, ingredient, etc." + }, + "searchExercise": "Traži vježbe koje želiš dodati", + "@searchExercise": { + "description": "Label on set form. Selected exercises are added to the set" + }, + "muscles": "Mišići", + "@muscles": { + "description": "(main) muscles trained by an exercise" + }, + "dayDescriptionHelp": "Opis onoga što se radi na današnji dan (npr. „dan povlačenja”) ili koji su dijelovi tijela trenirani (npr. „prsa i ramena”)", + "@dayDescriptionHelp": {}, + "setNr": "Serija br. {nr}", + "@setNr": { + "description": "Header in form indicating the number of the current set. Can also be translated as something like 'Set Nr. xy'.", + "type": "text", + "placeholders": { + "nr": { + "type": "String" + } + } + }, + "sameRepetitions": "Ako radiš ista ponavljanja i težinu za sve serije, ispuni jedan redak. Na primjer, za 4 serije jednostavno upiši 10 za ponavljanja, to automatski postaje „4 × 10”.", + "@sameRepetitions": {}, + "comment": "Komentar", + "@comment": { + "description": "Comment, additional information" + }, + "impression": "Dojam", + "@impression": { + "description": "General impression (e.g. for a workout session) such as good, bad, etc." + }, + "notes": "Bilješke", + "@notes": { + "description": "Personal notes, e.g. for a workout session" + }, + "workoutSession": "Sesija treninga", + "@workoutSession": { + "description": "A (logged) workout session" + }, + "newDay": "Novi dan", + "@newDay": {}, + "newSet": "Nova serija", + "@newSet": { + "description": "Header when adding a new set to a workout day" + }, + "selectExercises": "Ako želiš izraditi nasdkup, traži i odaberi vježbe koje će se grupirati u jednu grupu", + "@selectExercises": {}, + "gymMode": "Modus teretane", + "@gymMode": { + "description": "Label when starting the gym mode" + }, + "plateCalculator": "Ploče", + "@plateCalculator": { + "description": "Label used for the plate calculator in the gym mode" + }, + "plateCalculatorNotDivisible": "Nije moguće postići težinu s dostupnim pločastim utezima", + "@plateCalculatorNotDivisible": { + "description": "Error message when the current weight is not reachable with plates (e.g. 33.1 kg)" + }, + "pause": "Pauza", + "@pause": { + "description": "Noun, not an imperative! Label used for the pause when using the gym mode" + }, + "weightUnit": "Jedinica težine", + "@weightUnit": {}, + "appUpdateTitle": "Potrebna je nova verzija", + "@appUpdateTitle": {}, + "appUpdateContent": "Ova verzija aplikacije nije kompatibilna s poslužiteljem. Aktualiziraj svoju aplikaciju.", + "@appUpdateContent": {}, + "set": "Serija", + "@set": { + "description": "A set in a workout plan" + }, + "repetitionUnit": "Jedinica ponavljanja", + "@repetitionUnit": {}, + "recentlyUsedIngredients": "Nedavno dodani sastojci", + "@recentlyUsedIngredients": { + "description": "A message when a user adds a new ingredient to a meal." + }, + "logIngredient": "Zapiši sastojak u dnevnik prehrane", + "@logIngredient": {}, + "searchIngredient": "Traži sastojak", + "@searchIngredient": { + "description": "Label on ingredient search form" + }, + "weekAverage": "Sedmodnevni prosjek", + "@weekAverage": { + "description": "Header for the column of '7 day average' nutritional values, i.e. what was logged last week" + }, + "productFound": "Pronađeni proizvod", + "@productFound": { + "description": "Header label for dialog when product is found with barcode" + }, + "productFoundDescription": "Barkod odgovara ovom proizvodu: {productName}. Želiš li nastaviti?", + "@productFoundDescription": { + "description": "Dialog info when product is found with barcode", + "type": "text", + "placeholders": { + "productName": { + "type": "String" + } + } + }, + "productNotFound": "Proizvod nije pronađen", + "@productNotFound": { + "description": "Header label for dialog when product is not found with barcode" + }, + "productNotFoundDescription": "Proizvod sa skeniranim barkodom {barcode} nije pronađen u wger bazi podataka", + "@productNotFoundDescription": { + "description": "Dialog info when product is not found with barcode", + "type": "text", + "placeholders": { + "barcode": { + "type": "String" + } + } + }, + "scanBarcode": "Skeniraj barkod", + "@scanBarcode": { + "description": "Label for scan barcode button" + }, + "close": "Zatvori", + "@close": { + "description": "Translation for close" + }, + "enterMinCharacters": "Upiši barem {min} znakova", + "@enterMinCharacters": { + "description": "Error message when the user hasn't entered the minimum amount characters in a form", + "type": "text", + "placeholders": { + "min": { + "type": "String" + } + } + }, + "add_exercise_image_license": "Slike moraju biti kompatibilne s licencom CC BY SA. Ako si u nedoumici, prenesi samo svoje vlastite fotografije.", + "@add_exercise_image_license": {}, + "whatVariationsExist": "Koje varijante ove vježbe postoje?", + "@whatVariationsExist": {}, + "images": "Slike", + "@images": {}, + "alternativeNames": "Alternativna imena", + "@alternativeNames": {}, + "previous": "Prethodna", + "@previous": {}, + "oneNamePerLine": "Jedno ime po retku", + "@oneNamePerLine": {}, + "translation": "Prijevod", + "@translation": {}, + "addExercise": "Dodaj vježbu", + "@addExercise": {}, + "translateExercise": "Prevedi ovu vježbu", + "@translateExercise": {}, + "baseData": "Osnovni podaci na engleskom jeziku", + "@baseData": { + "description": "The base data for an exercise such as category, trained muscles, etc." + }, + "arms": "Ruke", + "@arms": { + "description": "Generated entry for translation for server strings" + }, + "back": "Leđa", + "@back": { + "description": "Generated entry for translation for server strings" + }, + "chest": "Prsa", + "@chest": { + "description": "Generated entry for translation for server strings" + }, + "sz_bar": "Zaobljena šipka", + "@sz_bar": { + "description": "Generated entry for translation for server strings" + }, + "userProfile": "Tvoj profil", + "@userProfile": {}, + "exerciseList": "Popis vježbi", + "@exerciseList": {}, + "exercises": "Vježbe", + "@exercises": { + "description": "Multiple exercises for a workout" + }, + "exerciseName": "Ime vježbe", + "@exerciseName": { + "description": "Label for the name of a workout exercise" + }, + "selectEntry": "Odaberi unos", + "@selectEntry": {}, + "success": "Uspjeh", + "@success": { + "description": "Message when an action completed successfully, usually used as a heading" + }, + "noMeasurementEntries": "Nemaš unose mjerenja", + "@noMeasurementEntries": {}, + "moreMeasurementEntries": "Dodaj novo mjerenje", + "@moreMeasurementEntries": { + "description": "Message shown when the user wants to add new measurement" + }, + "variations": "Varijante", + "@variations": { + "description": "Variations of one exercise (e.g. benchpress and benchpress narrow)" + }, + "alsoKnownAs": "Poznato i kao: {aliases}", + "@alsoKnownAs": { + "placeholders": { + "aliases": { + "type": "String" + } + }, + "description": "List of alternative names for an exercise" + }, + "verifiedEmail": "Potvrđena e-mail adresa", + "@verifiedEmail": {}, + "unVerifiedEmail": "Nepotvrđena e-mail adresa", + "@unVerifiedEmail": {}, + "verifiedEmailInfo": "E-mail poruka za potvrdu je poslana na {email}", + "@verifiedEmailInfo": { + "placeholders": { + "email": { + "type": "String" + } + } + }, + "contributeExerciseWarning": "Vježbe možeš dodati samo ako je tvoj račun stariji od {days} dana i ako si potvrdio/la tvoju e-mail adresu", + "@contributeExerciseWarning": { + "description": "Number of days before which a person can add exercise", + "placeholders": { + "days": { + "type": "String", + "example": "14" + } + } + }, + "cacheWarning": "Zbog predmemoriranja, vidljivost promjena u aplikaciji može nešto potrajati.", + "@cacheWarning": {}, + "verifiedEmailReason": "Za dodavanje vježbi moraš potvrditi tvoju e-mail adresu", + "@verifiedEmailReason": {}, + "cardio": "Kardio", + "@cardio": { + "description": "Generated entry for translation for server strings" + }, + "quads": "Ekstenzije nogu", + "@quads": { + "description": "Generated entry for translation for server strings" + }, + "pull_up_bar": "Šipka za povlačenje", + "@pull_up_bar": { + "description": "Generated entry for translation for server strings" + }, + "shoulders": "Ramena", + "@shoulders": { + "description": "Generated entry for translation for server strings" + }, + "triceps": "Triceps", + "@triceps": { + "description": "Generated entry for translation for server strings" + }, + "swiss_ball": "Gimnastička lopta", + "@swiss_ball": { + "description": "Generated entry for translation for server strings" + }, + "until_failure": "Do neuspjeha", + "@until_failure": { + "description": "Generated entry for translation for server strings" + }, + "none__bodyweight_exercise_": "ništa (vježba za tjelesnu težinu)", + "@none__bodyweight_exercise_": { + "description": "Generated entry for translation for server strings" + }, + "seconds": "Sekunde", + "@seconds": { + "description": "Generated entry for translation for server strings" + }, + "textPromptTitle": "Spreman?", + "@textPromptTitle": {}, + "barbell": "Šipka", + "@barbell": { + "description": "Generated entry for translation for server strings" + }, + "calves": "Lisni mišići", + "@calves": { + "description": "Generated entry for translation for server strings" + }, + "textPromptSubheading": "Počni pritiskom gumba radnje", + "@textPromptSubheading": {}, + "body_weight": "Tjelesna težina", + "@body_weight": { + "description": "Generated entry for translation for server strings" + }, + "kilometers": "Kilometri", + "@kilometers": { + "description": "Generated entry for translation for server strings" + }, + "kilometers_per_hour": "Kilometara na sat", + "@kilometers_per_hour": { + "description": "Generated entry for translation for server strings" + }, + "lats": "Leđni mišići", + "@lats": { + "description": "Generated entry for translation for server strings" + }, + "miles_per_hour": "Milja na sat", + "@miles_per_hour": { + "description": "Generated entry for translation for server strings" + }, + "minutes": "Minute", + "@minutes": { + "description": "Generated entry for translation for server strings" + }, + "plates": "Ploče", + "@plates": { + "description": "Generated entry for translation for server strings" + }, + "kg": "kg", + "@kg": { + "description": "Generated entry for translation for server strings" + }, + "lb": "funta", + "@lb": { + "description": "Generated entry for translation for server strings" + }, + "searchNamesInEnglish": "Također traži imena na engleskom jeziku", + "@searchNamesInEnglish": {}, + "language": "Jezik", + "@language": {}, + "aboutPageTitle": "Wger informacije", + "@aboutPageTitle": {}, + "abs": "Trbuh", + "@abs": { + "description": "Generated entry for translation for server strings" + }, + "gym_mat": "Podloga za treniranje", + "@gym_mat": { + "description": "Generated entry for translation for server strings" + }, + "incline_bench": "Nagnuta klupa", + "@incline_bench": { + "description": "Generated entry for translation for server strings" + }, + "baseNameEnglish": "Sve vježbe trebaju osnovno ime na engleskom jeziku", + "@baseNameEnglish": {}, + "next": "Sljedeća", + "@next": {}, + "contributeExercise": "Doprinesi vježbu", + "@contributeExercise": {}, + "bench": "Klupa", + "@bench": { + "description": "Generated entry for translation for server strings" + }, + "dumbbell": "Ručni uteg", + "@dumbbell": { + "description": "Generated entry for translation for server strings" + }, + "biceps": "Bicepsi", + "@biceps": { + "description": "Generated entry for translation for server strings" + }, + "glutes": "Stražnjica", + "@glutes": { + "description": "Generated entry for translation for server strings" + }, + "hamstrings": "Tetive koljena", + "@hamstrings": { + "description": "Generated entry for translation for server strings" + }, + "kettlebell": "Kuglasti uteg", + "@kettlebell": { + "description": "Generated entry for translation for server strings" + }, + "legs": "Noge", + "@legs": { + "description": "Generated entry for translation for server strings" + }, + "miles": "Milje", + "@miles": { + "description": "Generated entry for translation for server strings" + }, + "max_reps": "Maks. broj ponavljanja", + "@max_reps": { + "description": "Generated entry for translation for server strings" + }, + "verify": "Potvrdi", + "@verify": {}, + "lower_back": "Donji dio leđa", + "@lower_back": { + "description": "Generated entry for translation for server strings" + }, + "aboutMastodonTitle": "Mastodon", + "@aboutMastodonTitle": {}, + "noMatchingExerciseFound": "Nisu pronađene odgovarajuće vježbe", + "@noMatchingExerciseFound": { + "description": "Message returned if no exercises match the searched string" + }, + "aboutDonateTitle": "Doniraj", + "@aboutDonateTitle": {}, + "aboutDonateText": "Pomogni projektu: kupi nam kavu, plati troškove poslužitelja i potiči nas u našem radu", + "@aboutDonateText": {}, + "settingsTitle": "Postavke", + "@settingsTitle": {}, + "settingsCacheTitle": "Predmemorija", + "@settingsCacheTitle": {}, + "settingsExerciseCacheDescription": "Izvrši predmemoriju", + "@settingsExerciseCacheDescription": {}, + "settingsCacheDeletedSnackbar": "Predmemorija je uspješno izbrisana", + "@settingsCacheDeletedSnackbar": {}, + "useMetric": "Koristi metričke jedinice za tjelesnu težinu", + "@useMetric": {}, + "log": "Zapiši", + "@log": { + "description": "Log a specific meal (imperative form)" + }, + "done": "Obavljeno", + "@done": {}, + "onlyLogging": "Prati samo kalorije", + "@onlyLogging": {}, + "onlyLoggingHelpText": "Označi okvir ako želiš bilježiti samo svoje kalorije i ne želiš postaviti detaljan plan prehrane s određenim obrocima", + "@onlyLoggingHelpText": {}, + "percentValue": "{value} %", + "@percentValue": { + "description": "A value in percent, e.g. 10 %", + "type": "text", + "placeholders": { + "value": { + "type": "String" + } + } + }, + "goalEnergy": "Cilj za energiju", + "@goalEnergy": {}, + "goalProtein": "Cilj za proteine", + "@goalProtein": {}, + "goalCarbohydrates": "Cilj za ugljikohidrate", + "@goalCarbohydrates": {}, + "goalFat": "Cilj za mast", + "@goalFat": {}, + "today": "Danas", + "@today": {}, + "loggedToday": "Zapisano danas", + "@loggedToday": {}, + "kcalValue": "{value} kcal", + "@kcalValue": { + "description": "A value in kcal, e.g. 500 kcal", + "type": "text", + "placeholders": { + "value": { + "type": "String" + } + } + }, + "gValue": "{value} g", + "@gValue": { + "description": "A value in grams, e.g. 5 g", + "type": "text", + "placeholders": { + "value": { + "type": "String" + } + } + }, + "surplus": "višak", + "@surplus": { + "description": "Caloric surplus (either planned or unplanned)" + }, + "deficit": "manjak", + "@deficit": { + "description": "Caloric deficit (either planned or unplanned)" + }, + "goalFiber": "Cilj za vlakna", + "@goalFiber": {}, + "goalMacro": "Ciljevi za makronutrijente", + "@goalMacro": { + "description": "The goal for macronutrients" + }, + "selectMealToLog": "Odaberi obrok za zapis u dnevnik", + "@selectMealToLog": {}, + "ingredientLogged": "Sastojak je upisan u dnevnik", + "@ingredientLogged": {}, + "noIngredientsDefined": "Još nije određen nijedan sastojak", + "@noIngredientsDefined": {}, + "overallChangeWeight": "Sveukupna promjena", + "@overallChangeWeight": { + "description": "Overall change in weight, added for localization" + }, + "goalTypeMeals": "Od obroka", + "@goalTypeMeals": { + "description": "added for localization of Class GoalType's filed meals" + }, + "goalTypeBasic": "Osnovni", + "@goalTypeBasic": { + "description": "added for localization of Class GoalType's filed basic" + }, + "goalTypeAdvanced": "Napredni", + "@goalTypeAdvanced": { + "description": "added for localization of Class GoalType's filed advanced" + }, + "indicatorRaw": "sirovo", + "@indicatorRaw": { + "description": "added for localization of Class Indicator's field text" + }, + "indicatorAvg": "prosjek", + "@indicatorAvg": { + "description": "added for localization of Class Indicator's field text" + }, + "themeMode": "Modus teme", + "@themeMode": {}, + "darkMode": "Uvijek tamni modus", + "@darkMode": {}, + "lightMode": "Uvijek svijetli modus", + "@lightMode": {}, + "systemMode": "Postavke sustava", + "@systemMode": {}, + "chartAllTimeTitle": "{name} – svo vrijeme", + "@chartAllTimeTitle": { + "description": "All-time chart of 'name' (e.g. 'weight', 'body fat' etc.)", + "type": "text", + "placeholders": { + "name": { + "type": "String" + } + } + }, + "chartDuringPlanTitle": "{chartName} tijekom prehrambenog plana {planName}", + "@chartDuringPlanTitle": { + "description": "chart of 'chartName' (e.g. 'weight', 'body fat' etc.) logged during plan", + "type": "text", + "placeholders": { + "chartName": { + "type": "String" + }, + "planName": { + "type": "String" + } + } + }, + "settingsIngredientCacheDescription": "Predmemorija sastojaka", + "@settingsIngredientCacheDescription": {}, + "chart30DaysTitle": "{name} – zadnjih 30 dana", + "@chart30DaysTitle": { + "description": "last 30 days chart of 'name' (e.g. 'weight', 'body fat' etc.)", + "type": "text", + "placeholders": { + "name": { + "type": "String" + } + } + }, + "barWeight": "Težina šipke", + "@barWeight": {}, + "useColors": "Koristi boje", + "@useColors": {}, + "selectAvailablePlates": "Odaberi prosjećne ploće", + "@selectAvailablePlates": {}, + "useApiToken": "Koristi API Token", + "@useApiToken": {}, + "useUsernameAndPassword": "Koristi vjerodajenice (Korisničko ime i lozinku)", + "@useUsernameAndPassword": {}, + "apiToken": "API Token", + "@apiToken": {}, + "invalidApiToken": "Molimo provjerite API Token", + "@invalidApiToken": { + "description": "Error message when the user enters an invalid API key" + }, + "apiTokenValidChars": "API Token može sadržavati a-f, brojeve od 0-9 i mora biti točno 40 znakova dugačak.", + "@apiTokenValidChars": { + "description": "Error message when the user tries to input a API key with forbidden characters" + }, + "routines": "Rutina", + "@routines": {}, + "newRoutine": "Nova rutina", + "@newRoutine": {}, + "noRoutines": "Vi nemate rutine", + "@noRoutines": {}, + "restTime": "Period odmora", + "@restTime": {}, + "sets": "Vježba ima setova", + "@sets": { + "description": "The number of sets to be done for one exercise" } - }, - "contributeExerciseWarning": "Vježbe možeš dodati samo ako je tvoj račun stariji od {days} dana i ako si potvrdio/la tvoju e-mail adresu", - "@contributeExerciseWarning": { - "description": "Number of days before which a person can add exercise", - "placeholders": { - "days": { - "type": "String", - "example": "14" - } - } - }, - "cacheWarning": "Zbog predmemoriranja, vidljivost promjena u aplikaciji može nešto potrajati.", - "@cacheWarning": {}, - "verifiedEmailReason": "Za dodavanje vježbi moraš potvrditi tvoju e-mail adresu", - "@verifiedEmailReason": {}, - "cardio": "Kardio", - "@cardio": { - "description": "Generated entry for translation for server strings" - }, - "quads": "Ekstenzije nogu", - "@quads": { - "description": "Generated entry for translation for server strings" - }, - "pull_up_bar": "Šipka za povlačenje", - "@pull_up_bar": { - "description": "Generated entry for translation for server strings" - }, - "shoulders": "Ramena", - "@shoulders": { - "description": "Generated entry for translation for server strings" - }, - "triceps": "Triceps", - "@triceps": { - "description": "Generated entry for translation for server strings" - }, - "swiss_ball": "Gimnastička lopta", - "@swiss_ball": { - "description": "Generated entry for translation for server strings" - }, - "until_failure": "Do neuspjeha", - "@until_failure": { - "description": "Generated entry for translation for server strings" - }, - "none__bodyweight_exercise_": "ništa (vježba za tjelesnu težinu)", - "@none__bodyweight_exercise_": { - "description": "Generated entry for translation for server strings" - }, - "seconds": "Sekunde", - "@seconds": { - "description": "Generated entry for translation for server strings" - }, - "textPromptTitle": "Spreman?", - "@textPromptTitle": {}, - "barbell": "Šipka", - "@barbell": { - "description": "Generated entry for translation for server strings" - }, - "calves": "Lisni mišići", - "@calves": { - "description": "Generated entry for translation for server strings" - }, - "textPromptSubheading": "Počni pritiskom gumba radnje", - "@textPromptSubheading": {}, - "body_weight": "Tjelesna težina", - "@body_weight": { - "description": "Generated entry for translation for server strings" - }, - "kilometers": "Kilometri", - "@kilometers": { - "description": "Generated entry for translation for server strings" - }, - "kilometers_per_hour": "Kilometara na sat", - "@kilometers_per_hour": { - "description": "Generated entry for translation for server strings" - }, - "lats": "Leđni mišići", - "@lats": { - "description": "Generated entry for translation for server strings" - }, - "miles_per_hour": "Milja na sat", - "@miles_per_hour": { - "description": "Generated entry for translation for server strings" - }, - "minutes": "Minute", - "@minutes": { - "description": "Generated entry for translation for server strings" - }, - "plates": "Ploče", - "@plates": { - "description": "Generated entry for translation for server strings" - }, - "kg": "kg", - "@kg": { - "description": "Generated entry for translation for server strings" - }, - "lb": "funta", - "@lb": { - "description": "Generated entry for translation for server strings" - }, - "searchNamesInEnglish": "Također traži imena na engleskom jeziku", - "@searchNamesInEnglish": {}, - "language": "Jezik", - "@language": {}, - "aboutPageTitle": "Wger informacije", - "@aboutPageTitle": {}, - "abs": "Trbuh", - "@abs": { - "description": "Generated entry for translation for server strings" - }, - "gym_mat": "Podloga za treniranje", - "@gym_mat": { - "description": "Generated entry for translation for server strings" - }, - "incline_bench": "Nagnuta klupa", - "@incline_bench": { - "description": "Generated entry for translation for server strings" - }, - "baseNameEnglish": "Sve vježbe trebaju osnovno ime na engleskom jeziku", - "@baseNameEnglish": {}, - "next": "Sljedeća", - "@next": {}, - "contributeExercise": "Doprinesi vježbu", - "@contributeExercise": {}, - "bench": "Klupa", - "@bench": { - "description": "Generated entry for translation for server strings" - }, - "dumbbell": "Ručni uteg", - "@dumbbell": { - "description": "Generated entry for translation for server strings" - }, - "biceps": "Bicepsi", - "@biceps": { - "description": "Generated entry for translation for server strings" - }, - "glutes": "Stražnjica", - "@glutes": { - "description": "Generated entry for translation for server strings" - }, - "hamstrings": "Tetive koljena", - "@hamstrings": { - "description": "Generated entry for translation for server strings" - }, - "kettlebell": "Kuglasti uteg", - "@kettlebell": { - "description": "Generated entry for translation for server strings" - }, - "legs": "Noge", - "@legs": { - "description": "Generated entry for translation for server strings" - }, - "miles": "Milje", - "@miles": { - "description": "Generated entry for translation for server strings" - }, - "max_reps": "Maks. broj ponavljanja", - "@max_reps": { - "description": "Generated entry for translation for server strings" - }, - "verify": "Potvrdi", - "@verify": {}, - "lower_back": "Donji dio leđa", - "@lower_back": { - "description": "Generated entry for translation for server strings" - }, - "aboutMastodonTitle": "Mastodon", - "@aboutMastodonTitle": {}, - "noMatchingExerciseFound": "Nisu pronađene odgovarajuće vježbe", - "@noMatchingExerciseFound": { - "description": "Message returned if no exercises match the searched string" - }, - "aboutDonateTitle": "Doniraj", - "@aboutDonateTitle": {}, - "aboutDonateText": "Pomogni projektu: kupi nam kavu, plati troškove poslužitelja i potiči nas u našem radu", - "@aboutDonateText": {}, - "settingsTitle": "Postavke", - "@settingsTitle": {}, - "settingsCacheTitle": "Predmemorija", - "@settingsCacheTitle": {}, - "settingsExerciseCacheDescription": "Izvrši predmemoriju", - "@settingsExerciseCacheDescription": {}, - "settingsCacheDeletedSnackbar": "Predmemorija je uspješno izbrisana", - "@settingsCacheDeletedSnackbar": {}, - "useMetric": "Koristi metričke jedinice za tjelesnu težinu", - "@useMetric": {}, - "log": "Zapiši", - "@log": { - "description": "Log a specific meal (imperative form)" - }, - "done": "Obavljeno", - "@done": {}, - "onlyLogging": "Prati samo kalorije", - "@onlyLogging": {}, - "onlyLoggingHelpText": "Označi okvir ako želiš bilježiti samo svoje kalorije i ne želiš postaviti detaljan plan prehrane s određenim obrocima", - "@onlyLoggingHelpText": {}, - "percentValue": "{value} %", - "@percentValue": { - "description": "A value in percent, e.g. 10 %", - "type": "text", - "placeholders": { - "value": { - "type": "String" - } - } - }, - "goalEnergy": "Cilj za energiju", - "@goalEnergy": {}, - "goalProtein": "Cilj za proteine", - "@goalProtein": {}, - "goalCarbohydrates": "Cilj za ugljikohidrate", - "@goalCarbohydrates": {}, - "goalFat": "Cilj za mast", - "@goalFat": {}, - "today": "Danas", - "@today": {}, - "loggedToday": "Zapisano danas", - "@loggedToday": {}, - "kcalValue": "{value} kcal", - "@kcalValue": { - "description": "A value in kcal, e.g. 500 kcal", - "type": "text", - "placeholders": { - "value": { - "type": "String" - } - } - }, - "gValue": "{value} g", - "@gValue": { - "description": "A value in grams, e.g. 5 g", - "type": "text", - "placeholders": { - "value": { - "type": "String" - } - } - }, - "surplus": "višak", - "@surplus": { - "description": "Caloric surplus (either planned or unplanned)" - }, - "deficit": "manjak", - "@deficit": { - "description": "Caloric deficit (either planned or unplanned)" - }, - "goalFiber": "Cilj za vlakna", - "@goalFiber": {}, - "goalMacro": "Ciljevi za makronutrijente", - "@goalMacro": { - "description": "The goal for macronutrients" - }, - "selectMealToLog": "Odaberi obrok za zapis u dnevnik", - "@selectMealToLog": {}, - "ingredientLogged": "Sastojak je upisan u dnevnik", - "@ingredientLogged": {}, - "noIngredientsDefined": "Još nije određen nijedan sastojak", - "@noIngredientsDefined": {}, - "overallChangeWeight": "Sveukupna promjena", - "@overallChangeWeight": { - "description": "Overall change in weight, added for localization" - }, - "goalTypeMeals": "Od obroka", - "@goalTypeMeals": { - "description": "added for localization of Class GoalType's filed meals" - }, - "goalTypeBasic": "Osnovni", - "@goalTypeBasic": { - "description": "added for localization of Class GoalType's filed basic" - }, - "goalTypeAdvanced": "Napredni", - "@goalTypeAdvanced": { - "description": "added for localization of Class GoalType's filed advanced" - }, - "indicatorRaw": "sirovo", - "@indicatorRaw": { - "description": "added for localization of Class Indicator's field text" - }, - "indicatorAvg": "prosjek", - "@indicatorAvg": { - "description": "added for localization of Class Indicator's field text" - }, - "themeMode": "Modus teme", - "@themeMode": {}, - "darkMode": "Uvijek tamni modus", - "@darkMode": {}, - "lightMode": "Uvijek svijetli modus", - "@lightMode": {}, - "systemMode": "Postavke sustava", - "@systemMode": {}, - "chartAllTimeTitle": "{name} – svo vrijeme", - "@chartAllTimeTitle": { - "description": "All-time chart of 'name' (e.g. 'weight', 'body fat' etc.)", - "type": "text", - "placeholders": { - "name": { - "type": "String" - } - } - }, - "chartDuringPlanTitle": "{chartName} tijekom prehrambenog plana {planName}", - "@chartDuringPlanTitle": { - "description": "chart of 'chartName' (e.g. 'weight', 'body fat' etc.) logged during plan", - "type": "text", - "placeholders": { - "chartName": { - "type": "String" - }, - "planName": { - "type": "String" - } - } - }, - "settingsIngredientCacheDescription": "Predmemorija sastojaka", - "@settingsIngredientCacheDescription": {}, - "chart30DaysTitle": "{name} – zadnjih 30 dana", - "@chart30DaysTitle": { - "description": "last 30 days chart of 'name' (e.g. 'weight', 'body fat' etc.)", - "type": "text", - "placeholders": { - "name": { - "type": "String" - } - } - } } From 5836001151b36f37d215eefc705a7053806fa687 Mon Sep 17 00:00:00 2001 From: faciolihenrique Date: Mon, 18 Aug 2025 19:28:13 +0200 Subject: [PATCH 61/89] Translated using Weblate (Portuguese (Brazil)) Currently translated at 99.0% (309 of 312 strings) Translation: wger Workout Manager/Mobile App Translate-URL: https://hosted.weblate.org/projects/wger/mobile/pt_BR/ --- lib/l10n/app_pt_BR.arb | 2054 +++++++++++++++++++++------------------- 1 file changed, 1069 insertions(+), 985 deletions(-) diff --git a/lib/l10n/app_pt_BR.arb b/lib/l10n/app_pt_BR.arb index 97bfa4f9..cb84dcf3 100644 --- a/lib/l10n/app_pt_BR.arb +++ b/lib/l10n/app_pt_BR.arb @@ -1,988 +1,1072 @@ { - "nutritionalPlan": "Plano nutricional", - "@nutritionalPlan": {}, - "weight": "Peso", - "@weight": { - "description": "The weight of a workout log or body weight entry" - }, - "date": "Data", - "@date": { - "description": "The date of a workout log or body weight entry" - }, - "value": "Valor", - "@value": { - "description": "The value of a measurement entry" - }, - "unit": "Unidade", - "@unit": { - "description": "The unit used for a repetition (kg, time, etc.)" - }, - "edit": "Editar", - "@edit": {}, - "delete": "Excluir", - "@delete": {}, - "login": "Entrar", - "@login": { - "description": "Text for login button" - }, - "userProfile": "Seu perfil", - "@userProfile": {}, - "logout": "Sair", - "@logout": { - "description": "Text for logout button" - }, - "notes": "Comentários", - "@notes": { - "description": "Personal notes, e.g. for a workout session" - }, - "description": "Descrição", - "@description": {}, - "register": "Inscrever-se", - "@register": { - "description": "Text for registration button" - }, - "useDefaultServer": "Usar servidor padrão", - "@useDefaultServer": { - "description": "Toggle button allowing users to switch between the default and a custom wger server" - }, - "reset": "Redefinir", - "@reset": { - "description": "Button text allowing the user to reset the entered values to the default" - }, - "password": "Senha", - "@password": {}, - "invalidUsername": "Por favor insira um nome de usuário válido", - "@invalidUsername": { - "description": "Error message when the user enters an invalid username" - }, - "passwordTooShort": "A senha é muito curta", - "@passwordTooShort": { - "description": "Error message when the user a password that is too short" - }, - "email": "Endereço de email", - "@email": {}, - "username": "Usuário", - "@username": {}, - "customServerHint": "Digite o endereço do seu próprio servidor, caso contrário o padrão será usado", - "@customServerHint": { - "description": "Hint text for the form where the users can enter their own wger instance" - }, - "useCustomServer": "Usar servidor customizado", - "@useCustomServer": { - "description": "Toggle button allowing users to switch between the default and a custom wger server" - }, - "registerInstead": "Não tem uma conta? Registrar agora", - "@registerInstead": {}, - "usernameValidChars": "Um usuário deve apenas conter letras, digitos e os caracteres @, +, ., -, ou _", - "@usernameValidChars": { - "description": "Error message when the user tries to register a username with forbidden characters" - }, - "invalidUrl": "Por favor, digite uma URL válida", - "@invalidUrl": { - "description": "Error message when the user enters an invalid URL, e.g. in the login form" - }, - "customServerUrl": "URL da instância wger", - "@customServerUrl": { - "description": "Label in the form where the users can enter their own wger instance" - }, - "passwordsDontMatch": "As senhas não coincidem", - "@passwordsDontMatch": { - "description": "Error message when the user enters two different passwords during registration" - }, - "invalidEmail": "Por favor insira um endereço de e-mail válido", - "@invalidEmail": { - "description": "Error message when the user enters an invalid email" - }, - "confirmPassword": "Confirme sua senha", - "@confirmPassword": {}, - "comment": "Comentário", - "@comment": { - "description": "Comment, additional information" - }, - "logIngredient": "Salvar ingrediente no diário nutricional", - "@logIngredient": {}, - "equipment": "Equipamento", - "@equipment": { - "description": "Equipment needed to perform an exercise" - }, - "saturatedFat": "Gordura saturada", - "@saturatedFat": {}, - "mealLogged": "Refeição registrada no diário", - "@mealLogged": {}, - "images": "Imagens", - "@images": {}, - "close": "Fechar", - "@close": { - "description": "Translation for close" - }, - "successfullyDeleted": "Excluído", - "@successfullyDeleted": { - "description": "Message when an item was successfully deleted" - }, - "save": "Salvar", - "@save": {}, - "goToToday": "Vá para hoje", - "@goToToday": { - "description": "Label on button to jump back to 'today' in the calendar widget" - }, - "set": "Definir", - "@set": { - "description": "A set in a workout plan" - }, - "noMeasurementEntries": "Você não tem entradas de medição", - "@noMeasurementEntries": {}, - "newSet": "Novo conjunto", - "@newSet": { - "description": "Header when adding a new set to a workout day" - }, - "impression": "Impressão", - "@impression": { - "description": "General impression (e.g. for a workout session) such as good, bad, etc." - }, - "plateCalculator": "Pratos", - "@plateCalculator": { - "description": "Label used for the plate calculator in the gym mode" - }, - "newNutritionalPlan": "Novo plano nutricional", - "@newNutritionalPlan": {}, - "setNr": "Definir {nr}", - "@setNr": { - "description": "Header in form indicating the number of the current set. Can also be translated as something like 'Set Nr. xy'.", - "type": "text", - "placeholders": { - "nr": { - "type": "String" - } - } - }, - "fat": "Gordura", - "@fat": {}, - "timeStartAhead": "O horário de início não pode ser anterior ao horário de término", - "@timeStartAhead": {}, - "carbohydrates": "Carboidratos", - "@carbohydrates": {}, - "muscles": "Músculos", - "@muscles": { - "description": "(main) muscles trained by an exercise" - }, - "total": "Total", - "@total": { - "description": "Label used for total sums of e.g. calories or similar" - }, - "dayDescriptionHelp": "Uma descrição do que é feito neste dia (por exemplo, 'dia de puxar') ou quais partes do corpo são treinadas (por exemplo, 'peito e ombros')", - "@dayDescriptionHelp": {}, - "gymMode": "Modo Gym", - "@gymMode": { - "description": "Label when starting the gym mode" - }, - "logged": "Desconectar", - "@logged": { - "description": "Header for the column of 'logged' nutritional values, i.e. what was eaten" - }, - "amount": "Quantia", - "@amount": { - "description": "The amount (e.g. in grams) of an ingredient in a meal" - }, - "loginInstead": "Já tem uma conta ? Entre", - "@loginInstead": {}, - "pause": "Pausar", - "@pause": { - "description": "Noun, not an imperative! Label used for the pause when using the gym mode" - }, - "success": "Sucesso", - "@success": { - "description": "Message when an action completed successfully, usually used as a heading" - }, - "repetitionUnit": "Unidade de repetição", - "@repetitionUnit": {}, - "weightUnit": "Unidade de peso", - "@weightUnit": {}, - "searchIngredient": "Pesquisar Ingrediente", - "@searchIngredient": { - "description": "Label on ingredient search form" - }, - "anErrorOccurred": "Ocorreu um erro!", - "@anErrorOccurred": {}, - "enterValue": "por favor insira um valor", - "@enterValue": { - "description": "Error message when the user hasn't entered a value on a required field" - }, - "logMeal": "Registrar refeição para diário de nutrição", - "@logMeal": {}, - "newEntry": "Nova entrada", - "@newEntry": { - "description": "Title when adding a new entry such as a weight or log entry" - }, - "addSet": "Adicionar set", - "@addSet": { - "description": "Label for the button that adds a set (to a workout day)" - }, - "energyShort": "E", - "@energyShort": { - "description": "The first letter or short name of the word 'Energy', used in overviews" - }, - "name": "Nome", - "@name": { - "description": "Name for a workout or nutritional plan" - }, - "percentEnergy": "Porcentagem de energia", - "@percentEnergy": {}, - "searchNamesInEnglish": "Procure também nomes em inglês", - "@searchNamesInEnglish": {}, - "exercise": "Exercício", - "@exercise": { - "description": "An exercise for a workout" - }, - "addIngredient": "Adicionar ingrediente", - "@addIngredient": {}, - "fatShort": "G", - "@fatShort": { - "description": "The first letter or short name of the word 'Fat', used in overviews" - }, - "start": "Começar", - "@start": { - "description": "Label on button to start the gym mode (i.e., an imperative)" - }, - "jumpTo": "Pule para", - "@jumpTo": { - "description": "Imperative. Label used in popup allowing the user to jump to a specific exercise while in the gym mode" - }, - "difference": "Diferença", - "@difference": {}, - "fiber": "Fibra", - "@fiber": {}, - "aboutDescription": "Obrigado por usar o Wger! Wger é um projeto colaborativo de código aberto, feito por entusiastas do fitness de todo o mundo.", - "@aboutDescription": { - "description": "Text in the about dialog" - }, - "timeStart": "Hora de início", - "@timeStart": { - "description": "The starting time of a workout" - }, - "searchExercise": "Exercício de pesquisa para adicionar", - "@searchExercise": { - "description": "Label on set form. Selected exercises are added to the set" - }, - "moreMeasurementEntries": "Adicionar nova medição", - "@moreMeasurementEntries": { - "description": "Message shown when the user wants to add new measurement" - }, - "loadingText": "Carregando...", - "@loadingText": { - "description": "Text to show when entries are being loaded in the background: Loading..." - }, - "selectExercises": "Se quiser fazer um superset você pode procurar vários exercícios, eles estarão agrupados", - "@selectExercises": {}, - "nutritionalDiary": "Diário nutricional", - "@nutritionalDiary": {}, - "protein": "Proteína", - "@protein": {}, - "proteinShort": "P", - "@proteinShort": { - "description": "The first letter or short name of the word 'Protein', used in overviews" - }, - "noWeightEntries": "Você não tem entradas de peso", - "@noWeightEntries": { - "description": "Message shown when the user has no logged weight entries" - }, - "noNutritionalPlans": "Você não tem planos nutricionais", - "@noNutritionalPlans": { - "description": "Message shown when the user has no nutritional plans" - }, - "goToDetailPage": "Ir para a página de detalhes", - "@goToDetailPage": {}, - "labelWorkoutLogs": "Registros de treinos", - "@labelWorkoutLogs": { - "description": "(Workout) logs" - }, - "ingredient": "Ingrediente", - "@ingredient": {}, - "measurementCategoriesHelpText": "Categoria de medição, como 'bíceps' ou 'gordura corporal'", - "@measurementCategoriesHelpText": {}, - "rirNotUsed": "RiR não usado", - "@rirNotUsed": { - "description": "Label used in RiR slider when the RiR value is not used/saved for the current setting or log" - }, - "todaysWorkout": "Seu treino hoje", - "@todaysWorkout": {}, - "kJ": "kJ", - "@kJ": { - "description": "Energy in a meal in kilo joules, kJ" - }, - "sodium": "Sódio", - "@sodium": {}, - "translation": "Tradução", - "@translation": {}, - "successfullySaved": "Salvo", - "@successfullySaved": { - "description": "Message when an item was successfully saved" - }, - "exerciseList": "Lista de exercícios", - "@exerciseList": {}, - "energy": "Energia", - "@energy": { - "description": "Energy in a meal, ingredient etc. e.g. in kJ" - }, - "newDay": "Novo dia", - "@newDay": {}, - "toggleDetails": "Alterar detalhes", - "@toggleDetails": { - "description": "Switch to toggle detail / overview" - }, - "musclesSecondary": "Músculos secundários", - "@musclesSecondary": { - "description": "secondary muscles trained by an exercise" - }, - "labelDashboard": "Painel", - "@labelDashboard": { - "description": "Title for screen dashboard" - }, - "timeEnd": "Fim do tempo", - "@timeEnd": { - "description": "The end time of a workout" - }, - "planned": "Planejado", - "@planned": { - "description": "Header for the column of 'planned' nutritional values, i.e. what should be eaten" - }, - "logHelpEntries": "Se em um mesmo dia houver mais de uma inscrição com o mesmo número de repetições, mas pesos diferentes, apenas a inscrição com maior peso será mostrada no diagrama.", - "@logHelpEntries": {}, - "exerciseName": "Nome do exercício", - "@exerciseName": { - "description": "Label for the name of a workout exercise" - }, - "labelBottomNavNutrition": "Nutrição", - "@labelBottomNavNutrition": { - "description": "Label used in bottom navigation, use a short word" - }, - "language": "Linguagem", - "@language": {}, - "nutritionalPlans": "Planos nutricionais", - "@nutritionalPlans": {}, - "kcal": "kcal", - "@kcal": { - "description": "Energy in a meal in kilocalories, kcal" - }, - "g": "g", - "@g": { - "description": "Abbreviation for gram" - }, - "addMeal": "Adicionar refeição", - "@addMeal": {}, - "sameRepetitions": "Se você fizer as mesmas repetições e peso para todas as séries, poderá preencher apenas uma linha. Por exemplo, para 4 séries basta inserir 10 para as repetições, isso automaticamente se torna \"4 x 10\".", - "@sameRepetitions": {}, - "measurementEntriesHelpText": "A unidade usada para medir a categoria, como 'cm' ou '%'", - "@measurementEntriesHelpText": {}, - "sugars": "Açúcar", - "@sugars": {}, - "carbohydratesShort": "C", - "@carbohydratesShort": { - "description": "The first letter or short name of the word 'Carbohydrates', used in overviews" - }, - "measurements": "Medidas", - "@measurements": { - "description": "Categories for the measurements such as biceps size, body fat, etc." - }, - "macronutrients": "Macronutrientes", - "@macronutrients": {}, - "plateCalculatorNotDivisible": "Não é possível atingir o peso com os pratos disponíveis", - "@plateCalculatorNotDivisible": { - "description": "Error message when the current weight is not reachable with plates (e.g. 33.1 kg)" - }, - "confirmDelete": "Tem certeza de que deseja excluir '{toDelete}'?", - "@confirmDelete": { - "description": "Confirmation text before the user deletes an object", - "type": "text", - "placeholders": { - "toDelete": { - "type": "String" - } - } - }, - "gPerBodyKg": "g por kg corporal", - "@gPerBodyKg": { - "description": "Label used for total sums of e.g. calories or similar in grams per Kg of body weight" - }, - "weekAverage": "Média de 7 dias", - "@weekAverage": { - "description": "Header for the column of '7 day average' nutritional values, i.e. what was logged last week" - }, - "labelWorkoutPlan": "Plano de treino", - "@labelWorkoutPlan": { - "description": "Title for screen workout plan" - }, - "category": "Categoria", - "@category": { - "description": "Category for an exercise, ingredient, etc." - }, - "exercises": "Exercícios", - "@exercises": { - "description": "Multiple exercises for a workout" - }, - "time": "Tempo", - "@time": { - "description": "The time of a meal or workout" - }, - "calendar": "Calendário", - "@calendar": {}, - "verify": "Verificar", - "@verify": {}, - "workoutSession": "Sessão de treino", - "@workoutSession": { - "description": "A (logged) workout session" - }, - "logHelpEntriesUnits": "Observe que apenas as entradas com uma unidade de peso (kg ou lb) e repetições são registradas; outras combinações, como tempo ou até a falha, são ignoradas aqui.", - "@logHelpEntriesUnits": {}, - "measurement": "Medição", - "@measurement": {}, - "nrOfSets": "Séries por exercício: {nrOfSets}", - "@nrOfSets": { - "description": "Label shown on the slider where the user selects the nr of sets", - "type": "text", - "placeholders": { - "nrOfSets": { - "type": "String" - } - } - }, - "useMetric": "Use unidades métricas para peso corporal", - "@useMetric": {}, - "aboutMastodonTitle": "Mastodon", - "@aboutMastodonTitle": {}, - "selectEntry": "Por favor, selecione uma entrada", - "@selectEntry": {}, - "noMatchingExerciseFound": "Sem exercícios correspondentes encontrados", - "@noMatchingExerciseFound": { - "description": "Message returned if no exercises match the searched string" - }, - "selectExercise": "Por favor, selecione um exercício", - "@selectExercise": { - "description": "Error message when the user hasn't selected an exercise in the form" - }, - "enterValidNumber": "Por favor, insira um número válido", - "@enterValidNumber": { - "description": "Error message when the user has submitted an invalid number (e.g. '3,.,.,.')" - }, - "baseNameEnglish": "Todos os exercícios necessitam de um nome base em inglês", - "@baseNameEnglish": {}, - "labelBottomNavWorkout": "Treino", - "@labelBottomNavWorkout": { - "description": "Label used in bottom navigation, use a short word" - }, - "reps": "Repetições", - "@reps": { - "description": "Shorthand for repetitions, used when space constraints are tighter" - }, - "rir": "ReR", - "@rir": { - "description": "Shorthand for Repetitions In Reserve" - }, - "setUnitsAndRir": "Unidades e RIR da série", - "@setUnitsAndRir": { - "description": "Label shown on the slider where the user can toggle showing units and RiR", - "type": "text" - }, - "aboutDonateTitle": "Doações", - "@aboutDonateTitle": {}, - "aboutDonateText": "Compre-nos um café para ajudar no projeto, pague pelos custos do servidor e nos mantenha abastecidos", - "@aboutDonateText": {}, - "enterCharacters": "Por favor, utilize entre {min} e {max} caracteres", - "@enterCharacters": { - "description": "Error message when the user hasn't entered the correct number of characters in a form", - "type": "text", - "placeholders": { - "min": { - "type": "String" - }, - "max": { - "type": "String" - } - } - }, - "enterMinCharacters": "Por favor, utilize pelo menos {min} caracteres", - "@enterMinCharacters": { - "description": "Error message when the user hasn't entered the minimum amount characters in a form", - "type": "text", - "placeholders": { - "min": { - "type": "String" - } - } - }, - "gallery": "Galeria", - "@gallery": {}, - "alsoKnownAs": "Também conhecido como:{aliases}", - "@alsoKnownAs": { - "placeholders": { - "aliases": { - "type": "String" - } + "nutritionalPlan": "Plano nutricional", + "@nutritionalPlan": {}, + "weight": "Peso", + "@weight": { + "description": "The weight of a workout log or body weight entry" }, - "description": "List of alternative names for an exercise" - }, - "recentlyUsedIngredients": "Ingredientes adicionados recentemente", - "@recentlyUsedIngredients": { - "description": "A message when a user adds a new ingredient to a meal." - }, - "addImage": "Adicionar imagem", - "@addImage": {}, - "scanBarcode": "Escaneie o código de barras", - "@scanBarcode": { - "description": "Label for scan barcode button" - }, - "dataCopied": "Dados copiados para o novo registro", - "@dataCopied": { - "description": "Snackbar message to show on copying data to a new log entry" - }, - "appUpdateContent": "Esta versão do aplicativo não é compatível com o servidor, por favor atualize o aplicativo.", - "@appUpdateContent": {}, - "productFound": "Produto encontrado", - "@productFound": { - "description": "Header label for dialog when product is found with barcode" - }, - "appUpdateTitle": "Atualização necessária", - "@appUpdateTitle": {}, - "takePicture": "Tire uma foto", - "@takePicture": {}, - "selectIngredient": "Por favor, selecione um ingrediente", - "@selectIngredient": { - "description": "Error message when the user hasn't selected an ingredient from the autocompleter" - }, - "selectImage": "Por favor, selecione uma imagem", - "@selectImage": { - "description": "Label and error message when the user hasn't selected an image to save" - }, - "optionsLabel": "Opções", - "@optionsLabel": { - "description": "Label for the popup with general app options" - }, - "productNotFound": "Produto não encontrado", - "@productNotFound": { - "description": "Header label for dialog when product is not found with barcode" - }, - "variations": "Variações", - "@variations": { - "description": "Variations of one exercise (e.g. benchpress and benchpress narrow)" - }, - "verifiedEmail": "Email verificado", - "@verifiedEmail": {}, - "chooseFromLibrary": "Escolher na galeria", - "@chooseFromLibrary": {}, - "unVerifiedEmail": "Email não verificado", - "@unVerifiedEmail": {}, - "add_exercise_image_license": "As imagens devem ser compatíveis com a licença CC BY SA. Em caso de dúvida, faça upload apenas de fotos que você mesmo tenha tirado.", - "@add_exercise_image_license": {}, - "next": "Próximo", - "@next": {}, - "settingsCacheTitle": "Cache", - "@settingsCacheTitle": {}, - "settingsExerciseCacheDescription": "Cache do exercício", - "@settingsExerciseCacheDescription": {}, - "settingsCacheDeletedSnackbar": "Cache limpa com sucesso", - "@settingsCacheDeletedSnackbar": {}, - "translateExercise": "Traduza este exercício agora", - "@translateExercise": {}, - "contributeExerciseWarning": "Você só pode contribuir com exercícios se sua conta tiver mais de {days} dias e se você tiver verificado seu e-mail", - "@contributeExerciseWarning": { - "description": "Number of days before which a person can add exercise", - "placeholders": { - "days": { - "type": "String", - "example": "14" - } - } - }, - "whatVariationsExist": "Quais variações deste exercício existem, se houver?", - "@whatVariationsExist": {}, - "previous": "Anterior", - "@previous": {}, - "addExercise": "Adicionar exercício", - "@addExercise": {}, - "verifiedEmailInfo": "Um e-mail foi enviado para {email}", - "@verifiedEmailInfo": { - "placeholders": { - "email": { - "type": "String" - } - } - }, - "verifiedEmailReason": "Você precisa verificar seu e-mail para contribuir com exercícios", - "@verifiedEmailReason": {}, - "alternativeNames": "Nomes alternativos", - "@alternativeNames": {}, - "baseData": "Fundamentos em inglês", - "@baseData": { - "description": "The base data for an exercise such as category, trained muscles, etc." - }, - "aboutPageTitle": "Sobre o Wger", - "@aboutPageTitle": {}, - "productFoundDescription": "O código de barras corresponde a este produto: {productName}. Deseja continuar?", - "@productFoundDescription": { - "description": "Dialog info when product is found with barcode", - "type": "text", - "placeholders": { - "productName": { - "type": "String" - } - } - }, - "productNotFoundDescription": "O produto com o código de barras escaneado {barcode} não foi encontrado no banco de dados da wger", - "@productNotFoundDescription": { - "description": "Dialog info when product is not found with barcode", - "type": "text", - "placeholders": { - "barcode": { - "type": "String" - } - } - }, - "contributeExercise": "Contribuir com um exercício", - "@contributeExercise": {}, - "oneNamePerLine": "Um nome por linha", - "@oneNamePerLine": {}, - "settingsTitle": "Configurações", - "@settingsTitle": {}, - "onlyLogging": "Apenas acompanhe calorias", - "@onlyLogging": {}, - "ingredientLogged": "Ingrediente registrado no diário", - "@ingredientLogged": {}, - "noIngredientsDefined": "Nenhum ingrediente definido ainda", - "@noIngredientsDefined": {}, - "bench": "Banco", - "@bench": { - "description": "Generated entry for translation for server strings" - }, - "goalFiber": "Meta de fibras", - "@goalFiber": {}, - "overallChangeWeight": "Mudança geral", - "@overallChangeWeight": { - "description": "Overall change in weight, added for localization" - }, - "goalTypeMeals": "De refeições", - "@goalTypeMeals": { - "description": "added for localization of Class GoalType's filed meals" - }, - "goalTypeBasic": "Básico", - "@goalTypeBasic": { - "description": "added for localization of Class GoalType's filed basic" - }, - "goalTypeAdvanced": "Avançado", - "@goalTypeAdvanced": { - "description": "added for localization of Class GoalType's filed advanced" - }, - "indicatorRaw": "bruto", - "@indicatorRaw": { - "description": "added for localization of Class Indicator's field text" - }, - "indicatorAvg": "média", - "@indicatorAvg": { - "description": "added for localization of Class Indicator's field text" - }, - "seconds": "Segundos", - "@seconds": { - "description": "Generated entry for translation for server strings" - }, - "textPromptTitle": "Pronto para iniciar?", - "@textPromptTitle": {}, - "textPromptSubheading": "Aperte o botão de ação para começar", - "@textPromptSubheading": {}, - "chest": "Peito", - "@chest": { - "description": "Generated entry for translation for server strings" - }, - "max_reps": "Repetições Máximas", - "@max_reps": { - "description": "Generated entry for translation for server strings" - }, - "pull_up_bar": "Barra de Pull-up", - "@pull_up_bar": { - "description": "Generated entry for translation for server strings" - }, - "quads": "Quadríceps", - "@quads": { - "description": "Generated entry for translation for server strings" - }, - "goalFat": "Meta de gordura", - "@goalFat": {}, - "body_weight": "Peso Corporal", - "@body_weight": { - "description": "Generated entry for translation for server strings" - }, - "kilometers": "Quilômetros", - "@kilometers": { - "description": "Generated entry for translation for server strings" - }, - "kilometers_per_hour": "Quilômetros por hora", - "@kilometers_per_hour": { - "description": "Generated entry for translation for server strings" - }, - "miles_per_hour": "Milhas por hora", - "@miles_per_hour": { - "description": "Generated entry for translation for server strings" - }, - "minutes": "Minutos", - "@minutes": { - "description": "Generated entry for translation for server strings" - }, - "sz_bar": "Barra Curvada", - "@sz_bar": { - "description": "Generated entry for translation for server strings" - }, - "goalProtein": "Meta de proteína", - "@goalProtein": {}, - "goalEnergy": "Meta energética", - "@goalEnergy": {}, - "today": "Hoje", - "@today": {}, - "arms": "Braços", - "@arms": { - "description": "Generated entry for translation for server strings" - }, - "calves": "Panturrilha", - "@calves": { - "description": "Generated entry for translation for server strings" - }, - "triceps": "Tríceps", - "@triceps": { - "description": "Generated entry for translation for server strings" - }, - "goalCarbohydrates": "Meta de carbohidratos", - "@goalCarbohydrates": {}, - "onlyLoggingHelpText": "Marque a caixa se você apenas quiser registrar suas calorias e não quer configurar um plano nutricional detalhado com refeições específicas", - "@onlyLoggingHelpText": {}, - "kcalValue": "{value} kcal", - "@kcalValue": { - "description": "A value in kcal, e.g. 500 kcal", - "type": "text", - "placeholders": { - "value": { - "type": "String" - } - } - }, - "percentValue": "{value} %", - "@percentValue": { - "description": "A value in percent, e.g. 10 %", - "type": "text", - "placeholders": { - "value": { - "type": "String" - } - } - }, - "goalMacro": "Macro Objetivos", - "@goalMacro": { - "description": "The goal for macronutrients" - }, - "selectMealToLog": "Selecione uma refeição para registrar no diário", - "@selectMealToLog": {}, - "loggedToday": "Registrado hoje", - "@loggedToday": {}, - "surplus": "excedente", - "@surplus": { - "description": "Caloric surplus (either planned or unplanned)" - }, - "deficit": "déficit", - "@deficit": { - "description": "Caloric deficit (either planned or unplanned)" - }, - "gValue": "{value} g", - "@gValue": { - "description": "A value in grams, e.g. 5 g", - "type": "text", - "placeholders": { - "value": { - "type": "String" - } - } - }, - "abs": "Abdômen", - "@abs": { - "description": "Generated entry for translation for server strings" - }, - "back": "Costas", - "@back": { - "description": "Generated entry for translation for server strings" - }, - "barbell": "Barra", - "@barbell": { - "description": "Generated entry for translation for server strings" - }, - "cardio": "Cardio", - "@cardio": { - "description": "Generated entry for translation for server strings" - }, - "dumbbell": "Haltere", - "@dumbbell": { - "description": "Generated entry for translation for server strings" - }, - "glutes": "Glúteos", - "@glutes": { - "description": "Generated entry for translation for server strings" - }, - "gym_mat": "Tapete", - "@gym_mat": { - "description": "Generated entry for translation for server strings" - }, - "hamstrings": "Tendões", - "@hamstrings": { - "description": "Generated entry for translation for server strings" - }, - "kettlebell": "Kettlebell", - "@kettlebell": { - "description": "Generated entry for translation for server strings" - }, - "lats": "Dorsal", - "@lats": { - "description": "Generated entry for translation for server strings" - }, - "legs": "Pernas", - "@legs": { - "description": "Generated entry for translation for server strings" - }, - "lower_back": "Lombar", - "@lower_back": { - "description": "Generated entry for translation for server strings" - }, - "plates": "Anilhas", - "@plates": { - "description": "Generated entry for translation for server strings" - }, - "repetitions": "Repetições", - "@repetitions": { - "description": "Generated entry for translation for server strings" - }, - "shoulders": "Ombros", - "@shoulders": { - "description": "Generated entry for translation for server strings" - }, - "until_failure": "Até a falha", - "@until_failure": { - "description": "Generated entry for translation for server strings" - }, - "kg": "kg", - "@kg": { - "description": "Generated entry for translation for server strings" - }, - "none__bodyweight_exercise_": "nenhum (exercício com peso corporal)", - "@none__bodyweight_exercise_": { - "description": "Generated entry for translation for server strings" - }, - "lb": "lb", - "@lb": { - "description": "Generated entry for translation for server strings" - }, - "chartAllTimeTitle": "{name} total", - "@chartAllTimeTitle": { - "description": "All-time chart of 'name' (e.g. 'weight', 'body fat' etc.)", - "type": "text", - "placeholders": { - "name": { - "type": "String" - } - } - }, - "chart30DaysTitle": "{name} últimos 30 dias", - "@chart30DaysTitle": { - "description": "last 30 days chart of 'name' (e.g. 'weight', 'body fat' etc.)", - "type": "text", - "placeholders": { - "name": { - "type": "String" - } - } - }, - "chartDuringPlanTitle": "{chartName} durante plano nutricional {planName}", - "@chartDuringPlanTitle": { - "description": "chart of 'chartName' (e.g. 'weight', 'body fat' etc.) logged during plan", - "type": "text", - "placeholders": { - "chartName": { - "type": "String" - }, - "planName": { - "type": "String" - } - } - }, - "settingsIngredientCacheDescription": "Cache de Ingredientes", - "@settingsIngredientCacheDescription": {}, - "cacheWarning": "Devido ao cache pode demorar algum tempo até que mudanças estejam visíveis na aplicação.", - "@cacheWarning": {}, - "swiss_ball": "Bola Suíça", - "@swiss_ball": { - "description": "Generated entry for translation for server strings" - }, - "log": "Registro", - "@log": { - "description": "Log a specific meal (imperative form)" - }, - "done": "Feito", - "@done": {}, - "incline_bench": "Banco inclinado", - "@incline_bench": { - "description": "Generated entry for translation for server strings" - }, - "miles": "Milhas", - "@miles": { - "description": "Generated entry for translation for server strings" - }, - "biceps": "Bíceps", - "@biceps": { - "description": "Generated entry for translation for server strings" - }, - "useApiToken": "Usar API Token", - "@useApiToken": {}, - "useUsernameAndPassword": "Usar usuário e senha", - "@useUsernameAndPassword": {}, - "apiToken": "API Token", - "@apiToken": {}, - "invalidApiToken": "Por favor, entre com a API key válida", - "@invalidApiToken": { - "description": "Error message when the user enters an invalid API key" - }, - "apiTokenValidChars": "A chave API deve ter apenas letras a-f, números 0-9 e ter exatamente 40 caracteres", - "@apiTokenValidChars": { - "description": "Error message when the user tries to input a API key with forbidden characters" - }, - "routines": "Rotinas", - "@routines": {}, - "newRoutine": "Nova rotina", - "@newRoutine": {}, - "noRoutines": "Não tens rotinas", - "@noRoutines": {}, - "restTime": "Tempo de descanso", - "@restTime": {}, - "sets": "Conjuntos", - "@sets": { - "description": "The number of sets to be done for one exercise" - }, - "exerciseNr": "Exercício {nr}", - "@exerciseNr": { - "description": "Header in form indicating the number of the current exercise. Can also be translated as something like 'Set Nr. xy'.", - "type": "text", - "placeholders": { - "nr": { - "type": "String" - } - } - }, - "supersetNr": "Superset {nr}", - "@supersetNr": { - "description": "Header in form indicating the number of the current exercise. Can also be translated as something like 'Superset Nr. xy'.", - "type": "text", - "placeholders": { - "nr": { - "type": "String" - } - } - }, - "restDay": "Dia de descanso", - "@restDay": {}, - "isRestDay": "É dia de descanso", - "@isRestDay": {}, - "isRestDayHelp": "Por favor, note que todos os conjuntos e exercícios serão removidos quando marcar um dia como um dia de descanso.", - "@isRestDayHelp": {}, - "needsLogsToAdvance": "Precisa de logs para avançar", - "@needsLogsToAdvance": {} + "date": "Data", + "@date": { + "description": "The date of a workout log or body weight entry" + }, + "value": "Valor", + "@value": { + "description": "The value of a measurement entry" + }, + "unit": "Unidade", + "@unit": { + "description": "The unit used for a repetition (kg, time, etc.)" + }, + "edit": "Editar", + "@edit": {}, + "delete": "Excluir", + "@delete": {}, + "login": "Entrar", + "@login": { + "description": "Text for login button" + }, + "userProfile": "Seu perfil", + "@userProfile": {}, + "logout": "Sair", + "@logout": { + "description": "Text for logout button" + }, + "notes": "Comentários", + "@notes": { + "description": "Personal notes, e.g. for a workout session" + }, + "description": "Descrição", + "@description": {}, + "register": "Inscrever-se", + "@register": { + "description": "Text for registration button" + }, + "useDefaultServer": "Usar servidor padrão", + "@useDefaultServer": { + "description": "Toggle button allowing users to switch between the default and a custom wger server" + }, + "reset": "Redefinir", + "@reset": { + "description": "Button text allowing the user to reset the entered values to the default" + }, + "password": "Senha", + "@password": {}, + "invalidUsername": "Por favor insira um nome de usuário válido", + "@invalidUsername": { + "description": "Error message when the user enters an invalid username" + }, + "passwordTooShort": "A senha é muito curta", + "@passwordTooShort": { + "description": "Error message when the user a password that is too short" + }, + "email": "Endereço de email", + "@email": {}, + "username": "Usuário", + "@username": {}, + "customServerHint": "Digite o endereço do seu próprio servidor, caso contrário o padrão será usado", + "@customServerHint": { + "description": "Hint text for the form where the users can enter their own wger instance" + }, + "useCustomServer": "Usar servidor customizado", + "@useCustomServer": { + "description": "Toggle button allowing users to switch between the default and a custom wger server" + }, + "registerInstead": "Não tem uma conta? Registrar agora", + "@registerInstead": {}, + "usernameValidChars": "Um usuário deve apenas conter letras, digitos e os caracteres @, +, ., -, ou _", + "@usernameValidChars": { + "description": "Error message when the user tries to register a username with forbidden characters" + }, + "invalidUrl": "Por favor, digite uma URL válida", + "@invalidUrl": { + "description": "Error message when the user enters an invalid URL, e.g. in the login form" + }, + "customServerUrl": "URL da instância wger", + "@customServerUrl": { + "description": "Label in the form where the users can enter their own wger instance" + }, + "passwordsDontMatch": "As senhas não coincidem", + "@passwordsDontMatch": { + "description": "Error message when the user enters two different passwords during registration" + }, + "invalidEmail": "Por favor insira um endereço de e-mail válido", + "@invalidEmail": { + "description": "Error message when the user enters an invalid email" + }, + "confirmPassword": "Confirme sua senha", + "@confirmPassword": {}, + "comment": "Comentário", + "@comment": { + "description": "Comment, additional information" + }, + "logIngredient": "Salvar ingrediente no diário nutricional", + "@logIngredient": {}, + "equipment": "Equipamento", + "@equipment": { + "description": "Equipment needed to perform an exercise" + }, + "saturatedFat": "Gordura saturada", + "@saturatedFat": {}, + "mealLogged": "Refeição registrada no diário", + "@mealLogged": {}, + "images": "Imagens", + "@images": {}, + "close": "Fechar", + "@close": { + "description": "Translation for close" + }, + "successfullyDeleted": "Excluído", + "@successfullyDeleted": { + "description": "Message when an item was successfully deleted" + }, + "save": "Salvar", + "@save": {}, + "goToToday": "Vá para hoje", + "@goToToday": { + "description": "Label on button to jump back to 'today' in the calendar widget" + }, + "set": "Definir", + "@set": { + "description": "A set in a workout plan" + }, + "noMeasurementEntries": "Você não tem entradas de medição", + "@noMeasurementEntries": {}, + "newSet": "Novo conjunto", + "@newSet": { + "description": "Header when adding a new set to a workout day" + }, + "impression": "Impressão", + "@impression": { + "description": "General impression (e.g. for a workout session) such as good, bad, etc." + }, + "plateCalculator": "Pratos", + "@plateCalculator": { + "description": "Label used for the plate calculator in the gym mode" + }, + "newNutritionalPlan": "Novo plano nutricional", + "@newNutritionalPlan": {}, + "setNr": "Definir {nr}", + "@setNr": { + "description": "Header in form indicating the number of the current set. Can also be translated as something like 'Set Nr. xy'.", + "type": "text", + "placeholders": { + "nr": { + "type": "String" + } + } + }, + "fat": "Gordura", + "@fat": {}, + "timeStartAhead": "O horário de início não pode ser anterior ao horário de término", + "@timeStartAhead": {}, + "carbohydrates": "Carboidratos", + "@carbohydrates": {}, + "muscles": "Músculos", + "@muscles": { + "description": "(main) muscles trained by an exercise" + }, + "total": "Total", + "@total": { + "description": "Label used for total sums of e.g. calories or similar" + }, + "dayDescriptionHelp": "Uma descrição do que é feito neste dia (por exemplo, 'dia de puxar') ou quais partes do corpo são treinadas (por exemplo, 'peito e ombros')", + "@dayDescriptionHelp": {}, + "gymMode": "Modo Gym", + "@gymMode": { + "description": "Label when starting the gym mode" + }, + "logged": "Desconectar", + "@logged": { + "description": "Header for the column of 'logged' nutritional values, i.e. what was eaten" + }, + "amount": "Quantia", + "@amount": { + "description": "The amount (e.g. in grams) of an ingredient in a meal" + }, + "loginInstead": "Já tem uma conta ? Entre", + "@loginInstead": {}, + "pause": "Pausar", + "@pause": { + "description": "Noun, not an imperative! Label used for the pause when using the gym mode" + }, + "success": "Sucesso", + "@success": { + "description": "Message when an action completed successfully, usually used as a heading" + }, + "repetitionUnit": "Unidade de repetição", + "@repetitionUnit": {}, + "weightUnit": "Unidade de peso", + "@weightUnit": {}, + "searchIngredient": "Pesquisar Ingrediente", + "@searchIngredient": { + "description": "Label on ingredient search form" + }, + "anErrorOccurred": "Ocorreu um erro!", + "@anErrorOccurred": {}, + "enterValue": "por favor insira um valor", + "@enterValue": { + "description": "Error message when the user hasn't entered a value on a required field" + }, + "logMeal": "Registrar refeição para diário de nutrição", + "@logMeal": {}, + "newEntry": "Nova entrada", + "@newEntry": { + "description": "Title when adding a new entry such as a weight or log entry" + }, + "addSet": "Adicionar set", + "@addSet": { + "description": "Label for the button that adds a set (to a workout day)" + }, + "energyShort": "E", + "@energyShort": { + "description": "The first letter or short name of the word 'Energy', used in overviews" + }, + "name": "Nome", + "@name": { + "description": "Name for a workout or nutritional plan" + }, + "percentEnergy": "Porcentagem de energia", + "@percentEnergy": {}, + "searchNamesInEnglish": "Procure também nomes em inglês", + "@searchNamesInEnglish": {}, + "exercise": "Exercício", + "@exercise": { + "description": "An exercise for a workout" + }, + "addIngredient": "Adicionar ingrediente", + "@addIngredient": {}, + "fatShort": "G", + "@fatShort": { + "description": "The first letter or short name of the word 'Fat', used in overviews" + }, + "start": "Começar", + "@start": { + "description": "Label on button to start the gym mode (i.e., an imperative)" + }, + "jumpTo": "Pule para", + "@jumpTo": { + "description": "Imperative. Label used in popup allowing the user to jump to a specific exercise while in the gym mode" + }, + "difference": "Diferença", + "@difference": {}, + "fiber": "Fibra", + "@fiber": {}, + "aboutDescription": "Obrigado por usar o Wger! Wger é um projeto colaborativo de código aberto, feito por entusiastas do fitness de todo o mundo.", + "@aboutDescription": { + "description": "Text in the about dialog" + }, + "timeStart": "Hora de início", + "@timeStart": { + "description": "The starting time of a workout" + }, + "searchExercise": "Exercício de pesquisa para adicionar", + "@searchExercise": { + "description": "Label on set form. Selected exercises are added to the set" + }, + "moreMeasurementEntries": "Adicionar nova medição", + "@moreMeasurementEntries": { + "description": "Message shown when the user wants to add new measurement" + }, + "loadingText": "Carregando...", + "@loadingText": { + "description": "Text to show when entries are being loaded in the background: Loading..." + }, + "selectExercises": "Se quiser fazer um superset você pode procurar vários exercícios, eles estarão agrupados", + "@selectExercises": {}, + "nutritionalDiary": "Diário nutricional", + "@nutritionalDiary": {}, + "protein": "Proteína", + "@protein": {}, + "proteinShort": "P", + "@proteinShort": { + "description": "The first letter or short name of the word 'Protein', used in overviews" + }, + "noWeightEntries": "Você não tem entradas de peso", + "@noWeightEntries": { + "description": "Message shown when the user has no logged weight entries" + }, + "noNutritionalPlans": "Você não tem planos nutricionais", + "@noNutritionalPlans": { + "description": "Message shown when the user has no nutritional plans" + }, + "goToDetailPage": "Ir para a página de detalhes", + "@goToDetailPage": {}, + "labelWorkoutLogs": "Registros de treinos", + "@labelWorkoutLogs": { + "description": "(Workout) logs" + }, + "ingredient": "Ingrediente", + "@ingredient": {}, + "measurementCategoriesHelpText": "Categoria de medição, como 'bíceps' ou 'gordura corporal'", + "@measurementCategoriesHelpText": {}, + "rirNotUsed": "RiR não usado", + "@rirNotUsed": { + "description": "Label used in RiR slider when the RiR value is not used/saved for the current setting or log" + }, + "todaysWorkout": "Seu treino hoje", + "@todaysWorkout": {}, + "kJ": "kJ", + "@kJ": { + "description": "Energy in a meal in kilo joules, kJ" + }, + "sodium": "Sódio", + "@sodium": {}, + "translation": "Tradução", + "@translation": {}, + "successfullySaved": "Salvo", + "@successfullySaved": { + "description": "Message when an item was successfully saved" + }, + "exerciseList": "Lista de exercícios", + "@exerciseList": {}, + "energy": "Energia", + "@energy": { + "description": "Energy in a meal, ingredient etc. e.g. in kJ" + }, + "newDay": "Novo dia", + "@newDay": {}, + "toggleDetails": "Alterar detalhes", + "@toggleDetails": { + "description": "Switch to toggle detail / overview" + }, + "musclesSecondary": "Músculos secundários", + "@musclesSecondary": { + "description": "secondary muscles trained by an exercise" + }, + "labelDashboard": "Painel", + "@labelDashboard": { + "description": "Title for screen dashboard" + }, + "timeEnd": "Fim do tempo", + "@timeEnd": { + "description": "The end time of a workout" + }, + "planned": "Planejado", + "@planned": { + "description": "Header for the column of 'planned' nutritional values, i.e. what should be eaten" + }, + "logHelpEntries": "Se em um mesmo dia houver mais de uma inscrição com o mesmo número de repetições, mas pesos diferentes, apenas a inscrição com maior peso será mostrada no diagrama.", + "@logHelpEntries": {}, + "exerciseName": "Nome do exercício", + "@exerciseName": { + "description": "Label for the name of a workout exercise" + }, + "labelBottomNavNutrition": "Nutrição", + "@labelBottomNavNutrition": { + "description": "Label used in bottom navigation, use a short word" + }, + "language": "Linguagem", + "@language": {}, + "nutritionalPlans": "Planos nutricionais", + "@nutritionalPlans": {}, + "kcal": "kcal", + "@kcal": { + "description": "Energy in a meal in kilocalories, kcal" + }, + "g": "g", + "@g": { + "description": "Abbreviation for gram" + }, + "addMeal": "Adicionar refeição", + "@addMeal": {}, + "sameRepetitions": "Se você fizer as mesmas repetições e peso para todas as séries, poderá preencher apenas uma linha. Por exemplo, para 4 séries basta inserir 10 para as repetições, isso automaticamente se torna \"4 x 10\".", + "@sameRepetitions": {}, + "measurementEntriesHelpText": "A unidade usada para medir a categoria, como 'cm' ou '%'", + "@measurementEntriesHelpText": {}, + "sugars": "Açúcar", + "@sugars": {}, + "carbohydratesShort": "C", + "@carbohydratesShort": { + "description": "The first letter or short name of the word 'Carbohydrates', used in overviews" + }, + "measurements": "Medidas", + "@measurements": { + "description": "Categories for the measurements such as biceps size, body fat, etc." + }, + "macronutrients": "Macronutrientes", + "@macronutrients": {}, + "plateCalculatorNotDivisible": "Não é possível atingir o peso com os pratos disponíveis", + "@plateCalculatorNotDivisible": { + "description": "Error message when the current weight is not reachable with plates (e.g. 33.1 kg)" + }, + "confirmDelete": "Tem certeza de que deseja excluir '{toDelete}'?", + "@confirmDelete": { + "description": "Confirmation text before the user deletes an object", + "type": "text", + "placeholders": { + "toDelete": { + "type": "String" + } + } + }, + "gPerBodyKg": "g por kg corporal", + "@gPerBodyKg": { + "description": "Label used for total sums of e.g. calories or similar in grams per Kg of body weight" + }, + "weekAverage": "Média de 7 dias", + "@weekAverage": { + "description": "Header for the column of '7 day average' nutritional values, i.e. what was logged last week" + }, + "labelWorkoutPlan": "Plano de treino", + "@labelWorkoutPlan": { + "description": "Title for screen workout plan" + }, + "category": "Categoria", + "@category": { + "description": "Category for an exercise, ingredient, etc." + }, + "exercises": "Exercícios", + "@exercises": { + "description": "Multiple exercises for a workout" + }, + "time": "Tempo", + "@time": { + "description": "The time of a meal or workout" + }, + "calendar": "Calendário", + "@calendar": {}, + "verify": "Verificar", + "@verify": {}, + "workoutSession": "Sessão de treino", + "@workoutSession": { + "description": "A (logged) workout session" + }, + "logHelpEntriesUnits": "Observe que apenas as entradas com uma unidade de peso (kg ou lb) e repetições são registradas; outras combinações, como tempo ou até a falha, são ignoradas aqui.", + "@logHelpEntriesUnits": {}, + "measurement": "Medição", + "@measurement": {}, + "nrOfSets": "Séries por exercício: {nrOfSets}", + "@nrOfSets": { + "description": "Label shown on the slider where the user selects the nr of sets", + "type": "text", + "placeholders": { + "nrOfSets": { + "type": "String" + } + } + }, + "useMetric": "Use unidades métricas para peso corporal", + "@useMetric": {}, + "aboutMastodonTitle": "Mastodon", + "@aboutMastodonTitle": {}, + "selectEntry": "Por favor, selecione uma entrada", + "@selectEntry": {}, + "noMatchingExerciseFound": "Sem exercícios correspondentes encontrados", + "@noMatchingExerciseFound": { + "description": "Message returned if no exercises match the searched string" + }, + "selectExercise": "Por favor, selecione um exercício", + "@selectExercise": { + "description": "Error message when the user hasn't selected an exercise in the form" + }, + "enterValidNumber": "Por favor, insira um número válido", + "@enterValidNumber": { + "description": "Error message when the user has submitted an invalid number (e.g. '3,.,.,.')" + }, + "baseNameEnglish": "Todos os exercícios necessitam de um nome base em inglês", + "@baseNameEnglish": {}, + "labelBottomNavWorkout": "Treino", + "@labelBottomNavWorkout": { + "description": "Label used in bottom navigation, use a short word" + }, + "reps": "Repetições", + "@reps": { + "description": "Shorthand for repetitions, used when space constraints are tighter" + }, + "rir": "ReR", + "@rir": { + "description": "Shorthand for Repetitions In Reserve" + }, + "setUnitsAndRir": "Unidades e RIR da série", + "@setUnitsAndRir": { + "description": "Label shown on the slider where the user can toggle showing units and RiR", + "type": "text" + }, + "aboutDonateTitle": "Faça uma doação", + "@aboutDonateTitle": {}, + "aboutDonateText": "Enquanto o aplicativo e serviço é de graça, desenvolvê-lo não é. O desenvolvimento tomar tempo e recursos de voluntários. Sua contribuição pode ajudar a tornar o aplicativo melhor e a manter o serviço rodando por mais tempo.", + "@aboutDonateText": {}, + "enterCharacters": "Por favor, utilize entre {min} e {max} caracteres", + "@enterCharacters": { + "description": "Error message when the user hasn't entered the correct number of characters in a form", + "type": "text", + "placeholders": { + "min": { + "type": "String" + }, + "max": { + "type": "String" + } + } + }, + "enterMinCharacters": "Por favor, utilize pelo menos {min} caracteres", + "@enterMinCharacters": { + "description": "Error message when the user hasn't entered the minimum amount characters in a form", + "type": "text", + "placeholders": { + "min": { + "type": "String" + } + } + }, + "gallery": "Galeria", + "@gallery": {}, + "alsoKnownAs": "Também conhecido como:{aliases}", + "@alsoKnownAs": { + "placeholders": { + "aliases": { + "type": "String" + } + }, + "description": "List of alternative names for an exercise" + }, + "recentlyUsedIngredients": "Ingredientes adicionados recentemente", + "@recentlyUsedIngredients": { + "description": "A message when a user adds a new ingredient to a meal." + }, + "addImage": "Adicionar imagem", + "@addImage": {}, + "scanBarcode": "Escaneie o código de barras", + "@scanBarcode": { + "description": "Label for scan barcode button" + }, + "dataCopied": "Dados copiados para o novo registro", + "@dataCopied": { + "description": "Snackbar message to show on copying data to a new log entry" + }, + "appUpdateContent": "Esta versão do aplicativo não é compatível com o servidor, por favor atualize o aplicativo.", + "@appUpdateContent": {}, + "productFound": "Produto encontrado", + "@productFound": { + "description": "Header label for dialog when product is found with barcode" + }, + "appUpdateTitle": "Atualização necessária", + "@appUpdateTitle": {}, + "takePicture": "Tire uma foto", + "@takePicture": {}, + "selectIngredient": "Por favor, selecione um ingrediente", + "@selectIngredient": { + "description": "Error message when the user hasn't selected an ingredient from the autocompleter" + }, + "selectImage": "Por favor, selecione uma imagem", + "@selectImage": { + "description": "Label and error message when the user hasn't selected an image to save" + }, + "optionsLabel": "Opções", + "@optionsLabel": { + "description": "Label for the popup with general app options" + }, + "productNotFound": "Produto não encontrado", + "@productNotFound": { + "description": "Header label for dialog when product is not found with barcode" + }, + "variations": "Variações", + "@variations": { + "description": "Variations of one exercise (e.g. benchpress and benchpress narrow)" + }, + "verifiedEmail": "Email verificado", + "@verifiedEmail": {}, + "chooseFromLibrary": "Escolher na galeria", + "@chooseFromLibrary": {}, + "unVerifiedEmail": "Email não verificado", + "@unVerifiedEmail": {}, + "add_exercise_image_license": "As imagens devem ser compatíveis com a licença CC BY SA. Em caso de dúvida, faça upload apenas de fotos que você mesmo tenha tirado.", + "@add_exercise_image_license": {}, + "next": "Próximo", + "@next": {}, + "settingsCacheTitle": "Cache", + "@settingsCacheTitle": {}, + "settingsExerciseCacheDescription": "Cache do exercício", + "@settingsExerciseCacheDescription": {}, + "settingsCacheDeletedSnackbar": "Cache limpa com sucesso", + "@settingsCacheDeletedSnackbar": {}, + "translateExercise": "Traduza este exercício agora", + "@translateExercise": {}, + "contributeExerciseWarning": "Você só pode contribuir com exercícios se sua conta tiver mais de {days} dias e se você tiver verificado seu e-mail", + "@contributeExerciseWarning": { + "description": "Number of days before which a person can add exercise", + "placeholders": { + "days": { + "type": "String", + "example": "14" + } + } + }, + "whatVariationsExist": "Quais variações deste exercício existem, se houver?", + "@whatVariationsExist": {}, + "previous": "Anterior", + "@previous": {}, + "addExercise": "Adicionar exercício", + "@addExercise": {}, + "verifiedEmailInfo": "Um e-mail foi enviado para {email}", + "@verifiedEmailInfo": { + "placeholders": { + "email": { + "type": "String" + } + } + }, + "verifiedEmailReason": "Você precisa verificar seu e-mail para contribuir com exercícios", + "@verifiedEmailReason": {}, + "alternativeNames": "Nomes alternativos", + "@alternativeNames": {}, + "baseData": "Fundamentos em inglês", + "@baseData": { + "description": "The base data for an exercise such as category, trained muscles, etc." + }, + "aboutPageTitle": "Sobre o nós & Suporte", + "@aboutPageTitle": {}, + "productFoundDescription": "O código de barras corresponde a este produto: {productName}. Deseja continuar?", + "@productFoundDescription": { + "description": "Dialog info when product is found with barcode", + "type": "text", + "placeholders": { + "productName": { + "type": "String" + } + } + }, + "productNotFoundDescription": "O produto com o código de barras escaneado {barcode} não foi encontrado no banco de dados da wger", + "@productNotFoundDescription": { + "description": "Dialog info when product is not found with barcode", + "type": "text", + "placeholders": { + "barcode": { + "type": "String" + } + } + }, + "contributeExercise": "Contribuir com um exercício", + "@contributeExercise": {}, + "oneNamePerLine": "Um nome por linha", + "@oneNamePerLine": {}, + "settingsTitle": "Configurações", + "@settingsTitle": {}, + "onlyLogging": "Apenas acompanhe calorias", + "@onlyLogging": {}, + "ingredientLogged": "Ingrediente registrado no diário", + "@ingredientLogged": {}, + "noIngredientsDefined": "Nenhum ingrediente definido ainda", + "@noIngredientsDefined": {}, + "bench": "Banco", + "@bench": { + "description": "Generated entry for translation for server strings" + }, + "goalFiber": "Meta de fibras", + "@goalFiber": {}, + "overallChangeWeight": "Mudança geral", + "@overallChangeWeight": { + "description": "Overall change in weight, added for localization" + }, + "goalTypeMeals": "De refeições", + "@goalTypeMeals": { + "description": "added for localization of Class GoalType's filed meals" + }, + "goalTypeBasic": "Básico", + "@goalTypeBasic": { + "description": "added for localization of Class GoalType's filed basic" + }, + "goalTypeAdvanced": "Avançado", + "@goalTypeAdvanced": { + "description": "added for localization of Class GoalType's filed advanced" + }, + "indicatorRaw": "bruto", + "@indicatorRaw": { + "description": "added for localization of Class Indicator's field text" + }, + "indicatorAvg": "média", + "@indicatorAvg": { + "description": "added for localization of Class Indicator's field text" + }, + "seconds": "Segundos", + "@seconds": { + "description": "Generated entry for translation for server strings" + }, + "textPromptTitle": "Pronto para iniciar?", + "@textPromptTitle": {}, + "textPromptSubheading": "Aperte o botão de ação para começar", + "@textPromptSubheading": {}, + "chest": "Peito", + "@chest": { + "description": "Generated entry for translation for server strings" + }, + "max_reps": "Repetições Máximas", + "@max_reps": { + "description": "Generated entry for translation for server strings" + }, + "pull_up_bar": "Barra de Pull-up", + "@pull_up_bar": { + "description": "Generated entry for translation for server strings" + }, + "quads": "Quadríceps", + "@quads": { + "description": "Generated entry for translation for server strings" + }, + "goalFat": "Meta de gordura", + "@goalFat": {}, + "body_weight": "Peso Corporal", + "@body_weight": { + "description": "Generated entry for translation for server strings" + }, + "kilometers": "Quilômetros", + "@kilometers": { + "description": "Generated entry for translation for server strings" + }, + "kilometers_per_hour": "Quilômetros por hora", + "@kilometers_per_hour": { + "description": "Generated entry for translation for server strings" + }, + "miles_per_hour": "Milhas por hora", + "@miles_per_hour": { + "description": "Generated entry for translation for server strings" + }, + "minutes": "Minutos", + "@minutes": { + "description": "Generated entry for translation for server strings" + }, + "sz_bar": "Barra Curvada", + "@sz_bar": { + "description": "Generated entry for translation for server strings" + }, + "goalProtein": "Meta de proteína", + "@goalProtein": {}, + "goalEnergy": "Meta energética", + "@goalEnergy": {}, + "today": "Hoje", + "@today": {}, + "arms": "Braços", + "@arms": { + "description": "Generated entry for translation for server strings" + }, + "calves": "Panturrilha", + "@calves": { + "description": "Generated entry for translation for server strings" + }, + "triceps": "Tríceps", + "@triceps": { + "description": "Generated entry for translation for server strings" + }, + "goalCarbohydrates": "Meta de carbohidratos", + "@goalCarbohydrates": {}, + "onlyLoggingHelpText": "Marque a caixa se você apenas quiser registrar suas calorias e não quer configurar um plano nutricional detalhado com refeições específicas", + "@onlyLoggingHelpText": {}, + "kcalValue": "{value} kcal", + "@kcalValue": { + "description": "A value in kcal, e.g. 500 kcal", + "type": "text", + "placeholders": { + "value": { + "type": "String" + } + } + }, + "percentValue": "{value} %", + "@percentValue": { + "description": "A value in percent, e.g. 10 %", + "type": "text", + "placeholders": { + "value": { + "type": "String" + } + } + }, + "goalMacro": "Macro Objetivos", + "@goalMacro": { + "description": "The goal for macronutrients" + }, + "selectMealToLog": "Selecione uma refeição para registrar no diário", + "@selectMealToLog": {}, + "loggedToday": "Registrado hoje", + "@loggedToday": {}, + "surplus": "excedente", + "@surplus": { + "description": "Caloric surplus (either planned or unplanned)" + }, + "deficit": "déficit", + "@deficit": { + "description": "Caloric deficit (either planned or unplanned)" + }, + "gValue": "{value} g", + "@gValue": { + "description": "A value in grams, e.g. 5 g", + "type": "text", + "placeholders": { + "value": { + "type": "String" + } + } + }, + "abs": "Abdômen", + "@abs": { + "description": "Generated entry for translation for server strings" + }, + "back": "Costas", + "@back": { + "description": "Generated entry for translation for server strings" + }, + "barbell": "Barra", + "@barbell": { + "description": "Generated entry for translation for server strings" + }, + "cardio": "Cardio", + "@cardio": { + "description": "Generated entry for translation for server strings" + }, + "dumbbell": "Haltere", + "@dumbbell": { + "description": "Generated entry for translation for server strings" + }, + "glutes": "Glúteos", + "@glutes": { + "description": "Generated entry for translation for server strings" + }, + "gym_mat": "Tapete", + "@gym_mat": { + "description": "Generated entry for translation for server strings" + }, + "hamstrings": "Tendões", + "@hamstrings": { + "description": "Generated entry for translation for server strings" + }, + "kettlebell": "Kettlebell", + "@kettlebell": { + "description": "Generated entry for translation for server strings" + }, + "lats": "Dorsal", + "@lats": { + "description": "Generated entry for translation for server strings" + }, + "legs": "Pernas", + "@legs": { + "description": "Generated entry for translation for server strings" + }, + "lower_back": "Lombar", + "@lower_back": { + "description": "Generated entry for translation for server strings" + }, + "plates": "Anilhas", + "@plates": { + "description": "Generated entry for translation for server strings" + }, + "repetitions": "Repetições", + "@repetitions": { + "description": "Generated entry for translation for server strings" + }, + "shoulders": "Ombros", + "@shoulders": { + "description": "Generated entry for translation for server strings" + }, + "until_failure": "Até a falha", + "@until_failure": { + "description": "Generated entry for translation for server strings" + }, + "kg": "kg", + "@kg": { + "description": "Generated entry for translation for server strings" + }, + "none__bodyweight_exercise_": "nenhum (exercício com peso corporal)", + "@none__bodyweight_exercise_": { + "description": "Generated entry for translation for server strings" + }, + "lb": "lb", + "@lb": { + "description": "Generated entry for translation for server strings" + }, + "chartAllTimeTitle": "{name} total", + "@chartAllTimeTitle": { + "description": "All-time chart of 'name' (e.g. 'weight', 'body fat' etc.)", + "type": "text", + "placeholders": { + "name": { + "type": "String" + } + } + }, + "chart30DaysTitle": "{name} últimos 30 dias", + "@chart30DaysTitle": { + "description": "last 30 days chart of 'name' (e.g. 'weight', 'body fat' etc.)", + "type": "text", + "placeholders": { + "name": { + "type": "String" + } + } + }, + "chartDuringPlanTitle": "{chartName} durante plano nutricional {planName}", + "@chartDuringPlanTitle": { + "description": "chart of 'chartName' (e.g. 'weight', 'body fat' etc.) logged during plan", + "type": "text", + "placeholders": { + "chartName": { + "type": "String" + }, + "planName": { + "type": "String" + } + } + }, + "settingsIngredientCacheDescription": "Cache de Ingredientes", + "@settingsIngredientCacheDescription": {}, + "cacheWarning": "Devido ao cache pode demorar algum tempo até que mudanças estejam visíveis na aplicação.", + "@cacheWarning": {}, + "swiss_ball": "Bola Suíça", + "@swiss_ball": { + "description": "Generated entry for translation for server strings" + }, + "log": "Registro", + "@log": { + "description": "Log a specific meal (imperative form)" + }, + "done": "Feito", + "@done": {}, + "incline_bench": "Banco inclinado", + "@incline_bench": { + "description": "Generated entry for translation for server strings" + }, + "miles": "Milhas", + "@miles": { + "description": "Generated entry for translation for server strings" + }, + "biceps": "Bíceps", + "@biceps": { + "description": "Generated entry for translation for server strings" + }, + "useApiToken": "Usar Token API", + "@useApiToken": {}, + "useUsernameAndPassword": "Usar usuário e senha", + "@useUsernameAndPassword": {}, + "apiToken": "Token API", + "@apiToken": {}, + "invalidApiToken": "Por favor, entre com a API key válida", + "@invalidApiToken": { + "description": "Error message when the user enters an invalid API key" + }, + "apiTokenValidChars": "A chave API deve ter apenas letras a-f, números 0-9 e ter exatamente 40 caracteres", + "@apiTokenValidChars": { + "description": "Error message when the user tries to input a API key with forbidden characters" + }, + "routines": "Rotinas", + "@routines": {}, + "newRoutine": "Nova rotina", + "@newRoutine": {}, + "noRoutines": "Não tens rotinas", + "@noRoutines": {}, + "restTime": "Tempo de descanso", + "@restTime": {}, + "sets": "Conjuntos", + "@sets": { + "description": "The number of sets to be done for one exercise" + }, + "exerciseNr": "Exercício {nr}", + "@exerciseNr": { + "description": "Header in form indicating the number of the current exercise. Can also be translated as something like 'Set Nr. xy'.", + "type": "text", + "placeholders": { + "nr": { + "type": "String" + } + } + }, + "supersetNr": "Superset {nr}", + "@supersetNr": { + "description": "Header in form indicating the number of the current exercise. Can also be translated as something like 'Superset Nr. xy'.", + "type": "text", + "placeholders": { + "nr": { + "type": "String" + } + } + }, + "restDay": "Dia de descanso", + "@restDay": {}, + "isRestDay": "É dia de descanso", + "@isRestDay": {}, + "isRestDayHelp": "Por favor, note que todos os conjuntos e exercícios serão removidos quando marcar um dia como um dia de descanso.", + "@isRestDayHelp": {}, + "needsLogsToAdvance": "Precisa de logs para avançar", + "@needsLogsToAdvance": {}, + "selectAvailablePlates": "Selecione os pesos disponíveis", + "@selectAvailablePlates": {}, + "barWeight": "Peso da barra", + "@barWeight": {}, + "useColors": "Use cores", + "@useColors": {}, + "needsLogsToAdvanceHelp": "Selecione se deseja que a rotina de treino avance para o próximo dia agendado somente se você cadastrou o dia de treino", + "@needsLogsToAdvanceHelp": {}, + "routineDays": "Dias de treino", + "@routineDays": {}, + "resultingRoutine": "Treino resultante", + "@resultingRoutine": {}, + "yourCurrentNutritionPlanHasNoMealsDefinedYet": "Seu plano nutricional não tem refeições definidas", + "@yourCurrentNutritionPlanHasNoMealsDefinedYet": { + "description": "Message shown when a nutrition plan doesn't have any meals" + }, + "toAddMealsToThePlanGoToNutritionalPlanDetails": "Para adicionar refeições para o planejamento, vá para Detalhes de Plano Nutricional", + "@toAddMealsToThePlanGoToNutritionalPlanDetails": { + "description": "Message shown to guide users to the nutritional plan details page to add meals" + }, + "errorInfoDescription": "Algo de errado aconteceu. Você pode nos ajudar a concertar esse problema reportando o problema no Github", + "@errorInfoDescription": {}, + "errorInfoDescription2": "Você pode continuar usando o applicativo, mas algumas funcionalidades não estarão disponíveis.", + "@errorInfoDescription2": {}, + "errorViewDetails": "Detalhes técnicos", + "@errorViewDetails": {}, + "errorCouldNotConnectToServer": "Não foi possível conectar ao servidor", + "@errorCouldNotConnectToServer": {}, + "errorCouldNotConnectToServerDetails": "O aplicativo não conseguiu conectar ao servidor. Verifique sua conexão de internet ou a URL do servidor e tente novamente. Se o problema persistir, contact o administrador.", + "@errorCouldNotConnectToServerDetails": {}, + "copyToClipboard": "Copiar ao clipboard", + "@copyToClipboard": {}, + "min": "Min", + "@min": {}, + "max": "Max", + "@max": {}, + "aboutWhySupportTitle": "Open Source & free to use ❤️", + "@aboutWhySupportTitle": {}, + "aboutContributeTitle": "Contribua", + "@aboutContributeTitle": {}, + "aboutContributeText": "Todos os tipos de contribuidores são bem vindos. Se você é um desenvolvedor, tradutor ou alguém apaixonado pelo fitness, toda ajuda é bem vinda!", + "@aboutContributeText": {}, + "aboutBugsListTitle": "Reportar um problema ou sugerir uma funcionalidade", + "@aboutBugsListTitle": {}, + "aboutTranslationListTitle": "Traduzir a aplicação", + "@aboutTranslationListTitle": {}, + "aboutSourceListTitle": "Ver o código fonte", + "@aboutSourceListTitle": {}, + "aboutJoinCommunityTitle": "Entre para a comunidade", + "@aboutJoinCommunityTitle": {}, + "aboutDiscordTitle": "Discord", + "@aboutDiscordTitle": {}, + "others": "Outros", + "@others": {}, + "fitInWeek": "Treino na semana", + "@fitInWeek": {}, + "fitInWeekHelp": "Se ligado, os dias vão se repetir semanalmente, caso contrário os dias seguirão sequencialmente se considerar o começo de uma nova semana.", + "@fitInWeekHelp": {}, + "addSuperset": "Adicionar superset", + "@addSuperset": {}, + "setHasProgression": "Treino tem prograssão", + "@setHasProgression": {}, + "setHasProgressionWarning": "Observe que, no momento, não é possível editar todas as configurações de um conjunto no aplicativo móvel nem configurar a progressão automática. Por enquanto, use o aplicativo web.", + "@setHasProgressionWarning": {}, + "setHasNoExercises": "Este treino ainda não tem exercícios!", + "@setHasNoExercises": {}, + "simpleMode": "Modo simples", + "@simpleMode": {}, + "simpleModeHelp": "Esconder informações avançadas enquanto estiver editando exercicio", + "@simpleModeHelp": {}, + "progressionRules": "Este exercício tem regras de progressão e não pode ser editado no aplicativo móvel. Use o aplicativo web para editá-lo.", + "@progressionRules": {}, + "resistance_band": "Resistance band", + "@resistance_band": { + "description": "Generated entry for translation for server strings" + }, + "themeMode": "Tema", + "@themeMode": {}, + "darkMode": "Sempre modo escuro", + "@darkMode": {}, + "lightMode": "Sempre modo claro", + "@lightMode": {}, + "systemMode": "Configurações do sistema", + "@systemMode": {} } From b28e958d5424db53d9f043073c6f0c2aba71cadc Mon Sep 17 00:00:00 2001 From: clafalco Date: Fri, 22 Aug 2025 14:18:08 +0200 Subject: [PATCH 62/89] Translated using Weblate (Italian) Currently translated at 88.7% (277 of 312 strings) Translation: wger Workout Manager/Mobile App Translate-URL: https://hosted.weblate.org/projects/wger/mobile/it/ --- lib/l10n/app_it.arb | 1976 ++++++++++++++++++++++--------------------- 1 file changed, 993 insertions(+), 983 deletions(-) diff --git a/lib/l10n/app_it.arb b/lib/l10n/app_it.arb index 83dc1d59..f2a44e49 100644 --- a/lib/l10n/app_it.arb +++ b/lib/l10n/app_it.arb @@ -1,986 +1,996 @@ { - "anErrorOccurred": "È avvenuto un errore!", - "@anErrorOccurred": {}, - "selectIngredient": "Seleziona un ingrediente", - "@selectIngredient": { - "description": "Error message when the user hasn't selected an ingredient from the autocompleter" - }, - "enterValidNumber": "Inserisci un numero valido", - "@enterValidNumber": { - "description": "Error message when the user has submitted an invalid number (e.g. '3,.,.,.')" - }, - "enterValue": "Inserisci un valore", - "@enterValue": { - "description": "Error message when the user hasn't entered a value on a required field" - }, - "goToToday": "Seleziona giorno", - "@goToToday": { - "description": "Label on button to jump back to 'today' in the calendar widget" - }, - "calendar": "Calendario", - "@calendar": {}, - "toggleDetails": "Scegli dettagli", - "@toggleDetails": { - "description": "Switch to toggle detail / overview" - }, - "newNutritionalPlan": "Nuovo piano nutrizionale", - "@newNutritionalPlan": {}, - "confirmDelete": "Sei sicuro/a di voler cancellare '{toDelete}'?", - "@confirmDelete": { - "description": "Confirmation text before the user deletes an object", - "type": "text", - "placeholders": { - "toDelete": { - "type": "String" - } - } - }, - "delete": "Elimina", - "@delete": {}, - "loadingText": "Caricamento…", - "@loadingText": { - "description": "Text to show when entries are being loaded in the background: Loading..." - }, - "edit": "Modifica", - "@edit": {}, - "noWeightEntries": "Non hai nessun dato sul peso", - "@noWeightEntries": { - "description": "Message shown when the user has no logged weight entries" - }, - "newEntry": "Nuovo dato", - "@newEntry": { - "description": "Title when adding a new entry such as a weight or log entry" - }, - "unit": "Unità", - "@unit": { - "description": "The unit used for a repetition (kg, time, etc.)" - }, - "amount": "Quatità", - "@amount": { - "description": "The amount (e.g. in grams) of an ingredient in a meal" - }, - "sodium": "Sodio", - "@sodium": {}, - "fiber": "Fibre", - "@fiber": {}, - "saturatedFat": "Grassi saturi", - "@saturatedFat": {}, - "fat": "Grassi", - "@fat": {}, - "sugars": "Zuccheri", - "@sugars": {}, - "carbohydrates": "Carboidrati", - "@carbohydrates": {}, - "protein": "Proteine", - "@protein": {}, - "g": "g", - "@g": { - "description": "Abbreviation for gram" - }, - "kJ": "kJ", - "@kJ": { - "description": "Energy in a meal in kilo joules, kJ" - }, - "kcal": "kcal", - "@kcal": { - "description": "Energy in a meal in kilocalories, kcal" - }, - "energy": "Energia", - "@energy": { - "description": "Energy in a meal, ingredient etc. e.g. in kJ" - }, - "ingredient": "Ingrediente", - "@ingredient": {}, - "timeEnd": "Ora di fine", - "@timeEnd": { - "description": "The end time of a workout" - }, - "timeStart": "Ora di inizio", - "@timeStart": { - "description": "The starting time of a workout" - }, - "time": "Orario", - "@time": { - "description": "The time of a meal or workout" - }, - "date": "Data", - "@date": { - "description": "The date of a workout log or body weight entry" - }, - "weight": "Peso", - "@weight": { - "description": "The weight of a workout log or body weight entry" - }, - "noNutritionalPlans": "Non hai nessun piano nutrizionale", - "@noNutritionalPlans": { - "description": "Message shown when the user has no nutritional plans" - }, - "nutritionalPlans": "Piani nutrizionali", - "@nutritionalPlans": {}, - "nutritionalDiary": "Diario nutrizionale", - "@nutritionalDiary": {}, - "nutritionalPlan": "Piano nutrizionale", - "@nutritionalPlan": {}, - "addIngredient": "Aggiungi ingrediente", - "@addIngredient": {}, - "mealLogged": "Pasto registrato nel diario", - "@mealLogged": {}, - "addMeal": "Aggiungi pasto", - "@addMeal": {}, - "add": "Aggiungi", - "@add": {}, - "cancel": "Cancella", - "@cancel": {}, - "save": "Salva", - "@save": {}, - "description": "Descrizione", - "@description": {}, - "logHelpEntriesUnits": "Da notare che solo i dati con l'unità del peso (kg o lb) e le ripetizioni sono mostrate. Altre combinazioni come tempo o «a cedimento» sono ignorate.", - "@logHelpEntriesUnits": {}, - "logHelpEntries": "Se in una giornata c'è più di esercizio con lo stesso numero di ripetizioni, ma con pesi differenti, solo l'esercizio con il peso più alto viene mostrato nel diagramma.", - "@logHelpEntries": {}, - "gymMode": "Modalità allenamento", - "@gymMode": { - "description": "Label when starting the gym mode" - }, - "newSet": "Nuova serie", - "@newSet": { - "description": "Header when adding a new set to a workout day" - }, - "newDay": "Nuovo giorno", - "@newDay": {}, - "workoutSession": "Sessione di allenamento", - "@workoutSession": { - "description": "A (logged) workout session" - }, - "notes": "Note", - "@notes": { - "description": "Personal notes, e.g. for a workout session" - }, - "impression": "Sensazione", - "@impression": { - "description": "General impression (e.g. for a workout session) such as good, bad, etc." - }, - "comment": "Commento", - "@comment": { - "description": "Comment, additional information" - }, - "rir": "RiR", - "@rir": { - "description": "Shorthand for Repetitions In Reserve" - }, - "repetitions": "Ripetizioni", - "@repetitions": { - "description": "Repetitions for an exercise set" - }, - "addExercise": "Aggiungi esercizi", - "@addExercise": {}, - "exercise": "Esercizio", - "@exercise": { - "description": "An exercise for a workout" - }, - "successfullyDeleted": "Cancellato", - "@successfullyDeleted": { - "description": "Message when an item was successfully deleted" - }, - "labelDashboard": "Pannello di controllo", - "@labelDashboard": { - "description": "Title for screen dashboard" - }, - "labelWorkoutPlan": "Piano di allenamento", - "@labelWorkoutPlan": { - "description": "Title for screen workout plan" - }, - "loginInstead": "Hai già un account? Registrati ora", - "@loginInstead": {}, - "registerInstead": "Non hai un account? Registrati ora", - "@registerInstead": {}, - "reset": "Rerimposta", - "@reset": { - "description": "Button text allowing the user to reset the entered values to the default" - }, - "customServerHint": "Inserisci l'indirizzo del tuo server personale o quello predefinito verrà utilizzato", - "@customServerHint": { - "description": "Hint text for the form where the users can enter their own wger instance" - }, - "customServerUrl": "URL istanza wger", - "@customServerUrl": { - "description": "Label in the form where the users can enter their own wger instance" - }, - "invalidUsername": "Inserisci un nome utente valido", - "@invalidUsername": { - "description": "Error message when the user enters an invalid username" - }, - "username": "Nome utente", - "@username": {}, - "email": "Indirizzo e-mail", - "@email": {}, - "invalidEmail": "Inserisci un indirizzo e-mail valido", - "@invalidEmail": { - "description": "Error message when the user enters an invalid email" - }, - "confirmPassword": "Conferma password", - "@confirmPassword": {}, - "password": "Password", - "@password": {}, - "passwordTooShort": "La password è troppo corta", - "@passwordTooShort": { - "description": "Error message when the user a password that is too short" - }, - "passwordsDontMatch": "Le passwords non coincidono", - "@passwordsDontMatch": { - "description": "Error message when the user enters two different passwords during registration" - }, - "invalidUrl": "Inserisci un URL valido", - "@invalidUrl": { - "description": "Error message when the user enters an invalid URL, e.g. in the login form" - }, - "useCustomServer": "Usa un server personale", - "@useCustomServer": { - "description": "Toggle button allowing users to switch between the default and a custom wger server" - }, - "useDefaultServer": "Usa il server predefinito", - "@useDefaultServer": { - "description": "Toggle button allowing users to switch between the default and a custom wger server" - }, - "register": "Registrati", - "@register": { - "description": "Text for registration button" - }, - "login": "Entra", - "@login": { - "description": "Text for login button" - }, - "nrOfSets": "Serie per esercizio: {nrOfSets}", - "@nrOfSets": { - "description": "Label shown on the slider where the user selects the nr of sets", - "type": "text", - "placeholders": { - "nrOfSets": { - "type": "String" - } - } - }, - "enterCharacters": "Inserisci una stringa tra {min} e {max} caratteri", - "@enterCharacters": { - "description": "Error message when the user hasn't entered the correct number of characters in a form", - "type": "text", - "placeholders": { - "min": { - "type": "String" - }, - "max": { - "type": "String" - } - } - }, - "selectExercise": "Prego, seleziona un esercizio", - "@selectExercise": { - "description": "Error message when the user hasn't selected an exercise in the form" - }, - "todaysWorkout": "Allenamento di oggi", - "@todaysWorkout": {}, - "selectExercises": "Se vuoi fare un circuito (super set), puoi cercare e aggiungere diversi esercizi. Questi verranno collegati come circuito", - "@selectExercises": {}, - "sameRepetitions": "Se fai le stesse ripetizioni e peso per tutte le serie puoi compilare una sola riga. Per esempio per 4 serie inserisci semplicemente 10 per le ripetizioni, automaticamente diventerà una 4x10.", - "@sameRepetitions": {}, - "setNr": "Serie {nr}", - "@setNr": { - "description": "Header in form indicating the number of the current set. Can also be translated as something like 'Set Nr. xy'.", - "type": "text", - "placeholders": { - "nr": { - "type": "String" - } - } - }, - "dayDescriptionHelp": "Una descrizione di ciò che è stato fatto. (p.e. «allenamento gambe») o quale parte del corpo sono state allenate (p.e. «petto e spalle»)", - "@dayDescriptionHelp": {}, - "set": "Serie", - "@set": { - "description": "A set in a workout plan" - }, - "repetitionUnit": "Unità ripetizioni", - "@repetitionUnit": {}, - "weightUnit": "Unità peso", - "@weightUnit": {}, - "reps": "Ripetizioni", - "@reps": { - "description": "Shorthand for repetitions, used when space constraints are tighter" - }, - "addSet": "Aggiungi serie", - "@addSet": { - "description": "Label for the button that adds a set (to a workout day)" - }, - "start": "Inizia", - "@start": { - "description": "Label on button to start the gym mode (i.e., an imperative)" - }, - "successfullySaved": "Salvato", - "@successfullySaved": { - "description": "Message when an item was successfully saved" - }, - "labelWorkoutLogs": "Registri allenamenti", - "@labelWorkoutLogs": { - "description": "(Workout) logs" - }, - "logout": "Disconnetti", - "@logout": { - "description": "Text for logout button" - }, - "aboutDescription": "Grazie per esserti registrato/a su wger! wger è un progetto collaborativo con codice aperto, creato da entusiasti del fitness in tutto il mondo.", - "@aboutDescription": { - "description": "Text in the about dialog" - }, - "logMeal": "Registra questo pasto nel diario", - "@logMeal": {}, - "category": "Categoria", - "@category": { - "description": "Category for an exercise, ingredient, etc." - }, - "equipment": "Equipaggiamento", - "@equipment": { - "description": "Equipment needed to perform an exercise" - }, - "musclesSecondary": "Muscoli secondari", - "@musclesSecondary": { - "description": "secondary muscles trained by an exercise" - }, - "muscles": "Muscoli", - "@muscles": { - "description": "(main) muscles trained by an exercise" - }, - "addImage": "Aggiungi un'immagine", - "@addImage": {}, - "gallery": "Galleria", - "@gallery": {}, - "chooseFromLibrary": "Scegli dalla raccolta", - "@chooseFromLibrary": {}, - "takePicture": "Scatta una foto", - "@takePicture": {}, - "selectImage": "Si prega di selezionare un'immagine", - "@selectImage": { - "description": "Label and error message when the user hasn't selected an image to save" - }, - "name": "Nome", - "@name": { - "description": "Name for a workout or nutritional plan" - }, - "optionsLabel": "Opzioni", - "@optionsLabel": { - "description": "Label for the popup with general app options" - }, - "goToDetailPage": "Vai alla pagina dettagli", - "@goToDetailPage": {}, - "jumpTo": "Vai a", - "@jumpTo": { - "description": "Imperative. Label used in popup allowing the user to jump to a specific exercise while in the gym mode" - }, - "pause": "Pausa", - "@pause": { - "description": "Noun, not an imperative! Label used for the pause when using the gym mode" - }, - "searchExercise": "Cerca esercizio da aggiungere", - "@searchExercise": { - "description": "Label on set form. Selected exercises are added to the set" - }, - "labelBottomNavWorkout": "Allenamento", - "@labelBottomNavWorkout": { - "description": "Label used in bottom navigation, use a short word" - }, - "setUnitsAndRir": "Scegli le unità e le RiR", - "@setUnitsAndRir": { - "description": "Label shown on the slider where the user can toggle showing units and RiR", - "type": "text" - }, - "rirNotUsed": "RiR (Repetitions in Reserve) non utilizzato", - "@rirNotUsed": { - "description": "Label used in RiR slider when the RiR value is not used/saved for the current setting or log" - }, - "labelBottomNavNutrition": "Nutrizione", - "@labelBottomNavNutrition": { - "description": "Label used in bottom navigation, use a short word" - }, - "usernameValidChars": "Un nome utente può contenere solo lettere, cifre e i caratteri @, +, ., - e _", - "@usernameValidChars": { - "description": "Error message when the user tries to register a username with forbidden characters" - }, - "total": "Totale", - "@total": { - "description": "Label used for total sums of e.g. calories or similar" - }, - "appUpdateTitle": "Aggiornamento necessario", - "@appUpdateTitle": {}, - "appUpdateContent": "Questa versione dell'applicazione non è compatibile con il server, per favore aggiorna la tua applicazione.", - "@appUpdateContent": {}, - "dataCopied": "Dati copiati nella nuova voce", - "@dataCopied": { - "description": "Snackbar message to show on copying data to a new log entry" - }, - "proteinShort": "P", - "@proteinShort": { - "description": "The first letter or short name of the word 'Protein', used in overviews" - }, - "carbohydratesShort": "C", - "@carbohydratesShort": { - "description": "The first letter or short name of the word 'Carbohydrates', used in overviews" - }, - "percentEnergy": "Percentuale di energia", - "@percentEnergy": {}, - "fatShort": "Gr", - "@fatShort": { - "description": "The first letter or short name of the word 'Fat', used in overviews" - }, - "logged": "Registrato", - "@logged": { - "description": "Header for the column of 'logged' nutritional values, i.e. what was eaten" - }, - "difference": "Differenza", - "@difference": {}, - "gPerBodyKg": "g per kg di corpo", - "@gPerBodyKg": { - "description": "Label used for total sums of e.g. calories or similar in grams per Kg of body weight" - }, - "timeStartAhead": "L'ora di inizio non può essere più avanti dell'ora di fine", - "@timeStartAhead": {}, - "value": "Valore", - "@value": { - "description": "The value of a measurement entry" - }, - "measurements": "Misure", - "@measurements": { - "description": "Categories for the measurements such as biceps size, body fat, etc." - }, - "measurementCategoriesHelpText": "Categoria di misura, come «bicipiti» o «grasso corporeo»", - "@measurementCategoriesHelpText": {}, - "measurementEntriesHelpText": "L'unità usata per misurare la categoria come «cm» o «%»", - "@measurementEntriesHelpText": {}, - "energyShort": "E", - "@energyShort": { - "description": "The first letter or short name of the word 'Energy', used in overviews" - }, - "macronutrients": "Macronutrienti", - "@macronutrients": {}, - "planned": "Pianificato", - "@planned": { - "description": "Header for the column of 'planned' nutritional values, i.e. what should be eaten" - }, - "measurement": "Misura", - "@measurement": {}, - "recentlyUsedIngredients": "Ingredienti aggiunti di recente", - "@recentlyUsedIngredients": { - "description": "A message when a user adds a new ingredient to a meal." - }, - "plateCalculator": "Piastre", - "@plateCalculator": { - "description": "Label used for the plate calculator in the gym mode" - }, - "plateCalculatorNotDivisible": "Non è possibile raggiungere il peso con le piastre disponibili", - "@plateCalculatorNotDivisible": { - "description": "Error message when the current weight is not reachable with plates (e.g. 33.1 kg)" - }, - "productNotFoundDescription": "Il prodotto con il codice a barre scansionato {barcode} non è stato trovato nel database wger", - "@productNotFoundDescription": { - "description": "Dialog info when product is not found with barcode", - "type": "text", - "placeholders": { - "barcode": { - "type": "String" - } - } - }, - "productNotFound": "Prodotto non trovato", - "@productNotFound": { - "description": "Header label for dialog when product is not found with barcode" - }, - "scanBarcode": "Scansiona il codice a barre", - "@scanBarcode": { - "description": "Label for scan barcode button" - }, - "weekAverage": "Media di 7 giorni", - "@weekAverage": { - "description": "Header for the column of '7 day average' nutritional values, i.e. what was logged last week" - }, - "productFound": "Prodotto trovato", - "@productFound": { - "description": "Header label for dialog when product is found with barcode" - }, - "productFoundDescription": "Il codice a barre corrisponde a questo prodotto: {productName}. Vuoi continuare?", - "@productFoundDescription": { - "description": "Dialog info when product is found with barcode", - "type": "text", - "placeholders": { - "productName": { - "type": "String" - } - } - }, - "close": "Chiudi", - "@close": { - "description": "Translation for close" - }, - "logIngredient": "Salva l'ingrediente nel diario nutrizionale", - "@logIngredient": {}, - "searchIngredient": "Cerca ingrediente", - "@searchIngredient": { - "description": "Label on ingredient search form" - }, - "userProfile": "Il tuo profilo", - "@userProfile": {}, - "exerciseList": "Lista esercizi", - "@exerciseList": {}, - "exercises": "Esercizi", - "@exercises": { - "description": "Multiple exercises for a workout" - }, - "exerciseName": "Nome Esercizio", - "@exerciseName": { - "description": "Label for the name of a workout exercise" - }, - "previous": "Precedente", - "@previous": {}, - "next": "Successivo", - "@next": {}, - "gym_mat": "Materassino da palestra", - "@gym_mat": { - "description": "Generated entry for translation for server strings" - }, - "verifiedEmailInfo": "Un'email di verifica è stata inviata a {email}", - "@verifiedEmailInfo": { - "placeholders": { - "email": { - "type": "String" - } - } - }, - "oneNamePerLine": "Un nome per linea", - "@oneNamePerLine": {}, - "textPromptTitle": "Pronto a iniziare?", - "@textPromptTitle": {}, - "moreMeasurementEntries": "Aggiungi una nuova misura", - "@moreMeasurementEntries": { - "description": "Message shown when the user wants to add new measurement" - }, - "searchNamesInEnglish": "Cerca anche nei nomi in inglese", - "@searchNamesInEnglish": {}, - "verify": "Verifica", - "@verify": {}, - "legs": "Gambe", - "@legs": { - "description": "Generated entry for translation for server strings" - }, - "miles": "Miglia", - "@miles": { - "description": "Generated entry for translation for server strings" - }, - "seconds": "Secondi", - "@seconds": { - "description": "Generated entry for translation for server strings" - }, - "shoulders": "Spalle", - "@shoulders": { - "description": "Generated entry for translation for server strings" - }, - "max_reps": "Ripetizioni massime", - "@max_reps": { - "description": "Generated entry for translation for server strings" - }, - "kg": "kg", - "@kg": { - "description": "Generated entry for translation for server strings" - }, - "triceps": "Tricipiti", - "@triceps": { - "description": "Generated entry for translation for server strings" - }, - "chest": "Petto", - "@chest": { - "description": "Generated entry for translation for server strings" - }, - "selectEntry": "Per favore seleziona un elemento", - "@selectEntry": {}, - "success": "Completato", - "@success": { - "description": "Message when an action completed successfully, usually used as a heading" - }, - "verifiedEmailReason": "Devi verificare la tua email per contribuire agli esercizi", - "@verifiedEmailReason": {}, - "cardio": "Cardio", - "@cardio": { - "description": "Generated entry for translation for server strings" - }, - "quads": "Quadricipiti", - "@quads": { - "description": "Generated entry for translation for server strings" - }, - "kilometers_per_hour": "Chilometri all'ora", - "@kilometers_per_hour": { - "description": "Generated entry for translation for server strings" - }, - "kilometers": "Chilometri", - "@kilometers": { - "description": "Generated entry for translation for server strings" - }, - "glutes": "Glutei", - "@glutes": { - "description": "Generated entry for translation for server strings" - }, - "minutes": "Minuti", - "@minutes": { - "description": "Generated entry for translation for server strings" - }, - "miles_per_hour": "Miglia per ora", - "@miles_per_hour": { - "description": "Generated entry for translation for server strings" - }, - "noMeasurementEntries": "Non hai voci di misurazione", - "@noMeasurementEntries": {}, - "add_exercise_image_license": "Le immagini devono essere compatibili con la licenza CC BY SA. In caso di dubbi, carica solo le foto che hai scattato tu stesso.", - "@add_exercise_image_license": {}, - "baseNameEnglish": "Tutti gli esercizi necessitano di un nome base in inglese", - "@baseNameEnglish": {}, - "aboutMastodonTitle": "Mastodonte", - "@aboutMastodonTitle": {}, - "enterMinCharacters": "Inserisci almeno {min} caratteri", - "@enterMinCharacters": { - "description": "Error message when the user hasn't entered the minimum amount characters in a form", - "type": "text", - "placeholders": { - "min": { - "type": "String" - } - } - }, - "sz_bar": "SZ-Bar", - "@sz_bar": { - "description": "Generated entry for translation for server strings" - }, - "variations": "Variazioni", - "@variations": { - "description": "Variations of one exercise (e.g. benchpress and benchpress narrow)" - }, - "unVerifiedEmail": "Email non Verificata", - "@unVerifiedEmail": {}, - "alsoKnownAs": "Conosciuto anche come: {aliases}", - "@alsoKnownAs": { - "placeholders": { - "aliases": { - "type": "String" - } + "anErrorOccurred": "È avvenuto un errore!", + "@anErrorOccurred": {}, + "selectIngredient": "Seleziona un ingrediente", + "@selectIngredient": { + "description": "Error message when the user hasn't selected an ingredient from the autocompleter" }, - "description": "List of alternative names for an exercise" - }, - "verifiedEmail": "Email Verificata", - "@verifiedEmail": {}, - "alternativeNames": "Nomi Alternativi", - "@alternativeNames": {}, - "translation": "Traduzione", - "@translation": {}, - "translateExercise": "Traduci questo esercizio ora", - "@translateExercise": {}, - "baseData": "Informazioni Base in Inglese", - "@baseData": { - "description": "The base data for an exercise such as category, trained muscles, etc." - }, - "contributeExercise": "Contribuisci aggiungendo un esercizio", - "@contributeExercise": {}, - "barbell": "Bilanciere", - "@barbell": { - "description": "Generated entry for translation for server strings" - }, - "swiss_ball": "Fitball", - "@swiss_ball": { - "description": "Generated entry for translation for server strings" - }, - "none__bodyweight_exercise_": "nessuno (esercizio con il peso corporeo)", - "@none__bodyweight_exercise_": { - "description": "Generated entry for translation for server strings" - }, - "biceps": "Bicipiti", - "@biceps": { - "description": "Generated entry for translation for server strings" - }, - "calves": "Polpacci", - "@calves": { - "description": "Generated entry for translation for server strings" - }, - "abs": "Addominali", - "@abs": { - "description": "Generated entry for translation for server strings" - }, - "kettlebell": "Kettlebell", - "@kettlebell": { - "description": "Generated entry for translation for server strings" - }, - "images": "Immagini", - "@images": {}, - "incline_bench": "Panca Inclinata", - "@incline_bench": { - "description": "Generated entry for translation for server strings" - }, - "lats": "Muscoli Dorsali", - "@lats": { - "description": "Generated entry for translation for server strings" - }, - "aboutPageTitle": "A proposito di Wger", - "@aboutPageTitle": {}, - "contributeExerciseWarning": "Puoi contribuire agli esercizi solo se il tuo account è più vecchio di {days} giorni e hai verificato la tua email", - "@contributeExerciseWarning": { - "description": "Number of days before which a person can add exercise", - "placeholders": { - "days": { - "type": "String", - "example": "14" - } - } - }, - "language": "Lingua", - "@language": {}, - "textPromptSubheading": "Premi il pulsante azione per iniziare", - "@textPromptSubheading": {}, - "arms": "Braccia", - "@arms": { - "description": "Generated entry for translation for server strings" - }, - "bench": "Panca", - "@bench": { - "description": "Generated entry for translation for server strings" - }, - "body_weight": "Peso Corporeo", - "@body_weight": { - "description": "Generated entry for translation for server strings" - }, - "dumbbell": "Manubrio", - "@dumbbell": { - "description": "Generated entry for translation for server strings" - }, - "plates": "Piastre", - "@plates": { - "description": "Generated entry for translation for server strings" - }, - "until_failure": "Fino al fallimento", - "@until_failure": { - "description": "Generated entry for translation for server strings" - }, - "lb": "lb", - "@lb": { - "description": "Generated entry for translation for server strings" - }, - "hamstrings": "Cosce", - "@hamstrings": { - "description": "Generated entry for translation for server strings" - }, - "pull_up_bar": "Barra per trazioni", - "@pull_up_bar": { - "description": "Generated entry for translation for server strings" - }, - "noMatchingExerciseFound": "Non sono stati trovati esercizi corrispondenti", - "@noMatchingExerciseFound": { - "description": "Message returned if no exercises match the searched string" - }, - "whatVariationsExist": "Ci sono delle variazioni per questo esercizio, se ne esistono?", - "@whatVariationsExist": {}, - "cacheWarning": "A causa del caching potrebbe volerci del tempo affinchè i cambiamenti siano visibili attraverso l'applicazione.", - "@cacheWarning": {}, - "back": "Schiena", - "@back": { - "description": "Generated entry for translation for server strings" - }, - "lower_back": "Zona Lombare", - "@lower_back": { - "description": "Generated entry for translation for server strings" - }, - "useMetric": "Us", - "@useMetric": {}, - "log": "Log", - "@log": { - "description": "Log a specific meal (imperative form)" - }, - "aboutDonateTitle": "Donare", - "@aboutDonateTitle": {}, - "aboutDonateText": "Offrici un caffè per aiutare il progetto, pagare i costi del server e mantenerci alimentati", - "@aboutDonateText": {}, - "settingsTitle": "Impostazioni", - "@settingsTitle": {}, - "settingsCacheTitle": "Cache", - "@settingsCacheTitle": {}, - "settingsExerciseCacheDescription": "Cache degli esercizi", - "@settingsExerciseCacheDescription": {}, - "settingsCacheDeletedSnackbar": "Cache svuotata con successo", - "@settingsCacheDeletedSnackbar": {}, - "done": "Fatto", - "@done": {}, - "ingredientLogged": "Ingrediente registrato nel diario", - "@ingredientLogged": {}, - "chartDuringPlanTitle": "{chartName} durante il piano nutrizionale {planName}", - "@chartDuringPlanTitle": { - "description": "chart of 'chartName' (e.g. 'weight', 'body fat' etc.) logged during plan", - "type": "text", - "placeholders": { - "chartName": { - "type": "String" - }, - "planName": { - "type": "String" - } - } - }, - "chart30DaysTitle": "{name} ultimi 30 giorni", - "@chart30DaysTitle": { - "description": "last 30 days chart of 'name' (e.g. 'weight', 'body fat' etc.)", - "type": "text", - "placeholders": { - "name": { - "type": "String" - } - } - }, - "goalMacro": "Obiettivi dei macronutrienti", - "@goalMacro": { - "description": "The goal for macronutrients" - }, - "goalFiber": "Obbiettivo fibre", - "@goalFiber": {}, - "overallChangeWeight": "Variazione complessiva", - "@overallChangeWeight": { - "description": "Overall change in weight, added for localization" - }, - "goalTypeMeals": "Dai pasti", - "@goalTypeMeals": { - "description": "added for localization of Class GoalType's filed meals" - }, - "goalTypeBasic": "Base", - "@goalTypeBasic": { - "description": "added for localization of Class GoalType's filed basic" - }, - "goalTypeAdvanced": "Avanzato", - "@goalTypeAdvanced": { - "description": "added for localization of Class GoalType's filed advanced" - }, - "indicatorRaw": "grezzo", - "@indicatorRaw": { - "description": "added for localization of Class Indicator's field text" - }, - "indicatorAvg": "med", - "@indicatorAvg": { - "description": "added for localization of Class Indicator's field text" - }, - "themeMode": "Modalità del tema", - "@themeMode": {}, - "lightMode": "Sempre in modalità chiara", - "@lightMode": {}, - "systemMode": "Parametri di sistema", - "@systemMode": {}, - "settingsIngredientCacheDescription": "Cache ingredienti", - "@settingsIngredientCacheDescription": {}, - "onlyLogging": "Traccia solo le calorie", - "@onlyLogging": {}, - "goalEnergy": "Obiettivo energetico", - "@goalEnergy": {}, - "goalProtein": "Obbiettivo proteine", - "@goalProtein": {}, - "goalCarbohydrates": "Obbiettivo carboidrati", - "@goalCarbohydrates": {}, - "goalFat": "Obbiettivo grassi", - "@goalFat": {}, - "today": "Oggi", - "@today": {}, - "loggedToday": "Registrato oggi", - "@loggedToday": {}, - "kcalValue": "{value} kcal", - "@kcalValue": { - "description": "A value in kcal, e.g. 500 kcal", - "type": "text", - "placeholders": { - "value": { - "type": "String" - } - } - }, - "gValue": "{value} g", - "@gValue": { - "description": "A value in grams, e.g. 5 g", - "type": "text", - "placeholders": { - "value": { - "type": "String" - } - } - }, - "percentValue": "{value} %", - "@percentValue": { - "description": "A value in percent, e.g. 10 %", - "type": "text", - "placeholders": { - "value": { - "type": "String" - } - } - }, - "onlyLoggingHelpText": "Selezionate la casella se volete registrare solo le calorie e non volete impostare un piano nutrizionale dettagliato con pasti specifici", - "@onlyLoggingHelpText": {}, - "noIngredientsDefined": "Nessun ingrediente ancora definito", - "@noIngredientsDefined": {}, - "selectMealToLog": "Selezionare un pasto da registrare nel diario", - "@selectMealToLog": {}, - "surplus": "eccedenza", - "@surplus": { - "description": "Caloric surplus (either planned or unplanned)" - }, - "deficit": "deficit", - "@deficit": { - "description": "Caloric deficit (either planned or unplanned)" - }, - "chartAllTimeTitle": "{name} per tutto il periodo", - "@chartAllTimeTitle": { - "description": "All-time chart of 'name' (e.g. 'weight', 'body fat' etc.)", - "type": "text", - "placeholders": { - "name": { - "type": "String" - } - } - }, - "darkMode": "Sempre in modalità scura", - "@darkMode": {}, - "routines": "Routine", - "@routines": {}, - "newRoutine": "Nuova routine", - "@newRoutine": {}, - "noRoutines": "Non hai nessuna routine", - "@noRoutines": {}, - "restTime": "Tempo di riposo", - "@restTime": {}, - "exerciseNr": "Esercizio {nr}", - "@exerciseNr": { - "description": "Header in form indicating the number of the current exercise. Can also be translated as something like 'Set Nr. xy'.", - "type": "text", - "placeholders": { - "nr": { - "type": "String" - } - } - }, - "restDay": "Giorno di riposo", - "@restDay": {}, - "needsLogsToAdvance": "Ha bisogno di registri per avanzare", - "@needsLogsToAdvance": {}, - "isRestDayHelp": "Tieni presente che tutte le serie e gli esercizi verranno rimossi quando contrassegni un giorno come giorno di riposo.", - "@isRestDayHelp": {}, - "useColors": "Usa colori", - "@useColors": {}, - "invalidApiToken": "Per favore inserisci una chiave API valida", - "@invalidApiToken": { - "description": "Error message when the user enters an invalid API key" - }, - "apiToken": "API Token", - "@apiToken": {}, - "useApiToken": "Usa il Token API", - "@useApiToken": {}, - "useUsernameAndPassword": "Usa username e password", - "@useUsernameAndPassword": {}, - "apiTokenValidChars": "Una chiave API può contenere solo lettere a-f, numeri 0-9 e deve essere lunga 40 caratteri", - "@apiTokenValidChars": { - "description": "Error message when the user tries to input a API key with forbidden characters" - } + "enterValidNumber": "Inserisci un numero valido", + "@enterValidNumber": { + "description": "Error message when the user has submitted an invalid number (e.g. '3,.,.,.')" + }, + "enterValue": "Inserisci un valore", + "@enterValue": { + "description": "Error message when the user hasn't entered a value on a required field" + }, + "goToToday": "Seleziona giorno", + "@goToToday": { + "description": "Label on button to jump back to 'today' in the calendar widget" + }, + "calendar": "Calendario", + "@calendar": {}, + "toggleDetails": "Scegli dettagli", + "@toggleDetails": { + "description": "Switch to toggle detail / overview" + }, + "newNutritionalPlan": "Nuovo piano nutrizionale", + "@newNutritionalPlan": {}, + "confirmDelete": "Sei sicuro/a di voler cancellare '{toDelete}'?", + "@confirmDelete": { + "description": "Confirmation text before the user deletes an object", + "type": "text", + "placeholders": { + "toDelete": { + "type": "String" + } + } + }, + "delete": "Elimina", + "@delete": {}, + "loadingText": "Caricamento…", + "@loadingText": { + "description": "Text to show when entries are being loaded in the background: Loading..." + }, + "edit": "Modifica", + "@edit": {}, + "noWeightEntries": "Non hai nessun dato sul peso", + "@noWeightEntries": { + "description": "Message shown when the user has no logged weight entries" + }, + "newEntry": "Nuovo dato", + "@newEntry": { + "description": "Title when adding a new entry such as a weight or log entry" + }, + "unit": "Unità", + "@unit": { + "description": "The unit used for a repetition (kg, time, etc.)" + }, + "amount": "Quatità", + "@amount": { + "description": "The amount (e.g. in grams) of an ingredient in a meal" + }, + "sodium": "Sodio", + "@sodium": {}, + "fiber": "Fibre", + "@fiber": {}, + "saturatedFat": "Grassi saturi", + "@saturatedFat": {}, + "fat": "Grassi", + "@fat": {}, + "sugars": "Zuccheri", + "@sugars": {}, + "carbohydrates": "Carboidrati", + "@carbohydrates": {}, + "protein": "Proteine", + "@protein": {}, + "g": "g", + "@g": { + "description": "Abbreviation for gram" + }, + "kJ": "kJ", + "@kJ": { + "description": "Energy in a meal in kilo joules, kJ" + }, + "kcal": "kcal", + "@kcal": { + "description": "Energy in a meal in kilocalories, kcal" + }, + "energy": "Energia", + "@energy": { + "description": "Energy in a meal, ingredient etc. e.g. in kJ" + }, + "ingredient": "Ingrediente", + "@ingredient": {}, + "timeEnd": "Ora di fine", + "@timeEnd": { + "description": "The end time of a workout" + }, + "timeStart": "Ora di inizio", + "@timeStart": { + "description": "The starting time of a workout" + }, + "time": "Orario", + "@time": { + "description": "The time of a meal or workout" + }, + "date": "Data", + "@date": { + "description": "The date of a workout log or body weight entry" + }, + "weight": "Peso", + "@weight": { + "description": "The weight of a workout log or body weight entry" + }, + "noNutritionalPlans": "Non hai nessun piano nutrizionale", + "@noNutritionalPlans": { + "description": "Message shown when the user has no nutritional plans" + }, + "nutritionalPlans": "Piani nutrizionali", + "@nutritionalPlans": {}, + "nutritionalDiary": "Diario nutrizionale", + "@nutritionalDiary": {}, + "nutritionalPlan": "Piano nutrizionale", + "@nutritionalPlan": {}, + "addIngredient": "Aggiungi ingrediente", + "@addIngredient": {}, + "mealLogged": "Pasto registrato nel diario", + "@mealLogged": {}, + "addMeal": "Aggiungi pasto", + "@addMeal": {}, + "add": "Aggiungi", + "@add": {}, + "cancel": "Cancella", + "@cancel": {}, + "save": "Salva", + "@save": {}, + "description": "Descrizione", + "@description": {}, + "logHelpEntriesUnits": "Da notare che solo i dati con l'unità del peso (kg o lb) e le ripetizioni sono mostrate. Altre combinazioni come tempo o «a cedimento» sono ignorate.", + "@logHelpEntriesUnits": {}, + "logHelpEntries": "Se in una giornata c'è più di esercizio con lo stesso numero di ripetizioni, ma con pesi differenti, solo l'esercizio con il peso più alto viene mostrato nel diagramma.", + "@logHelpEntries": {}, + "gymMode": "Modalità allenamento", + "@gymMode": { + "description": "Label when starting the gym mode" + }, + "newSet": "Nuova serie", + "@newSet": { + "description": "Header when adding a new set to a workout day" + }, + "newDay": "Nuovo giorno", + "@newDay": {}, + "workoutSession": "Sessione di allenamento", + "@workoutSession": { + "description": "A (logged) workout session" + }, + "notes": "Note", + "@notes": { + "description": "Personal notes, e.g. for a workout session" + }, + "impression": "Sensazione", + "@impression": { + "description": "General impression (e.g. for a workout session) such as good, bad, etc." + }, + "comment": "Commento", + "@comment": { + "description": "Comment, additional information" + }, + "rir": "RiR", + "@rir": { + "description": "Shorthand for Repetitions In Reserve" + }, + "repetitions": "Ripetizioni", + "@repetitions": { + "description": "Repetitions for an exercise set" + }, + "addExercise": "Aggiungi esercizi", + "@addExercise": {}, + "exercise": "Esercizio", + "@exercise": { + "description": "An exercise for a workout" + }, + "successfullyDeleted": "Cancellato", + "@successfullyDeleted": { + "description": "Message when an item was successfully deleted" + }, + "labelDashboard": "Pannello di controllo", + "@labelDashboard": { + "description": "Title for screen dashboard" + }, + "labelWorkoutPlan": "Piano di allenamento", + "@labelWorkoutPlan": { + "description": "Title for screen workout plan" + }, + "loginInstead": "Hai già un account? Registrati ora", + "@loginInstead": {}, + "registerInstead": "Non hai un account? Registrati ora", + "@registerInstead": {}, + "reset": "Rerimposta", + "@reset": { + "description": "Button text allowing the user to reset the entered values to the default" + }, + "customServerHint": "Inserisci l'indirizzo del tuo server personale o quello predefinito verrà utilizzato", + "@customServerHint": { + "description": "Hint text for the form where the users can enter their own wger instance" + }, + "customServerUrl": "URL istanza wger", + "@customServerUrl": { + "description": "Label in the form where the users can enter their own wger instance" + }, + "invalidUsername": "Inserisci un nome utente valido", + "@invalidUsername": { + "description": "Error message when the user enters an invalid username" + }, + "username": "Nome utente", + "@username": {}, + "email": "Indirizzo e-mail", + "@email": {}, + "invalidEmail": "Inserisci un indirizzo e-mail valido", + "@invalidEmail": { + "description": "Error message when the user enters an invalid email" + }, + "confirmPassword": "Conferma password", + "@confirmPassword": {}, + "password": "Password", + "@password": {}, + "passwordTooShort": "La password è troppo corta", + "@passwordTooShort": { + "description": "Error message when the user a password that is too short" + }, + "passwordsDontMatch": "Le passwords non coincidono", + "@passwordsDontMatch": { + "description": "Error message when the user enters two different passwords during registration" + }, + "invalidUrl": "Inserisci un URL valido", + "@invalidUrl": { + "description": "Error message when the user enters an invalid URL, e.g. in the login form" + }, + "useCustomServer": "Usa un server personale", + "@useCustomServer": { + "description": "Toggle button allowing users to switch between the default and a custom wger server" + }, + "useDefaultServer": "Usa il server predefinito", + "@useDefaultServer": { + "description": "Toggle button allowing users to switch between the default and a custom wger server" + }, + "register": "Registrati", + "@register": { + "description": "Text for registration button" + }, + "login": "Entra", + "@login": { + "description": "Text for login button" + }, + "nrOfSets": "Serie per esercizio: {nrOfSets}", + "@nrOfSets": { + "description": "Label shown on the slider where the user selects the nr of sets", + "type": "text", + "placeholders": { + "nrOfSets": { + "type": "String" + } + } + }, + "enterCharacters": "Inserisci una stringa tra {min} e {max} caratteri", + "@enterCharacters": { + "description": "Error message when the user hasn't entered the correct number of characters in a form", + "type": "text", + "placeholders": { + "min": { + "type": "String" + }, + "max": { + "type": "String" + } + } + }, + "selectExercise": "Prego, seleziona un esercizio", + "@selectExercise": { + "description": "Error message when the user hasn't selected an exercise in the form" + }, + "todaysWorkout": "Allenamento di oggi", + "@todaysWorkout": {}, + "selectExercises": "Se vuoi fare un circuito (super set), puoi cercare e aggiungere diversi esercizi. Questi verranno collegati come circuito", + "@selectExercises": {}, + "sameRepetitions": "Se fai le stesse ripetizioni e peso per tutte le serie puoi compilare una sola riga. Per esempio per 4 serie inserisci semplicemente 10 per le ripetizioni, automaticamente diventerà una 4x10.", + "@sameRepetitions": {}, + "setNr": "Serie {nr}", + "@setNr": { + "description": "Header in form indicating the number of the current set. Can also be translated as something like 'Set Nr. xy'.", + "type": "text", + "placeholders": { + "nr": { + "type": "String" + } + } + }, + "dayDescriptionHelp": "Una descrizione di ciò che è stato fatto. (p.e. «allenamento gambe») o quale parte del corpo sono state allenate (p.e. «petto e spalle»)", + "@dayDescriptionHelp": {}, + "set": "Serie", + "@set": { + "description": "A set in a workout plan" + }, + "repetitionUnit": "Unità ripetizioni", + "@repetitionUnit": {}, + "weightUnit": "Unità peso", + "@weightUnit": {}, + "reps": "Ripetizioni", + "@reps": { + "description": "Shorthand for repetitions, used when space constraints are tighter" + }, + "addSet": "Aggiungi serie", + "@addSet": { + "description": "Label for the button that adds a set (to a workout day)" + }, + "start": "Inizia", + "@start": { + "description": "Label on button to start the gym mode (i.e., an imperative)" + }, + "successfullySaved": "Salvato", + "@successfullySaved": { + "description": "Message when an item was successfully saved" + }, + "labelWorkoutLogs": "Registri allenamenti", + "@labelWorkoutLogs": { + "description": "(Workout) logs" + }, + "logout": "Disconnetti", + "@logout": { + "description": "Text for logout button" + }, + "aboutDescription": "Grazie per esserti registrato/a su wger! wger è un progetto collaborativo con codice aperto, creato da entusiasti del fitness in tutto il mondo.", + "@aboutDescription": { + "description": "Text in the about dialog" + }, + "logMeal": "Registra questo pasto nel diario", + "@logMeal": {}, + "category": "Categoria", + "@category": { + "description": "Category for an exercise, ingredient, etc." + }, + "equipment": "Equipaggiamento", + "@equipment": { + "description": "Equipment needed to perform an exercise" + }, + "musclesSecondary": "Muscoli secondari", + "@musclesSecondary": { + "description": "secondary muscles trained by an exercise" + }, + "muscles": "Muscoli", + "@muscles": { + "description": "(main) muscles trained by an exercise" + }, + "addImage": "Aggiungi un'immagine", + "@addImage": {}, + "gallery": "Galleria", + "@gallery": {}, + "chooseFromLibrary": "Scegli dalla raccolta", + "@chooseFromLibrary": {}, + "takePicture": "Scatta una foto", + "@takePicture": {}, + "selectImage": "Si prega di selezionare un'immagine", + "@selectImage": { + "description": "Label and error message when the user hasn't selected an image to save" + }, + "name": "Nome", + "@name": { + "description": "Name for a workout or nutritional plan" + }, + "optionsLabel": "Opzioni", + "@optionsLabel": { + "description": "Label for the popup with general app options" + }, + "goToDetailPage": "Vai alla pagina dettagli", + "@goToDetailPage": {}, + "jumpTo": "Vai a", + "@jumpTo": { + "description": "Imperative. Label used in popup allowing the user to jump to a specific exercise while in the gym mode" + }, + "pause": "Pausa", + "@pause": { + "description": "Noun, not an imperative! Label used for the pause when using the gym mode" + }, + "searchExercise": "Cerca esercizio da aggiungere", + "@searchExercise": { + "description": "Label on set form. Selected exercises are added to the set" + }, + "labelBottomNavWorkout": "Allenamento", + "@labelBottomNavWorkout": { + "description": "Label used in bottom navigation, use a short word" + }, + "setUnitsAndRir": "Scegli le unità e le RiR", + "@setUnitsAndRir": { + "description": "Label shown on the slider where the user can toggle showing units and RiR", + "type": "text" + }, + "rirNotUsed": "RiR (Repetitions in Reserve) non utilizzato", + "@rirNotUsed": { + "description": "Label used in RiR slider when the RiR value is not used/saved for the current setting or log" + }, + "labelBottomNavNutrition": "Nutrizione", + "@labelBottomNavNutrition": { + "description": "Label used in bottom navigation, use a short word" + }, + "usernameValidChars": "Un nome utente può contenere solo lettere, cifre e i caratteri @, +, ., - e _", + "@usernameValidChars": { + "description": "Error message when the user tries to register a username with forbidden characters" + }, + "total": "Totale", + "@total": { + "description": "Label used for total sums of e.g. calories or similar" + }, + "appUpdateTitle": "Aggiornamento necessario", + "@appUpdateTitle": {}, + "appUpdateContent": "Questa versione dell'applicazione non è compatibile con il server, per favore aggiorna la tua applicazione.", + "@appUpdateContent": {}, + "dataCopied": "Dati copiati nella nuova voce", + "@dataCopied": { + "description": "Snackbar message to show on copying data to a new log entry" + }, + "proteinShort": "P", + "@proteinShort": { + "description": "The first letter or short name of the word 'Protein', used in overviews" + }, + "carbohydratesShort": "C", + "@carbohydratesShort": { + "description": "The first letter or short name of the word 'Carbohydrates', used in overviews" + }, + "percentEnergy": "Percentuale di energia", + "@percentEnergy": {}, + "fatShort": "Gr", + "@fatShort": { + "description": "The first letter or short name of the word 'Fat', used in overviews" + }, + "logged": "Registrato", + "@logged": { + "description": "Header for the column of 'logged' nutritional values, i.e. what was eaten" + }, + "difference": "Differenza", + "@difference": {}, + "gPerBodyKg": "g per kg di corpo", + "@gPerBodyKg": { + "description": "Label used for total sums of e.g. calories or similar in grams per Kg of body weight" + }, + "timeStartAhead": "L'ora di inizio non può essere più avanti dell'ora di fine", + "@timeStartAhead": {}, + "value": "Valore", + "@value": { + "description": "The value of a measurement entry" + }, + "measurements": "Misure", + "@measurements": { + "description": "Categories for the measurements such as biceps size, body fat, etc." + }, + "measurementCategoriesHelpText": "Categoria di misura, come «bicipiti» o «grasso corporeo»", + "@measurementCategoriesHelpText": {}, + "measurementEntriesHelpText": "L'unità usata per misurare la categoria come «cm» o «%»", + "@measurementEntriesHelpText": {}, + "energyShort": "E", + "@energyShort": { + "description": "The first letter or short name of the word 'Energy', used in overviews" + }, + "macronutrients": "Macronutrienti", + "@macronutrients": {}, + "planned": "Pianificato", + "@planned": { + "description": "Header for the column of 'planned' nutritional values, i.e. what should be eaten" + }, + "measurement": "Misura", + "@measurement": {}, + "recentlyUsedIngredients": "Ingredienti aggiunti di recente", + "@recentlyUsedIngredients": { + "description": "A message when a user adds a new ingredient to a meal." + }, + "plateCalculator": "Piastre", + "@plateCalculator": { + "description": "Label used for the plate calculator in the gym mode" + }, + "plateCalculatorNotDivisible": "Non è possibile raggiungere il peso con le piastre disponibili", + "@plateCalculatorNotDivisible": { + "description": "Error message when the current weight is not reachable with plates (e.g. 33.1 kg)" + }, + "productNotFoundDescription": "Il prodotto con il codice a barre scansionato {barcode} non è stato trovato nel database wger", + "@productNotFoundDescription": { + "description": "Dialog info when product is not found with barcode", + "type": "text", + "placeholders": { + "barcode": { + "type": "String" + } + } + }, + "productNotFound": "Prodotto non trovato", + "@productNotFound": { + "description": "Header label for dialog when product is not found with barcode" + }, + "scanBarcode": "Scansiona il codice a barre", + "@scanBarcode": { + "description": "Label for scan barcode button" + }, + "weekAverage": "Media di 7 giorni", + "@weekAverage": { + "description": "Header for the column of '7 day average' nutritional values, i.e. what was logged last week" + }, + "productFound": "Prodotto trovato", + "@productFound": { + "description": "Header label for dialog when product is found with barcode" + }, + "productFoundDescription": "Il codice a barre corrisponde a questo prodotto: {productName}. Vuoi continuare?", + "@productFoundDescription": { + "description": "Dialog info when product is found with barcode", + "type": "text", + "placeholders": { + "productName": { + "type": "String" + } + } + }, + "close": "Chiudi", + "@close": { + "description": "Translation for close" + }, + "logIngredient": "Salva l'ingrediente nel diario nutrizionale", + "@logIngredient": {}, + "searchIngredient": "Cerca ingrediente", + "@searchIngredient": { + "description": "Label on ingredient search form" + }, + "userProfile": "Il tuo profilo", + "@userProfile": {}, + "exerciseList": "Lista esercizi", + "@exerciseList": {}, + "exercises": "Esercizi", + "@exercises": { + "description": "Multiple exercises for a workout" + }, + "exerciseName": "Nome Esercizio", + "@exerciseName": { + "description": "Label for the name of a workout exercise" + }, + "previous": "Precedente", + "@previous": {}, + "next": "Successivo", + "@next": {}, + "gym_mat": "Materassino da palestra", + "@gym_mat": { + "description": "Generated entry for translation for server strings" + }, + "verifiedEmailInfo": "Un'email di verifica è stata inviata a {email}", + "@verifiedEmailInfo": { + "placeholders": { + "email": { + "type": "String" + } + } + }, + "oneNamePerLine": "Un nome per linea", + "@oneNamePerLine": {}, + "textPromptTitle": "Pronto a iniziare?", + "@textPromptTitle": {}, + "moreMeasurementEntries": "Aggiungi una nuova misura", + "@moreMeasurementEntries": { + "description": "Message shown when the user wants to add new measurement" + }, + "searchNamesInEnglish": "Cerca anche nei nomi in inglese", + "@searchNamesInEnglish": {}, + "verify": "Verifica", + "@verify": {}, + "legs": "Gambe", + "@legs": { + "description": "Generated entry for translation for server strings" + }, + "miles": "Miglia", + "@miles": { + "description": "Generated entry for translation for server strings" + }, + "seconds": "Secondi", + "@seconds": { + "description": "Generated entry for translation for server strings" + }, + "shoulders": "Spalle", + "@shoulders": { + "description": "Generated entry for translation for server strings" + }, + "max_reps": "Ripetizioni massime", + "@max_reps": { + "description": "Generated entry for translation for server strings" + }, + "kg": "kg", + "@kg": { + "description": "Generated entry for translation for server strings" + }, + "triceps": "Tricipiti", + "@triceps": { + "description": "Generated entry for translation for server strings" + }, + "chest": "Petto", + "@chest": { + "description": "Generated entry for translation for server strings" + }, + "selectEntry": "Per favore seleziona un elemento", + "@selectEntry": {}, + "success": "Completato", + "@success": { + "description": "Message when an action completed successfully, usually used as a heading" + }, + "verifiedEmailReason": "Devi verificare la tua email per contribuire agli esercizi", + "@verifiedEmailReason": {}, + "cardio": "Cardio", + "@cardio": { + "description": "Generated entry for translation for server strings" + }, + "quads": "Quadricipiti", + "@quads": { + "description": "Generated entry for translation for server strings" + }, + "kilometers_per_hour": "Chilometri all'ora", + "@kilometers_per_hour": { + "description": "Generated entry for translation for server strings" + }, + "kilometers": "Chilometri", + "@kilometers": { + "description": "Generated entry for translation for server strings" + }, + "glutes": "Glutei", + "@glutes": { + "description": "Generated entry for translation for server strings" + }, + "minutes": "Minuti", + "@minutes": { + "description": "Generated entry for translation for server strings" + }, + "miles_per_hour": "Miglia per ora", + "@miles_per_hour": { + "description": "Generated entry for translation for server strings" + }, + "noMeasurementEntries": "Non hai voci di misurazione", + "@noMeasurementEntries": {}, + "add_exercise_image_license": "Le immagini devono essere compatibili con la licenza CC BY SA. In caso di dubbi, carica solo le foto che hai scattato tu stesso.", + "@add_exercise_image_license": {}, + "baseNameEnglish": "Tutti gli esercizi necessitano di un nome base in inglese", + "@baseNameEnglish": {}, + "aboutMastodonTitle": "Mastodonte", + "@aboutMastodonTitle": {}, + "enterMinCharacters": "Inserisci almeno {min} caratteri", + "@enterMinCharacters": { + "description": "Error message when the user hasn't entered the minimum amount characters in a form", + "type": "text", + "placeholders": { + "min": { + "type": "String" + } + } + }, + "sz_bar": "SZ-Bar", + "@sz_bar": { + "description": "Generated entry for translation for server strings" + }, + "variations": "Variazioni", + "@variations": { + "description": "Variations of one exercise (e.g. benchpress and benchpress narrow)" + }, + "unVerifiedEmail": "Email non Verificata", + "@unVerifiedEmail": {}, + "alsoKnownAs": "Conosciuto anche come: {aliases}", + "@alsoKnownAs": { + "placeholders": { + "aliases": { + "type": "String" + } + }, + "description": "List of alternative names for an exercise" + }, + "verifiedEmail": "Email Verificata", + "@verifiedEmail": {}, + "alternativeNames": "Nomi Alternativi", + "@alternativeNames": {}, + "translation": "Traduzione", + "@translation": {}, + "translateExercise": "Traduci questo esercizio ora", + "@translateExercise": {}, + "baseData": "Informazioni Base in Inglese", + "@baseData": { + "description": "The base data for an exercise such as category, trained muscles, etc." + }, + "contributeExercise": "Contribuisci aggiungendo un esercizio", + "@contributeExercise": {}, + "barbell": "Bilanciere", + "@barbell": { + "description": "Generated entry for translation for server strings" + }, + "swiss_ball": "Fitball", + "@swiss_ball": { + "description": "Generated entry for translation for server strings" + }, + "none__bodyweight_exercise_": "nessuno (esercizio con il peso corporeo)", + "@none__bodyweight_exercise_": { + "description": "Generated entry for translation for server strings" + }, + "biceps": "Bicipiti", + "@biceps": { + "description": "Generated entry for translation for server strings" + }, + "calves": "Polpacci", + "@calves": { + "description": "Generated entry for translation for server strings" + }, + "abs": "Addominali", + "@abs": { + "description": "Generated entry for translation for server strings" + }, + "kettlebell": "Kettlebell", + "@kettlebell": { + "description": "Generated entry for translation for server strings" + }, + "images": "Immagini", + "@images": {}, + "incline_bench": "Panca Inclinata", + "@incline_bench": { + "description": "Generated entry for translation for server strings" + }, + "lats": "Muscoli Dorsali", + "@lats": { + "description": "Generated entry for translation for server strings" + }, + "aboutPageTitle": "A proposito di Wger", + "@aboutPageTitle": {}, + "contributeExerciseWarning": "Puoi contribuire agli esercizi solo se il tuo account è più vecchio di {days} giorni e hai verificato la tua email", + "@contributeExerciseWarning": { + "description": "Number of days before which a person can add exercise", + "placeholders": { + "days": { + "type": "String", + "example": "14" + } + } + }, + "language": "Lingua", + "@language": {}, + "textPromptSubheading": "Premi il pulsante azione per iniziare", + "@textPromptSubheading": {}, + "arms": "Braccia", + "@arms": { + "description": "Generated entry for translation for server strings" + }, + "bench": "Panca", + "@bench": { + "description": "Generated entry for translation for server strings" + }, + "body_weight": "Peso Corporeo", + "@body_weight": { + "description": "Generated entry for translation for server strings" + }, + "dumbbell": "Manubrio", + "@dumbbell": { + "description": "Generated entry for translation for server strings" + }, + "plates": "Piastre", + "@plates": { + "description": "Generated entry for translation for server strings" + }, + "until_failure": "Fino al fallimento", + "@until_failure": { + "description": "Generated entry for translation for server strings" + }, + "lb": "lb", + "@lb": { + "description": "Generated entry for translation for server strings" + }, + "hamstrings": "Cosce", + "@hamstrings": { + "description": "Generated entry for translation for server strings" + }, + "pull_up_bar": "Barra per trazioni", + "@pull_up_bar": { + "description": "Generated entry for translation for server strings" + }, + "noMatchingExerciseFound": "Non sono stati trovati esercizi corrispondenti", + "@noMatchingExerciseFound": { + "description": "Message returned if no exercises match the searched string" + }, + "whatVariationsExist": "Ci sono delle variazioni per questo esercizio, se ne esistono?", + "@whatVariationsExist": {}, + "cacheWarning": "A causa del caching potrebbe volerci del tempo affinchè i cambiamenti siano visibili attraverso l'applicazione.", + "@cacheWarning": {}, + "back": "Schiena", + "@back": { + "description": "Generated entry for translation for server strings" + }, + "lower_back": "Zona Lombare", + "@lower_back": { + "description": "Generated entry for translation for server strings" + }, + "useMetric": "Us", + "@useMetric": {}, + "log": "Log", + "@log": { + "description": "Log a specific meal (imperative form)" + }, + "aboutDonateTitle": "Donare", + "@aboutDonateTitle": {}, + "aboutDonateText": "Offrici un caffè per aiutare il progetto, pagare i costi del server e mantenerci alimentati", + "@aboutDonateText": {}, + "settingsTitle": "Impostazioni", + "@settingsTitle": {}, + "settingsCacheTitle": "Cache", + "@settingsCacheTitle": {}, + "settingsExerciseCacheDescription": "Cache degli esercizi", + "@settingsExerciseCacheDescription": {}, + "settingsCacheDeletedSnackbar": "Cache svuotata con successo", + "@settingsCacheDeletedSnackbar": {}, + "done": "Fatto", + "@done": {}, + "ingredientLogged": "Ingrediente registrato nel diario", + "@ingredientLogged": {}, + "chartDuringPlanTitle": "{chartName} durante il piano nutrizionale {planName}", + "@chartDuringPlanTitle": { + "description": "chart of 'chartName' (e.g. 'weight', 'body fat' etc.) logged during plan", + "type": "text", + "placeholders": { + "chartName": { + "type": "String" + }, + "planName": { + "type": "String" + } + } + }, + "chart30DaysTitle": "{name} ultimi 30 giorni", + "@chart30DaysTitle": { + "description": "last 30 days chart of 'name' (e.g. 'weight', 'body fat' etc.)", + "type": "text", + "placeholders": { + "name": { + "type": "String" + } + } + }, + "goalMacro": "Obiettivi dei macronutrienti", + "@goalMacro": { + "description": "The goal for macronutrients" + }, + "goalFiber": "Obbiettivo fibre", + "@goalFiber": {}, + "overallChangeWeight": "Variazione complessiva", + "@overallChangeWeight": { + "description": "Overall change in weight, added for localization" + }, + "goalTypeMeals": "Dai pasti", + "@goalTypeMeals": { + "description": "added for localization of Class GoalType's filed meals" + }, + "goalTypeBasic": "Base", + "@goalTypeBasic": { + "description": "added for localization of Class GoalType's filed basic" + }, + "goalTypeAdvanced": "Avanzato", + "@goalTypeAdvanced": { + "description": "added for localization of Class GoalType's filed advanced" + }, + "indicatorRaw": "grezzo", + "@indicatorRaw": { + "description": "added for localization of Class Indicator's field text" + }, + "indicatorAvg": "med", + "@indicatorAvg": { + "description": "added for localization of Class Indicator's field text" + }, + "themeMode": "Modalità del tema", + "@themeMode": {}, + "lightMode": "Sempre in modalità chiara", + "@lightMode": {}, + "systemMode": "Parametri di sistema", + "@systemMode": {}, + "settingsIngredientCacheDescription": "Cache ingredienti", + "@settingsIngredientCacheDescription": {}, + "onlyLogging": "Traccia solo le calorie", + "@onlyLogging": {}, + "goalEnergy": "Obiettivo energetico", + "@goalEnergy": {}, + "goalProtein": "Obbiettivo proteine", + "@goalProtein": {}, + "goalCarbohydrates": "Obbiettivo carboidrati", + "@goalCarbohydrates": {}, + "goalFat": "Obbiettivo grassi", + "@goalFat": {}, + "today": "Oggi", + "@today": {}, + "loggedToday": "Registrato oggi", + "@loggedToday": {}, + "kcalValue": "{value} kcal", + "@kcalValue": { + "description": "A value in kcal, e.g. 500 kcal", + "type": "text", + "placeholders": { + "value": { + "type": "String" + } + } + }, + "gValue": "{value} g", + "@gValue": { + "description": "A value in grams, e.g. 5 g", + "type": "text", + "placeholders": { + "value": { + "type": "String" + } + } + }, + "percentValue": "{value} %", + "@percentValue": { + "description": "A value in percent, e.g. 10 %", + "type": "text", + "placeholders": { + "value": { + "type": "String" + } + } + }, + "onlyLoggingHelpText": "Selezionate la casella se volete registrare solo le calorie e non volete impostare un piano nutrizionale dettagliato con pasti specifici", + "@onlyLoggingHelpText": {}, + "noIngredientsDefined": "Nessun ingrediente ancora definito", + "@noIngredientsDefined": {}, + "selectMealToLog": "Selezionare un pasto da registrare nel diario", + "@selectMealToLog": {}, + "surplus": "eccedenza", + "@surplus": { + "description": "Caloric surplus (either planned or unplanned)" + }, + "deficit": "deficit", + "@deficit": { + "description": "Caloric deficit (either planned or unplanned)" + }, + "chartAllTimeTitle": "{name} per tutto il periodo", + "@chartAllTimeTitle": { + "description": "All-time chart of 'name' (e.g. 'weight', 'body fat' etc.)", + "type": "text", + "placeholders": { + "name": { + "type": "String" + } + } + }, + "darkMode": "Sempre in modalità scura", + "@darkMode": {}, + "routines": "Routine", + "@routines": {}, + "newRoutine": "Nuova routine", + "@newRoutine": {}, + "noRoutines": "Non hai nessuna routine", + "@noRoutines": {}, + "restTime": "Tempo di riposo", + "@restTime": {}, + "exerciseNr": "Esercizio {nr}", + "@exerciseNr": { + "description": "Header in form indicating the number of the current exercise. Can also be translated as something like 'Set Nr. xy'.", + "type": "text", + "placeholders": { + "nr": { + "type": "String" + } + } + }, + "restDay": "Giorno di riposo", + "@restDay": {}, + "needsLogsToAdvance": "Ha bisogno di registri per avanzare", + "@needsLogsToAdvance": {}, + "isRestDayHelp": "Tieni presente che tutte le serie e gli esercizi verranno rimossi quando contrassegni un giorno come giorno di riposo.", + "@isRestDayHelp": {}, + "useColors": "Usa colori", + "@useColors": {}, + "invalidApiToken": "Per favore inserisci una chiave API valida", + "@invalidApiToken": { + "description": "Error message when the user enters an invalid API key" + }, + "apiToken": "API Token", + "@apiToken": {}, + "useApiToken": "Usa il Token API", + "@useApiToken": {}, + "useUsernameAndPassword": "Usa username e password", + "@useUsernameAndPassword": {}, + "apiTokenValidChars": "Una chiave API può contenere solo lettere a-f, numeri 0-9 e deve essere lunga 40 caratteri", + "@apiTokenValidChars": { + "description": "Error message when the user tries to input a API key with forbidden characters" + }, + "selectAvailablePlates": "Seleziona i piatti disponibili", + "@selectAvailablePlates": {}, + "barWeight": "Peso della barra", + "@barWeight": {}, + "isRestDay": "È il giorno di riposo", + "@isRestDay": {}, + "needsLogsToAdvanceHelp": "Seleziona se desideri che la routine proceda al giorno programmato successivo solo se hai registrato un allenamento per quel giorno", + "@needsLogsToAdvanceHelp": {}, + "routineDays": "Giorni di routine", + "@routineDays": {} } From b996b4b88b66223d73edaa7e3e43ec41e64379b4 Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Mon, 25 Aug 2025 19:31:26 +0200 Subject: [PATCH 63/89] Bump last selectable date to 1 year in the future --- lib/widgets/dashboard/calendar.dart | 2 +- lib/widgets/routines/forms/routine.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/widgets/dashboard/calendar.dart b/lib/widgets/dashboard/calendar.dart index 049b0d78..d875de58 100644 --- a/lib/widgets/dashboard/calendar.dart +++ b/lib/widgets/dashboard/calendar.dart @@ -225,7 +225,7 @@ class _DashboardCalendarWidgetState extends State TableCalendar( locale: Localizations.localeOf(context).languageCode, firstDay: DateTime.now().subtract(const Duration(days: 1000)), - lastDay: DateTime.now().add(const Duration(days: 112)), + lastDay: DateTime.now().add(const Duration(days: 365)), focusedDay: _focusedDay, selectedDayPredicate: (day) => isSameDay(_selectedDay, day), rangeStartDay: _rangeStart, diff --git a/lib/widgets/routines/forms/routine.dart b/lib/widgets/routines/forms/routine.dart index cb1f9ad8..2e4d3fd8 100644 --- a/lib/widgets/routines/forms/routine.dart +++ b/lib/widgets/routines/forms/routine.dart @@ -163,7 +163,7 @@ class _RoutineFormState extends State { context: context, initialDate: endDate, firstDate: DateTime(DateTime.now().year - 10), - lastDate: DateTime.now().add(const Duration(days: 112)), + lastDate: DateTime.now().add(const Duration(days: 365)), ); if (picked == null) { From 1787d5dd4c2f6ca777e81ad7becd8305f44371dc Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Thu, 14 Aug 2025 12:04:53 +0200 Subject: [PATCH 64/89] Bump used flutter version --- .github/actions/flutter-common/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/flutter-common/action.yml b/.github/actions/flutter-common/action.yml index 72c0e7b9..2f3c19bc 100644 --- a/.github/actions/flutter-common/action.yml +++ b/.github/actions/flutter-common/action.yml @@ -9,7 +9,7 @@ runs: uses: subosito/flutter-action@v2 with: channel: stable - flutter-version: 3.32.2 + flutter-version: 3.32.8 cache: true - name: Install Flutter dependencies From c4aff2f1cf8c36f23457659e1cc4acf5fdc86a5c Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Thu, 21 Aug 2025 15:47:47 +0200 Subject: [PATCH 65/89] Use correct API endpoint... --- lib/providers/routines.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/providers/routines.dart b/lib/providers/routines.dart index e7b52031..16535d6e 100644 --- a/lib/providers/routines.dart +++ b/lib/providers/routines.dart @@ -59,7 +59,7 @@ class RoutinesProvider with ChangeNotifier { static const _routineConfigRepetitions = 'repetitions-config'; static const _routineConfigMaxRepetitions = 'max-repetitions-config'; static const _routineConfigRir = 'rir-config'; - static const _routineConfigMaxRir = 'rest-config'; + static const _routineConfigMaxRir = 'max-rir-config'; static const _routineConfigRestTime = 'rest-config'; static const _routineConfigMaxRestTime = 'max-rest-config'; From e63616a403c76e5237590b85b64034657d0fb744 Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Mon, 25 Aug 2025 19:20:19 +0200 Subject: [PATCH 66/89] Recreate generated files --- .../exercises/exercise_api.freezed.dart | 732 +++++++++++++++++- .../exercises/ingredient_api.freezed.dart | 468 ++++++++++- 2 files changed, 1196 insertions(+), 4 deletions(-) diff --git a/lib/models/exercises/exercise_api.freezed.dart b/lib/models/exercises/exercise_api.freezed.dart index 711987ac..85554ce8 100644 --- a/lib/models/exercises/exercise_api.freezed.dart +++ b/lib/models/exercises/exercise_api.freezed.dart @@ -1,6 +1,5 @@ -// dart format width=80 -// coverage:ignore-file // GENERATED CODE - DO NOT MODIFY BY HAND +// coverage:ignore-file // ignore_for_file: type=lint // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark @@ -217,6 +216,252 @@ class _$ExerciseApiDataCopyWithImpl<$Res> implements $ExerciseApiDataCopyWith<$R } } +/// Adds pattern-matching-related methods to [ExerciseApiData]. +extension ExerciseApiDataPatterns on ExerciseApiData { + /// A variant of `map` that fallback to returning `orElse`. + /// + /// It is equivalent to doing: + /// ```dart + /// switch (sealedClass) { + /// case final Subclass value: + /// return ...; + /// case _: + /// return orElse(); + /// } + /// ``` + + @optionalTypeArgs + TResult maybeMap( + TResult Function(_ExerciseBaseData value)? $default, { + required TResult orElse(), + }) { + final _that = this; + switch (_that) { + case _ExerciseBaseData() when $default != null: + return $default(_that); + case _: + return orElse(); + } + } + + /// A `switch`-like method, using callbacks. + /// + /// Callbacks receives the raw object, upcasted. + /// It is equivalent to doing: + /// ```dart + /// switch (sealedClass) { + /// case final Subclass value: + /// return ...; + /// case final Subclass2 value: + /// return ...; + /// } + /// ``` + + @optionalTypeArgs + TResult map( + TResult Function(_ExerciseBaseData value) $default, + ) { + final _that = this; + switch (_that) { + case _ExerciseBaseData(): + return $default(_that); + } + } + + /// A variant of `map` that fallback to returning `null`. + /// + /// It is equivalent to doing: + /// ```dart + /// switch (sealedClass) { + /// case final Subclass value: + /// return ...; + /// case _: + /// return null; + /// } + /// ``` + + @optionalTypeArgs + TResult? mapOrNull( + TResult? Function(_ExerciseBaseData value)? $default, + ) { + final _that = this; + switch (_that) { + case _ExerciseBaseData() when $default != null: + return $default(_that); + case _: + return null; + } + } + + /// A variant of `when` that fallback to an `orElse` callback. + /// + /// It is equivalent to doing: + /// ```dart + /// switch (sealedClass) { + /// case Subclass(:final field): + /// return ...; + /// case _: + /// return orElse(); + /// } + /// ``` + + @optionalTypeArgs + TResult maybeWhen( + TResult Function( + int id, + String uuid, + @JsonKey(name: 'variations') int? variationId, + @JsonKey(name: 'created') DateTime created, + @JsonKey(name: 'last_update') DateTime lastUpdate, + @JsonKey(name: 'last_update_global') DateTime lastUpdateGlobal, + ExerciseCategory category, + List muscles, + @JsonKey(name: 'muscles_secondary') List musclesSecondary, + List equipment, + @JsonKey(name: 'translations', defaultValue: []) List translations, + List images, + List