Files
MatchLiveTv/native/ios/MatchLiveTv/Core/AppLanguage.swift
T
eminuxandCursor 41d4235258 Aggiunge copertina sponsor custom solo Premium Full, con override in wizard e slate sui nodi di streaming.
Permette upload da portale e app con ereditarietà partita→squadra→società, generazione MP4 via ffmpeg e distribuzione su home lab e nodi CPX per pause e assenza segnale.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-19 23:47:17 +02:00

1688 lines
107 KiB
Swift

import Foundation
import SwiftUI
/// Preferenza lingua app (override del sistema). Persistita in UserDefaults.
enum AppLanguage: String, CaseIterable, Identifiable {
case system
case it
case en
case fr
case de
case es
var id: String { rawValue }
var nativeLabel: String {
switch self {
case .system: return L10n.t("language.system")
case .it: return L10n.t("language.italian")
case .en: return L10n.t("language.english")
case .fr: return L10n.t("language.french")
case .de: return L10n.t("language.german")
case .es: return L10n.t("language.spanish")
}
}
static var current: AppLanguage {
get {
let raw = UserDefaults.standard.string(forKey: storageKey) ?? system.rawValue
return AppLanguage(rawValue: raw) ?? .system
}
set {
if newValue == .system {
UserDefaults.standard.removeObject(forKey: storageKey)
} else {
UserDefaults.standard.set(newValue.rawValue, forKey: storageKey)
}
NotificationCenter.default.post(name: .appLanguageDidChange, object: nil)
}
}
/// Locale effettiva per le stringhe (risolve "system").
static var resolvedCode: String {
switch current {
case .system:
let code = Locale.current.language.languageCode?.identifier ?? "it"
let supported = ["it", "en", "fr", "de", "es"]
return supported.contains(code) ? code : "en"
default:
return current.rawValue
}
}
static var locale: Locale { Locale(identifier: resolvedCode) }
private static let storageKey = "mltv.appLanguage"
}
extension Notification.Name {
static let appLanguageDidChange = Notification.Name("mltv.appLanguageDidChange")
}
enum L10n {
static func t(_ key: String) -> String {
let code = AppLanguage.resolvedCode
if let value = table[code]?[key] { return value }
if let value = table["it"]?[key] { return value }
return key
}
static func t(_ key: String, _ args: CVarArg...) -> String {
String(format: t(key), locale: AppLanguage.locale, arguments: args)
}
private static let table: [String: [String: String]] = [
"it": [
"action.cancel": "Annulla",
"action.delete": "Elimina",
"action.exit": "Esci",
"action.login": "Accedi",
"action.logout": "Esci",
"account.confirm.password": "Conferma password",
"account.current.password": "Password attuale",
"account.name.label": "Nome",
"account.new.password": "Nuova password (min. 8, almeno 3 tipi di caratteri)",
"account.password.heading": "Cambia password",
"account.password.saved": "Password aggiornata",
"account.profile.heading": "Profilo",
"account.profile.saved": "Profilo aggiornato",
"account.role": "Ruolo: %1$@",
"account.save.password": "Aggiorna password",
"account.save.profile": "Salva profilo",
"account.title": "Account",
"forgot.password.lead": "Inserisci l'email dell'account: ti invieremo un link per reimpostare la password.",
"forgot.password.submit": "Invia link di reset",
"forgot.password.success": "Se l'email è registrata, riceverai a breve un link per reimpostare la password.",
"forgot.password.title": "Password dimenticata",
"login.forgot.password": "Password dimenticata?",
"action.ok": "OK",
"action.save": "Salva",
"api.error.decoding": "Risposta del server non valida",
"api.error.forbidden": "Operazione non consentita",
"api.error.http": "Errore HTTP %1$d",
"api.error.invalid.url": "URL non valido",
"api.error.not.found": "Risorsa non trovata",
"api.error.score.invalid": "Risposta punteggio non valida",
"api.error.server": "Errore del server. Riprova tra qualche istante.",
"api.error.unauthorized": "Sessione scaduta. Accedi di nuovo.",
"app.name": "Match Live TV",
"app.slogan": "Ogni partita, ogni evento, per i tuoi tifosi.",
"broadcast.close.set.button": "CHIUDI SET",
"broadcast.error.camera.preview.not.ready": "Anteprima camera non pronta",
"broadcast.error.permissions.camera.mic": "Permessi camera e microfono richiesti",
"broadcast.error.reconnect.failed": "Riconnessione non riuscita",
"broadcast.error.regia.link": "Errore link regia",
"broadcast.error.regia.link.invalid": "Link regia non valido",
"broadcast.error.rtmp.connect.failed": "Connessione RTMP fallita",
"broadcast.error.rtmp.missing": "URL RTMP mancante",
"broadcast.error.rtmp.session.create": "Impossibile creare sessione RTMP",
"broadcast.error.rtmp.url.invalid": "URL RTMP non valido",
"broadcast.error.session.unavailable": "Sessione non disponibile",
"broadcast.hide.controls.cd": "Nascondi controlli",
"broadcast.min.quality.applied": "Qualità minima: %1$@",
"broadcast.min.quality.auto": "Automatica",
"broadcast.min.quality.cd": "Qualità minima di trasmissione",
"broadcast.min.quality.error": "Impossibile impostare la qualità minima",
"broadcast.min.quality.hint": "L'encoder non scende sotto questo livello. Automatica adatta il bitrate per ridurre i salti.",
"broadcast.min.quality.title": "Qualità minima",
"broadcast.mute.cd": "Silenzia audio",
"broadcast.next.period.cd": "Periodo successivo",
"broadcast.pause.cd": "Pausa diretta",
"broadcast.period.label.timed": "%1$d° tempo",
"broadcast.permissions.grant.action": "CONCEDI PERMESSI",
"broadcast.permissions.required": "Consenti camera e microfono per andare in diretta",
"broadcast.points.target": "%1$d pt",
"broadcast.resume.cd": "Riprendi diretta",
"broadcast.scoreboard.connected": "Tabellone OK",
"broadcast.scoreboard.offline": "Tabellone offline",
"broadcast.set.progress": "Set %1$d · %2$d pt",
"broadcast.sets.won": "Set vinti %1$d-%2$d",
"broadcast.share.chooser.title": "Condividi",
"broadcast.share.link.unavailable": "Link diretta non ancora disponibile",
"broadcast.share.live.cd": "Condividi diretta",
"broadcast.share.regia.cd": "Condividi link regia",
"broadcast.share.regia.subject": "Link regia — %1$@",
"broadcast.share.subject.fallback": "Diretta Match Live TV",
"broadcast.show.controls.cd": "Mostra controlli",
"broadcast.side.away": "ospite",
"broadcast.side.home": "casa",
"broadcast.snackbar.closed.remote": "Diretta chiusa dalla regia",
"broadcast.snackbar.min.quality.remote": "Qualità minima aggiornata dalla regia",
"broadcast.snackbar.mute.error": "Audio: %1$@",
"broadcast.snackbar.muted": "Audio silenziato",
"broadcast.snackbar.muted.remote": "Audio silenziato dalla regia",
"broadcast.snackbar.pause.error": "Pausa: %1$@",
"broadcast.snackbar.paused": "Diretta in pausa",
"broadcast.snackbar.paused.remote": "Pausa dalla regia",
"broadcast.snackbar.reconnect.started": "Riconnessione avviata",
"broadcast.snackbar.resume.error": "Ripresa: %1$@",
"broadcast.snackbar.resume.rtmp.error": "Ripresa RTMP: %1$@",
"broadcast.snackbar.resumed": "Diretta ripresa",
"broadcast.snackbar.resumed.remote": "Ripresa dalla regia",
"broadcast.snackbar.unmuted": "Audio riattivato",
"broadcast.snackbar.unmuted.remote": "Audio riattivato dalla regia",
"broadcast.status.connecting": "CONNESSIONE…",
"broadcast.status.error.fallback": "ERRORE",
"broadcast.status.live": "IN DIRETTA",
"broadcast.status.paused": "PAUSA",
"broadcast.status.preview": "PREVIEW",
"broadcast.status.reconnecting": "RICONNESSIONE…",
"broadcast.team.away.label": "OSPITE",
"broadcast.team.home.label": "CASA",
"broadcast.team.sets.count": "%1$d set",
"broadcast.terminate.cd": "Termina diretta",
"broadcast.terminate.confirm": "TERMINA",
"broadcast.terminate.message": "Lo streaming verrà chiuso per tutti gli spettatori.",
"broadcast.terminate.title": "Terminare la diretta?",
"broadcast.tooltip.add.point": "Aggiungi punto %1$@",
"broadcast.tooltip.plus.side": "+%1$d %2$@",
"broadcast.tooltip.remove.point": "Togli punto %1$@",
"broadcast.unmute.cd": "Riattiva audio",
"broadcast.audio.muted.label": "Audio off",
"common.close": "Chiudi",
"common.error.generic": "errore",
"common.error.title": "Errore",
"error.operation.failed": "Operazione non riuscita",
"error.rtmp.failed": "Connessione RTMP fallita. Verifica rete e server streaming.",
"error.rtmp.failed.dev": "Connessione RTMP fallita. Verifica che MediaMTX sia raggiungibile (in dev: porta 1935 su localhost).",
"error.rtmp.interrupted": "Connessione RTMP interrotta",
"error.rtmp.invalid.url": "URL RTMP non valido. Controlla l'indirizzo di ingest dal server.",
"error.rtmp.timeout": "Timeout connessione RTMP. Verifica rete e server MediaMTX (porta 1935).",
"error.rtmp.unreachable": "Server RTMP non raggiungibile. In dev locale usa localhost:1935 (non l'host Docker «mediamtx»).",
"language.english": "English",
"language.french": "Français",
"language.german": "Deutsch",
"language.italian": "Italiano",
"language.label": "Lingua",
"language.spanish": "Español",
"language.system": "Sistema",
"login.email": "Email",
"login.email.placeholder": "coach@team.com",
"login.error.credentials": "Email o password non corretti",
"login.error.generic": "Login fallito",
"login.error.unreachable": "Server non raggiungibile. Verifica la connessione.",
"login.password": "Password",
"login.submit": "Accedi",
"match.status.live": "IN CORSO",
"match.status.resume": "RIPRENDI",
"match.status.scheduled": "PROGRAMMATA",
"match.status.start": "AVVIA",
"matches.active.team": "Squadra attiva: %1$@.",
"matches.change": "Cambia",
"matches.empty.hint": "Tocca «Nuova partita» per programmare in anticipo o avviare subito.",
"matches.empty.title": "Nessuna partita in calendario",
"matches.hello": "Ciao, %1$@",
"matches.load.error": "Errore caricamento",
"matches.msg.create.failed": "Impossibile creare la partita",
"matches.msg.delete.failed": "Impossibile eliminare",
"matches.msg.deleted": "Partita eliminata",
"matches.msg.load.error": "Errore caricamento",
"matches.msg.resume.failed": "Impossibile riprendere la diretta",
"matches.msg.schedule.error": "Errore creazione partita",
"matches.msg.scheduled.ok": "Partita programmata — visibile sul sito",
"matches.multi.team.hint": "Hai più squadre: verifica quella selezionata sopra.",
"matches.new": "Nuova partita",
"matches.no.other": "Nessuna altra partita in calendario.",
"matches.no.team.body": "Per trasmettere devi essere responsabile della trasmissione di almeno una squadra. Chiedi al tuo club di aggiungerti come staff trasmissione.",
"matches.no.team.title": "Nessuna squadra assegnata",
"matches.ready.title": "Pronte da avviare",
"matches.retry": "Riprova",
"matches.scheduled.title": "Partite programmate",
"matches.subtitle": "Riprendi una diretta in corso o avvia una nuova partita.",
"matches.tap.change.team": "Tocca per cambiare squadra",
"matches.team.for.live": "Squadra per la diretta",
"matches.title": "Partite",
"network.type.cellular": "4G",
"network.type.ethernet": "Ethernet",
"network.type.unknown": "Sconosciuto",
"network.type.wifi": "WiFi",
"overlay.set.label": "Set %1$d",
"score.action.close.anyway": "Chiudi comunque",
"score.action.close.live": "Chiudi diretta",
"score.action.close.set": "Chiudi set",
"score.action.continue.live": "Continua in onda",
"score.action.continue.scoring": "Continua a segnare",
"score.close.set.anyway.message": "Il punteggio non soddisfa ancora le regole del torneo. Chiudere il set comunque?",
"score.match.won.message": "%1$@ vince la partita (%2$d-%3$d set).\\n\\nChiudere definitivamente la diretta?",
"score.match.won.title": "Partita terminata",
"score.set.won.message": "%1$@ vince il set %2$d-%3$d.\\n\\nChiudere il set e passare al successivo?",
"score.set.won.title": "Set concluso",
"session.error.no.active": "Nessuna sessione attiva",
"session.error.not.connected": "Sessione non collegata",
"sheet.badge.calendar": "IN CALENDARIO",
"sheet.badge.draft": "BOZZA",
"sheet.badge.scheduled": "PROGRAMMATA",
"sheet.choose.match": "Scegli partita",
"sheet.choose.match.lead": "Partite già programmate sul sito o in app.",
"sheet.choose.team": "Scegli squadra",
"sheet.configure": "Configura",
"sheet.configure.now.body": "Puoi preparare la trasmissione subito, oppure tornare quando sei in palestra.",
"sheet.configure.now.title": "Configurare ora?",
"sheet.continue.setup": "CONTINUA CONFIGURAZIONE",
"sheet.date.time": "Data e ora",
"sheet.delete": "Elimina",
"sheet.delete.match.body": "Eliminare «%1$@ vs %2$@»?\n\nL'operazione non si può annullare.",
"sheet.delete.match.title": "Elimina partita",
"sheet.later": "Più tardi",
"sheet.live.in.progress": "Diretta in corso",
"sheet.location.optional": "Luogo (opzionale)",
"sheet.new.match.lead": "Programma in anticipo o avvia la configurazione diretta subito.",
"sheet.new.match.title": "Nuova partita",
"sheet.opponent": "Avversario",
"sheet.quick.option": "Avvia subito",
"sheet.quick.option.sub": "Crea la partita e passa al wizard senza orario",
"sheet.resume.banner": "Riprendi diretta in corso",
"sheet.resume.camera": "RIPRENDI CAMERA E TRASMETTI",
"sheet.save.schedule": "SALVA IN PROGRAMMA",
"sheet.schedule.lead": "La diretta non parte ora: comparirà sul sito con data e ora. Avvierai lo streaming dall'app quando sei in palestra.",
"sheet.schedule.option": "Programma partita",
"sheet.schedule.option.sub": "Data, ora e avversario — visibile anche sul sito",
"sheet.schedule.title": "Programma partita",
"sheet.section.scheduled": "Programmate",
"sheet.section.unscheduled": "Senza orario",
"sheet.status": "Stato: %1$@",
"thermal.alert.continue": "Continua",
"thermal.alert.message": "Il dispositivo è molto caldo da oltre un minuto. iOS potrebbe chiudere l'app per proteggere il dispositivo. Considera di interrompere la diretta.",
"thermal.alert.stop": "Interrompi diretta",
"thermal.alert.title": "Surriscaldamento",
"thermal.notice.critical": "Surriscaldamento imminente: qualità ulteriormente ridotta.",
"thermal.notice.serious": "Il dispositivo si sta scaldando. La qualità dello streaming è stata ridotta per garantire stabilità.",
"thermal.state.critical": "Rischio surriscaldamento",
"thermal.state.fair": "Temperatura alta",
"thermal.state.nominal": "Temperatura OK",
"thermal.state.serious": "Dispositivo caldo",
"wizard.action.back": "Indietro",
"wizard.action.copy": "COPIA",
"wizard.action.next": "AVANTI >",
"wizard.action.share": "CONDIVIDI",
"wizard.action.share.regia.link": "CONDIVIDI LINK REGIA",
"wizard.action.start": "INIZIA >",
"wizard.branding.cancel": "ANNULLA",
"wizard.branding.color.label": "Colore squadra",
"wizard.branding.customize.title": "Personalizza",
"wizard.branding.edit.team.cd": "Modifica squadra",
"wizard.branding.logo.label": "Logo",
"wizard.branding.no.logo": "Nessun logo",
"wizard.branding.opponent.name.placeholder": "Nome avversario",
"wizard.branding.remove.logo": "RIMUOVI",
"wizard.branding.save": "SALVA",
"wizard.branding.team.fallback.name": "Squadra",
"wizard.branding.team.name.label": "Nome squadra",
"wizard.branding.upload.logo": "CARICA LOGO",
"wizard.color.hue": "Tonalità",
"wizard.complete.transmission.step": "Completa lo step Trasmissione",
"wizard.error.opponent.name.required": "Inserisci il nome avversario",
"wizard.error.overtime.duration.required": "Inserisci la durata dei supplementari in minuti",
"wizard.error.period.duration.required": "Inserisci la durata del periodo in minuti",
"wizard.error.points.per.set.required": "Inserisci i punti per vincere un set",
"wizard.error.regia.link": "Errore link regia",
"wizard.error.save.generic": "Errore nel salvataggio",
"wizard.error.session.create": "Errore creazione sessione",
"wizard.error.start.live": "Errore avvio diretta",
"wizard.error.tiebreak.points.required": "Inserisci i punti del tie-break",
"wizard.error.youtube.unavailable": "YouTube non disponibile per questa squadra",
"wizard.match.away.team.label": "Squadra avversaria",
"wizard.match.category.hint": "Es. Serie C, torneo estivo — lo useremo in descrizione e overlay.",
"wizard.match.cover.title": "Copertina in pausa",
"wizard.match.cover.source.label": "Origine: %1$@",
"wizard.match.cover.source.default": "Match Live TV",
"wizard.match.cover.source.club": "Società",
"wizard.match.cover.source.team": "Squadra",
"wizard.match.cover.source.match": "Questa partita",
"wizard.match.cover.hint": "Mostrata in pausa o senza segnale finché non riparte la diretta.",
"wizard.match.cover.change": "Cambia copertina per questa partita",
"wizard.match.cover.reset": "Usa quella predefinita",
"wizard.match.cover.premium.required": "Copertina sponsor personalizzata con Premium Full",
"wizard.match.category.label": "Campionato (facoltativo)",
"wizard.match.custom.overlay.label": "Overlay video personalizzato",
"wizard.match.custom.rules.label": "Regole punteggio personalizzate",
"wizard.match.details.title": "Dettagli partita",
"wizard.match.home.team.label": "Squadra di casa",
"wizard.match.location.label": "Luogo",
"wizard.match.minutes.per.period.basket": "Minuti per quarto",
"wizard.match.minutes.per.period.timed": "Minuti per tempo",
"wizard.match.not.found": "Partita non trovata",
"wizard.match.overtime.minutes.label": "Minuti supplementari",
"wizard.match.periods.basket.label": "Quarti",
"wizard.match.periods.timed.label": "Tempi",
"wizard.match.points.per.set.label": "Punti per vincere un set",
"wizard.match.rules.custom.sets": "Torneo non standard: imposta set e punteggi.",
"wizard.match.rules.custom.timed": "Torneo non standard: tempi e periodi personalizzati.",
"wizard.match.rules.standard.sets": "Standard FIPAV: 3 set per vincere, set a 25, tie-break a 15.",
"wizard.match.rules.standard.sport": "Regole standard dello sport selezionato.",
"wizard.match.scheduled.label": "Programmata per",
"wizard.match.sets.to.win.label": "Set da vincere la partita",
"wizard.match.tiebreak.points.label": "Punti tie-break (ultimo set)",
"wizard.network.download.label": "Download",
"wizard.network.latency.label": "Latenza",
"wizard.network.link.live.label": "Link diretta",
"wizard.network.link.youtube.label": "Link YouTube",
"wizard.network.quality.label": "Qualità streaming (automatica)",
"wizard.network.ready.label": "PRONTO PER ANDARE IN DIRETTA",
"wizard.network.share.subject": "Diretta — %1$@ vs %2$@",
"wizard.network.test.running.label": "TEST IN CORSO...",
"wizard.network.test.start.label": "AVVIA TEST RETE",
"wizard.network.test.subtitle": "Verifica che la connessione regga l'upload della diretta.",
"wizard.network.test.title": "Test rete",
"wizard.network.type.label": "Tipo rete",
"wizard.network.upload.label": "Upload",
"wizard.share.chooser.live": "Condividi diretta",
"wizard.share.chooser.regia": "Condividi regia",
"wizard.step.title.match": "01 · Partita",
"wizard.step.title.network": "03 · Test rete",
"wizard.step.title.transmission": "02 · Trasmissione",
"wizard.transmission.backend.note": "La partita resta sempre visibile nel backend della squadra per tutta la durata dell'abbonamento.",
"wizard.transmission.plan.label": "Piano %1$@",
"wizard.transmission.platform.site.subtitle": "Diretta sul nostro sito (incluso)",
"wizard.transmission.platform.title": "Piattaforma",
"wizard.transmission.public.desc": "Compare nell'elenco dirette su MatchLiveTV.it, nelle ricerche e sul canale YouTube (se selezionato).",
"wizard.transmission.public.label": "PUBBLICO",
"wizard.transmission.unlisted.desc": "Non compare negli elenchi pubblici né nelle ricerche. Solo chi ha il link può guardare.",
"wizard.transmission.unlisted.label": "NON IN ELENCO",
"wizard.transmission.visibility.title": "Visibilità",
"wizard.transmission.youtube.activating": "Canale in attivazione",
"wizard.transmission.youtube.badge": "Premium",
"wizard.transmission.youtube.premium.required": "Premium Light o Full",
"youtube.channel.club": "Canale società · %1$@",
"youtube.channel.club.fallback": "società",
"youtube.channel.platform": "Canale Match Live TV"
],
"en": [
"action.cancel": "Cancel",
"action.delete": "Delete",
"action.exit": "Exit",
"action.login": "Log in",
"action.logout": "Log out",
"account.confirm.password": "Confirm password",
"account.current.password": "Current password",
"account.name.label": "Name",
"account.new.password": "New password (min. 8, at least 3 character types)",
"account.password.heading": "Change password",
"account.password.saved": "Password updated",
"account.profile.heading": "Profile",
"account.profile.saved": "Profile updated",
"account.role": "Role: %1$@",
"account.save.password": "Update password",
"account.save.profile": "Save profile",
"account.title": "Account",
"forgot.password.lead": "Enter your account email: we will send you a link to reset your password.",
"forgot.password.submit": "Send reset link",
"forgot.password.success": "If the email is registered, you will receive a password reset link shortly.",
"forgot.password.title": "Forgot password",
"login.forgot.password": "Forgot password?",
"action.ok": "OK",
"action.save": "Save",
"api.error.decoding": "Invalid server response",
"api.error.forbidden": "Operation not allowed",
"api.error.http": "HTTP error %1$d",
"api.error.invalid.url": "Invalid URL",
"api.error.not.found": "Resource not found",
"api.error.score.invalid": "Invalid score response",
"api.error.server": "Server error. Please try again in a moment.",
"api.error.unauthorized": "Session expired. Please sign in again.",
"app.name": "Match Live TV",
"app.slogan": "Every match, every event, for your fans.",
"broadcast.close.set.button": "CLOSE SET",
"broadcast.error.camera.preview.not.ready": "Camera preview not ready",
"broadcast.error.permissions.camera.mic": "Camera and microphone permission required",
"broadcast.error.reconnect.failed": "Reconnection failed",
"broadcast.error.regia.link": "Control room link error",
"broadcast.error.regia.link.invalid": "Invalid control-room link",
"broadcast.error.rtmp.connect.failed": "RTMP connection failed",
"broadcast.error.rtmp.missing": "Missing RTMP URL",
"broadcast.error.rtmp.session.create": "Unable to create RTMP session",
"broadcast.error.rtmp.url.invalid": "Invalid RTMP URL",
"broadcast.error.session.unavailable": "Session not available",
"broadcast.hide.controls.cd": "Hide controls",
"broadcast.min.quality.applied": "Minimum quality: %1$@",
"broadcast.min.quality.auto": "Automatic",
"broadcast.min.quality.cd": "Minimum streaming quality",
"broadcast.min.quality.error": "Unable to set minimum quality",
"broadcast.min.quality.hint": "The encoder will not go below this level. Automatic adapts bitrate to reduce stalls.",
"broadcast.min.quality.title": "Minimum quality",
"broadcast.mute.cd": "Mute audio",
"broadcast.next.period.cd": "Next period",
"broadcast.pause.cd": "Pause live",
"broadcast.period.label.timed": "Period %1$d",
"broadcast.permissions.grant.action": "GRANT PERMISSIONS",
"broadcast.permissions.required": "Allow camera and microphone to go live",
"broadcast.points.target": "%1$d pts",
"broadcast.resume.cd": "Resume live",
"broadcast.scoreboard.connected": "Scoreboard OK",
"broadcast.scoreboard.offline": "Scoreboard offline",
"broadcast.set.progress": "Set %1$d · %2$d pts",
"broadcast.sets.won": "Sets won %1$d-%2$d",
"broadcast.share.chooser.title": "Share",
"broadcast.share.link.unavailable": "Live link not available yet",
"broadcast.share.live.cd": "Share live stream",
"broadcast.share.regia.cd": "Share control room link",
"broadcast.share.regia.subject": "Control room link — %1$@",
"broadcast.share.subject.fallback": "Match Live TV stream",
"broadcast.show.controls.cd": "Show controls",
"broadcast.side.away": "away",
"broadcast.side.home": "home",
"broadcast.snackbar.closed.remote": "Live closed from control room",
"broadcast.snackbar.min.quality.remote": "Minimum quality updated from control room",
"broadcast.snackbar.mute.error": "Audio: %1$@",
"broadcast.snackbar.muted": "Audio muted",
"broadcast.snackbar.muted.remote": "Audio muted from control room",
"broadcast.snackbar.pause.error": "Pause: %1$@",
"broadcast.snackbar.paused": "Live paused",
"broadcast.snackbar.paused.remote": "Paused from control room",
"broadcast.snackbar.reconnect.started": "Reconnecting…",
"broadcast.snackbar.resume.error": "Resume: %1$@",
"broadcast.snackbar.resume.rtmp.error": "RTMP resume: %1$@",
"broadcast.snackbar.resumed": "Live resumed",
"broadcast.snackbar.resumed.remote": "Resumed from control room",
"broadcast.snackbar.unmuted": "Audio restored",
"broadcast.snackbar.unmuted.remote": "Audio restored from control room",
"broadcast.status.connecting": "CONNECTING…",
"broadcast.status.error.fallback": "ERROR",
"broadcast.status.live": "LIVE",
"broadcast.status.paused": "PAUSED",
"broadcast.status.preview": "PREVIEW",
"broadcast.status.reconnecting": "RECONNECTING…",
"broadcast.team.away.label": "AWAY",
"broadcast.team.home.label": "HOME",
"broadcast.team.sets.count": "%1$d sets",
"broadcast.terminate.cd": "End live",
"broadcast.terminate.confirm": "END",
"broadcast.terminate.message": "The stream will be closed for all viewers.",
"broadcast.terminate.title": "End the live stream?",
"broadcast.tooltip.add.point": "Add point %1$@",
"broadcast.tooltip.plus.side": "+%1$d %2$@",
"broadcast.tooltip.remove.point": "Remove point %1$@",
"broadcast.unmute.cd": "Unmute audio",
"broadcast.audio.muted.label": "Audio off",
"common.close": "Close",
"common.error.generic": "error",
"common.error.title": "Error",
"error.operation.failed": "Operation failed",
"error.rtmp.failed": "RTMP connection failed. Check network and streaming server.",
"error.rtmp.failed.dev": "RTMP connection failed. Check that MediaMTX is reachable (in dev: port 1935 on localhost).",
"error.rtmp.interrupted": "RTMP connection interrupted",
"error.rtmp.invalid.url": "Invalid RTMP URL. Check the ingest address from the server.",
"error.rtmp.timeout": "RTMP connection timeout. Check network and MediaMTX server (port 1935).",
"error.rtmp.unreachable": "RTMP server unreachable. In local dev use localhost:1935 (not the Docker host «mediamtx»).",
"language.english": "English",
"language.french": "Français",
"language.german": "Deutsch",
"language.italian": "Italiano",
"language.label": "Language",
"language.spanish": "Español",
"language.system": "System",
"login.email": "Email",
"login.email.placeholder": "coach@team.com",
"login.error.credentials": "Incorrect email or password",
"login.error.generic": "Login failed",
"login.error.unreachable": "Server unreachable. Check your connection.",
"login.password": "Password",
"login.submit": "Log in",
"match.status.live": "LIVE",
"match.status.resume": "RESUME",
"match.status.scheduled": "SCHEDULED",
"match.status.start": "START",
"matches.active.team": "Active team: %1$@.",
"matches.change": "Change",
"matches.empty.hint": "Tap «New match» to schedule ahead or start right away.",
"matches.empty.title": "No matches on the calendar",
"matches.hello": "Hi, %1$@",
"matches.load.error": "Loading error",
"matches.msg.create.failed": "Could not create the match",
"matches.msg.delete.failed": "Could not delete",
"matches.msg.deleted": "Match deleted",
"matches.msg.load.error": "Loading error",
"matches.msg.resume.failed": "Could not resume the live stream",
"matches.msg.schedule.error": "Error creating match",
"matches.msg.scheduled.ok": "Match scheduled — visible on the site",
"matches.multi.team.hint": "You have multiple teams: check the one selected above.",
"matches.new": "New match",
"matches.no.other": "No other matches on the calendar.",
"matches.no.team.body": "To stream you must be transmission staff for at least one team. Ask your club to add you as streaming staff.",
"matches.no.team.title": "No team assigned",
"matches.ready.title": "Ready to start",
"matches.retry": "Retry",
"matches.scheduled.title": "Scheduled matches",
"matches.subtitle": "Resume a live stream or start a new match.",
"matches.tap.change.team": "Tap to change team",
"matches.team.for.live": "Team for the live stream",
"matches.title": "Matches",
"network.type.cellular": "4G",
"network.type.ethernet": "Ethernet",
"network.type.unknown": "Unknown",
"network.type.wifi": "WiFi",
"overlay.set.label": "Set %1$d",
"score.action.close.anyway": "Close anyway",
"score.action.close.live": "End live",
"score.action.close.set": "Close set",
"score.action.continue.live": "Keep streaming",
"score.action.continue.scoring": "Keep scoring",
"score.close.set.anyway.message": "The score doesn't meet the tournament rules yet. Close the set anyway?",
"score.match.won.message": "%1$@ wins the match (%2$d-%3$d sets).\\n\\nEnd the live stream for good?",
"score.match.won.title": "Match finished",
"score.set.won.message": "%1$@ wins the set %2$d-%3$d.\\n\\nClose the set and move to the next one?",
"score.set.won.title": "Set finished",
"session.error.no.active": "No active session",
"session.error.not.connected": "Session not connected",
"sheet.badge.calendar": "ON CALENDAR",
"sheet.badge.draft": "DRAFT",
"sheet.badge.scheduled": "SCHEDULED",
"sheet.choose.match": "Choose match",
"sheet.choose.match.lead": "Matches already scheduled on the site or in the app.",
"sheet.choose.team": "Choose team",
"sheet.configure": "Configure",
"sheet.configure.now.body": "You can prepare the stream now, or come back when you are at the gym.",
"sheet.configure.now.title": "Configure now?",
"sheet.continue.setup": "CONTINUE SETUP",
"sheet.date.time": "Date and time",
"sheet.delete": "Delete",
"sheet.delete.match.body": "Delete «%1$@ vs %2$@»?\n\nThis cannot be undone.",
"sheet.delete.match.title": "Delete match",
"sheet.later": "Later",
"sheet.live.in.progress": "Live in progress",
"sheet.location.optional": "Location (optional)",
"sheet.new.match.lead": "Schedule ahead or start live setup right away.",
"sheet.new.match.title": "New match",
"sheet.opponent": "Opponent",
"sheet.quick.option": "Start now",
"sheet.quick.option.sub": "Create the match and open the wizard without a time",
"sheet.resume.banner": "Resume live stream",
"sheet.resume.camera": "RESUME CAMERA AND STREAM",
"sheet.save.schedule": "SAVE TO SCHEDULE",
"sheet.schedule.lead": "Streaming does not start now: it will appear on the site with date and time. You will start streaming from the app when you are at the gym.",
"sheet.schedule.option": "Schedule match",
"sheet.schedule.option.sub": "Date, time and opponent — also visible on the site",
"sheet.schedule.title": "Schedule match",
"sheet.section.scheduled": "Scheduled",
"sheet.section.unscheduled": "No time set",
"sheet.status": "Status: %1$@",
"thermal.alert.continue": "Continue",
"thermal.alert.message": "The device has been very hot for over a minute. iOS may quit the app to protect the device. Consider stopping the live stream.",
"thermal.alert.stop": "Stop live",
"thermal.alert.title": "Overheating",
"thermal.notice.critical": "Overheating imminent: quality reduced further.",
"thermal.notice.serious": "The device is getting warm. Streaming quality was reduced to keep things stable.",
"thermal.state.critical": "Overheating risk",
"thermal.state.fair": "High temperature",
"thermal.state.nominal": "Temperature OK",
"thermal.state.serious": "Device warm",
"wizard.action.back": "Back",
"wizard.action.copy": "COPY",
"wizard.action.next": "NEXT >",
"wizard.action.share": "SHARE",
"wizard.action.share.regia.link": "SHARE CONTROL ROOM LINK",
"wizard.action.start": "START >",
"wizard.branding.cancel": "CANCEL",
"wizard.branding.color.label": "Team color",
"wizard.branding.customize.title": "Customize",
"wizard.branding.edit.team.cd": "Edit team",
"wizard.branding.logo.label": "Logo",
"wizard.branding.no.logo": "No logo",
"wizard.branding.opponent.name.placeholder": "Opponent name",
"wizard.branding.remove.logo": "REMOVE",
"wizard.branding.save": "SAVE",
"wizard.branding.team.fallback.name": "Team",
"wizard.branding.team.name.label": "Team name",
"wizard.branding.upload.logo": "UPLOAD LOGO",
"wizard.color.hue": "Hue",
"wizard.complete.transmission.step": "Complete the Broadcast step",
"wizard.error.opponent.name.required": "Enter the opponent's name",
"wizard.error.overtime.duration.required": "Enter the overtime duration in minutes",
"wizard.error.period.duration.required": "Enter the period duration in minutes",
"wizard.error.points.per.set.required": "Enter the points to win a set",
"wizard.error.regia.link": "Control room link error",
"wizard.error.save.generic": "Error while saving",
"wizard.error.session.create": "Error creating session",
"wizard.error.start.live": "Error starting the live stream",
"wizard.error.tiebreak.points.required": "Enter the tie-break points",
"wizard.error.youtube.unavailable": "YouTube not available for this team",
"wizard.match.away.team.label": "Away team",
"wizard.match.category.hint": "E.g. Serie C, summer tournament — we'll use it in the description and overlay.",
"wizard.match.cover.title": "Pause cover",
"wizard.match.cover.source.label": "Source: %1$@",
"wizard.match.cover.source.default": "Match Live TV",
"wizard.match.cover.source.club": "Club",
"wizard.match.cover.source.team": "Team",
"wizard.match.cover.source.match": "This match",
"wizard.match.cover.hint": "Shown while paused or offline until the stream resumes.",
"wizard.match.cover.change": "Change cover for this match",
"wizard.match.cover.reset": "Use default cover",
"wizard.match.cover.premium.required": "Custom sponsor cover requires Premium Full",
"wizard.match.category.label": "Category (optional)",
"wizard.match.custom.overlay.label": "Custom video overlay",
"wizard.match.custom.rules.label": "Custom scoring rules",
"wizard.match.details.title": "Match details",
"wizard.match.home.team.label": "Home team",
"wizard.match.location.label": "Location",
"wizard.match.minutes.per.period.basket": "Minutes per quarter",
"wizard.match.minutes.per.period.timed": "Minutes per half",
"wizard.match.not.found": "Match not found",
"wizard.match.overtime.minutes.label": "Overtime minutes",
"wizard.match.periods.basket.label": "Quarters",
"wizard.match.periods.timed.label": "Halves",
"wizard.match.points.per.set.label": "Points to win a set",
"wizard.match.rules.custom.sets": "Non-standard tournament: set your sets and points.",
"wizard.match.rules.custom.timed": "Non-standard tournament: custom times and periods.",
"wizard.match.rules.standard.sets": "FIVB standard: 3 sets to win, sets to 25, tie-break to 15.",
"wizard.match.rules.standard.sport": "Standard rules for the selected sport.",
"wizard.match.scheduled.label": "Scheduled for",
"wizard.match.sets.to.win.label": "Sets to win the match",
"wizard.match.tiebreak.points.label": "Tie-break points (last set)",
"wizard.network.download.label": "Download",
"wizard.network.latency.label": "Latency",
"wizard.network.link.live.label": "Live link",
"wizard.network.link.youtube.label": "YouTube link",
"wizard.network.quality.label": "Streaming quality (automatic)",
"wizard.network.ready.label": "READY TO GO LIVE",
"wizard.network.share.subject": "Live — %1$@ vs %2$@",
"wizard.network.test.running.label": "TEST IN PROGRESS...",
"wizard.network.test.start.label": "START NETWORK TEST",
"wizard.network.test.subtitle": "Check that your connection can handle the live upload.",
"wizard.network.test.title": "Network test",
"wizard.network.type.label": "Network type",
"wizard.network.upload.label": "Upload",
"wizard.share.chooser.live": "Share live stream",
"wizard.share.chooser.regia": "Share control room",
"wizard.step.title.match": "01 · Match",
"wizard.step.title.network": "03 · Network test",
"wizard.step.title.transmission": "02 · Broadcast",
"wizard.transmission.backend.note": "The match always stays visible in the team backend for the whole subscription period.",
"wizard.transmission.plan.label": "Plan %1$@",
"wizard.transmission.platform.site.subtitle": "Live on our site (included)",
"wizard.transmission.platform.title": "Platform",
"wizard.transmission.public.desc": "Shown in the live list on MatchLiveTV.it, in search and on the YouTube channel (if selected).",
"wizard.transmission.public.label": "PUBLIC",
"wizard.transmission.unlisted.desc": "Not shown in public lists or search. Only those with the link can watch.",
"wizard.transmission.unlisted.label": "UNLISTED",
"wizard.transmission.visibility.title": "Visibility",
"wizard.transmission.youtube.activating": "Channel being activated",
"wizard.transmission.youtube.badge": "Premium",
"wizard.transmission.youtube.premium.required": "Premium Light or Full",
"youtube.channel.club": "Club channel · %1$@",
"youtube.channel.club.fallback": "club",
"youtube.channel.platform": "Match Live TV channel"
],
"fr": [
"action.cancel": "Annuler",
"action.delete": "Supprimer",
"action.exit": "Quitter",
"action.login": "Connexion",
"action.logout": "Déconnexion",
"account.confirm.password": "Confirmer le mot de passe",
"account.current.password": "Mot de passe actuel",
"account.name.label": "Nom",
"account.new.password": "Nouveau mot de passe (min. 8, au moins 3 types de caractères)",
"account.password.heading": "Changer le mot de passe",
"account.password.saved": "Mot de passe mis à jour",
"account.profile.heading": "Profil",
"account.profile.saved": "Profil mis à jour",
"account.role": "Rôle : %1$@",
"account.save.password": "Mettre à jour le mot de passe",
"account.save.profile": "Enregistrer le profil",
"account.title": "Compte",
"forgot.password.lead": "Saisissez l'e-mail du compte : nous vous enverrons un lien pour réinitialiser le mot de passe.",
"forgot.password.submit": "Envoyer le lien",
"forgot.password.success": "Si l'e-mail est enregistré, vous recevrez bientôt un lien de réinitialisation.",
"forgot.password.title": "Mot de passe oublié",
"login.forgot.password": "Mot de passe oublié ?",
"action.ok": "OK",
"action.save": "Enregistrer",
"api.error.decoding": "Réponse du serveur non valide",
"api.error.forbidden": "Opération non autorisée",
"api.error.http": "Erreur HTTP %1$d",
"api.error.invalid.url": "URL non valide",
"api.error.not.found": "Ressource introuvable",
"api.error.score.invalid": "Réponse de score non valide",
"api.error.server": "Erreur serveur. Réessayez dans un instant.",
"api.error.unauthorized": "Session expirée. Connectez-vous à nouveau.",
"app.name": "Match Live TV",
"app.slogan": "Chaque match, chaque événement, pour vos fans.",
"broadcast.close.set.button": "FERMER LE SET",
"broadcast.error.camera.preview.not.ready": "Aperçu caméra non prêt",
"broadcast.error.permissions.camera.mic": "Autorisations caméra et micro requises",
"broadcast.error.reconnect.failed": "Échec de la reconnexion",
"broadcast.error.regia.link": "Erreur du lien régie",
"broadcast.error.regia.link.invalid": "Lien régie non valide",
"broadcast.error.rtmp.connect.failed": "Échec de la connexion RTMP",
"broadcast.error.rtmp.missing": "URL RTMP manquante",
"broadcast.error.rtmp.session.create": "Impossible de créer la session RTMP",
"broadcast.error.rtmp.url.invalid": "URL RTMP non valide",
"broadcast.error.session.unavailable": "Session non disponible",
"broadcast.hide.controls.cd": "Masquer les commandes",
"broadcast.min.quality.applied": "Qualité minimale : %1$@",
"broadcast.min.quality.auto": "Automatique",
"broadcast.min.quality.cd": "Qualité minimale de transmission",
"broadcast.min.quality.error": "Impossible de définir la qualité minimale",
"broadcast.min.quality.hint": "L'encodeur ne descend pas en dessous de ce niveau. Automatique adapte le débit pour limiter les coupures.",
"broadcast.min.quality.title": "Qualité minimale",
"broadcast.mute.cd": "Couper l'audio",
"broadcast.next.period.cd": "Période suivante",
"broadcast.pause.cd": "Mettre le direct en pause",
"broadcast.period.label.timed": "Période %1$d",
"broadcast.permissions.grant.action": "ACCORDER LES AUTORISATIONS",
"broadcast.permissions.required": "Autorisez la caméra et le micro pour passer en direct",
"broadcast.points.target": "%1$d pts",
"broadcast.resume.cd": "Reprendre le direct",
"broadcast.scoreboard.connected": "Tableau OK",
"broadcast.scoreboard.offline": "Tableau hors ligne",
"broadcast.set.progress": "Set %1$d · %2$d pts",
"broadcast.sets.won": "Sets gagnés %1$d-%2$d",
"broadcast.share.chooser.title": "Partager",
"broadcast.share.link.unavailable": "Lien du direct pas encore disponible",
"broadcast.share.live.cd": "Partager le direct",
"broadcast.share.regia.cd": "Partager le lien régie",
"broadcast.share.regia.subject": "Lien régie — %1$@",
"broadcast.share.subject.fallback": "Direct Match Live TV",
"broadcast.show.controls.cd": "Afficher les commandes",
"broadcast.side.away": "extérieur",
"broadcast.side.home": "domicile",
"broadcast.snackbar.closed.remote": "Direct fermé depuis la régie",
"broadcast.snackbar.min.quality.remote": "Qualité minimale mise à jour depuis la régie",
"broadcast.snackbar.mute.error": "Audio : %1$@",
"broadcast.snackbar.muted": "Audio coupé",
"broadcast.snackbar.muted.remote": "Audio coupé depuis la régie",
"broadcast.snackbar.pause.error": "Pause : %1$@",
"broadcast.snackbar.paused": "Direct en pause",
"broadcast.snackbar.paused.remote": "Mis en pause depuis la régie",
"broadcast.snackbar.reconnect.started": "Reconnexion en cours…",
"broadcast.snackbar.resume.error": "Reprise : %1$@",
"broadcast.snackbar.resume.rtmp.error": "Reprise RTMP : %1$@",
"broadcast.snackbar.resumed": "Direct repris",
"broadcast.snackbar.resumed.remote": "Repris depuis la régie",
"broadcast.snackbar.unmuted": "Audio rétabli",
"broadcast.snackbar.unmuted.remote": "Audio rétabli depuis la régie",
"broadcast.status.connecting": "CONNEXION…",
"broadcast.status.error.fallback": "ERREUR",
"broadcast.status.live": "EN DIRECT",
"broadcast.status.paused": "PAUSE",
"broadcast.status.preview": "APERÇU",
"broadcast.status.reconnecting": "RECONNEXION…",
"broadcast.team.away.label": "EXTÉRIEUR",
"broadcast.team.home.label": "DOMICILE",
"broadcast.team.sets.count": "%1$d sets",
"broadcast.terminate.cd": "Terminer le direct",
"broadcast.terminate.confirm": "TERMINER",
"broadcast.terminate.message": "Le streaming sera fermé pour tous les spectateurs.",
"broadcast.terminate.title": "Terminer le direct ?",
"broadcast.tooltip.add.point": "Ajouter un point %1$@",
"broadcast.tooltip.plus.side": "+%1$d %2$@",
"broadcast.tooltip.remove.point": "Retirer un point %1$@",
"broadcast.unmute.cd": "Réactiver l'audio",
"broadcast.audio.muted.label": "Audio off",
"common.close": "Fermer",
"common.error.generic": "erreur",
"common.error.title": "Erreur",
"error.operation.failed": "Opération échouée",
"error.rtmp.failed": "Échec de la connexion RTMP. Vérifiez le réseau et le serveur de streaming.",
"error.rtmp.failed.dev": "Échec de la connexion RTMP. Vérifiez que MediaMTX est accessible (en dev : port 1935 sur localhost).",
"error.rtmp.interrupted": "Connexion RTMP interrompue",
"error.rtmp.invalid.url": "URL RTMP non valide. Vérifiez l'adresse d'ingest du serveur.",
"error.rtmp.timeout": "Délai de connexion RTMP dépassé. Vérifiez le réseau et MediaMTX (port 1935).",
"error.rtmp.unreachable": "Serveur RTMP inaccessible. En local, utilisez localhost:1935 (pas l'hôte Docker «mediamtx»).",
"language.english": "English",
"language.french": "Français",
"language.german": "Deutsch",
"language.italian": "Italiano",
"language.label": "Langue",
"language.spanish": "Español",
"language.system": "Système",
"login.email": "E-mail",
"login.email.placeholder": "coach@equipe.com",
"login.error.credentials": "E-mail ou mot de passe incorrect",
"login.error.generic": "Échec de la connexion",
"login.error.unreachable": "Serveur inaccessible. Vérifiez la connexion.",
"login.password": "Mot de passe",
"login.submit": "Connexion",
"match.status.live": "EN DIRECT",
"match.status.resume": "REPRENDRE",
"match.status.scheduled": "PLANIFIÉ",
"match.status.start": "DÉMARRER",
"matches.active.team": "Équipe active : %1$@.",
"matches.change": "Changer",
"matches.empty.hint": "Touchez « Nouveau match » pour planifier à l'avance ou démarrer tout de suite.",
"matches.empty.title": "Aucun match au calendrier",
"matches.hello": "Bonjour, %1$@",
"matches.load.error": "Erreur de chargement",
"matches.msg.create.failed": "Impossible de créer le match",
"matches.msg.delete.failed": "Impossible de supprimer",
"matches.msg.deleted": "Match supprimé",
"matches.msg.load.error": "Erreur de chargement",
"matches.msg.resume.failed": "Impossible de reprendre le direct",
"matches.msg.schedule.error": "Erreur lors de la création du match",
"matches.msg.scheduled.ok": "Match planifié — visible sur le site",
"matches.multi.team.hint": "Vous avez plusieurs équipes : vérifiez celle sélectionnée ci-dessus.",
"matches.new": "Nouveau match",
"matches.no.other": "Aucun autre match au calendrier.",
"matches.no.team.body": "Pour diffuser, vous devez être responsable de la transmission d'au moins une équipe. Demandez à votre club de vous ajouter comme staff diffusion.",
"matches.no.team.title": "Aucune équipe assignée",
"matches.ready.title": "Prêts à démarrer",
"matches.retry": "Réessayer",
"matches.scheduled.title": "Matchs programmés",
"matches.subtitle": "Reprenez un direct en cours ou démarrez un nouveau match.",
"matches.tap.change.team": "Appuyez pour changer d'équipe",
"matches.team.for.live": "Équipe pour le direct",
"matches.title": "Matchs",
"network.type.cellular": "4G",
"network.type.ethernet": "Ethernet",
"network.type.unknown": "Inconnu",
"network.type.wifi": "WiFi",
"overlay.set.label": "Set %1$d",
"score.action.close.anyway": "Fermer quand même",
"score.action.close.live": "Fermer le direct",
"score.action.close.set": "Fermer le set",
"score.action.continue.live": "Continuer le direct",
"score.action.continue.scoring": "Continuer à marquer",
"score.close.set.anyway.message": "Le score ne respecte pas encore les règles du tournoi. Fermer le set quand même ?",
"score.match.won.message": "%1$@ remporte le match (%2$d-%3$d sets).\\n\\nFermer définitivement le direct ?",
"score.match.won.title": "Match terminé",
"score.set.won.message": "%1$@ remporte le set %2$d-%3$d.\\n\\nFermer le set et passer au suivant ?",
"score.set.won.title": "Set terminé",
"session.error.no.active": "Aucune session active",
"session.error.not.connected": "Session non connectée",
"sheet.badge.calendar": "AU CALENDRIER",
"sheet.badge.draft": "BROUILLON",
"sheet.badge.scheduled": "PLANIFIÉ",
"sheet.choose.match": "Choisir le match",
"sheet.choose.match.lead": "Matchs déjà planifiés sur le site ou dans l'app.",
"sheet.choose.team": "Choisir l'équipe",
"sheet.configure": "Configurer",
"sheet.configure.now.body": "Vous pouvez préparer la diffusion maintenant, ou revenir une fois en salle.",
"sheet.configure.now.title": "Configurer maintenant ?",
"sheet.continue.setup": "CONTINUER LA CONFIGURATION",
"sheet.date.time": "Date et heure",
"sheet.delete": "Supprimer",
"sheet.delete.match.body": "Supprimer « %1$@ vs %2$@ » ?\n\nCette action est irréversible.",
"sheet.delete.match.title": "Supprimer le match",
"sheet.later": "Plus tard",
"sheet.live.in.progress": "Direct en cours",
"sheet.location.optional": "Lieu (facultatif)",
"sheet.new.match.lead": "Planifiez à l'avance ou lancez la configuration du direct tout de suite.",
"sheet.new.match.title": "Nouveau match",
"sheet.opponent": "Adversaire",
"sheet.quick.option": "Démarrer maintenant",
"sheet.quick.option.sub": "Créez le match et ouvrez l'assistant sans horaire",
"sheet.resume.banner": "Reprendre le direct en cours",
"sheet.resume.camera": "REPRENDRE CAMÉRA ET DIFFUSER",
"sheet.save.schedule": "ENREGISTRER AU CALENDRIER",
"sheet.schedule.lead": "Le direct ne démarre pas maintenant : il apparaîtra sur le site avec date et heure. Vous lancerez le streaming depuis l'app une fois en salle.",
"sheet.schedule.option": "Planifier le match",
"sheet.schedule.option.sub": "Date, heure et adversaire — aussi visibles sur le site",
"sheet.schedule.title": "Planifier le match",
"sheet.section.scheduled": "Planifiés",
"sheet.section.unscheduled": "Sans horaire",
"sheet.status": "État : %1$@",
"thermal.alert.continue": "Continuer",
"thermal.alert.message": "L'appareil est très chaud depuis plus d'une minute. iOS peut fermer l'app pour protéger l'appareil. Envisagez d'interrompre le direct.",
"thermal.alert.stop": "Arrêter le direct",
"thermal.alert.title": "Surchauffe",
"thermal.notice.critical": "Surchauffe imminente : qualité encore réduite.",
"thermal.notice.serious": "L'appareil chauffe. La qualité du streaming a été réduite pour assurer la stabilité.",
"thermal.state.critical": "Risque de surchauffe",
"thermal.state.fair": "Température élevée",
"thermal.state.nominal": "Température OK",
"thermal.state.serious": "Appareil chaud",
"wizard.action.back": "Retour",
"wizard.action.copy": "COPIER",
"wizard.action.next": "SUIVANT >",
"wizard.action.share": "PARTAGER",
"wizard.action.share.regia.link": "PARTAGER LE LIEN RÉGIE",
"wizard.action.start": "DÉMARRER >",
"wizard.branding.cancel": "ANNULER",
"wizard.branding.color.label": "Couleur de l'équipe",
"wizard.branding.customize.title": "Personnaliser",
"wizard.branding.edit.team.cd": "Modifier l'équipe",
"wizard.branding.logo.label": "Logo",
"wizard.branding.no.logo": "Aucun logo",
"wizard.branding.opponent.name.placeholder": "Nom de l'adversaire",
"wizard.branding.remove.logo": "SUPPRIMER",
"wizard.branding.save": "ENREGISTRER",
"wizard.branding.team.fallback.name": "Équipe",
"wizard.branding.team.name.label": "Nom de l'équipe",
"wizard.branding.upload.logo": "CHARGER LE LOGO",
"wizard.color.hue": "Teinte",
"wizard.complete.transmission.step": "Complétez l'étape Diffusion",
"wizard.error.opponent.name.required": "Saisissez le nom de l'adversaire",
"wizard.error.overtime.duration.required": "Saisissez la durée de la prolongation en minutes",
"wizard.error.period.duration.required": "Saisissez la durée de la période en minutes",
"wizard.error.points.per.set.required": "Saisissez les points pour gagner un set",
"wizard.error.regia.link": "Erreur du lien régie",
"wizard.error.save.generic": "Erreur lors de l'enregistrement",
"wizard.error.session.create": "Erreur lors de la création de la session",
"wizard.error.start.live": "Erreur au démarrage du direct",
"wizard.error.tiebreak.points.required": "Saisissez les points du tie-break",
"wizard.error.youtube.unavailable": "YouTube non disponible pour cette équipe",
"wizard.match.away.team.label": "Équipe adverse",
"wizard.match.category.hint": "Ex. Serie C, tournoi d'été — utilisé dans la description et l'overlay.",
"wizard.match.cover.title": "Image de pause",
"wizard.match.cover.source.label": "Source : %1$@",
"wizard.match.cover.source.default": "Match Live TV",
"wizard.match.cover.source.club": "Club",
"wizard.match.cover.source.team": "Équipe",
"wizard.match.cover.source.match": "Ce match",
"wizard.match.cover.hint": "Affichée en pause ou sans signal jusqu'à la reprise du direct.",
"wizard.match.cover.change": "Changer l'image pour ce match",
"wizard.match.cover.reset": "Utiliser l'image par défaut",
"wizard.match.cover.premium.required": "Image sponsor personnalisée avec Premium Full",
"wizard.match.category.label": "Championnat (facultatif)",
"wizard.match.custom.overlay.label": "Overlay vidéo personnalisé",
"wizard.match.custom.rules.label": "Règles de score personnalisées",
"wizard.match.details.title": "Détails du match",
"wizard.match.home.team.label": "Équipe à domicile",
"wizard.match.location.label": "Lieu",
"wizard.match.minutes.per.period.basket": "Minutes par quart-temps",
"wizard.match.minutes.per.period.timed": "Minutes par mi-temps",
"wizard.match.not.found": "Match introuvable",
"wizard.match.overtime.minutes.label": "Minutes de prolongation",
"wizard.match.periods.basket.label": "Quart-temps",
"wizard.match.periods.timed.label": "Mi-temps",
"wizard.match.points.per.set.label": "Points pour gagner un set",
"wizard.match.rules.custom.sets": "Tournoi non standard : définissez sets et points.",
"wizard.match.rules.custom.timed": "Tournoi non standard : temps et périodes personnalisés.",
"wizard.match.rules.standard.sets": "Standard FIVB : 3 sets gagnants, sets à 25, tie-break à 15.",
"wizard.match.rules.standard.sport": "Règles standard du sport sélectionné.",
"wizard.match.scheduled.label": "Programmé pour",
"wizard.match.sets.to.win.label": "Sets pour gagner le match",
"wizard.match.tiebreak.points.label": "Points du tie-break (dernier set)",
"wizard.network.download.label": "Téléchargement",
"wizard.network.latency.label": "Latence",
"wizard.network.link.live.label": "Lien du direct",
"wizard.network.link.youtube.label": "Lien YouTube",
"wizard.network.quality.label": "Qualité de streaming (automatique)",
"wizard.network.ready.label": "PRÊT À PASSER EN DIRECT",
"wizard.network.share.subject": "Direct — %1$@ vs %2$@",
"wizard.network.test.running.label": "TEST EN COURS...",
"wizard.network.test.start.label": "LANCER LE TEST RÉSEAU",
"wizard.network.test.subtitle": "Vérifiez que votre connexion supporte l'envoi du direct.",
"wizard.network.test.title": "Test réseau",
"wizard.network.type.label": "Type de réseau",
"wizard.network.upload.label": "Envoi",
"wizard.share.chooser.live": "Partager le direct",
"wizard.share.chooser.regia": "Partager la régie",
"wizard.step.title.match": "01 · Match",
"wizard.step.title.network": "03 · Test réseau",
"wizard.step.title.transmission": "02 · Diffusion",
"wizard.transmission.backend.note": "Le match reste toujours visible dans le backend de l'équipe pendant toute la durée de l'abonnement.",
"wizard.transmission.plan.label": "Forfait %1$@",
"wizard.transmission.platform.site.subtitle": "Direct sur notre site (inclus)",
"wizard.transmission.platform.title": "Plateforme",
"wizard.transmission.public.desc": "Apparaît dans la liste des directs sur MatchLiveTV.it, dans les recherches et sur la chaîne YouTube (si sélectionnée).",
"wizard.transmission.public.label": "PUBLIC",
"wizard.transmission.unlisted.desc": "N'apparaît pas dans les listes publiques ni dans les recherches. Seules les personnes ayant le lien peuvent regarder.",
"wizard.transmission.unlisted.label": "NON RÉPERTORIÉ",
"wizard.transmission.visibility.title": "Visibilité",
"wizard.transmission.youtube.activating": "Chaîne en cours d'activation",
"wizard.transmission.youtube.badge": "Premium",
"wizard.transmission.youtube.premium.required": "Premium Light ou Full",
"youtube.channel.club": "Chaîne club · %1$@",
"youtube.channel.club.fallback": "club",
"youtube.channel.platform": "Chaîne Match Live TV"
],
"de": [
"action.cancel": "Abbrechen",
"action.delete": "Löschen",
"action.exit": "Beenden",
"action.login": "Anmelden",
"action.logout": "Abmelden",
"account.confirm.password": "Passwort bestätigen",
"account.current.password": "Aktuelles Passwort",
"account.name.label": "Name",
"account.new.password": "Neues Passwort (mind. 8, mindestens 3 Zeichenarten)",
"account.password.heading": "Passwort ändern",
"account.password.saved": "Passwort aktualisiert",
"account.profile.heading": "Profil",
"account.profile.saved": "Profil aktualisiert",
"account.role": "Rolle: %1$@",
"account.save.password": "Passwort aktualisieren",
"account.save.profile": "Profil speichern",
"account.title": "Konto",
"forgot.password.lead": "Gib die E-Mail des Kontos ein: Wir senden dir einen Link zum Zurücksetzen des Passworts.",
"forgot.password.submit": "Reset-Link senden",
"forgot.password.success": "Wenn die E-Mail registriert ist, erhältst du in Kürze einen Link zum Zurücksetzen.",
"forgot.password.title": "Passwort vergessen",
"login.forgot.password": "Passwort vergessen?",
"action.ok": "OK",
"action.save": "Speichern",
"api.error.decoding": "Ungültige Serverantwort",
"api.error.forbidden": "Vorgang nicht erlaubt",
"api.error.http": "HTTP-Fehler %1$d",
"api.error.invalid.url": "Ungültige URL",
"api.error.not.found": "Ressource nicht gefunden",
"api.error.score.invalid": "Ungültige Punktestand-Antwort",
"api.error.server": "Serverfehler. Bitte gleich noch einmal versuchen.",
"api.error.unauthorized": "Sitzung abgelaufen. Bitte erneut anmelden.",
"app.name": "Match Live TV",
"app.slogan": "Jedes Spiel, jedes Event, für eure Fans.",
"broadcast.close.set.button": "SATZ BEENDEN",
"broadcast.error.camera.preview.not.ready": "Kameravorschau nicht bereit",
"broadcast.error.permissions.camera.mic": "Kamera- und Mikrofonberechtigung erforderlich",
"broadcast.error.reconnect.failed": "Wiederverbindung fehlgeschlagen",
"broadcast.error.regia.link": "Fehler beim Regie-Link",
"broadcast.error.regia.link.invalid": "Ungültiger Regie-Link",
"broadcast.error.rtmp.connect.failed": "RTMP-Verbindung fehlgeschlagen",
"broadcast.error.rtmp.missing": "RTMP-URL fehlt",
"broadcast.error.rtmp.session.create": "RTMP-Sitzung konnte nicht erstellt werden",
"broadcast.error.rtmp.url.invalid": "Ungültige RTMP-URL",
"broadcast.error.session.unavailable": "Sitzung nicht verfügbar",
"broadcast.hide.controls.cd": "Steuerung ausblenden",
"broadcast.min.quality.applied": "Mindestqualität: %1$@",
"broadcast.min.quality.auto": "Automatisch",
"broadcast.min.quality.cd": "Minimale Übertragungsqualität",
"broadcast.min.quality.error": "Mindestqualität konnte nicht gesetzt werden",
"broadcast.min.quality.hint": "Der Encoder fällt nicht unter dieses Niveau. Automatisch passt die Bitrate an, um Aussetzer zu reduzieren.",
"broadcast.min.quality.title": "Mindestqualität",
"broadcast.mute.cd": "Audio stummschalten",
"broadcast.next.period.cd": "Nächste Periode",
"broadcast.pause.cd": "Livestream pausieren",
"broadcast.period.label.timed": "Halbzeit %1$d",
"broadcast.permissions.grant.action": "BERECHTIGUNGEN ERTEILEN",
"broadcast.permissions.required": "Erlaube Kamera und Mikrofon, um live zu gehen",
"broadcast.points.target": "%1$d Pkt.",
"broadcast.resume.cd": "Livestream fortsetzen",
"broadcast.scoreboard.connected": "Anzeigetafel OK",
"broadcast.scoreboard.offline": "Anzeigetafel offline",
"broadcast.set.progress": "Satz %1$d · %2$d Pkt.",
"broadcast.sets.won": "Sätze gewonnen %1$d-%2$d",
"broadcast.share.chooser.title": "Teilen",
"broadcast.share.link.unavailable": "Live-Link noch nicht verfügbar",
"broadcast.share.live.cd": "Livestream teilen",
"broadcast.share.regia.cd": "Regie-Link teilen",
"broadcast.share.regia.subject": "Regie-Link — %1$@",
"broadcast.share.subject.fallback": "Match Live TV Livestream",
"broadcast.show.controls.cd": "Steuerung einblenden",
"broadcast.side.away": "Gast",
"broadcast.side.home": "Heim",
"broadcast.snackbar.closed.remote": "Livestream von der Regie beendet",
"broadcast.snackbar.min.quality.remote": "Mindestqualität von der Regie aktualisiert",
"broadcast.snackbar.mute.error": "Audio: %1$@",
"broadcast.snackbar.muted": "Audio stummgeschaltet",
"broadcast.snackbar.muted.remote": "Audio von der Regie stummgeschaltet",
"broadcast.snackbar.pause.error": "Pause: %1$@",
"broadcast.snackbar.paused": "Livestream pausiert",
"broadcast.snackbar.paused.remote": "Von der Regie pausiert",
"broadcast.snackbar.reconnect.started": "Wiederverbindung gestartet",
"broadcast.snackbar.resume.error": "Fortsetzen: %1$@",
"broadcast.snackbar.resume.rtmp.error": "RTMP-Fortsetzung: %1$@",
"broadcast.snackbar.resumed": "Livestream fortgesetzt",
"broadcast.snackbar.resumed.remote": "Von der Regie fortgesetzt",
"broadcast.snackbar.unmuted": "Audio wieder aktiv",
"broadcast.snackbar.unmuted.remote": "Audio von der Regie wieder aktiviert",
"broadcast.status.connecting": "VERBINDUNG…",
"broadcast.status.error.fallback": "FEHLER",
"broadcast.status.live": "LIVE",
"broadcast.status.paused": "PAUSE",
"broadcast.status.preview": "VORSCHAU",
"broadcast.status.reconnecting": "NEUVERBINDUNG…",
"broadcast.team.away.label": "GAST",
"broadcast.team.home.label": "HEIM",
"broadcast.team.sets.count": "%1$d Sätze",
"broadcast.terminate.cd": "Livestream beenden",
"broadcast.terminate.confirm": "BEENDEN",
"broadcast.terminate.message": "Der Stream wird für alle Zuschauer beendet.",
"broadcast.terminate.title": "Livestream beenden?",
"broadcast.tooltip.add.point": "Punkt hinzufügen %1$@",
"broadcast.tooltip.plus.side": "+%1$d %2$@",
"broadcast.tooltip.remove.point": "Punkt entfernen %1$@",
"broadcast.unmute.cd": "Audio einschalten",
"broadcast.audio.muted.label": "Audio aus",
"common.close": "Schließen",
"common.error.generic": "Fehler",
"common.error.title": "Fehler",
"error.operation.failed": "Vorgang fehlgeschlagen",
"error.rtmp.failed": "RTMP-Verbindung fehlgeschlagen. Netzwerk und Streaming-Server prüfen.",
"error.rtmp.failed.dev": "RTMP-Verbindung fehlgeschlagen. Prüfen Sie, ob MediaMTX erreichbar ist (Dev: Port 1935 auf localhost).",
"error.rtmp.interrupted": "RTMP-Verbindung unterbrochen",
"error.rtmp.invalid.url": "Ungültige RTMP-URL. Prüfen Sie die Ingest-Adresse vom Server.",
"error.rtmp.timeout": "RTMP-Timeout. Netzwerk und MediaMTX (Port 1935) prüfen.",
"error.rtmp.unreachable": "RTMP-Server nicht erreichbar. Lokal localhost:1935 verwenden (nicht Docker-Host «mediamtx»).",
"language.english": "English",
"language.french": "Français",
"language.german": "Deutsch",
"language.italian": "Italiano",
"language.label": "Sprache",
"language.spanish": "Español",
"language.system": "System",
"login.email": "E-Mail",
"login.email.placeholder": "coach@team.com",
"login.error.credentials": "Falsche E-Mail oder Passwort",
"login.error.generic": "Anmeldung fehlgeschlagen",
"login.error.unreachable": "Server nicht erreichbar. Verbindung prüfen.",
"login.password": "Passwort",
"login.submit": "Anmelden",
"match.status.live": "LIVE",
"match.status.resume": "FORTSETZEN",
"match.status.scheduled": "GEPLANT",
"match.status.start": "STARTEN",
"matches.active.team": "Aktives Team: %1$@.",
"matches.change": "Wechseln",
"matches.empty.hint": "Tippe auf «Neues Spiel», um im Voraus zu planen oder sofort zu starten.",
"matches.empty.title": "Keine Spiele im Kalender",
"matches.hello": "Hallo, %1$@",
"matches.load.error": "Ladefehler",
"matches.msg.create.failed": "Spiel konnte nicht erstellt werden",
"matches.msg.delete.failed": "Löschen fehlgeschlagen",
"matches.msg.deleted": "Spiel gelöscht",
"matches.msg.load.error": "Ladefehler",
"matches.msg.resume.failed": "Livestream konnte nicht fortgesetzt werden",
"matches.msg.schedule.error": "Fehler beim Erstellen des Spiels",
"matches.msg.scheduled.ok": "Spiel geplant — auf der Website sichtbar",
"matches.multi.team.hint": "Du hast mehrere Teams: prüfe die oben ausgewählte.",
"matches.new": "Neues Spiel",
"matches.no.other": "Keine weiteren Spiele im Kalender.",
"matches.no.team.body": "Zum Streamen musst du Übertragungs-Staff für mindestens ein Team sein. Bitte deinen Verein, dich als Streaming-Staff hinzuzufügen.",
"matches.no.team.title": "Kein Team zugewiesen",
"matches.ready.title": "Bereit zum Start",
"matches.retry": "Erneut versuchen",
"matches.scheduled.title": "Geplante Spiele",
"matches.subtitle": "Nimm einen laufenden Livestream wieder auf oder starte ein neues Spiel.",
"matches.tap.change.team": "Tippen zum Teamwechsel",
"matches.team.for.live": "Team für den Livestream",
"matches.title": "Spiele",
"network.type.cellular": "4G",
"network.type.ethernet": "Ethernet",
"network.type.unknown": "Unbekannt",
"network.type.wifi": "WiFi",
"overlay.set.label": "Satz %1$d",
"score.action.close.anyway": "Trotzdem beenden",
"score.action.close.live": "Livestream beenden",
"score.action.close.set": "Satz beenden",
"score.action.continue.live": "Weiter senden",
"score.action.continue.scoring": "Weiter punkten",
"score.close.set.anyway.message": "Der Punktestand erfüllt die Turnierregeln noch nicht. Satz trotzdem beenden?",
"score.match.won.message": "%1$@ gewinnt das Spiel (%2$d:%3$d Sätze).\\n\\nLivestream endgültig beenden?",
"score.match.won.title": "Spiel beendet",
"score.set.won.message": "%1$@ gewinnt den Satz %2$d:%3$d.\\n\\nSatz beenden und zum nächsten wechseln?",
"score.set.won.title": "Satz beendet",
"session.error.no.active": "Keine aktive Sitzung",
"session.error.not.connected": "Sitzung nicht verbunden",
"sheet.badge.calendar": "IM KALENDER",
"sheet.badge.draft": "ENTWURF",
"sheet.badge.scheduled": "GEPLANT",
"sheet.choose.match": "Spiel wählen",
"sheet.choose.match.lead": "Bereits auf der Website oder in der App geplante Spiele.",
"sheet.choose.team": "Team wählen",
"sheet.configure": "Einrichten",
"sheet.configure.now.body": "Du kannst die Übertragung jetzt vorbereiten oder zurückkommen, wenn du in der Halle bist.",
"sheet.configure.now.title": "Jetzt einrichten?",
"sheet.continue.setup": "EINRICHTUNG FORTSETZEN",
"sheet.date.time": "Datum und Uhrzeit",
"sheet.delete": "Löschen",
"sheet.delete.match.body": "«%1$@ vs %2$@» löschen?\n\nDies kann nicht rückgängig gemacht werden.",
"sheet.delete.match.title": "Spiel löschen",
"sheet.later": "Später",
"sheet.live.in.progress": "Live läuft",
"sheet.location.optional": "Ort (optional)",
"sheet.new.match.lead": "Im Voraus planen oder die Live-Einrichtung sofort starten.",
"sheet.new.match.title": "Neues Spiel",
"sheet.opponent": "Gegner",
"sheet.quick.option": "Jetzt starten",
"sheet.quick.option.sub": "Spiel erstellen und Wizard ohne Uhrzeit öffnen",
"sheet.resume.banner": "Laufenden Livestream fortsetzen",
"sheet.resume.camera": "KAMERA FORTSETZEN UND STREAMEN",
"sheet.save.schedule": "IM KALENDER SPEICHERN",
"sheet.schedule.lead": "Der Livestream startet jetzt nicht: Er erscheint auf der Website mit Datum und Uhrzeit. Du startest das Streaming in der App, wenn du in der Halle bist.",
"sheet.schedule.option": "Spiel planen",
"sheet.schedule.option.sub": "Datum, Uhrzeit und Gegner — auch auf der Website sichtbar",
"sheet.schedule.title": "Spiel planen",
"sheet.section.scheduled": "Geplant",
"sheet.section.unscheduled": "Ohne Uhrzeit",
"sheet.status": "Status: %1$@",
"thermal.alert.continue": "Weiter",
"thermal.alert.message": "Das Gerät ist seit über einer Minute sehr heiß. iOS kann die App zum Schutz beenden. Erwägen Sie, den Livestream zu stoppen.",
"thermal.alert.stop": "Live beenden",
"thermal.alert.title": "Überhitzung",
"thermal.notice.critical": "Überhitzung droht: Qualität weiter reduziert.",
"thermal.notice.serious": "Das Gerät wird warm. Die Streaming-Qualität wurde für mehr Stabilität reduziert.",
"thermal.state.critical": "Überhitzungsrisiko",
"thermal.state.fair": "Hohe Temperatur",
"thermal.state.nominal": "Temperatur OK",
"thermal.state.serious": "Gerät warm",
"wizard.action.back": "Zurück",
"wizard.action.copy": "KOPIEREN",
"wizard.action.next": "WEITER >",
"wizard.action.share": "TEILEN",
"wizard.action.share.regia.link": "REGIE-LINK TEILEN",
"wizard.action.start": "STARTEN >",
"wizard.branding.cancel": "ABBRECHEN",
"wizard.branding.color.label": "Teamfarbe",
"wizard.branding.customize.title": "Anpassen",
"wizard.branding.edit.team.cd": "Team bearbeiten",
"wizard.branding.logo.label": "Logo",
"wizard.branding.no.logo": "Kein Logo",
"wizard.branding.opponent.name.placeholder": "Name des Gegners",
"wizard.branding.remove.logo": "ENTFERNEN",
"wizard.branding.save": "SPEICHERN",
"wizard.branding.team.fallback.name": "Team",
"wizard.branding.team.name.label": "Teamname",
"wizard.branding.upload.logo": "LOGO HOCHLADEN",
"wizard.color.hue": "Farbton",
"wizard.complete.transmission.step": "Schließe den Schritt Übertragung ab",
"wizard.error.opponent.name.required": "Gib den Namen des Gegners ein",
"wizard.error.overtime.duration.required": "Gib die Dauer der Verlängerung in Minuten ein",
"wizard.error.period.duration.required": "Gib die Dauer der Periode in Minuten ein",
"wizard.error.points.per.set.required": "Gib die Punkte zum Satzgewinn ein",
"wizard.error.regia.link": "Fehler beim Regie-Link",
"wizard.error.save.generic": "Fehler beim Speichern",
"wizard.error.session.create": "Fehler beim Erstellen der Sitzung",
"wizard.error.start.live": "Fehler beim Starten des Livestreams",
"wizard.error.tiebreak.points.required": "Gib die Tie-Break-Punkte ein",
"wizard.error.youtube.unavailable": "YouTube für dieses Team nicht verfügbar",
"wizard.match.away.team.label": "Gastteam",
"wizard.match.category.hint": "Z. B. Serie C, Sommerturnier — wird in Beschreibung und Overlay verwendet.",
"wizard.match.cover.title": "Pausenbild",
"wizard.match.cover.source.label": "Quelle: %1$@",
"wizard.match.cover.source.default": "Match Live TV",
"wizard.match.cover.source.club": "Verein",
"wizard.match.cover.source.team": "Team",
"wizard.match.cover.source.match": "Dieses Spiel",
"wizard.match.cover.hint": "Wird bei Pause oder ohne Signal angezeigt, bis der Stream weitergeht.",
"wizard.match.cover.change": "Bild für dieses Spiel ändern",
"wizard.match.cover.reset": "Standardbild verwenden",
"wizard.match.cover.premium.required": "Individuelles Sponsor-Bild mit Premium Full",
"wizard.match.category.label": "Liga (optional)",
"wizard.match.custom.overlay.label": "Individuelles Video-Overlay",
"wizard.match.custom.rules.label": "Individuelle Punkteregeln",
"wizard.match.details.title": "Spieldetails",
"wizard.match.home.team.label": "Heimteam",
"wizard.match.location.label": "Ort",
"wizard.match.minutes.per.period.basket": "Minuten pro Viertel",
"wizard.match.minutes.per.period.timed": "Minuten pro Halbzeit",
"wizard.match.not.found": "Spiel nicht gefunden",
"wizard.match.overtime.minutes.label": "Verlängerungsminuten",
"wizard.match.periods.basket.label": "Viertel",
"wizard.match.periods.timed.label": "Halbzeiten",
"wizard.match.points.per.set.label": "Punkte zum Satzgewinn",
"wizard.match.rules.custom.sets": "Nicht standardmäßiges Turnier: Sätze und Punkte festlegen.",
"wizard.match.rules.custom.timed": "Nicht standardmäßiges Turnier: individuelle Zeiten und Perioden.",
"wizard.match.rules.standard.sets": "FIVB-Standard: 3 Gewinnsätze, Sätze bis 25, Tie-Break bis 15.",
"wizard.match.rules.standard.sport": "Standardregeln der gewählten Sportart.",
"wizard.match.scheduled.label": "Geplant für",
"wizard.match.sets.to.win.label": "Sätze zum Spielgewinn",
"wizard.match.tiebreak.points.label": "Tie-Break-Punkte (letzter Satz)",
"wizard.network.download.label": "Download",
"wizard.network.latency.label": "Latenz",
"wizard.network.link.live.label": "Live-Link",
"wizard.network.link.youtube.label": "YouTube-Link",
"wizard.network.quality.label": "Streaming-Qualität (automatisch)",
"wizard.network.ready.label": "BEREIT FÜR DEN LIVE-START",
"wizard.network.share.subject": "Live — %1$@ gegen %2$@",
"wizard.network.test.running.label": "TEST LÄUFT...",
"wizard.network.test.start.label": "NETZWERKTEST STARTEN",
"wizard.network.test.subtitle": "Prüfe, ob deine Verbindung den Live-Upload verkraftet.",
"wizard.network.test.title": "Netzwerktest",
"wizard.network.type.label": "Netzwerktyp",
"wizard.network.upload.label": "Upload",
"wizard.share.chooser.live": "Livestream teilen",
"wizard.share.chooser.regia": "Regie teilen",
"wizard.step.title.match": "01 · Spiel",
"wizard.step.title.network": "03 · Netzwerktest",
"wizard.step.title.transmission": "02 · Übertragung",
"wizard.transmission.backend.note": "Das Spiel bleibt für die gesamte Abo-Dauer im Team-Backend sichtbar.",
"wizard.transmission.plan.label": "Tarif %1$@",
"wizard.transmission.platform.site.subtitle": "Live auf unserer Website (inklusive)",
"wizard.transmission.platform.title": "Plattform",
"wizard.transmission.public.desc": "Erscheint in der Live-Liste auf MatchLiveTV.it, in der Suche und im YouTube-Kanal (falls ausgewählt).",
"wizard.transmission.public.label": "ÖFFENTLICH",
"wizard.transmission.unlisted.desc": "Erscheint nicht in öffentlichen Listen oder in der Suche. Nur mit dem Link kann zugesehen werden.",
"wizard.transmission.unlisted.label": "NICHT GELISTET",
"wizard.transmission.visibility.title": "Sichtbarkeit",
"wizard.transmission.youtube.activating": "Kanal wird aktiviert",
"wizard.transmission.youtube.badge": "Premium",
"wizard.transmission.youtube.premium.required": "Premium Light oder Full",
"youtube.channel.club": "Vereinskanal · %1$@",
"youtube.channel.club.fallback": "Verein",
"youtube.channel.platform": "Match Live TV-Kanal"
],
"es": [
"action.cancel": "Cancelar",
"action.delete": "Eliminar",
"action.exit": "Salir",
"action.login": "Acceder",
"action.logout": "Salir",
"account.confirm.password": "Confirmar contraseña",
"account.current.password": "Contraseña actual",
"account.name.label": "Nombre",
"account.new.password": "Nueva contraseña (mín. 8, al menos 3 tipos de caracteres)",
"account.password.heading": "Cambiar contraseña",
"account.password.saved": "Contraseña actualizada",
"account.profile.heading": "Perfil",
"account.profile.saved": "Perfil actualizado",
"account.role": "Rol: %1$@",
"account.save.password": "Actualizar contraseña",
"account.save.profile": "Guardar perfil",
"account.title": "Cuenta",
"forgot.password.lead": "Introduce el email de la cuenta: te enviaremos un enlace para restablecer la contraseña.",
"forgot.password.submit": "Enviar enlace",
"forgot.password.success": "Si el email está registrado, recibirás en breve un enlace para restablecer la contraseña.",
"forgot.password.title": "Contraseña olvidada",
"login.forgot.password": "¿Olvidaste la contraseña?",
"action.ok": "OK",
"action.save": "Guardar",
"api.error.decoding": "Respuesta del servidor no válida",
"api.error.forbidden": "Operación no permitida",
"api.error.http": "Error HTTP %1$d",
"api.error.invalid.url": "URL no válida",
"api.error.not.found": "Recurso no encontrado",
"api.error.score.invalid": "Respuesta de marcador no válida",
"api.error.server": "Error del servidor. Inténtalo de nuevo en un momento.",
"api.error.unauthorized": "Sesión caducada. Vuelve a iniciar sesión.",
"app.name": "Match Live TV",
"app.slogan": "Cada partido, cada evento, para tus aficionados.",
"broadcast.close.set.button": "CERRAR SET",
"broadcast.error.camera.preview.not.ready": "Vista previa de cámara no lista",
"broadcast.error.permissions.camera.mic": "Se requieren permisos de cámara y micrófono",
"broadcast.error.reconnect.failed": "Reconexión fallida",
"broadcast.error.regia.link": "Error en el enlace de regie",
"broadcast.error.regia.link.invalid": "Enlace de regia no válido",
"broadcast.error.rtmp.connect.failed": "Conexión RTMP fallida",
"broadcast.error.rtmp.missing": "Falta la URL RTMP",
"broadcast.error.rtmp.session.create": "No se pudo crear la sesión RTMP",
"broadcast.error.rtmp.url.invalid": "URL RTMP no válida",
"broadcast.error.session.unavailable": "Sesión no disponible",
"broadcast.hide.controls.cd": "Ocultar controles",
"broadcast.min.quality.applied": "Calidad mínima: %1$@",
"broadcast.min.quality.auto": "Automática",
"broadcast.min.quality.cd": "Calidad mínima de transmisión",
"broadcast.min.quality.error": "No se pudo fijar la calidad mínima",
"broadcast.min.quality.hint": "El encoder no baja de este nivel. Automática adapta el bitrate para reducir los cortes.",
"broadcast.min.quality.title": "Calidad mínima",
"broadcast.mute.cd": "Silenciar audio",
"broadcast.next.period.cd": "Periodo siguiente",
"broadcast.pause.cd": "Pausar directo",
"broadcast.period.label.timed": "Tiempo %1$d",
"broadcast.permissions.grant.action": "CONCEDER PERMISOS",
"broadcast.permissions.required": "Permite la cámara y el micrófono para salir en directo",
"broadcast.points.target": "%1$d pts",
"broadcast.resume.cd": "Reanudar directo",
"broadcast.scoreboard.connected": "Marcador OK",
"broadcast.scoreboard.offline": "Marcador sin conexión",
"broadcast.set.progress": "Set %1$d · %2$d pts",
"broadcast.sets.won": "Sets ganados %1$d-%2$d",
"broadcast.share.chooser.title": "Compartir",
"broadcast.share.link.unavailable": "Enlace del directo aún no disponible",
"broadcast.share.live.cd": "Compartir directo",
"broadcast.share.regia.cd": "Compartir enlace de regie",
"broadcast.share.regia.subject": "Enlace de regie — %1$@",
"broadcast.share.subject.fallback": "Directo de Match Live TV",
"broadcast.show.controls.cd": "Mostrar controles",
"broadcast.side.away": "visitante",
"broadcast.side.home": "local",
"broadcast.snackbar.closed.remote": "Directo cerrado desde regie",
"broadcast.snackbar.min.quality.remote": "Calidad mínima actualizada desde la regie",
"broadcast.snackbar.mute.error": "Audio: %1$@",
"broadcast.snackbar.muted": "Audio silenciado",
"broadcast.snackbar.muted.remote": "Audio silenciado desde regie",
"broadcast.snackbar.pause.error": "Pausa: %1$@",
"broadcast.snackbar.paused": "Directo en pausa",
"broadcast.snackbar.paused.remote": "Pausado desde regie",
"broadcast.snackbar.reconnect.started": "Reconexión iniciada",
"broadcast.snackbar.resume.error": "Reanudación: %1$@",
"broadcast.snackbar.resume.rtmp.error": "Reanudación RTMP: %1$@",
"broadcast.snackbar.resumed": "Directo reanudado",
"broadcast.snackbar.resumed.remote": "Reanudado desde regie",
"broadcast.snackbar.unmuted": "Audio reactivado",
"broadcast.snackbar.unmuted.remote": "Audio reactivado desde regie",
"broadcast.status.connecting": "CONECTANDO…",
"broadcast.status.error.fallback": "ERROR",
"broadcast.status.live": "EN DIRECTO",
"broadcast.status.paused": "PAUSA",
"broadcast.status.preview": "VISTA PREVIA",
"broadcast.status.reconnecting": "RECONECTANDO…",
"broadcast.team.away.label": "VISITANTE",
"broadcast.team.home.label": "LOCAL",
"broadcast.team.sets.count": "%1$d sets",
"broadcast.terminate.cd": "Terminar directo",
"broadcast.terminate.confirm": "TERMINAR",
"broadcast.terminate.message": "El streaming se cerrará para todos los espectadores.",
"broadcast.terminate.title": "¿Terminar el directo?",
"broadcast.tooltip.add.point": "Añadir punto %1$@",
"broadcast.tooltip.plus.side": "+%1$d %2$@",
"broadcast.tooltip.remove.point": "Quitar punto %1$@",
"broadcast.unmute.cd": "Reactivar audio",
"broadcast.audio.muted.label": "Audio off",
"common.close": "Cerrar",
"common.error.generic": "error",
"common.error.title": "Error",
"error.operation.failed": "Operación fallida",
"error.rtmp.failed": "Conexión RTMP fallida. Comprueba la red y el servidor de streaming.",
"error.rtmp.failed.dev": "Conexión RTMP fallida. Comprueba que MediaMTX sea alcanzable (en dev: puerto 1935 en localhost).",
"error.rtmp.interrupted": "Conexión RTMP interrumpida",
"error.rtmp.invalid.url": "URL RTMP no válida. Comprueba la dirección de ingest del servidor.",
"error.rtmp.timeout": "Tiempo de espera RTMP. Comprueba la red y MediaMTX (puerto 1935).",
"error.rtmp.unreachable": "Servidor RTMP no alcanzable. En local usa localhost:1935 (no el host Docker «mediamtx»).",
"language.english": "English",
"language.french": "Français",
"language.german": "Deutsch",
"language.italian": "Italiano",
"language.label": "Idioma",
"language.spanish": "Español",
"language.system": "Sistema",
"login.email": "Email",
"login.email.placeholder": "coach@equipo.com",
"login.error.credentials": "Email o contraseña incorrectos",
"login.error.generic": "Error de acceso",
"login.error.unreachable": "Servidor no disponible. Comprueba la conexión.",
"login.password": "Contraseña",
"login.submit": "Acceder",
"match.status.live": "EN DIRECTO",
"match.status.resume": "REANUDAR",
"match.status.scheduled": "PROGRAMADO",
"match.status.start": "INICIAR",
"matches.active.team": "Equipo activo: %1$@.",
"matches.change": "Cambiar",
"matches.empty.hint": "Toca «Nuevo partido» para programar con antelación o empezar ya.",
"matches.empty.title": "Ningún partido en el calendario",
"matches.hello": "Hola, %1$@",
"matches.load.error": "Error de carga",
"matches.msg.create.failed": "No se pudo crear el partido",
"matches.msg.delete.failed": "No se pudo eliminar",
"matches.msg.deleted": "Partido eliminado",
"matches.msg.load.error": "Error de carga",
"matches.msg.resume.failed": "No se pudo reanudar el directo",
"matches.msg.schedule.error": "Error al crear el partido",
"matches.msg.scheduled.ok": "Partido programado — visible en el sitio",
"matches.multi.team.hint": "Tienes varios equipos: comprueba el seleccionado arriba.",
"matches.new": "Nuevo partido",
"matches.no.other": "Ningún otro partido en el calendario.",
"matches.no.team.body": "Para emitir debes ser responsable de transmisión de al menos un equipo. Pide a tu club que te añada como staff de streaming.",
"matches.no.team.title": "Ningún equipo asignado",
"matches.ready.title": "Listos para empezar",
"matches.retry": "Reintentar",
"matches.scheduled.title": "Partidos programados",
"matches.subtitle": "Reanuda un directo en curso o inicia un nuevo partido.",
"matches.tap.change.team": "Toca para cambiar de equipo",
"matches.team.for.live": "Equipo para el directo",
"matches.title": "Partidos",
"network.type.cellular": "4G",
"network.type.ethernet": "Ethernet",
"network.type.unknown": "Desconocido",
"network.type.wifi": "WiFi",
"overlay.set.label": "Set %1$d",
"score.action.close.anyway": "Cerrar de todas formas",
"score.action.close.live": "Cerrar directo",
"score.action.close.set": "Cerrar set",
"score.action.continue.live": "Seguir en directo",
"score.action.continue.scoring": "Seguir puntuando",
"score.close.set.anyway.message": "El marcador aún no cumple las reglas del torneo. ¿Cerrar el set de todas formas?",
"score.match.won.message": "%1$@ gana el partido (%2$d-%3$d sets).\\n\\n¿Cerrar definitivamente el directo?",
"score.match.won.title": "Partido finalizado",
"score.set.won.message": "%1$@ gana el set %2$d-%3$d.\\n\\n¿Cerrar el set y pasar al siguiente?",
"score.set.won.title": "Set finalizado",
"session.error.no.active": "Ninguna sesión activa",
"session.error.not.connected": "Sesión no conectada",
"sheet.badge.calendar": "EN CALENDARIO",
"sheet.badge.draft": "BORRADOR",
"sheet.badge.scheduled": "PROGRAMADO",
"sheet.choose.match": "Elegir partido",
"sheet.choose.match.lead": "Partidos ya programados en el sitio o en la app.",
"sheet.choose.team": "Elegir equipo",
"sheet.configure": "Configurar",
"sheet.configure.now.body": "Puedes preparar la emisión ahora o volver cuando estés en el pabellón.",
"sheet.configure.now.title": "¿Configurar ahora?",
"sheet.continue.setup": "CONTINUAR CONFIGURACIÓN",
"sheet.date.time": "Fecha y hora",
"sheet.delete": "Eliminar",
"sheet.delete.match.body": "¿Eliminar «%1$@ vs %2$@»?\n\nEsta acción no se puede deshacer.",
"sheet.delete.match.title": "Eliminar partido",
"sheet.later": "Más tarde",
"sheet.live.in.progress": "Directo en curso",
"sheet.location.optional": "Lugar (opcional)",
"sheet.new.match.lead": "Programa con antelación o inicia ya la configuración del directo.",
"sheet.new.match.title": "Nuevo partido",
"sheet.opponent": "Rival",
"sheet.quick.option": "Empezar ahora",
"sheet.quick.option.sub": "Crea el partido y abre el asistente sin horario",
"sheet.resume.banner": "Reanudar directo en curso",
"sheet.resume.camera": "REANUDAR CÁMARA Y EMITIR",
"sheet.save.schedule": "GUARDAR EN EL CALENDARIO",
"sheet.schedule.lead": "El directo no empieza ahora: aparecerá en el sitio con fecha y hora. Iniciarás el streaming desde la app cuando estés en el pabellón.",
"sheet.schedule.option": "Programar partido",
"sheet.schedule.option.sub": "Fecha, hora y rival — también visible en el sitio",
"sheet.schedule.title": "Programar partido",
"sheet.section.scheduled": "Programados",
"sheet.section.unscheduled": "Sin horario",
"sheet.status": "Estado: %1$@",
"thermal.alert.continue": "Continuar",
"thermal.alert.message": "El dispositivo lleva más de un minuto muy caliente. iOS podría cerrar la app para protegerlo. Considera interrumpir la directa.",
"thermal.alert.stop": "Interrumpir directa",
"thermal.alert.title": "Sobrecalentamiento",
"thermal.notice.critical": "Sobrecalentamiento inminente: calidad reducida aún más.",
"thermal.notice.serious": "El dispositivo se está calentando. Se redujo la calidad del streaming para mantener la estabilidad.",
"thermal.state.critical": "Riesgo de sobrecalentamiento",
"thermal.state.fair": "Temperatura alta",
"thermal.state.nominal": "Temperatura OK",
"thermal.state.serious": "Dispositivo caliente",
"wizard.action.back": "Atrás",
"wizard.action.copy": "COPIAR",
"wizard.action.next": "SIGUIENTE >",
"wizard.action.share": "COMPARTIR",
"wizard.action.share.regia.link": "COMPARTIR ENLACE DE REGIE",
"wizard.action.start": "EMPEZAR >",
"wizard.branding.cancel": "CANCELAR",
"wizard.branding.color.label": "Color del equipo",
"wizard.branding.customize.title": "Personalizar",
"wizard.branding.edit.team.cd": "Editar equipo",
"wizard.branding.logo.label": "Logo",
"wizard.branding.no.logo": "Sin logo",
"wizard.branding.opponent.name.placeholder": "Nombre del rival",
"wizard.branding.remove.logo": "QUITAR",
"wizard.branding.save": "GUARDAR",
"wizard.branding.team.fallback.name": "Equipo",
"wizard.branding.team.name.label": "Nombre del equipo",
"wizard.branding.upload.logo": "SUBIR LOGO",
"wizard.color.hue": "Tono",
"wizard.complete.transmission.step": "Completa el paso Transmisión",
"wizard.error.opponent.name.required": "Introduce el nombre del rival",
"wizard.error.overtime.duration.required": "Introduce la duración de la prórroga en minutos",
"wizard.error.period.duration.required": "Introduce la duración del periodo en minutos",
"wizard.error.points.per.set.required": "Introduce los puntos para ganar un set",
"wizard.error.regia.link": "Error en el enlace de regie",
"wizard.error.save.generic": "Error al guardar",
"wizard.error.session.create": "Error al crear la sesión",
"wizard.error.start.live": "Error al iniciar el directo",
"wizard.error.tiebreak.points.required": "Introduce los puntos del tie-break",
"wizard.error.youtube.unavailable": "YouTube no disponible para este equipo",
"wizard.match.away.team.label": "Equipo visitante",
"wizard.match.category.hint": "Ej. Serie C, torneo de verano — lo usaremos en la descripción y el overlay.",
"wizard.match.cover.title": "Imagen de pausa",
"wizard.match.cover.source.label": "Origen: %1$@",
"wizard.match.cover.source.default": "Match Live TV",
"wizard.match.cover.source.club": "Club",
"wizard.match.cover.source.team": "Equipo",
"wizard.match.cover.source.match": "Este partido",
"wizard.match.cover.hint": "Se muestra en pausa o sin señal hasta que retome la transmisión.",
"wizard.match.cover.change": "Cambiar imagen para este partido",
"wizard.match.cover.reset": "Usar imagen predeterminada",
"wizard.match.cover.premium.required": "Imagen de patrocinio personalizada con Premium Full",
"wizard.match.category.label": "Categoría (opcional)",
"wizard.match.custom.overlay.label": "Overlay de vídeo personalizado",
"wizard.match.custom.rules.label": "Reglas de puntuación personalizadas",
"wizard.match.details.title": "Detalles del partido",
"wizard.match.home.team.label": "Equipo local",
"wizard.match.location.label": "Lugar",
"wizard.match.minutes.per.period.basket": "Minutos por cuarto",
"wizard.match.minutes.per.period.timed": "Minutos por tiempo",
"wizard.match.not.found": "Partido no encontrado",
"wizard.match.overtime.minutes.label": "Minutos de prórroga",
"wizard.match.periods.basket.label": "Cuartos",
"wizard.match.periods.timed.label": "Tiempos",
"wizard.match.points.per.set.label": "Puntos para ganar un set",
"wizard.match.rules.custom.sets": "Torneo no estándar: define sets y puntos.",
"wizard.match.rules.custom.timed": "Torneo no estándar: tiempos y periodos personalizados.",
"wizard.match.rules.standard.sets": "Estándar FIVB: 3 sets para ganar, sets a 25, tie-break a 15.",
"wizard.match.rules.standard.sport": "Reglas estándar del deporte seleccionado.",
"wizard.match.scheduled.label": "Programado para",
"wizard.match.sets.to.win.label": "Sets para ganar el partido",
"wizard.match.tiebreak.points.label": "Puntos del tie-break (último set)",
"wizard.network.download.label": "Descarga",
"wizard.network.latency.label": "Latencia",
"wizard.network.link.live.label": "Enlace del directo",
"wizard.network.link.youtube.label": "Enlace de YouTube",
"wizard.network.quality.label": "Calidad de streaming (automática)",
"wizard.network.ready.label": "LISTO PARA EMITIR EN DIRECTO",
"wizard.network.share.subject": "Directo — %1$@ vs %2$@",
"wizard.network.test.running.label": "TEST EN CURSO...",
"wizard.network.test.start.label": "INICIAR TEST DE RED",
"wizard.network.test.subtitle": "Comprueba que tu conexión soporta la subida del directo.",
"wizard.network.test.title": "Test de red",
"wizard.network.type.label": "Tipo de red",
"wizard.network.upload.label": "Subida",
"wizard.share.chooser.live": "Compartir directo",
"wizard.share.chooser.regia": "Compartir regie",
"wizard.step.title.match": "01 · Partido",
"wizard.step.title.network": "03 · Test de red",
"wizard.step.title.transmission": "02 · Transmisión",
"wizard.transmission.backend.note": "El partido permanece siempre visible en el backend del equipo durante toda la suscripción.",
"wizard.transmission.plan.label": "Plan %1$@",
"wizard.transmission.platform.site.subtitle": "En directo en nuestro sitio (incluido)",
"wizard.transmission.platform.title": "Plataforma",
"wizard.transmission.public.desc": "Aparece en la lista de directos de MatchLiveTV.it, en las búsquedas y en el canal de YouTube (si se selecciona).",
"wizard.transmission.public.label": "PÚBLICO",
"wizard.transmission.unlisted.desc": "No aparece en listas públicas ni en búsquedas. Solo puede verlo quien tenga el enlace.",
"wizard.transmission.unlisted.label": "NO LISTADO",
"wizard.transmission.visibility.title": "Visibilidad",
"wizard.transmission.youtube.activating": "Canal en activación",
"wizard.transmission.youtube.badge": "Premium",
"wizard.transmission.youtube.premium.required": "Premium Light o Full",
"youtube.channel.club": "Canal del club · %1$@",
"youtube.channel.club.fallback": "club",
"youtube.channel.platform": "Canal Match Live TV"
]
]
}
struct LanguagePickerView: View {
@Environment(\.dismiss) private var dismiss
@State private var selected = AppLanguage.current
var body: some View {
NavigationStack {
List {
ForEach(AppLanguage.allCases) { lang in
Button {
selected = lang
AppLanguage.current = lang
dismiss()
} label: {
HStack {
Text(lang.nativeLabel)
.foregroundStyle(MatchColors.textSecondary)
Spacer()
if selected == lang {
Image(systemName: "checkmark")
.foregroundStyle(MatchColors.primaryRed)
}
}
}
}
}
.navigationTitle(L10n.t("language.label"))
.toolbar {
ToolbarItem(placement: .cancellationAction) {
Button(L10n.t("action.cancel")) { dismiss() }
}
}
}
}
}