cc0fa09219
- PHP generateRecipeStream: wrap entire body in try/catch(\Throwable) to catch any PHP fatal/exception mid-stream and send it as a proper SSE error event - PHP: curl timeout raised 60s→90s; capture curl errno/errmsg on failure - PHP: HTTP error messages now include a human-readable status label (e.g. 'Quota API esaurita (429)', 'Nessuna risposta da Gemini (cURL: ...)') - JS catch block: show err.message alongside error.connection so the actual JS network error (NetworkError, AbortError, etc.) is visible - JS no-recipe+no-error path: show recipes.stream_interrupted instead of generic error.connection - Translation: added recipes.stream_interrupted in it/en/de
1353 lines
64 KiB
JSON
1353 lines
64 KiB
JSON
{
|
||
"app": {
|
||
"name": "EverShelf",
|
||
"loading": "Caricamento..."
|
||
},
|
||
"nav": {
|
||
"title": "EverShelf",
|
||
"home": "Home",
|
||
"inventory": "Dispensa",
|
||
"recipes": "Ricette",
|
||
"shopping": "Spesa",
|
||
"log": "Storico",
|
||
"settings": "Config"
|
||
},
|
||
"btn": {
|
||
"back": "← Indietro",
|
||
"save": "💾 Salva",
|
||
"cancel": "✕ Annulla",
|
||
"close": "Chiudi",
|
||
"add": "✅ Aggiungi",
|
||
"delete": "Elimina",
|
||
"edit": "✏️ Modifica",
|
||
"use": "Usa",
|
||
"edit_item": "Modifica",
|
||
"search": "🔍 Cerca",
|
||
"go": "✅ Vai",
|
||
"toggle_password": "👁️ Mostra/Nascondi",
|
||
"load_more": "Carica altri...",
|
||
"save_config": "💾 Salva Configurazione",
|
||
"save_product": "💾 Salva Prodotto",
|
||
"restart": "↺ Ricomincia",
|
||
"reset_default": "↺ Ripristina default",
|
||
"save_info": "💾 Salva informazioni",
|
||
"retry": "🔄 Riprova",
|
||
"yes_short": "Sì",
|
||
"no_short": "No"
|
||
},
|
||
"form": {
|
||
"select_placeholder": "-- Seleziona --"
|
||
},
|
||
"locations": {
|
||
"dispensa": "Dispensa",
|
||
"frigo": "Frigo",
|
||
"freezer": "Freezer",
|
||
"altro": "Altro"
|
||
},
|
||
"categories": {
|
||
"latticini": "Latticini",
|
||
"carne": "Carne",
|
||
"pesce": "Pesce",
|
||
"frutta": "Frutta",
|
||
"verdura": "Verdura",
|
||
"pasta": "Pasta & Riso",
|
||
"pane": "Pane & Forno",
|
||
"surgelati": "Surgelati",
|
||
"bevande": "Bevande",
|
||
"condimenti": "Condimenti",
|
||
"snack": "Snack & Dolci",
|
||
"conserve": "Conserve",
|
||
"cereali": "Cereali & Legumi",
|
||
"igiene": "Igiene",
|
||
"pulizia": "Pulizia Casa",
|
||
"altro": "Altro",
|
||
"select": "-- Seleziona --"
|
||
},
|
||
"units": {
|
||
"pz": "pz",
|
||
"conf": "conf",
|
||
"g": "g",
|
||
"ml": "ml",
|
||
"pieces": "Pezzi",
|
||
"grams": "Grammi",
|
||
"box": "Confezione",
|
||
"boxes": "Confezioni",
|
||
"millilitres": "Millilitri",
|
||
"from": "da"
|
||
},
|
||
"shopping_sections": {
|
||
"frutta_verdura": "Frutta & Verdura",
|
||
"carne_pesce": "Carne & Pesce",
|
||
"latticini": "Latticini & Fresco",
|
||
"pane_dolci": "Pane & Dolci",
|
||
"pasta": "Pasta & Cereali",
|
||
"conserve": "Conserve & Salse",
|
||
"surgelati": "Surgelati",
|
||
"bevande": "Bevande",
|
||
"pulizia_igiene": "Pulizia & Igiene",
|
||
"altro": "Altro"
|
||
},
|
||
"dashboard": {
|
||
"expired_title": "🚫 Scaduti",
|
||
"expiring_title": "⏰ Prossime Scadenze",
|
||
"stats_period": "📊 Ultimi 30 giorni",
|
||
"opened_title": "📦 Prodotti Aperti",
|
||
"review_title": "🔍 Da revisionare",
|
||
"review_hint": "Quantità che sembrano anomale. Conferma se corrette o modifica.",
|
||
"quick_recipe": "Ricetta veloce con prodotti in scadenza",
|
||
"banner_review_title": "Quantità anomala",
|
||
"banner_review_action_ok": "È corretto",
|
||
"banner_review_action_finish": "🗑️ È finito tutto",
|
||
"banner_review_action_edit": "Correggi",
|
||
"banner_review_action_weigh": "Pesa",
|
||
"banner_review_dismiss": "Ignora",
|
||
"banner_prediction_title": "Consumo da verificare",
|
||
"banner_prediction_hint": "La stima di consumo si adatta ai dati recenti: verifica solo se la quantità corrente è corretta.",
|
||
"banner_prediction_action_confirm": "Confermo {qty} {unit}",
|
||
"banner_prediction_action_weigh": "Pesa ora",
|
||
"banner_prediction_action_edit": "Aggiorna quantità",
|
||
"banner_expired_title": "Prodotto scaduto",
|
||
"banner_expired_today": "Scaduto oggi",
|
||
"banner_expired_days": "Scaduto da {days} giorni",
|
||
"banner_expired_action_use": "Usa comunque",
|
||
"banner_expired_action_finished": "L'ho finito!",
|
||
"banner_expired_action_throw": "L'ho buttato",
|
||
"banner_expired_action_edit": "Correggi data",
|
||
"banner_expired_action_modify": "Modifica",
|
||
"banner_expired_action_vacuum": "Metti sottovuoto",
|
||
"banner_anomaly_action_edit": "Correggi inventario",
|
||
"banner_anomaly_action_dismiss": "La quantità è giusta",
|
||
"banner_no_expiry_title": "Scadenza mancante: {name}",
|
||
"banner_no_expiry_detail": "Questo prodotto non ha una data di scadenza. Vuoi aggiungerla o confermare che non scade?",
|
||
"banner_no_expiry_action_set": "Imposta scadenza",
|
||
"banner_no_expiry_action_dismiss": "Non scade ✓",
|
||
"banner_no_expiry_toast_dismissed": "Segnato come 'non scade'",
|
||
"banner_expiring_title": "In scadenza",
|
||
"banner_expiring_today": "Scade oggi!",
|
||
"banner_expiring_tomorrow": "Scade domani",
|
||
"banner_expiring_days": "Scade tra {days} giorni",
|
||
"banner_expiring_action_use": "Usa ora",
|
||
"banner_finished_title": "è finito?",
|
||
"banner_finished_detail": "Ho registrato che {name} ha toccato quota zero. È davvero finito o hai ancora delle scorte?",
|
||
"banner_finished_action_yes": "Sì, è finito",
|
||
"banner_finished_action_no": "No, ne ho ancora",
|
||
"banner_review_unusual_pkg_title": "Confezione insolita",
|
||
"banner_review_unusual_pkg_detail": "Hai impostato una confezione da {qty} {unit} — la dimensione sembra molto alta. Controlla se è corretta o modifica.",
|
||
"banner_review_low_qty_title": "Quantità molto bassa",
|
||
"banner_review_low_qty_detail": "Hai solo {qty} in inventario — sembra poco, potrebbe essere un errore. Conferma se è corretto.",
|
||
"banner_review_high_qty_title": "Quantità insolitamente alta",
|
||
"banner_review_high_qty_detail": "Hai {qty} in inventario — la cifra sembra molto alta. Conferma se è corretto o correggi.",
|
||
"banner_prediction_rate_day": "Media ~{n} {unit}/giorno",
|
||
"banner_prediction_rate_week": "Media ~{n} {unit}/settimana",
|
||
"banner_prediction_days_ago": "{n} giorni fa hai rifornito",
|
||
"banner_prediction_more": "stima precedente: {expected} {unit}{time}; quantità attuale: {actual} {unit}.",
|
||
"banner_prediction_less": "stima: {expected} {unit}{time}; quantità attuale: {actual} {unit}. Se hai cambiato ritmo d'uso, la previsione si aggiorna automaticamente.",
|
||
"banner_finished_zero": "L'inventario segna zero, ma i movimenti registrati dicono che non dovrebbe essere finito.",
|
||
"banner_finished_expected": "Secondo le registrazioni dovresti averne ancora {qty} {unit}.",
|
||
"banner_finished_check": "Puoi controllare?",
|
||
"banner_anomaly_phantom_title": "hai più scorte del previsto",
|
||
"banner_anomaly_phantom_detail": "L'inventario segna {inv_qty} {unit}, ma in base alle registrazioni ne dovresti avere solo {expected_qty} {unit}. Hai aggiunto scorte senza registrarle?",
|
||
"banner_anomaly_untracked_title": "scorte non registrate come entrata",
|
||
"banner_anomaly_untracked_detail": "Hai <strong>{inv_qty} {unit}</strong> in inventario, ma le uscite registrate superano le entrate — le scorte iniziali probabilmente non sono mai state aggiunte come entrata. Puoi correggere la quantità o registrare le entrate mancanti.",
|
||
"banner_anomaly_ghost_title": "hai meno scorte del previsto",
|
||
"banner_anomaly_ghost_detail": "In base alle operazioni registrate dovresti avere {expected_qty} {unit} di {name}, ma l'inventario mostra solo {inv_qty} {unit}. Hai prelevato senza registrarlo?",
|
||
"consumed": "Consumati: {n} ({pct}%)",
|
||
"wasted": "Buttati: {n} ({pct}%)",
|
||
"more_opened": "e altri {n} prodotti aperti...",
|
||
"banner_expired_detail": "{when} · hai ancora <strong>{qty}</strong>.",
|
||
"banner_opened_detail": "{when} in {location} · hai ancora <strong>{qty}</strong>.",
|
||
"banner_explain_title": "Chiedi a Gemini una spiegazione",
|
||
"banner_explain_btn": "Spiega",
|
||
"banner_analyzing": "🤖 Analizzo…"
|
||
},
|
||
"inventory": {
|
||
"title": "Dispensa",
|
||
"filter_all": "Tutti",
|
||
"search_placeholder": "🔍 Cerca prodotto...",
|
||
"recent_title": "🕐 Ultimi usati",
|
||
"popular_title": "⭐ Più usati",
|
||
"empty": "Nessun prodotto qui.\nScansiona un prodotto per aggiungerlo!",
|
||
"no_items_found": "Nessuna voce di inventario trovata",
|
||
"qty_remainder_suffix": "rimasti",
|
||
"vacuum_badge": "🫙 Sotto vuoto",
|
||
"opened_badge": "📭 Aperto",
|
||
"label_expiry": "📅 Scadenza",
|
||
"label_storage": "🫙 Conservazione",
|
||
"label_status": "📭 Stato",
|
||
"opened_since": "Aperto dal {date}",
|
||
"label_position": "📍 Posizione",
|
||
"label_quantity": "📦 Quantità",
|
||
"label_added": "📅 Aggiunto",
|
||
"empty_text": "Nessun prodotto qui.<br>Scansiona un prodotto per aggiungerlo!",
|
||
"empty_db": "Nessun prodotto nel database.<br>Scansiona un prodotto per iniziare!",
|
||
"qty_trace": "< 1"
|
||
},
|
||
"scan": {
|
||
"title": "Scansiona",
|
||
"mode_shopping": "🛒 Modalità Spesa",
|
||
"mode_shopping_end": "✅ Fine spesa",
|
||
"spesa_btn": "🛒 Spesa",
|
||
"zoom": "Zoom",
|
||
"tab_barcode": "Barcode",
|
||
"tab_name": "Nome",
|
||
"tab_ai": "AI",
|
||
"recents_label": "Recenti",
|
||
"torch_hint": "Torcia",
|
||
"torch_on": "Torcia accesa",
|
||
"torch_off": "Torcia spenta",
|
||
"torch_unavailable": "Torcia non disponibile su questo dispositivo",
|
||
"flip_hint": "Cambia fotocamera",
|
||
"flip_front": "Fotocamera anteriore",
|
||
"flip_back": "Fotocamera posteriore",
|
||
"num_ocr_btn": "🔢 Leggi numeri con AI",
|
||
"num_ocr_searching": "Cerco il codice con AI...",
|
||
"num_ocr_found": "Codice trovato: {code}",
|
||
"num_ocr_not_found": "Nessun codice trovato nell'immagine",
|
||
"barcode_placeholder": "Inserisci codice a barre...",
|
||
"quick_name_divider": "oppure scrivi il nome",
|
||
"quick_name_placeholder": "Es: Mele, Zucchine, Pane...",
|
||
"manual_entry": "✏️ Inserimento Manuale",
|
||
"ai_identify": "🤖 Identifica con AI",
|
||
"hint": "Scansiona il barcode, scrivi il nome del prodotto, oppure usa l'AI per identificarlo",
|
||
"debug_toggle": "🐛 Debug Log",
|
||
"barcode_acquired": "🔖 Barcode acquisito: {code}",
|
||
"scan_barcode": "🔖 Scansiona Barcode",
|
||
"create_named": "Crea {name}",
|
||
"new_without_barcode": "Nuovo prodotto senza barcode",
|
||
"stock_in_pantry": "Hai gia in dispensa:"
|
||
},
|
||
"action": {
|
||
"title": "Cosa vuoi fare?",
|
||
"add_btn": "📥 AGGIUNGI",
|
||
"add_sub": "in dispensa/frigo",
|
||
"use_btn": "USA",
|
||
"use_sub": "dalla dispensa/frigo",
|
||
"have_title": "📦 Ce l'hai già!",
|
||
"add_more_sub": "altra quantità",
|
||
"use_qty_sub": "quanto ne hai usato",
|
||
"throw_btn": "🗑️ BUTTA",
|
||
"throw_sub": "butta il prodotto",
|
||
"edit_sub": "scadenza, luogo…",
|
||
"create_recipe_btn": "Ricetta",
|
||
"related_stock_title": "Hai anche in casa"
|
||
},
|
||
"add": {
|
||
"title": "Aggiungi alla Dispensa",
|
||
"location_label": "📍 Dove lo metti?",
|
||
"quantity_label": "📦 Quantità",
|
||
"conf_size_label": "📦 Ogni confezione contiene:",
|
||
"conf_size_placeholder": "es. 300",
|
||
"vacuum_label": "🫙 Sotto vuoto",
|
||
"vacuum_hint": "La scadenza verrà estesa automaticamente",
|
||
"submit": "✅ Aggiungi",
|
||
"purchase_type_label": "🛒 Questo prodotto è...",
|
||
"new_btn": "🆕 Appena comprato",
|
||
"existing_btn": "📦 Ce l'avevo già",
|
||
"remaining_label": "📦 Quantità rimasta",
|
||
"remaining_hint": "Quanto è rimasto approssimativamente?",
|
||
"remaining_full": "🟢 Pieno",
|
||
"remaining_half": "🟠 Metà",
|
||
"estimated_expiry": "Scadenza stimata:",
|
||
"suffix_freezer": "(freezer)",
|
||
"suffix_vacuum": "(sotto vuoto)",
|
||
"hint_modify": "📝 Puoi modificare la data o scansionarla con la fotocamera",
|
||
"scan_expiry_title": "📷 Scansiona Data Scadenza",
|
||
"product_added": "✅ {name} aggiunto!{qty}",
|
||
"suffix_freezer_vacuum": "(freezer + sotto vuoto)",
|
||
"history_badge_tip": "Media da {n} inserimenti precedenti",
|
||
"vacuum_question": "Messo sotto vuoto?",
|
||
"vacuum_saved": "🔒 Sotto vuoto registrato"
|
||
},
|
||
"use": {
|
||
"title": "Usa / Consuma",
|
||
"location_label": "📍 Da dove?",
|
||
"quantity_label": "Quanto hai usato?",
|
||
"change": "cambia",
|
||
"partial_hint": "Oppure specifica la quantità usata:",
|
||
"partial_piece_hint": "Hai usato solo una parte?",
|
||
"piece": "pezzo",
|
||
"one_whole": "1 intero",
|
||
"use_all": "🗑️ Usato TUTTO / Finito",
|
||
"submit": "📤 Usa questa quantità",
|
||
"available": "📦 Disponibile:",
|
||
"opened_badge": "APERTO",
|
||
"not_in_inventory": "⚠️ Prodotto non presente nell'inventario.",
|
||
"expiry_warning": "⚠️ Usa prima quella{loc} che scade il {date} — {when}!",
|
||
"expiry_warning_opened": "⚠️ Quella{loc}, aperta da {when} — usala prima!",
|
||
"throw_title": "🗑️ Butta Prodotto",
|
||
"throw_all": "🗑️ Butta TUTTO ({qty})",
|
||
"throw_qty_label": "Quanto butti?",
|
||
"throw_qty_hint": "oppure specifica la quantità:",
|
||
"throw_partial_btn": "🗑️ Butta questa quantità",
|
||
"when_expired": "scaduta da {n} giorni",
|
||
"when_today": "scade <strong>oggi</strong>",
|
||
"when_tomorrow": "scade <strong>domani</strong>",
|
||
"when_days": "scade tra <strong>{n} giorni</strong>",
|
||
"toast_used": "📤 Usato {qty} di {name}",
|
||
"toast_bring": "🛒 Prodotto finito → aggiunto a Bring!",
|
||
"toast_opened_finished": "🔓 Confezione aperta di {name} finita!",
|
||
"disambiguation_hint": "Cosa intendi con \"finito tutto\"?",
|
||
"disambiguation_all": "🗑️ Finito TUTTO ({qty})",
|
||
"error_exceeds_stock": "⚠️ Non puoi usare più di quanto hai disponibile!",
|
||
"use_all_confirm_title": "✅ Finisci tutto",
|
||
"use_all_confirm_msg": "Conferma che hai finito tutto il prodotto:",
|
||
"use_all_confirm_btn": "✅ Sì, finito",
|
||
"throw_all_confirm_title": "🗑️ Butta tutto",
|
||
"throw_all_confirm_msg": "Vuoi davvero buttare via tutto il prodotto?",
|
||
"throw_all_confirm_btn": "🗑️ Sì, butta"
|
||
},
|
||
"product": {
|
||
"title_new": "Nuovo Prodotto",
|
||
"title_edit": "Modifica Prodotto",
|
||
"ai_fill": "📷 Scatta foto e identifica con AI",
|
||
"ai_fill_hint": "L'AI compilerà automaticamente i campi del prodotto",
|
||
"name_label": "🏷️ Nome Prodotto *",
|
||
"name_placeholder": "Es: Latte intero, Pasta penne rigate...",
|
||
"brand_label": "🏢 Marca",
|
||
"brand_placeholder": "Es: Barilla, Granarolo, Mutti...",
|
||
"category_label": "📂 Categoria",
|
||
"unit_label": "📏 Unità di misura",
|
||
"default_qty_label": "🔢 Quantità default",
|
||
"conf_size_label": "📦 Ogni confezione contiene:",
|
||
"conf_size_placeholder": "es. 300",
|
||
"notes_label": "📝 Note",
|
||
"notes_placeholder": "Es: senza lattosio, bio, conservare in frigo dopo apertura...",
|
||
"barcode_label": "🔖 Barcode",
|
||
"barcode_placeholder": "Codice a barre (se disponibile)",
|
||
"barcode_hint": "⚠️ Aggiungi il barcode così al prossimo acquisto basta scansionarlo!",
|
||
"submit": "💾 Salva Prodotto",
|
||
"name_required": "Inserisci il nome del prodotto",
|
||
"conf_size_required": "Specifica il contenuto di ogni confezione",
|
||
"expiry_estimated": "Scadenza stimata:",
|
||
"scan_expiry": "Scansiona data scadenza",
|
||
"expiry_hint": "📝 Puoi modificare la data o scansionarla con la fotocamera",
|
||
"add_batch": "📦 + Lotto con scadenza diversa",
|
||
"package_info": "📦 Confezione: {info}",
|
||
"edit_catalog": "⚙️ Modifica scheda prodotto (nome, marca, categoria…)",
|
||
"not_recognized": "⚠️ Prodotto non riconosciuto",
|
||
"edit_info": "✏️ Modifica informazioni",
|
||
"modify_details": "MODIFICA\nscadenza, luogo…",
|
||
"already_in_pantry": "📋 Già in dispensa",
|
||
"no_barcode": "Senza barcode",
|
||
"unknown_product": "Prodotto non riconosciuto",
|
||
"edit_name_brand": "Modifica nome/marca",
|
||
"weight_label": "Peso",
|
||
"origin_label": "Origine",
|
||
"labels_label": "Etichette",
|
||
"select_variant": "Seleziona la variante esatta o usa i dati AI:"
|
||
},
|
||
"products": {
|
||
"title": "📦 Tutti i Prodotti",
|
||
"search_placeholder": "🔍 Cerca prodotto...",
|
||
"empty": "Nessun prodotto nel database.\nScansiona un prodotto per iniziare!",
|
||
"no_category": "Nessun prodotto in questa categoria"
|
||
},
|
||
"recipes": {
|
||
"title": "🍳 Ricette",
|
||
"generate": "✨ Genera nuova ricetta",
|
||
"archive_empty": "Nessuna ricetta salvata. Genera la tua prima ricetta!",
|
||
"dialog_title": "🍳 Ricetta",
|
||
"dialog_desc": "Genero una ricetta sana con gli ingredienti in dispensa, dando priorità a quelli in scadenza.",
|
||
"meal_label": "🕐 Per quale pasto?",
|
||
"persons_label": "👥 Quante persone?",
|
||
"meal_type_label": "🎯 Tipo di pasto",
|
||
"opt_fast": "⚡ Pasto Veloce",
|
||
"opt_light": "🥗 Poca Fame",
|
||
"opt_expiry": "⏰ Priorità Scadenze",
|
||
"opt_healthy": "💚 Extra Salutare",
|
||
"opt_opened": "📦 Priorità Cose Aperte",
|
||
"opt_zero_waste": "♻️ Zero Sprechi",
|
||
"generate_btn": "✨ Genera Ricetta",
|
||
"loading_msg": "Sto preparando la ricetta...",
|
||
"start_cooking": "👨🍳 Modalità Cucina",
|
||
"regenerate": "🔄 Generane un'altra",
|
||
"close_btn": "✅ Chiudi",
|
||
"ingredients_title": "🧾 Ingredienti",
|
||
"tools_title": "Strumenti necessari",
|
||
"steps_title": "👨🍳 Procedimento",
|
||
"no_steps": "Nessun procedimento disponibile",
|
||
"generate_error": "Errore nella generazione",
|
||
"stream_interrupted": "Generazione interrotta (risposta incompleta dal server). Controlla i log o riprova.",
|
||
"persons_short": "pers.",
|
||
"use_ingredient_title": "Usa ingrediente",
|
||
"recipe_qty_label": "Ricetta",
|
||
"from_where_label": "Da dove?",
|
||
"amount_label": "Quanto",
|
||
"use_amount_btn": "Usa questa quantità",
|
||
"use_all_btn": "Usa TUTTO / Finito",
|
||
"packs_label": "Confezioni",
|
||
"quantity_in_total": "Quantità in {unit} (totale: {total})",
|
||
"packs_of_have": "Confezioni da {size} (hai {count} conf)",
|
||
"scale_wait_stable": "Attendi 10s di stabilità per la compilazione automatica…",
|
||
"ingredient_scaled_toast": "📦 Ingrediente scalato dalla dispensa!",
|
||
"finished_added_bring_toast": "🛒 Prodotto finito → aggiunto a Bring!",
|
||
"load_error": "Errore nel caricamento"
|
||
},
|
||
"shopping": {
|
||
"title": "🛒 Lista della Spesa",
|
||
"bring_loading": "Connessione a Bring!...",
|
||
"bring_not_configured": "Bring! non è configurato. Aggiungi email e password nelle <a href='#' onclick=\"showPage('settings');return false;\">impostazioni</a>.",
|
||
"tab_to_buy": "🛍️ Da comprare",
|
||
"tab_forecast": "🧠 In previsione",
|
||
"total_label": "💰 Totale stimato",
|
||
"section_to_buy": "🛍️ Da comprare",
|
||
"suggestions_title": "💡 Suggerimenti AI",
|
||
"suggestions_add": "✅ Aggiungi selezionati a Bring!",
|
||
"search_prices": "🔍 Cerca tutti i prezzi",
|
||
"suggest_btn": "Suggerisci cosa comprare",
|
||
"smart_title": "🧠 Previsioni intelligenti",
|
||
"smart_empty": "Nessuna previsione disponibile.<br>Aggiungi prodotti alla dispensa per ricevere previsioni intelligenti.",
|
||
"smart_filter_all": "Tutti",
|
||
"smart_filter_critical": "🔴 Urgenti",
|
||
"smart_filter_high": "🟠 Presto",
|
||
"smart_filter_medium": "🟡 Pianifica",
|
||
"smart_filter_low": "🟢 Previsione",
|
||
"smart_add": "🛒 Aggiungi selezionati a Bring!",
|
||
"empty": "Lista della spesa vuota!\nUsa il pulsante sotto per generare suggerimenti.",
|
||
"already_in_list": "🛒 \"{name}\" già nella lista della spesa",
|
||
"already_in_list_short": "ℹ️ Già nella lista della spesa",
|
||
"add_prompt": "Vuoi aggiungerlo alla lista della spesa?",
|
||
"smart_already": "📊 La spesa intelligente prevede già {name}",
|
||
"all_searched": "Tutti i prodotti sono già stati cercati. Usa 🔄 per ricercare singoli.",
|
||
"search_complete": "Ricerca completata: {count} prodotti",
|
||
"removed_sufficient": "🧹 {removed} prodotto/i con scorte sufficienti rimosso/i dalla lista",
|
||
"suggest_buy": "🛒 Compra: {qty} {unit}",
|
||
"suggest_buy_approx": "🛒 Almeno: {qty} {unit}",
|
||
"suggest_buy_tip": "Quantità suggerita in base al consumo degli ultimi 14 giorni",
|
||
"suggest_buy_approx_tip": "Stima minima basata sul consumo (compra la confezione più vicina)",
|
||
"bring_badge": "🛒 Già su Bring!",
|
||
"add_urgent_toast": "🔴 {n} prodotto/i urgente/i aggiunto/i automaticamente a Bring!",
|
||
"migration_done": "✅ {migrated} aggiornati, {skipped} già ok",
|
||
"added_to_bring": "🛒 {n} prodotti aggiunti a Bring!",
|
||
"added_to_bring_skip": "{n} già presenti",
|
||
"all_on_bring": "Tutti i prodotti erano già su Bring!",
|
||
"freq_high": "📈 Uso frequente",
|
||
"freq_regular": "📊 Uso regolare",
|
||
"freq_occasional": "📉 Uso occasionale",
|
||
"out_of_stock": "Esaurito",
|
||
"scan_toast": "📷 Scansiona: {name}",
|
||
"empty_category": "Nessun prodotto in questa categoria",
|
||
"session_empty": "🛒 Nessun prodotto ancora",
|
||
"urgency_critical": "Urgente",
|
||
"urgency_high": "Presto",
|
||
"urgency_medium": "Pianifica",
|
||
"urgency_low": "Previsione",
|
||
"urgency_medium_short": "Medio",
|
||
"urgency_low_short": "Ok",
|
||
"tag_urgent": "🔴 Urgente",
|
||
"tag_priority": "⭐ Priorità",
|
||
"tag_check": "✅ Verificare",
|
||
"smart_already_predicted": "📊 La spesa intelligente prevede già <strong>{name}</strong>{urgency}.",
|
||
"item_removed": "✅ {name} rimosso dalla lista!",
|
||
"urgency_spec_critical": "⚡ Urgente",
|
||
"urgency_spec_high": "🟠 Presto",
|
||
"bring_add_n": "Aggiungi {n} a Bring!",
|
||
"bring_add_selected": "Aggiungi selezionati a Bring!",
|
||
"bring_adding": "Aggiunta in corso...",
|
||
"bring_added_one": "1 prodotto aggiunto a Bring!",
|
||
"bring_added_many": "{n} prodotti aggiunti a Bring!",
|
||
"bring_skipped": "({n} già in lista)",
|
||
"force_sync": "Forza sincronizzazione Bring!",
|
||
"scan_target_label": "Stai cercando",
|
||
"scan_target_found": "Trovato! Rimuovi dalla lista",
|
||
"bring_add_one": "Aggiungi 1 prodotto a Bring!",
|
||
"bring_add_many": "Aggiungi {n} prodotti a Bring!",
|
||
"syncing": "Sincronizzazione…",
|
||
"sync_done": "Sincronizzazione completata",
|
||
"price_searching": "Cerco...",
|
||
"search_action": "Ricerca",
|
||
"open_action": "Apri",
|
||
"not_found": "Non trovato",
|
||
"search_price": "Cerca prezzo",
|
||
"tap_to_scan": "Tocca per scansionare",
|
||
"tag_title": "Tag",
|
||
"remove_title": "Rimuovi",
|
||
"found_count": "{found}/{total} prodotti trovati",
|
||
"savings_offers": "· 🏷️ Risparmi €{amount} con le offerte",
|
||
"searching_progress": "Cerco {current}/{total}...",
|
||
"remove_error": "Errore nella rimozione",
|
||
"btn_fetch_prices": "Cerca i prezzi",
|
||
"price_total_label": "💰 Spesa stimata:",
|
||
"price_loading": "Ricerca prezzi…",
|
||
"price_not_found": "prezzo n/d",
|
||
"suggest_loading": "Analisi in corso...",
|
||
"suggest_error": "Errore nella generazione",
|
||
"priority_high": "Alta",
|
||
"priority_medium": "Media",
|
||
"priority_low": "Bassa",
|
||
"smart_last_update": "Aggiornato {time}",
|
||
"names_already_updated": "Tutti i nomi sono già aggiornati",
|
||
"pantry_hint": "Hai gia {qty} in dispensa"
|
||
},
|
||
"ai": {
|
||
"title": "🤖 Identificazione AI",
|
||
"capture": "📸 Scatta Foto",
|
||
"retake": "🔄 Riscatta",
|
||
"hint": "Scatta una foto del prodotto e l'AI cercherà di identificarlo",
|
||
"identifying": "🤖 Identifico il prodotto...",
|
||
"no_api_key": "⚠️ Chiave API Gemini non configurata.\n<small>Aggiungi GEMINI_API_KEY nel file .env sul server.</small>",
|
||
"fields_filled": "✅ Campi compilati dall'AI",
|
||
"use_data": "✅ Usa dati AI",
|
||
"use_data_no_barcode": "✅ Usa dati AI (senza barcode)"
|
||
},
|
||
"log": {
|
||
"title": "📒 Storico",
|
||
"type_added": "Aggiunto",
|
||
"type_waste": "Buttato",
|
||
"type_used": "Usato",
|
||
"type_bring": "Aggiunto a Bring!",
|
||
"undone_badge": "Annullato",
|
||
"undo_title": "Annulla questa operazione",
|
||
"load_error": "Errore nel caricamento log",
|
||
"empty": "Nessuna operazione registrata.",
|
||
"undo_action_remove": "rimozione di",
|
||
"undo_action_restore": "ripristino di",
|
||
"undo_confirm": "Annullare questa operazione?\n→ {action} {name}",
|
||
"undo_success": "↩ Operazione annullata per {name}",
|
||
"already_undone": "Operazione già annullata",
|
||
"too_old": "Non è possibile annullare operazioni più vecchie di 24 ore",
|
||
"undo_error": "Errore durante l'annullamento",
|
||
"recipe_prefix": "Ricetta"
|
||
},
|
||
"chat": {
|
||
"title": "Gemini Chef",
|
||
"welcome": "Ciao! Sono il tuo assistente cucina",
|
||
"welcome_desc": "Chiedimi di prepararti un succo, uno spuntino, un piatto veloce... Conosco la tua dispensa, i tuoi elettrodomestici e le tue preferenze!",
|
||
"suggestion_snack": "🍿 Spuntino veloce",
|
||
"suggestion_juice": "🥤 Succo/Frullato",
|
||
"suggestion_light": "🥗 Qualcosa di leggero",
|
||
"suggestion_expiry": "⏰ Usa le scadenze",
|
||
"clear": "Nuova conversazione",
|
||
"placeholder": "Chiedi qualcosa...",
|
||
"cleared": "Chat cancellata",
|
||
"suggestion_snack_text": "Cosa posso preparare per uno spuntino veloce?",
|
||
"suggestion_juice_text": "Fammi un succo o frullato con quello che ho",
|
||
"suggestion_light_text": "Ho fame ma voglio qualcosa di leggero",
|
||
"suggestion_expiry_text": "Cosa sta per scadere e come posso usarlo?",
|
||
"transfer_to_recipes": "Trasferisci a Ricette",
|
||
"transferring": "Trasferimento in corso...",
|
||
"transferred": "Aggiunta alle Ricette!",
|
||
"open_recipe": "Apri la ricetta",
|
||
"quick_recipe_prompt": "Suggeriscimi una ricetta veloce PER UNA PERSONA usando i prodotti che scadono prima! Ignora i prodotti in freezer, concentrati su frigo e dispensa."
|
||
},
|
||
"cooking": {
|
||
"close": "Chiudi",
|
||
"tts_btn": "Leggi ad alta voce",
|
||
"restart": "↺ Ricomincia",
|
||
"replay": "🔊 Rileggi",
|
||
"timer": "⏱️ {time} · Timer",
|
||
"prev": "◀ Precedente",
|
||
"next": "Successivo ▶",
|
||
"ingredient_used": "✔️ Scalato",
|
||
"ingredient_use_btn": "Usa",
|
||
"ingredient_deduct_title": "Scala dalla dispensa",
|
||
"timer_expired_tts": "Timer {label} scaduto!",
|
||
"timer_warning_tts": "Attenzione! {label}: mancano 10 secondi!",
|
||
"recipe_done_tts": "Ricetta completata! Buon appetito!",
|
||
"expires_chip": "scade {date}",
|
||
"finish": "✅ Fine",
|
||
"step_fallback": "Passo {n}",
|
||
"zerowaste_label": "♻️ Scarto",
|
||
"zerowaste_tip_title": "Consiglio anti-spreco"
|
||
},
|
||
"settings": {
|
||
"title": "⚙️ Configurazione",
|
||
"tab_api": "API Keys",
|
||
"tab_bring": "Bring!",
|
||
"tab_recipe": "Ricette",
|
||
"tab_mealplan": "Piano Settimanale",
|
||
"tab_appliances": "Elettrodomestici",
|
||
"tab_spesa": "Spesa Online",
|
||
"tab_camera": "Fotocamera",
|
||
"tab_security": "Sicurezza",
|
||
"tab_tts": "Voce (TTS)",
|
||
"tab_language": "Lingua",
|
||
"tab_scale": "Bilancia Smart",
|
||
"gemini": {
|
||
"title": "🤖 Google Gemini AI",
|
||
"hint": "Chiave API per identificazione prodotti, scadenze e ricette.",
|
||
"key_label": "API Key Gemini"
|
||
},
|
||
"bring": {
|
||
"title": "🛒 Bring! Shopping List",
|
||
"hint": "Credenziali per l'integrazione con la lista della spesa Bring!",
|
||
"email_label": "📧 Email Bring!",
|
||
"password_label": "🔒 Password Bring!"
|
||
},
|
||
"price": {
|
||
"title": "💰 Stima Prezzi (AI)",
|
||
"hint": "Mostra il costo stimato di ogni prodotto nella lista della spesa usando l'AI.",
|
||
"enabled_label": "Attiva stima prezzi",
|
||
"country_label": "🌍 Paese di riferimento",
|
||
"currency_label": "💱 Valuta",
|
||
"update_label": "🔄 Aggiorna prezzi ogni",
|
||
"update_suffix": "mesi"
|
||
},
|
||
"recipe": {
|
||
"title": "🍳 Preferenze Ricette",
|
||
"hint": "Configura le opzioni predefinite per la generazione delle ricette.",
|
||
"persons_label": "👥 Persone predefinite",
|
||
"options_label": "🎯 Opzioni ricetta predefinite",
|
||
"fast": "⚡ Pasto Veloce",
|
||
"light": "🥗 Poca Fame",
|
||
"expiry": "⏰ Priorità Scadenze",
|
||
"healthy": "💚 Extra Salutare",
|
||
"opened": "📦 Priorità Cose Aperte",
|
||
"zerowaste": "♻️ Zero Sprechi",
|
||
"dietary_label": "🚫 Intolleranze / Restrizioni",
|
||
"dietary_placeholder": "Es: senza glutine, senza lattosio, vegetariano..."
|
||
},
|
||
"mealplan": {
|
||
"title": "📅 Piano Pasti Settimanale",
|
||
"hint": "Imposta la tipologia di pasto per ogni giorno. Sarà usata come guida nella generazione delle ricette.",
|
||
"enabled": "✅ Attiva piano pasti settimanale",
|
||
"legend": "🌤️ = Pranzo · 🌙 = Cena · Tocca un badge per cambiarlo.",
|
||
"types_title": "📋 Tipologie disponibili",
|
||
"reset_btn": "↺ Ripristina default"
|
||
},
|
||
"appliances": {
|
||
"title": "🔌 Elettrodomestici Disponibili",
|
||
"hint": "Indica gli elettrodomestici che hai a disposizione. Saranno considerati nella generazione delle ricette.",
|
||
"new_placeholder": "Es: Macchina del pane, Bimby, Friggitrice ad aria...",
|
||
"quick_title": "Aggiungi velocemente:",
|
||
"oven": "🔥 Forno",
|
||
"microwave": "📡 Microonde",
|
||
"air_fryer": "🍟 Friggitrice ad aria",
|
||
"bread_maker": "🍞 Macchina pane",
|
||
"bimby": "🤖 Bimby/Cookeo",
|
||
"mixer": "🌀 Planetaria",
|
||
"steamer": "♨️ Vaporiera",
|
||
"pressure_cooker": "🫕 Pentola pressione",
|
||
"toaster": "🍞 Tostapane",
|
||
"blender": "🍹 Frullatore",
|
||
"empty": "Nessun elettrodomestico aggiunto"
|
||
},
|
||
"spesa": {
|
||
"title": "🛍️ Spesa Online",
|
||
"hint": "Configura il provider per la spesa online.",
|
||
"provider_label": "🏪 Provider",
|
||
"email_label": "📧 Email",
|
||
"password_label": "🔒 Password",
|
||
"login_btn": "🔐 Accedi",
|
||
"ai_prompt_label": "🤖 Prompt AI selezione prodotto",
|
||
"ai_prompt_placeholder": "Istruzioni per l'AI quando deve scegliere tra più prodotti...",
|
||
"ai_prompt_hint": "L'AI usa questo prompt per scegliere il prodotto più appropriato tra i risultati. Lascia vuoto per il comportamento predefinito.",
|
||
"configure_first": "Configura prima la Spesa Online nelle impostazioni",
|
||
"missing_credentials": "Inserisci email e password",
|
||
"login_in_progress": "Accesso in corso...",
|
||
"login_error_prefix": "Errore:",
|
||
"login_network_error_prefix": "Errore di rete:",
|
||
"login_success_default": "Login effettuato!",
|
||
"result_name_label": "Nome",
|
||
"result_card_label": "Tessera",
|
||
"result_pickup_label": "Punto Ritiro",
|
||
"result_points_label": "Punti Fedeltà",
|
||
"connected_relogin": "✅ Connesso — Riaccedi",
|
||
"connected_as": "Connesso come {name}"
|
||
},
|
||
"camera": {
|
||
"title": "📷 Fotocamera",
|
||
"hint": "Scegli quale fotocamera utilizzare per la scansione barcode e l'identificazione AI.",
|
||
"device_label": "📸 Fotocamera predefinita",
|
||
"back": "📱 Posteriore (default)",
|
||
"front": "🤳 Anteriore",
|
||
"devices_hint": "Se hai più fotocamere, puoi selezionarne una specifica dall'elenco sopra dopo aver concesso i permessi.",
|
||
"detect_btn": "🔄 Rileva fotocamere"
|
||
},
|
||
"security": {
|
||
"title": "🔒 Certificato HTTPS",
|
||
"hint": "Se il browser mostra l'errore \"La connessione non è privata\" (ERR_CERT_AUTHORITY_INVALID), devi installare il certificato CA nel dispositivo.",
|
||
"download_btn": "📥 Scarica Certificato CA",
|
||
"token_title": "🔑 Token Impostazioni",
|
||
"token_label": "Token di accesso",
|
||
"token_hint": "Se `SETTINGS_TOKEN` è configurato nel `.env` server, inserisci qui il token prima di salvare le impostazioni. Lascia vuoto se non configurato.",
|
||
"token_placeholder": "(vuoto = nessuna protezione)",
|
||
"token_required_hint": "🔒 Questo server richiede un token per salvare le impostazioni.",
|
||
"cert_instructions": "<strong>Istruzioni per Chrome (Android):</strong><br>1. Scarica il certificato qui sopra<br>2. Vai in <em>Impostazioni → Sicurezza e privacy → Altre impostazioni di sicurezza → Installa da archivio dispositivo</em><br>3. Seleziona il file <em>EverShelf_CA.crt</em> scaricato<br>4. Scegli \"CA\" e conferma<br>5. Riavvia Chrome<br><br><strong>Istruzioni per Chrome (PC):</strong><br>1. Scarica il certificato qui sopra<br>2. Vai in <em>chrome://settings/certificates</em> (o Impostazioni → Privacy e sicurezza → Sicurezza → Gestisci certificati)<br>3. Tab \"Autorità\" → Importa → seleziona il file<br>4. Spunta \"Considera attendibile per identificare siti web\"<br>5. Riavvia Chrome"
|
||
},
|
||
"tts": {
|
||
"title": "🔊 Voce & TTS",
|
||
"hint": "Configura la sintesi vocale tramite qualsiasi API REST esterna. I passi della ricetta e i timer scaduti verranno inviati all'endpoint configurato.",
|
||
"enabled": "✅ Attiva TTS",
|
||
"engine_label": "⚙️ Motore TTS",
|
||
"engine_browser": "🔇 Browser (offline, nessuna configurazione)",
|
||
"engine_server": "🌐 Server esterno (Home Assistant, API REST...)",
|
||
"voice_label": "🗣️ Voce",
|
||
"rate_label": "⚡ Velocità",
|
||
"pitch_label": "🎵 Tono",
|
||
"url_label": "🌐 URL Endpoint",
|
||
"method_label": "📡 Metodo HTTP",
|
||
"auth_label": "🔐 Autenticazione",
|
||
"auth_bearer": "Bearer Token",
|
||
"auth_custom": "Header personalizzato",
|
||
"auth_none": "Nessuna",
|
||
"token_label": "🔑 Bearer Token",
|
||
"custom_header_name": "📋 Nome header",
|
||
"custom_header_value": "📋 Valore header",
|
||
"content_type_label": "📄 Content-Type",
|
||
"payload_key_label": "🗝️ Campo testo nel payload",
|
||
"payload_key_hint": "Nome del campo JSON che conterrà il testo da leggere (es: message, text).",
|
||
"extra_fields_label": "➕ Campi extra (JSON)",
|
||
"extra_fields_placeholder": "{\"entity_id\": \"media_player.living_room\"}",
|
||
"extra_fields_hint": "Campi aggiuntivi da includere nel payload, in formato JSON. Lascia vuoto se non necessario.",
|
||
"test_btn": "🔊 Invia Test Vocale",
|
||
"voices_loading": "Caricamento voci…",
|
||
"voice_not_supported": "Voce non supportata dal browser",
|
||
"voices_none": "Nessuna voce disponibile su questo dispositivo",
|
||
"voices_hint": "Le voci disponibili dipendono dal sistema operativo e dal browser. Su macOS/iOS è disponibile la voce Paola (italiano). Premi ↺ se la lista non si carica.",
|
||
"url_missing": "⚠️ URL endpoint mancante.",
|
||
"test_sending": "⏳ Invio in corso…",
|
||
"test_ok": "✅ Risposta {code} — controlla che l'altoparlante abbia parlato."
|
||
},
|
||
"language": {
|
||
"title": "🌐 Lingua / Language",
|
||
"hint": "Seleziona la lingua dell'interfaccia. Select the interface language.",
|
||
"label": "🌐 Lingua",
|
||
"restart_notice": "La pagina verrà ricaricata per applicare la nuova lingua."
|
||
},
|
||
"screensaver": {
|
||
"label": "Attiva salvaschermo",
|
||
"card_title": "🌙 Salvaschermo",
|
||
"card_hint": "Mostra un orologio con fatti utili dopo 5 minuti di inattività. Di default è disattivato.",
|
||
"timeout_1": "1 minuto",
|
||
"timeout_2": "2 minuti",
|
||
"timeout_5": "5 minuti",
|
||
"timeout_10": "10 minuti",
|
||
"timeout_15": "15 minuti",
|
||
"timeout_30": "30 minuti",
|
||
"timeout_60": "1 ora",
|
||
"start_after": "⏱️ Avvia dopo"
|
||
},
|
||
"scale": {
|
||
"title": "⚖️ Bilancia Smart",
|
||
"hint": "Collega una bilancia Bluetooth tramite il gateway Android per leggere il peso automaticamente.",
|
||
"tab": "Bilancia Smart",
|
||
"enabled": "✅ Abilita bilancia smart",
|
||
"url_label": "🌐 URL Gateway WebSocket",
|
||
"url_placeholder": "ws://192.168.1.x:8765",
|
||
"url_hint": "URL mostrato dall'app Android (stessa rete Wi-Fi). Es:",
|
||
"test_btn": "🔗 Testa connessione",
|
||
"download_btn": "📥 Scarica Gateway Android (APK)",
|
||
"download_hint": "App Android che fa da ponte tra la bilancia BLE e questo sito.",
|
||
"download_sub": "Sorgente: evershelf-scale-gateway/ nella root del progetto",
|
||
"live_weight": "peso in tempo reale",
|
||
"auto_reconnect": "🔁 Riconnessione: automatica",
|
||
"kiosk_title": "📡 Bilancia BLE integrata nel Kiosk",
|
||
"kiosk_hint": "La bilancia è gestita direttamente dal Gateway BLE interno al kiosk. Per abbinare un nuovo dispositivo usa il wizard di configurazione.",
|
||
"kiosk_reconfigure": "🔄 Riconfigura bilancia BLE",
|
||
"ble_protocols": "<p style=\"margin:0 0 6px;font-weight:600\">🔌 Protocolli BLE supportati:</p><ul style=\"margin:0 0 0 16px;padding:0;font-size:0.8rem\"><li>Bluetooth SIG Weight Scale (0x181D)</li><li>Bluetooth SIG Body Composition (0x181B) — peso, grasso, BMI</li><li>Xiaomi Mi Body Composition Scale 2</li><li>Generico — heuristica automatica su 100+ modelli</li></ul>"
|
||
},
|
||
"kiosk": {
|
||
"hint": "Trasforma un tablet Android in un pannello EverShelf sempre acceso, con bilancia BLE integrata.",
|
||
"download_btn": "📥 Scarica EverShelf Kiosk (APK)",
|
||
"download_sub": "Modalità kiosk full-screen + gateway bilancia integrato. Sorgente: evershelf-kiosk/",
|
||
"native_title": "Configurazione Kiosk",
|
||
"native_hint": "URL server, bilancia BLE, salvaschermo e setup wizard.",
|
||
"native_btn": "Apri configurazione kiosk",
|
||
"native_tap_hint": "Tocca la rotella in alto a destra",
|
||
"native_update_hint": "Aggiorna l'app kiosk per usare questa funzione",
|
||
"update_title": "Aggiornamento Kiosk",
|
||
"check_updates_btn": "🔍 Cerca aggiornamenti",
|
||
"needs_update": "⚠️ Il kiosk installato non supporta questa funzione. Aggiorna l'app kiosk per abilitarla."
|
||
},
|
||
"saved": "✅ Configurazione salvata!",
|
||
"saved_local": "✅ Configurazione salvata localmente",
|
||
"saved_local_error": "⚠️ Salvato localmente, errore server: {error}",
|
||
"theme": {
|
||
"title": "🌙 Tema / Aspetto",
|
||
"hint": "Scegli il tema dell interfaccia.",
|
||
"label": "🌙 Tema",
|
||
"off": "☀️ Chiaro",
|
||
"on": "🌙 Scuro",
|
||
"auto": "🔄 Automatico (orario)"
|
||
},
|
||
"zerowaste": {
|
||
"card_title": "♻️ Suggerimenti zero-waste",
|
||
"card_hint": "Durante la cottura, mostra consigli su come riutilizzare gli scarti prodotti in ogni passo (bucce, acqua di cottura, ecc.). Disattivo per impostazione predefinita.",
|
||
"label": "Mostra suggerimenti durante la cottura"
|
||
},
|
||
"backup": {
|
||
"tab": "Backup",
|
||
"local_title": "Backup Locale",
|
||
"local_hint": "Snapshot giornaliero del database. Configura quanti giorni di backup conservare.",
|
||
"enabled": "Backup automatico quotidiano",
|
||
"retention_days": "Giorni di retention",
|
||
"retention_info": "I backup vengono conservati per",
|
||
"backup_now": "Backup Ora",
|
||
"backing_up": "Backup in corso…",
|
||
"backed_up": "Backup completato",
|
||
"backup_error": "Errore backup",
|
||
"last_backup": "Ultimo backup",
|
||
"no_backup_yet": "Nessun backup ancora eseguito",
|
||
"list_empty": "Nessun backup disponibile",
|
||
"restore_btn": "Ripristina",
|
||
"restore_confirm": "Ripristinare il backup",
|
||
"delete_btn": "Elimina",
|
||
"delete_confirm": "Eliminare il backup",
|
||
"gdrive_title": "Google Drive",
|
||
"gdrive_hint": "Backup automatici su Google Drive via OAuth 2.0. Nessuna libreria esterna richiesta.",
|
||
"gdrive_enabled": "Abilita backup Google Drive",
|
||
"gdrive_folder_id": "ID Cartella Drive",
|
||
"gdrive_folder_id_hint": "Copia l'ID dalla URL della cartella Drive: …/folders/<strong>ID</strong>",
|
||
"gdrive_retention_days": "Retention Drive (giorni, 0=tutto)",
|
||
"gdrive_test": "Testa Connessione",
|
||
"gdrive_ok": "Connessione riuscita!",
|
||
"gdrive_error": "Connessione fallita",
|
||
"gdrive_push_now": "Carica Ora su Drive",
|
||
"gdrive_pushing": "Upload in corso…",
|
||
"gdrive_pushed": "Caricato su Drive",
|
||
"gdrive_wizard_hint": "Opzionale: backup giornaliero automatico su Google Drive via OAuth 2.0.",
|
||
"gdrive_skip": "Salta — configura dopo in Impostazioni",
|
||
"gdrive_client_id": "Client ID",
|
||
"gdrive_client_secret": "Client Secret",
|
||
"gdrive_redirect_uri_label": "Redirect URI (da aggiungere in Google Cloud Console):",
|
||
"gdrive_redirect_uri_hint": "Aggiungi <strong>http://localhost</strong> come URI di reindirizzamento autorizzato in Google Cloud Console. Funziona su qualsiasi server, anche senza dominio pubblico.",
|
||
"gdrive_oauth_authorize": "Autorizza con Google",
|
||
"gdrive_oauth_authorized": "Autorizzato",
|
||
"gdrive_oauth_not_authorized": "Non ancora autorizzato",
|
||
"gdrive_oauth_window_opened": "Finestra aperta — autorizza e torna qui",
|
||
"gdrive_oauth_how_to": "Come configurare OAuth 2.0 (passo dopo passo)",
|
||
"gdrive_oauth_steps": "<li>Vai su <a href='https://console.cloud.google.com/' target='_blank' rel='noopener'>console.cloud.google.com</a> e seleziona il progetto</li><li>Abilita la <strong>Google Drive API</strong>: <em>API e servizi → Abilita API → Google Drive API</em></li><li>Vai su <em>API e servizi → Credenziali → Crea credenziali → ID client OAuth 2.0</em></li><li>Tipo applicazione: <strong>Applicazione web</strong>; aggiungi <strong>http://localhost</strong> come <em>URI di reindirizzamento autorizzato</em></li><li>Copia <strong>Client ID</strong> e <strong>Client Secret</strong> nei campi qui sopra e salva</li><li>Clicca <strong>Autorizza con Google</strong>, accedi e concedi l'accesso</li><li>Il browser aprirà <code>http://localhost</code> (possibile errore di connessione è normale): copia l'URL dalla barra degli indirizzi e incollalo nel campo che appare qui sotto</li>",
|
||
"gdrive_code_title": "Incolla l'URL o il codice di autorizzazione",
|
||
"gdrive_code_hint": "Dopo aver autorizzato, il browser aprirà http://localhost e potrebbe mostrare un errore. Copia l'URL dalla barra degli indirizzi (es. <code>http://localhost/?code=4%2F0A...</code>) e incollalo qui.",
|
||
"gdrive_code_submit": "Conferma",
|
||
"gdrive_code_empty": "Incolla prima l'URL o il codice di autorizzazione"
|
||
},
|
||
"info": {
|
||
"tab": "Info",
|
||
"ai_title": "Gemini AI — Utilizzo Token",
|
||
"ai_hint": "Consumo mensile e costo stimato per la chiave API corrente.",
|
||
"loading": "Caricamento…",
|
||
"total_tokens": "Token totali",
|
||
"est_cost": "Costo stimato",
|
||
"input_tok": "Token input",
|
||
"output_tok": "Token output",
|
||
"ai_calls": "Chiamate",
|
||
"by_action": "Dettaglio per funzione",
|
||
"by_model": "Dettaglio per modello",
|
||
"pricing_note": "Prezzi di riferimento Gemini: 2.5-flash $0.15/M in · $0.60/M out — 2.0-flash $0.10/M in · $0.40/M out.",
|
||
"system_title": "Sistema",
|
||
"db_size": "Database",
|
||
"log_size": "Log",
|
||
"log_level": "Livello log",
|
||
"ai_overview": "Prospetto utilizzo AI, inventario e stato del sistema",
|
||
"calls_unit": "call",
|
||
"inv_title": "Inventario",
|
||
"inv_active": "Attivi",
|
||
"inv_products": "Prodotti totali",
|
||
"inv_expiring": "In scadenza (7gg)",
|
||
"inv_expired": "Scaduti",
|
||
"inv_finished": "Finiti",
|
||
"act_title": "Attività del mese",
|
||
"act_tx_month": "Movimenti",
|
||
"act_restock": "Acquisti",
|
||
"act_use": "Consumi",
|
||
"act_new_products": "Nuovi prodotti",
|
||
"act_tx_year": "Movimenti anno",
|
||
"price_cache": "Cache prezzi",
|
||
"cache_entries": "prodotti",
|
||
"last_backup": "Ultimo backup",
|
||
"bring_days": "token scade tra {n} giorni",
|
||
"bring_expired": "token scaduto",
|
||
"year_label": "Anno {year}",
|
||
"currency_title": "Valuta",
|
||
"currency_hint": "La valuta usata per tutti i costi e i prezzi nell'app."
|
||
},
|
||
"tab_general": "Generali",
|
||
"shopping": {
|
||
"tab": "Lista spesa",
|
||
"title": "Lista della spesa",
|
||
"hint": "Configura la lista della spesa integrata o collega Bring!.",
|
||
"enable_label": "Abilita lista della spesa",
|
||
"mode_label": "Provider",
|
||
"mode_internal": "Interno (senza Bring!)",
|
||
"mode_bring": "Bring! (app esterna)",
|
||
"bring_section_title": "Configurazione Bring!",
|
||
"ai_section_title": "Assistenza AI",
|
||
"smart_suggestions_label": "Suggerimenti AI",
|
||
"forecast_label": "Previsione prodotti in esaurimento",
|
||
"auto_add_label": "Aggiungi automaticamente quando",
|
||
"auto_add_suffix": "rimasto in magazzino (0 = solo quando esaurito)"
|
||
}
|
||
},
|
||
"expiry": {
|
||
"today": "OGGI",
|
||
"tomorrow": "Domani",
|
||
"days": "{days} giorni",
|
||
"expired_days": "Da {days}g",
|
||
"expired_yesterday": "Da ieri",
|
||
"expired_today": "Oggi",
|
||
"badge_today": "⚠️ Scade oggi!",
|
||
"badge_tomorrow": "⏰ Domani",
|
||
"badge_tomorrow_long": "⏰ Scade domani",
|
||
"badge_days": "⏰ {n} giorni",
|
||
"badge_expired_ago": "⚠️ Scaduto da {n}g",
|
||
"badge_expired": "⛔ Scaduto!",
|
||
"badge_stable": "✅ Stabile",
|
||
"badge_expiring_short": "⏰ Scade fra {n}gg",
|
||
"badge_ok_still": "✅ Ancora {n}gg",
|
||
"badge_expires_red": "🔴 Scade tra {n}g",
|
||
"badge_expires_yellow": "🟡 Scade tra {n}g",
|
||
"badge_expired_bare": "⚠️ Scaduto",
|
||
"badge_expires_warn": "⚠️ Scade tra {n}gg",
|
||
"badge_days_left": "⏳ ~{n}gg rimasti",
|
||
"days_approx": "~{n} giorni",
|
||
"weeks_approx": "~{n} settimane",
|
||
"months_approx": "~{n} mesi",
|
||
"years_approx": "~{n} anni",
|
||
"expired_today_long": "Scaduto oggi",
|
||
"expired_ago_long": "Scaduto da {n} giorni",
|
||
"expired_suffix": "— Scaduto!",
|
||
"expired_suffix_ok": "— Scaduto (ancora ok)",
|
||
"expired_suffix_warning": "— Scaduto (controlla)",
|
||
"opened_ago_long": "Aperto da {n} giorni",
|
||
"opened_today_long": "Aperto oggi",
|
||
"opened_suffix": "— Aperto da troppo tempo!",
|
||
"opened_suffix_ok": "— Aperto (ancora ok)",
|
||
"opened_suffix_warning": "— Aperto (controlla)",
|
||
"days_compact": "{n}gg",
|
||
"badge_check_soon": "Controlla presto"
|
||
},
|
||
"status": {
|
||
"ok": "OK",
|
||
"check": "Controlla",
|
||
"discard": "Buttare",
|
||
"tip_freezer_ok": "In freezer: ancora sicuro (~{n}g di margine)",
|
||
"tip_freezer_check": "In freezer da molto, potrebbe aver perso qualità. Consumare presto",
|
||
"tip_freezer_danger": "In freezer da troppo tempo, rischio di bruciatura da gelo e degrado",
|
||
"tip_highRisk_check": "Scaduto da poco, controlla odore e aspetto prima di consumare",
|
||
"tip_highRisk_danger": "Prodotto deperibile scaduto: da buttare per sicurezza",
|
||
"tip_medRisk_check1": "Controlla aspetto e odore prima di consumare",
|
||
"tip_medRisk_check2": "Scaduto da un po', verificare bene prima dell'uso",
|
||
"tip_medRisk_danger": "Troppo tempo dalla scadenza, meglio buttare",
|
||
"tip_lowRisk_ok": "Prodotto a lunga conservazione, ancora sicuro da consumare",
|
||
"tip_lowRisk_check": "Scaduto da oltre un mese, controllare integrità confezione",
|
||
"tip_lowRisk_danger": "Scaduto da troppo tempo, meglio non rischiare"
|
||
},
|
||
"toast": {
|
||
"product_saved": "Prodotto salvato!",
|
||
"product_created": "Prodotto creato!",
|
||
"product_updated": "✅ Prodotto aggiornato!",
|
||
"product_removed": "Prodotto rimosso",
|
||
"updated": "Aggiornato!",
|
||
"quantity_confirmed": "✓ Quantità confermata",
|
||
"added_to_inventory": "✅ {name} aggiunto!",
|
||
"removed_from_list": "✅ {name} rimosso dalla lista!",
|
||
"removed_from_list_short": "Rimosso dalla lista",
|
||
"added_to_shopping": "🛒 Aggiunto alla lista della spesa!",
|
||
"removed_from_shopping": "🛒 Rimosso dalla lista della spesa",
|
||
"finished_to_bring": "🛒 Prodotto finito → aggiunto a Bring!",
|
||
"thrown_away": "🗑️ {name} buttato!",
|
||
"thrown_away_partial": "🗑️ Buttato {qty} {unit} di {name}",
|
||
"finished_all": "📤 {name} terminato!",
|
||
"vacuum_sealed": "{name} salvato come sottovuoto",
|
||
"product_finished_confirmed": "✅ Rimosso — riaggiungi quando ne ricompri",
|
||
"appliance_added": "Elettrodomestico aggiunto",
|
||
"item_added": "{name} aggiunto"
|
||
},
|
||
"antiwaste": {
|
||
"title": "🌱 Rapporto Anti-Spreco",
|
||
"grade_label": "Voto",
|
||
"you": "Tu",
|
||
"avg_label": "Media",
|
||
"better": "🎉 Perdi il {diff}% in meno della {country}!",
|
||
"worse": "⚠️ Perdi più della media {country}. Puoi migliorare!",
|
||
"on_par": "→ Sei nella media {country}. Prova a fare ancora meglio!",
|
||
"saved_money": "~{amount}/mese risparmiati",
|
||
"saved_meals": "~{n} pasti salvati",
|
||
"saved_co2": "{n} kg CO₂ evitata",
|
||
"trend_title": "Andamento (ultimi 3 mesi)",
|
||
"months_ago_2": "-60 gg",
|
||
"months_ago_1": "-30 gg",
|
||
"this_month": "Ora",
|
||
"country_it": "media italiana",
|
||
"country_de": "media tedesca",
|
||
"country_en": "media USA",
|
||
"source": "Fonti: REDUCE, Eurostat, USDA 2021",
|
||
"live_on": "Dati in tempo reale",
|
||
"live_off": "Offline",
|
||
"meals": "pasti",
|
||
"annual_info": "📅 Tu ~{you} kg/anno · media ~{avg} kg/anno",
|
||
"badge_rate": "tasso perdita",
|
||
"badge_saved_money": "risparmio vs media",
|
||
"badge_wasted": "prod. persi",
|
||
"badge_better": "in meno vs media"
|
||
},
|
||
"error": {
|
||
"generic": "Errore",
|
||
"network": "Errore di rete",
|
||
"no_api_key": "Configura la chiave API nelle impostazioni",
|
||
"loading": "Errore nel caricamento del prodotto",
|
||
"not_found": "Prodotto non trovato",
|
||
"not_found_manual": "Prodotto non trovato. Inseriscilo manualmente.",
|
||
"search": "Errore nella ricerca. Riprova.",
|
||
"search_short": "Errore nella ricerca",
|
||
"save": "Errore nel salvataggio",
|
||
"connection": "Errore di connessione",
|
||
"camera": "Impossibile accedere alla fotocamera",
|
||
"bring_add": "Errore nell'aggiunta a Bring!",
|
||
"bring_connection": "Errore connessione Bring!",
|
||
"identification": "Errore nell'identificazione",
|
||
"ai_quota": "Quota AI esaurita. Riprova tra qualche minuto.",
|
||
"barcode_empty": "Inserisci un codice a barre",
|
||
"barcode_format": "Il codice a barre deve contenere solo numeri (4-14 cifre)",
|
||
"min_chars": "Scrivi almeno 2 caratteri",
|
||
"not_in_inventory": "Prodotto non nell'inventario",
|
||
"appliance_exists": "Elettrodomestico già presente",
|
||
"already_exists": "Già presente",
|
||
"network_retry": "Errore di connessione. Riprova.",
|
||
"select_items": "Seleziona almeno un prodotto",
|
||
"server_offline": "Connessione al server persa",
|
||
"server_restored": "Connessione al server ripristinata",
|
||
"server_retry": "Riprova",
|
||
"unknown": "Errore sconosciuto",
|
||
"prefix": "Errore",
|
||
"no_inventory_entry": "Nessuna voce di inventario trovata"
|
||
},
|
||
"confirm": {
|
||
"remove_item": "Vuoi davvero rimuovere questo prodotto dall'inventario?",
|
||
"kiosk_exit": "Uscire dalla modalità kiosk?",
|
||
"cancel": "Annulla",
|
||
"proceed": "Conferma"
|
||
},
|
||
"location": {
|
||
"dispensa": "Dispensa",
|
||
"frigo": "Frigo",
|
||
"freezer": "Freezer"
|
||
},
|
||
"edit": {
|
||
"title": "Modifica {name}",
|
||
"unknown_hint": "Inserisci il nome e le informazioni del prodotto",
|
||
"label_name": "🏷️ Nome prodotto",
|
||
"choose_location_title": "Quale modifica?",
|
||
"choose_location_hint": "Scegli la posizione da modificare:"
|
||
},
|
||
"screensaver": {
|
||
"recipe_btn": "Ricette",
|
||
"scan_btn": "Scansiona prodotto"
|
||
},
|
||
"days": {
|
||
"mon": "Lunedì",
|
||
"tue": "Martedì",
|
||
"wed": "Mercoledì",
|
||
"thu": "Giovedì",
|
||
"fri": "Venerdì",
|
||
"sat": "Sabato",
|
||
"sun": "Domenica",
|
||
"mon_short": "Lun",
|
||
"tue_short": "Mar",
|
||
"wed_short": "Mer",
|
||
"thu_short": "Gio",
|
||
"fri_short": "Ven",
|
||
"sat_short": "Sab",
|
||
"sun_short": "Dom"
|
||
},
|
||
"meal_types": {
|
||
"lunch": "Pranzo",
|
||
"dinner": "Cena",
|
||
"colazione": "Colazione",
|
||
"merenda": "Merenda",
|
||
"dolce": "Dolce",
|
||
"succo": "Succo di Frutta",
|
||
"pranzo": "Pranzo",
|
||
"cena": "Cena"
|
||
},
|
||
"scale": {
|
||
"status_connected": "Bilancia connessa",
|
||
"status_searching": "Connesso al gateway, attesa bilancia…",
|
||
"status_disconnected": "Gateway bilancia non raggiungibile",
|
||
"status_error": "Errore connessione gateway",
|
||
"not_connected": "Gateway bilancia non connesso",
|
||
"read_btn": "⚖️ Leggi dalla bilancia",
|
||
"reading_title": "Lettura bilancia",
|
||
"place_on_scale": "Metti il prodotto sulla bilancia…",
|
||
"waiting_stable": "Il peso venire rilevato automaticamente quando la lettura sarà stabile.",
|
||
"no_url": "Inserisci l'URL del gateway",
|
||
"testing": "⏳ Test connessione…",
|
||
"connected_ok": "Connessione gateway riuscita!",
|
||
"timeout": "Timeout: nessuna risposta dal gateway",
|
||
"error_connect": "Impossibile connettersi al gateway",
|
||
"tab": "Bilancia Smart",
|
||
"low_weight": "Peso < 10 g · inserisci manualmente\n(la lettura automatica richiede almeno 10 g)",
|
||
"density_hint": "(densità {density} g/ml)",
|
||
"ml_hint": "(verrà convertito in ml)",
|
||
"weight_detected": "Peso rilevato — attendi 10s di stabilità…",
|
||
"weight_too_low": "Peso troppo basso — attendi…",
|
||
"stable": "✓ Stabile",
|
||
"auto_confirm": "✅ {val} {unit} — conferma automatica tra 5s (tocca per annullare)",
|
||
"cancelled_replace": "Annullato — rimetti l'ingrediente sulla bilancia per riprendere"
|
||
},
|
||
"prediction": {
|
||
"expected_qty": "Previsto: {expected} {unit}",
|
||
"actual_qty": "Attuale: {actual} {unit}",
|
||
"check_suggestion": "Verifica o pesa la quantità residua"
|
||
},
|
||
"date": {
|
||
"today": "📅 Oggi",
|
||
"yesterday": "📅 Ieri"
|
||
},
|
||
"scanner": {
|
||
"title_barcode": "🔖 Scansiona Barcode",
|
||
"barcode_hint": "Inquadra il codice a barre del prodotto",
|
||
"barcode_manual_placeholder": "O inserisci manualmente...",
|
||
"barcode_use_btn": "✅ Usa questo codice",
|
||
"ai_identifying": "🤖 Identifico il prodotto...",
|
||
"ai_analyzing": "🤖 Analisi AI in corso...",
|
||
"product_label_hint": "Inquadra l'etichetta del prodotto",
|
||
"expiry_label_hint": "Inquadra la data di scadenza stampata sul prodotto",
|
||
"capture_btn": "📸 Scatta",
|
||
"capture_photo_btn": "📸 Scatta Foto",
|
||
"retake_btn": "🔄 Riscatta",
|
||
"camera_error_hint": "Assicurati di usare HTTPS e di aver concesso i permessi della fotocamera.<br>Puoi inserire il barcode manualmente o usare l'identificazione AI.",
|
||
"no_barcode": "Senza barcode",
|
||
"save_new_btn": "🆕 Non è nessuno di questi — salva come nuovo",
|
||
"expiry_found": "Data trovata",
|
||
"expiry_read_fail": "Non riesco a leggere la data.",
|
||
"expiry_raw_label": "Letto"
|
||
},
|
||
"lowstock": {
|
||
"title": "⚠️ Sta per finire!",
|
||
"message": "{name} sta per finire — rimangono solo {qty}.",
|
||
"question": "Vuoi aggiungerlo alla lista della spesa?",
|
||
"yes": "🛒 Sì, aggiungi a Bring!",
|
||
"no": "No, per ora va bene"
|
||
},
|
||
"move": {
|
||
"title": "📦 Spostare il resto?",
|
||
"question": "Vuoi spostare {thing} di {name} in un'altra posizione?",
|
||
"question_short": "Vuoi spostare {thing} in un'altra posizione?",
|
||
"thing_opened": "la confezione aperta",
|
||
"thing_rest": "il resto",
|
||
"stay_btn": "No, resta in {location}",
|
||
"moved_toast": "📦 Confezione aperta spostata in {location}",
|
||
"vacuum_restore": "Torna sotto vuoto",
|
||
"vacuum_seal_rest": "Metti sotto vuoto il resto"
|
||
},
|
||
"nova": {
|
||
"1": "Non trasformato",
|
||
"2": "Ingrediente culinario",
|
||
"3": "Trasformato",
|
||
"4": "Ultra-trasformato"
|
||
},
|
||
"meal_plan_types": {
|
||
"pasta": "Pasta",
|
||
"riso": "Riso",
|
||
"carne": "Carne",
|
||
"pesce": "Pesce",
|
||
"legumi": "Legumi",
|
||
"uova": "Uova",
|
||
"formaggio": "Formaggio",
|
||
"pizza": "Pizza",
|
||
"affettati": "Affettati",
|
||
"verdure": "Verdure",
|
||
"zuppa": "Zuppa",
|
||
"insalata": "Insalata",
|
||
"pane": "Pane/Sandwich",
|
||
"dolce": "Dolce",
|
||
"libero": "Libero"
|
||
},
|
||
"meal_sub": {
|
||
"dolce_torta": "Torta",
|
||
"dolce_crema": "Crema / Budino",
|
||
"dolce_crumble": "Crumble / Crostata",
|
||
"dolce_biscotti": "Biscotti / Pasticcini",
|
||
"dolce_frutta": "Dolce alla Frutta",
|
||
"succo_dolce": "Dolce / Fruttato",
|
||
"succo_energizzante": "Energizzante",
|
||
"succo_detox": "Detox / Verde",
|
||
"succo_rinfrescante": "Rinfrescante",
|
||
"succo_vitaminico": "Vitaminico / Agrumi"
|
||
},
|
||
"meal_plan": {
|
||
"reset_success": "Piano settimanale ripristinato",
|
||
"suggested_by": "suggerito dal piano settimanale",
|
||
"not_available": "non disponibile in dispensa"
|
||
},
|
||
"kiosk_session": {
|
||
"first_item": "Primo prodotto: {name}!",
|
||
"items_two_four": "{n} prodotti — stai scaldando i motori 🚀",
|
||
"items_five_nine": "{n} prodotti — ottimo ritmo! 💪",
|
||
"items_ten_twenty": "{n} prodotti — quasi un recordman 🏆",
|
||
"items_twenty_plus": "{n} prodotti — spesa epica! 🛒🔥",
|
||
"duplicates_one": "1 bis (stessa cosa due volte)",
|
||
"duplicates_many": "{n} bis (roba presa più volte)",
|
||
"top_category": "Categoria top: {cat} ({count}×)",
|
||
"items_fallback": "{n} prodott{n} aggiunti"
|
||
},
|
||
"nutrition": {
|
||
"title": "🥗 Analisi Alimentare",
|
||
"score_excellent": "😄 Ottimo",
|
||
"score_good": "🙂 Discreto",
|
||
"score_improve": "😬 Migliorabile",
|
||
"label_health": "🌿 Salute",
|
||
"label_variety": "🎨 Varietà",
|
||
"label_fresh": "❄️ Freschi",
|
||
"source": "Basato su {n} prodotti in dispensa · EverShelf",
|
||
"products_count": "prodotti",
|
||
"today_title": "🥗 La tua dispensa oggi",
|
||
"products_n": "{n} prodotti"
|
||
},
|
||
"facts": {
|
||
"greeting_morning": "Buongiorno",
|
||
"greeting_afternoon": "Buon pomeriggio",
|
||
"greeting_evening": "Buonasera",
|
||
"pantry_waiting": "{greeting}! La tua Dispensa ti aspetta.",
|
||
"expired_one": "Hai 1 prodotto scaduto in dispensa. Controlla!",
|
||
"expired_many": "Hai {n} prodotti scaduti in dispensa. Controlla!",
|
||
"expired_list": "Prodotti scaduti: {names}",
|
||
"expired_list_more": "e altri {n}",
|
||
"freezer_expired_ok": "{name} è scaduto, ma essendo in freezer potrebbe essere ancora buono! Controlla.",
|
||
"freezer_expired_old": "{name} in freezer è scaduto da troppo tempo. Meglio buttarlo.",
|
||
"fridge_expired_one": "Hai 1 prodotto scaduto in frigo!",
|
||
"fridge_expired_many": "Hai {n} prodotti scaduti in frigo!",
|
||
"expiring_today": "{name} scade oggi! Usalo subito.",
|
||
"expiring_tomorrow": "{name} scade domani. Pensaci!",
|
||
"expiring_days": "{name} scade tra {days} giorni.",
|
||
"expiring_many": "Hai {n} prodotti in scadenza ravvicinata.",
|
||
"expiring_this_week": "Questa settimana scadono {n} prodotti. Pianifica i pasti di conseguenza!",
|
||
"expiring_item_loc": "{name} ({loc}) scade tra {days} {dayslabel}.",
|
||
"expiring_this_month": "In questo mese scadranno {n} prodotti.",
|
||
"shopping_add": "Metti in lista: {names} 🛒",
|
||
"shopping_more": "e altri {n}",
|
||
"shopping_empty": "Lista della spesa vuota. Tutto rifornito! ✅",
|
||
"in_fridge": "In frigo c'è: {name}.",
|
||
"in_freezer": "Nel freezer c'è: {name}. Non dimenticartelo!",
|
||
"top_category": "La categoria più presente è {icon} {cat} con {n} prodotti.",
|
||
"cat_meat": "Hai {n} prodotti di carne. 🥩",
|
||
"cat_dairy": "Hai {n} latticini in casa. 🥛",
|
||
"cat_veggies": "Hai {n} tipi di verdura. Ottimo per la salute! 🥬",
|
||
"cat_fruit": "Hai {n} tipi di frutta. 🍎",
|
||
"cat_drinks": "Hai {n} bevande disponibili. 🥤",
|
||
"cat_frozen": "Hai {n} surgelati nel freezer. ❄️",
|
||
"cat_pasta": "Hai {n} tipi di pasta. 🍝 Che ne dici di una carbonara?",
|
||
"cat_canned": "Hai {n} conserve in dispensa. 🥫",
|
||
"cat_snacks": "Hai {n} snack. Resisti alla tentazione! 🍪",
|
||
"cat_condiments": "Hai {n} condimenti a disposizione. 🧂",
|
||
"item_random": "Lo sapevi? Hai {name} in {loc}.",
|
||
"item_qty": "{name}: ne hai {qty}.",
|
||
"no_expiry_count": "{n} prodotti non hanno una data di scadenza impostata.",
|
||
"furthest_expiry": "Il prodotto con scadenza più lontana è {name}: {months} mesi.",
|
||
"high_qty": "Hai una bella scorta di {name}: {qty}!",
|
||
"low_qty_item": "{name} sta per finire. Aggiungilo alla spesa?",
|
||
"low_qty_count": "Ci sono {n} prodotti quasi finiti.",
|
||
"morning_bread": "Buongiorno! Hai del pane per la colazione. 🍞",
|
||
"morning_milk": "C'è del latte in frigo per il cappuccino? ☕🥛",
|
||
"morning_fruit": "Buongiorno! Una bella frutta fresca per iniziare bene. 🍎",
|
||
"noon_pasta": "Ora di pranzo… Un bel piatto di pasta? 🍝",
|
||
"noon_salad": "Un'insalata fresca per pranzo? Hai {n} verdure! 🥗",
|
||
"evening_meat": "Per cena potresti usare la carne che hai. 🥩",
|
||
"evening_fish": "Che ne dici di pesce per cena? 🐟",
|
||
"evening_expiring": "Hai {n} prodotti in scadenza questa settimana — usali stasera!",
|
||
"night_reminder": "Buonanotte! Domani ricordati di usare: {names}.",
|
||
"weekly_balance": "Bilancio settimana: +{in} aggiunti, −{out} consumati.",
|
||
"weekly_added": "Questa settimana hai aggiunto {n} prodotti.",
|
||
"weekly_consumed": "Questa settimana hai consumato {n} prodotti. Ottimo!",
|
||
"tip_freezer": "💡 I prodotti in freezer durano molto più a lungo della data di scadenza.",
|
||
"tip_bread": "💡 Il pane congelato mantiene la fragranza per settimane.",
|
||
"tip_fifo": "💡 Per evitare sprechi, usa prima i prodotti con scadenza più vicina (FIFO).",
|
||
"tip_meat": "💡 La carne in freezer può durare fino a 6 mesi senza problemi.",
|
||
"tip_no_refreeze": "💡 Non ricongelare mai un alimento già scongelato. Cucinalo subito!",
|
||
"tip_fridge": "💡 Un frigo ordinato ti fa risparmiare tempo e denaro.",
|
||
"tip_canned": "💡 Le conserve aperte vanno in frigo e consumate in pochi giorni.",
|
||
"top_brand": "Il marchio più presente nella tua dispensa è {brand} con {n} prodotti.",
|
||
"combo_pasta": "Hai pasta e condimenti: sei pronto per un primo piatto! 🍝",
|
||
"combo_sandwich": "Pane e carne: un panino veloce è sempre una buona idea! 🥪",
|
||
"combo_balanced": "Verdura e carne: hai tutto per un piatto equilibrato! 🥗🥩",
|
||
"pantry_empty": "La dispensa è vuota! Fai una bella spesa. 🛒",
|
||
"pantry_empty_scan": "Nessun prodotto registrato. Scansiona qualcosa per iniziare!",
|
||
"location_distribution": "Distribuzione: {parts}",
|
||
"day": "giorno",
|
||
"days": "giorni"
|
||
},
|
||
"kiosk": {
|
||
"check_btn": "🔍 Cerca aggiornamenti",
|
||
"checking": "⏳ Controllo…",
|
||
"error_check": "Errore durante il controllo",
|
||
"error_start_install": "Errore avvio installazione",
|
||
"version_installed": "Installata: {v}",
|
||
"update_available": "⬆️ Nuova versione disponibile: <strong>{latest}</strong> (installata: {current})",
|
||
"up_to_date": "✅ Sei già aggiornato — versione <strong>{v}</strong>",
|
||
"too_old": "⚠️ Il kiosk installato è troppo vecchio per il controllo automatico.<br>Premi il pulsante qui sotto per scaricare e installare la nuova versione direttamente.",
|
||
"manual_install": "⚠️ Questo kiosk non supporta l'installazione automatica.<br><strong>Procedura manuale:</strong><br>1. Esci dal kiosk (tasto ✕ in alto a sinistra)<br>2. Disinstalla l'app EverShelf Kiosk<br>3. Scarica e installa la nuova APK da GitHub:",
|
||
"starting_download": "⏳ Avvio download…",
|
||
"install_btn": "⬇️ Installa aggiornamento",
|
||
"exit_title": "Esci dal kiosk",
|
||
"refresh_title": "Aggiorna pagina"
|
||
},
|
||
"update": {
|
||
"new_version": "Nuova versione",
|
||
"btn": "Aggiorna"
|
||
},
|
||
"gemini": {
|
||
"chat_title": "Chat con Gemini",
|
||
"not_configured": "🤖 Gemini non configurato — imposta GEMINI_API_KEY nelle impostazioni"
|
||
},
|
||
"appliances": {
|
||
"empty": "Nessun elettrodomestico aggiunto"
|
||
},
|
||
"about": {
|
||
"title": "Informazioni",
|
||
"version": "Versione",
|
||
"report_bug": "Segnala un problema",
|
||
"report_bug_hint": "Qualcosa non funziona? Inviaci una segnalazione direttamente dall'app.",
|
||
"report_bug_modal_title": "Segnala un problema",
|
||
"report_type_bug": "Bug",
|
||
"report_type_feature": "Funzionalità",
|
||
"report_type_question": "Domanda",
|
||
"report_field_title": "Titolo",
|
||
"report_field_title_ph": "Breve descrizione del problema",
|
||
"report_field_desc": "Descrizione",
|
||
"report_field_desc_ph": "Descrivi il problema in dettaglio…",
|
||
"report_field_steps": "Passi per riprodurlo (opzionale)",
|
||
"report_field_steps_ph": "1. Vai su…\n2. Tocca…\n3. Vedi l'errore…",
|
||
"report_auto_info": "Saranno allegati automaticamente: versione {version}, lingua {lang}.",
|
||
"report_send_btn": "Invia segnalazione",
|
||
"report_bug_sending": "Invio in corso…",
|
||
"report_bug_sent": "Segnalazione inviata — grazie!",
|
||
"report_bug_error": "Impossibile inviare la segnalazione. Controlla la connessione.",
|
||
"changelog": "Changelog",
|
||
"github": "Repository GitHub"
|
||
},
|
||
"export": {
|
||
"title": "Esporta inventario",
|
||
"hint": "Scarica l inventario corrente in CSV o apri la versione stampabile (PDF).",
|
||
"btn_csv": "Scarica CSV",
|
||
"btn_pdf": "PDF / Stampa",
|
||
"btn_title": "Esporta"
|
||
},
|
||
"startup": {
|
||
"connecting": "Connessione al server...",
|
||
"check_php_memory": "Memoria PHP",
|
||
"check_php_timeout": "Timeout PHP",
|
||
"check_php_upload": "Upload PHP",
|
||
"check_data_dir": "Cartella dati",
|
||
"check_rate_limits": "Dir rate limits",
|
||
"check_backups": "Dir backup",
|
||
"check_write_test": "Test scrittura disco",
|
||
"check_disk_space": "Spazio disco",
|
||
"check_db_legacy": "DB legacy (dispensa.db)",
|
||
"check_db_connect": "Connessione database",
|
||
"check_db_tables": "Tabelle database",
|
||
"check_db_integrity": "Integrità database",
|
||
"check_db_wal": "WAL mode",
|
||
"check_db_size": "Dimensione database",
|
||
"check_db_rows": "Dati inventario",
|
||
"check_env": "File .env",
|
||
"check_gemini": "Chiave Gemini AI",
|
||
"check_bring_creds": "Credenziali Bring!",
|
||
"check_bring_token": "Token Bring!",
|
||
"check_tts": "URL Text-to-Speech",
|
||
"check_scale": "Gateway bilancia",
|
||
"check_curl_ssl": "cURL SSL",
|
||
"check_internet": "Connessione internet",
|
||
"fresh_install": "nuovo impianto",
|
||
"warnings_found": "avvisi rilevati",
|
||
"all_ok": "Sistema OK",
|
||
"critical_error_short": "Errore critico",
|
||
"critical_error": "Errore critico: l'app non può avviarsi. Controlla i log del server.",
|
||
"critical_error_intro": "L'app non può avviarsi a causa dei seguenti problemi:",
|
||
"error_network": "Impossibile contattare il server.",
|
||
"error_network_detail": "Il browser non riesce a raggiungere il server PHP.\n\nPossibili cause:\n• Il server Apache/PHP non è in esecuzione\n• Problema di rete o firewall\n• URL dell'app non corretta\n\nControlla che il server sia avviato e riprova.",
|
||
"retry": "Riprova"
|
||
}
|
||
} |