mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2025-12-24 02:39:20 -05:00
Merge branch 'master' into feature/vue3
# Conflicts: # requirements.txt
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
FROM python:3.10-alpine3.18
|
||||
FROM python:3.12-alpine3.19
|
||||
|
||||
#Install all dependencies.
|
||||
RUN apk add --no-cache postgresql-libs postgresql-client gettext zlib libjpeg libwebp libxml2-dev libxslt-dev openldap git
|
||||
@@ -25,8 +25,8 @@ RUN apk add --no-cache --virtual .build-deps gcc musl-dev postgresql-dev zlib-de
|
||||
echo -n "INPUT ( libldap.so )" > /usr/lib/libldap_r.so && \
|
||||
python -m venv venv && \
|
||||
/opt/recipes/venv/bin/python -m pip install --upgrade pip && \
|
||||
venv/bin/pip install wheel==0.37.1 && \
|
||||
venv/bin/pip install setuptools_rust==1.1.2 && \
|
||||
venv/bin/pip install wheel==0.42.0 && \
|
||||
venv/bin/pip install setuptools_rust==1.9.0 && \
|
||||
venv/bin/pip install -r requirements.txt --no-cache-dir &&\
|
||||
apk --purge del .build-deps
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2023-05-18 14:28+0200\n"
|
||||
"PO-Revision-Date: 2023-12-10 14:19+0000\n"
|
||||
"Last-Translator: Robin Wilmet <wilmetrobin@hotmail.com>\n"
|
||||
"PO-Revision-Date: 2024-03-03 23:19+0000\n"
|
||||
"Last-Translator: Jocelin Lebreton <jocelin.lebreton@gmail.com>\n"
|
||||
"Language-Team: French <http://translate.tandoor.dev/projects/tandoor/"
|
||||
"recipes-backend/fr/>\n"
|
||||
"Language: fr\n"
|
||||
@@ -1802,23 +1802,6 @@ msgstr ""
|
||||
" "
|
||||
|
||||
#: .\cookbook\templates\search_info.html:39
|
||||
#, fuzzy
|
||||
#| msgid ""
|
||||
#| " \n"
|
||||
#| " Web searches simulate functionality found on many web search "
|
||||
#| "sites supporting special syntax.\n"
|
||||
#| " Placing quotes around several words will convert those words "
|
||||
#| "into a phrase.\n"
|
||||
#| " 'or' is recongized as searching for the word (or phrase) "
|
||||
#| "immediately before 'or' OR the word (or phrase) directly after.\n"
|
||||
#| " '-' is recognized as searching for recipes that do not "
|
||||
#| "include the word (or phrase) that comes immediately after. \n"
|
||||
#| " For example searching for 'apple pie' or cherry -butter will "
|
||||
#| "return any recipe that includes the phrase 'apple pie' or the word "
|
||||
#| "'cherry' \n"
|
||||
#| " in any field included in the full text search but exclude any "
|
||||
#| "recipe that has the word 'butter' in any field included.\n"
|
||||
#| " "
|
||||
msgid ""
|
||||
" \n"
|
||||
" Web searches simulate functionality found on many web search "
|
||||
@@ -1869,19 +1852,6 @@ msgstr ""
|
||||
" "
|
||||
|
||||
#: .\cookbook\templates\search_info.html:59
|
||||
#, fuzzy
|
||||
#| msgid ""
|
||||
#| " \n"
|
||||
#| " Another approach to searching that also requires Postgresql "
|
||||
#| "is fuzzy search or trigram similarity. A trigram is a group of three "
|
||||
#| "consecutive characters.\n"
|
||||
#| " For example searching for 'apple' will create x trigrams "
|
||||
#| "'app', 'ppl', 'ple' and will create a score of how closely words match "
|
||||
#| "the generated trigrams.\n"
|
||||
#| " One benefit of searching trigams is that a search for "
|
||||
#| "'sandwich' will find mispelled words such as 'sandwhich' that would be "
|
||||
#| "missed by other methods.\n"
|
||||
#| " "
|
||||
msgid ""
|
||||
" \n"
|
||||
" Another approach to searching that also requires Postgresql is "
|
||||
@@ -2465,69 +2435,93 @@ msgstr ""
|
||||
|
||||
#: .\cookbook\views\api.py:687
|
||||
msgid "Query string matched (fuzzy) against object name."
|
||||
msgstr ""
|
||||
msgstr "Correspondance (floue) entre la chaîne de requête et le nom de l'objet."
|
||||
|
||||
#: .\cookbook\views\api.py:731
|
||||
msgid ""
|
||||
"Query string matched (fuzzy) against recipe name. In the future also "
|
||||
"fulltext search."
|
||||
msgstr ""
|
||||
"La chaîne d'interrogation correspond (de manière floue) au nom de la "
|
||||
"recette. À l'avenir, la recherche en texte intégral sera également possible."
|
||||
|
||||
#: .\cookbook\views\api.py:733
|
||||
msgid ""
|
||||
"ID of keyword a recipe should have. For multiple repeat parameter. "
|
||||
"Equivalent to keywords_or"
|
||||
msgstr ""
|
||||
"ID du mot-clé qu'une recette doit avoir. Pour les paramètres à répétition "
|
||||
"multiple. Equivalent à keywords_or"
|
||||
|
||||
#: .\cookbook\views\api.py:736
|
||||
msgid ""
|
||||
"Keyword IDs, repeat for multiple. Return recipes with any of the keywords"
|
||||
msgstr ""
|
||||
"ID des mots-clés, répéter pour plusieurs. Retourner les recettes avec "
|
||||
"n'importe quel mot-clé"
|
||||
|
||||
#: .\cookbook\views\api.py:739
|
||||
msgid ""
|
||||
"Keyword IDs, repeat for multiple. Return recipes with all of the keywords."
|
||||
msgstr ""
|
||||
"ID des mots-clés, répéter pour plusieurs. Retourner les recettes contenant "
|
||||
"tous les mots-clés."
|
||||
|
||||
#: .\cookbook\views\api.py:742
|
||||
msgid ""
|
||||
"Keyword IDs, repeat for multiple. Exclude recipes with any of the keywords."
|
||||
msgstr ""
|
||||
"ID des mots-clés, répéter pour plusieurs. Exclure les recettes contenant "
|
||||
"l'un des mots-clés."
|
||||
|
||||
#: .\cookbook\views\api.py:745
|
||||
msgid ""
|
||||
"Keyword IDs, repeat for multiple. Exclude recipes with all of the keywords."
|
||||
msgstr ""
|
||||
"ID des mots-clés, répéter pour plusieurs. Exclure les recettes contenant "
|
||||
"l'un des mots-clés."
|
||||
|
||||
#: .\cookbook\views\api.py:747
|
||||
msgid "ID of food a recipe should have. For multiple repeat parameter."
|
||||
msgstr ""
|
||||
"ID de l'aliment qu'une recette doit contenir. Pour les paramètres de "
|
||||
"répétition multiples."
|
||||
|
||||
#: .\cookbook\views\api.py:750
|
||||
msgid "Food IDs, repeat for multiple. Return recipes with any of the foods"
|
||||
msgstr ""
|
||||
"ID des aliments, répéter pour plusieurs. Retourner les recettes contenant "
|
||||
"l'un des aliments"
|
||||
|
||||
#: .\cookbook\views\api.py:752
|
||||
msgid "Food IDs, repeat for multiple. Return recipes with all of the foods."
|
||||
msgstr ""
|
||||
"ID des aliments, répéter pour plusieurs. Retourner les recettes avec tous "
|
||||
"les aliments."
|
||||
|
||||
#: .\cookbook\views\api.py:754
|
||||
msgid "Food IDs, repeat for multiple. Exclude recipes with any of the foods."
|
||||
msgstr ""
|
||||
"ID des aliments, répéter pour plusieurs. Exclure les recettes contenant l'un "
|
||||
"des aliments."
|
||||
|
||||
#: .\cookbook\views\api.py:756
|
||||
msgid "Food IDs, repeat for multiple. Exclude recipes with all of the foods."
|
||||
msgstr ""
|
||||
"ID des aliments, répéter pour plusieurs. Exclure les recettes contenant tous "
|
||||
"les aliments."
|
||||
|
||||
#: .\cookbook\views\api.py:757
|
||||
msgid "ID of unit a recipe should have."
|
||||
msgstr ""
|
||||
msgstr "ID de l'unité qu'une recette doit avoir."
|
||||
|
||||
#: .\cookbook\views\api.py:759
|
||||
msgid ""
|
||||
"Rating a recipe should have or greater. [0 - 5] Negative value filters "
|
||||
"rating less than."
|
||||
msgstr ""
|
||||
"Note qu'une recette devrait avoir ou être supérieure. [0 - 5] Une valeur "
|
||||
"négative filtre une note inférieure à."
|
||||
|
||||
#: .\cookbook\views\api.py:760
|
||||
msgid "ID of book a recipe should be in. For multiple repeat parameter."
|
||||
@@ -2686,10 +2680,8 @@ msgid "Invite Link"
|
||||
msgstr "Lien d’invitation"
|
||||
|
||||
#: .\cookbook\views\delete.py:200
|
||||
#, fuzzy
|
||||
#| msgid "Members"
|
||||
msgid "Space Membership"
|
||||
msgstr "Membres"
|
||||
msgstr "Adhésion à l'espace"
|
||||
|
||||
#: .\cookbook\views\edit.py:116
|
||||
msgid "You cannot edit this storage!"
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -11,7 +11,7 @@ msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2023-05-18 14:28+0200\n"
|
||||
"PO-Revision-Date: 2024-02-29 02:19+0000\n"
|
||||
"PO-Revision-Date: 2024-03-03 23:19+0000\n"
|
||||
"Last-Translator: M Ugur <mugurd@gmail.com>\n"
|
||||
"Language-Team: Turkish <http://translate.tandoor.dev/projects/tandoor/"
|
||||
"recipes-backend/tr/>\n"
|
||||
@@ -40,19 +40,19 @@ msgstr "Tema"
|
||||
|
||||
#: .\cookbook\forms.py:56
|
||||
msgid "Navbar color"
|
||||
msgstr ""
|
||||
msgstr "Gezinti çubuğu rengi"
|
||||
|
||||
#: .\cookbook\forms.py:57
|
||||
msgid "Sticky navbar"
|
||||
msgstr ""
|
||||
msgstr "Yapışkan gezinti çubuğu"
|
||||
|
||||
#: .\cookbook\forms.py:58
|
||||
msgid "Default page"
|
||||
msgstr ""
|
||||
msgstr "Varsayılan sayfa"
|
||||
|
||||
#: .\cookbook\forms.py:59
|
||||
msgid "Plan sharing"
|
||||
msgstr ""
|
||||
msgstr "Plan paylaşımı"
|
||||
|
||||
#: .\cookbook\forms.py:60
|
||||
msgid "Ingredient decimal places"
|
||||
@@ -87,10 +87,12 @@ msgid ""
|
||||
"Enables support for fractions in ingredient amounts (e.g. convert decimals "
|
||||
"to fractions automatically)"
|
||||
msgstr ""
|
||||
"Malzeme miktarı için kesir desteğini etkinleştir (örn. ondalıkları kesire "
|
||||
"otomatik çevir)"
|
||||
|
||||
#: .\cookbook\forms.py:73
|
||||
msgid "Display nutritional energy amounts in joules instead of calories"
|
||||
msgstr ""
|
||||
msgstr "Besin değerlerini kalori yerine jul olarak görüntüle"
|
||||
|
||||
#: .\cookbook\forms.py:74
|
||||
msgid "Users with whom newly created meal plans should be shared by default."
|
||||
@@ -127,11 +129,11 @@ msgstr ""
|
||||
|
||||
#: .\cookbook\forms.py:83 .\cookbook\forms.py:512
|
||||
msgid "Automatically add meal plan ingredients to shopping list."
|
||||
msgstr ""
|
||||
msgstr "Otomatik olarak yemek planındaki malzemeleri alışveriş listesine ekle."
|
||||
|
||||
#: .\cookbook\forms.py:84
|
||||
msgid "Exclude ingredients that are on hand."
|
||||
msgstr ""
|
||||
msgstr "Var olan malzemeleri hariç tut."
|
||||
|
||||
#: .\cookbook\forms.py:85
|
||||
msgid "Will optimize the UI for use with your left hand."
|
||||
@@ -142,6 +144,8 @@ msgid ""
|
||||
"Both fields are optional. If none are given the username will be displayed "
|
||||
"instead"
|
||||
msgstr ""
|
||||
"Her iki değer de tercihe bağlıdır. Hiç birisi verilmezse yerlerine kullanıcı "
|
||||
"adı gösterilecektir"
|
||||
|
||||
#: .\cookbook\forms.py:123 .\cookbook\forms.py:314
|
||||
msgid "Name"
|
||||
@@ -149,23 +153,23 @@ msgstr "İsim"
|
||||
|
||||
#: .\cookbook\forms.py:124 .\cookbook\forms.py:315 .\cookbook\views\lists.py:88
|
||||
msgid "Keywords"
|
||||
msgstr ""
|
||||
msgstr "Anahtar kelimeler"
|
||||
|
||||
#: .\cookbook\forms.py:125
|
||||
msgid "Preparation time in minutes"
|
||||
msgstr ""
|
||||
msgstr "Hazırlık süresi dakika cinsinden"
|
||||
|
||||
#: .\cookbook\forms.py:126
|
||||
msgid "Waiting time (cooking/baking) in minutes"
|
||||
msgstr ""
|
||||
msgstr "Bekleme süresi (pişirme/fırınlama) dakika cinsinden"
|
||||
|
||||
#: .\cookbook\forms.py:127 .\cookbook\forms.py:283 .\cookbook\forms.py:316
|
||||
msgid "Path"
|
||||
msgstr ""
|
||||
msgstr "Adres"
|
||||
|
||||
#: .\cookbook\forms.py:128
|
||||
msgid "Storage UID"
|
||||
msgstr ""
|
||||
msgstr "Saklama UID (biricik tanımlayıcı)"
|
||||
|
||||
#: .\cookbook\forms.py:161
|
||||
msgid "Default"
|
||||
|
||||
Binary file not shown.
@@ -146,6 +146,13 @@ This can either be a relative path from the applications base path or the url of
|
||||
MEDIA_URL=/media/
|
||||
```
|
||||
|
||||
#### Media root
|
||||
|
||||
> default `<basedir>/mediafiles` - options `/some/other/media/path`.
|
||||
|
||||
Where mediafiles should be stored on disk. The default location is a
|
||||
`mediafiles` subfolder at the root of the application directory.
|
||||
|
||||
#### Gunicorn Workers
|
||||
|
||||
> default `3` - options `1-X`
|
||||
|
||||
@@ -478,10 +478,10 @@ if os.getenv('S3_ACCESS_KEY', ''):
|
||||
AWS_S3_CUSTOM_DOMAIN = os.getenv('S3_CUSTOM_DOMAIN', '')
|
||||
|
||||
MEDIA_URL = os.getenv('MEDIA_URL', '/media/')
|
||||
MEDIA_ROOT = os.path.join(BASE_DIR, "mediafiles")
|
||||
MEDIA_ROOT = os.getenv('MEDIA_ROOT', os.path.join(BASE_DIR, "mediafiles"))
|
||||
else:
|
||||
MEDIA_URL = os.getenv('MEDIA_URL', '/media/')
|
||||
MEDIA_ROOT = os.path.join(BASE_DIR, "mediafiles")
|
||||
MEDIA_ROOT = os.getenv('MEDIA_ROOT', os.path.join(BASE_DIR, "mediafiles"))
|
||||
|
||||
# Serve static files with gzip
|
||||
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
|
||||
@@ -519,4 +519,19 @@ ACCOUNT_RATE_LIMITS = {"change_password": "1/m/user", "reset_password": "1/m/ip,
|
||||
DISABLE_EXTERNAL_CONNECTORS = bool(int(os.getenv('DISABLE_EXTERNAL_CONNECTORS', False)))
|
||||
EXTERNAL_CONNECTORS_QUEUE_SIZE = int(os.getenv('EXTERNAL_CONNECTORS_QUEUE_SIZE', 100))
|
||||
|
||||
# ACCOUNT_SIGNUP_FORM_CLASS = 'cookbook.forms.AllAuthSignupForm'
|
||||
ACCOUNT_FORMS = {
|
||||
'signup': 'cookbook.forms.AllAuthSignupForm',
|
||||
'reset_password': 'cookbook.forms.CustomPasswordResetForm'
|
||||
}
|
||||
|
||||
ACCOUNT_EMAIL_UNKNOWN_ACCOUNTS = False
|
||||
ACCOUNT_RATE_LIMITS = {
|
||||
"change_password": "1/m/user",
|
||||
"reset_password": "1/m/ip,1/m/key",
|
||||
"reset_password_from_key": "1/m/ip",
|
||||
"signup": "5/m/ip",
|
||||
"login": "5/m/ip",
|
||||
}
|
||||
|
||||
mimetypes.add_type("text/javascript", ".js", True)
|
||||
|
||||
@@ -45,7 +45,7 @@ django-auth-ldap==4.6.0
|
||||
pyppeteer==2.0.0
|
||||
validators==0.20.0
|
||||
pytube==15.0.0
|
||||
homeassistant-api==4.2.1
|
||||
homeassistant-api==4.1.1.post2
|
||||
django-vite==3.0.3
|
||||
|
||||
# Development
|
||||
|
||||
@@ -9,15 +9,15 @@
|
||||
|
||||
<b-tabs content-class="mt-2" v-model="current_tab" class="mt-md-1" style="margin-bottom: 20vh">
|
||||
<template #tabs-end>
|
||||
<li class="nav-item flex-grow-1" >
|
||||
<li class="nav-item flex-grow-1">
|
||||
|
||||
</li>
|
||||
<li class="nav-item" >
|
||||
<li class="nav-item">
|
||||
<a href="#" class="nav-link" @click="useShoppingListStore().undoChange()"> <i class="fas fa-undo fa-fw"></i> </a>
|
||||
</li>
|
||||
<li class="nav-item dropdown d-none d-md-inline-block" >
|
||||
<li class="nav-item dropdown d-none d-md-inline-block">
|
||||
<a class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-expanded="false">
|
||||
<i class="fas fa-download" ></i>
|
||||
<i class="fas fa-download"></i>
|
||||
</a>
|
||||
<div class="dropdown-menu">
|
||||
<DownloadPDF dom="#shoppinglist" name="shopping.pdf" :label="$t('download_pdf')"
|
||||
@@ -34,7 +34,7 @@
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="#" class="nav-link" id="id_filters_button">
|
||||
<i class="fas fa-filter fa-fw"/>
|
||||
<i class="fas fa-filter fa-fw"/>
|
||||
</a>
|
||||
</li>
|
||||
</template>
|
||||
@@ -59,7 +59,7 @@
|
||||
<b-row class="d-lg-block d-print-none d-none mb-3 mt-3">
|
||||
<b-col cols="12">
|
||||
<b-input-group>
|
||||
<b-form-input type="text" :placeholder="$t('Food')"
|
||||
<b-form-input type="text" :placeholder="$t('Shopping_input_placeholder')"
|
||||
v-model="new_item.ingredient"
|
||||
@keyup.enter="addItem"
|
||||
ref="amount_input_simple"></b-form-input>
|
||||
@@ -351,7 +351,7 @@
|
||||
<template #title>
|
||||
<div class="d-print-none">
|
||||
<i class="fas fa-user-cog fa-fw"></i>
|
||||
<!-- <span class="d-none d-lg-inline-block ml-1">{{ $t('Settings') }}</span>-->
|
||||
<!-- <span class="d-none d-lg-inline-block ml-1">{{ $t('Settings') }}</span>-->
|
||||
</div>
|
||||
</template>
|
||||
<div class="row justify-content-center">
|
||||
@@ -430,7 +430,7 @@
|
||||
<b-col cols="12">
|
||||
<template v-if="current_tab===0">
|
||||
<b-input-group>
|
||||
<b-form-input v-model="new_item.ingredient" :placeholder="$t('Food')"
|
||||
<b-form-input v-model="new_item.ingredient" :placeholder="$t('Shopping_input_placeholder')"
|
||||
@keyup.enter="addItem"></b-form-input>
|
||||
<b-input-group-append>
|
||||
<b-button @click="addItem" variant="success">
|
||||
@@ -562,6 +562,16 @@ export default {
|
||||
this.shopping_list_store.refreshFromAPI()
|
||||
useUserPreferenceStore().loadUserSettings(true)
|
||||
useUserPreferenceStore().loadDeviceSettings()
|
||||
|
||||
// update selected supermarkt because local setting become stale otherwise
|
||||
if (useUserPreferenceStore().device_settings.shopping_selected_supermarket != null) {
|
||||
let api = new ApiApiFactory()
|
||||
api.retrieveSupermarket(useUserPreferenceStore().device_settings.shopping_selected_supermarket.id).then(r => {
|
||||
useUserPreferenceStore().device_settings.shopping_selected_supermarket = r.data
|
||||
useUserPreferenceStore().updateDeviceSettings()
|
||||
})
|
||||
}
|
||||
|
||||
this.autoSyncLoop()
|
||||
},
|
||||
methods: {
|
||||
@@ -693,6 +703,10 @@ export default {
|
||||
apiClient.updateSupermarket(this.shopping_list_store.supermarkets[index].id, this.shopping_list_store.supermarkets[index]).then((r) => {
|
||||
StandardToasts.makeStandardToast(this, StandardToasts.SUCCESS_UPDATE)
|
||||
this.shopping_list_store.refreshFromAPI()
|
||||
|
||||
if (r.data.id === useUserPreferenceStore().device_settings.shopping_selected_supermarket.id){
|
||||
useUserPreferenceStore().device_settings.shopping_selected_supermarket = r.data
|
||||
}
|
||||
}).catch((err) => {
|
||||
StandardToasts.makeStandardToast(this, StandardToasts.FAIL_UPDATE, err)
|
||||
})
|
||||
|
||||
@@ -178,6 +178,7 @@
|
||||
"Ignore_Shopping": "Ignore Shopping",
|
||||
"Shopping_Category": "Shopping Category",
|
||||
"Shopping_Categories": "Shopping Categories",
|
||||
"Shopping_input_placeholder": "e.g. Potato/100 Potatoes/100 g Potatoes",
|
||||
"Edit_Food": "Edit Food",
|
||||
"Move_Food": "Move Food",
|
||||
"New_Food": "New Food",
|
||||
|
||||
@@ -521,5 +521,24 @@
|
||||
"Transpose_Words": "Transposer les mots",
|
||||
"Name_Replace": "Remplacer le Nom",
|
||||
"Food_Replace": "Remplacer l'aliment",
|
||||
"Unit_Replace": "Remplacer l'Unité"
|
||||
"Unit_Replace": "Remplacer l'Unité",
|
||||
"ShowRecentlyCompleted": "Afficher les éléments récemment complétés",
|
||||
"Input": "Entrée",
|
||||
"Undo": "annuler",
|
||||
"NoMoreUndo": "Aucun changement à annuler.",
|
||||
"Delete_All": "Supprimer tout",
|
||||
"created_by": "Créé par",
|
||||
"ShoppingBackgroundSyncWarning": "Mauvais réseau, en attente de synchronisation ...",
|
||||
"make_now_count": "Ingrédients manquants au maximum",
|
||||
"CustomTheme": "Thème personnalisé",
|
||||
"CustomThemeHelp": "Remplacer les styles du thème sélectionné en téléchargeant un fichier CSS personnalisé.",
|
||||
"CustomImageHelp": "Téléchargez une image à afficher dans l'aperçu de l'espace.",
|
||||
"CustomNavLogoHelp": "Téléchargez une image à utiliser comme logo de la barre de navigation.",
|
||||
"CustomLogoHelp": "Téléchargez des images carrées de différentes tailles pour les transformer en logo dans l'onglet du navigateur et dans l'application web installée.",
|
||||
"CustomLogos": "Logos personnalisés",
|
||||
"Calculator": "Calculatrice",
|
||||
"Created": "Créé",
|
||||
"Updated": "Mis à jour",
|
||||
"Unchanged": "Inchangé",
|
||||
"Error": "Erreur"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user