From 4b89d3a1af4975d8aae0d3fae53d9632f1698b91 Mon Sep 17 00:00:00 2001 From: Ptitlouis6012 <169227848+Ptitlouis6012@users.noreply.github.com> Date: Thu, 8 Oct 2026 15:58:04 +0200 Subject: [PATCH] Translate the sign-in and account pages into every language the device speaks The pages the QR code opens on a phone - the TigerTag sign-in, the Google pairing wait, the account page and the short replies - read their words from a table of four columns (PT, EN, ES, FR). German, Italian, Polish, Chinese and, with the previous commit, Russian and Dutch all fell back to English. The table gains six columns, DE, IT, PL, ZH, RU and NL, for all fifty rows, translated from the English; wl() maps each language to its column. Rows that are pasted into a JavaScript string carry no straight apostrophe. check-i18n.py already reads the column count from the declaration, so it checks the new width on its own; only its wording and the one doc that quoted "four languages" change. --- docs/ADOPTING-THIS-STANDARD.md | 4 +- firmware/src/webcfg.cpp | 291 ++++++++++++++++++++++++++------- scripts/check-i18n.py | 10 +- 3 files changed, 239 insertions(+), 66 deletions(-) diff --git a/docs/ADOPTING-THIS-STANDARD.md b/docs/ADOPTING-THIS-STANDARD.md index 16067be..f4df8ac 100644 --- a/docs/ADOPTING-THIS-STANDARD.md +++ b/docs/ADOPTING-THIS-STANDARD.md @@ -101,8 +101,8 @@ real; taking it would have violated the principle underneath it. key set. **Why it needed rewriting:** a second set does exist — the legacy configuration -page's table in `webcfg.cpp`. But it has a *different axis*: four languages where -the device speaks eight. Comparing their key sets would produce a permanent, +page's table in `webcfg.cpp`. But it has a *different axis*: ten columns where +the device speaks eleven languages. Comparing their key sets would produce a permanent, meaningless failure. `check-i18n.py` therefore checks each table against **its own** enum, on its own diff --git a/firmware/src/webcfg.cpp b/firmware/src/webcfg.cpp index 351325a..40abda1 100644 --- a/firmware/src/webcfg.cpp +++ b/firmware/src/webcfg.cpp @@ -46,12 +46,13 @@ extern LGFX_Sprite canvas; extern bool canvasReady; namespace { - // ---- legacy web page translations (UTF-8, order: PT, EN, ES, FR) ---- + // ---- legacy web page translations (UTF-8, order: PT, EN, ES, FR, DE, IT, PL, ZH, RU, NL) ---- // // Words for the small pages this file still serves itself: the account - // sign-in, the Google pairing wait, and the short replies. Four languages, - // where the portal and the device screens speak eight - these are seen - // once, and by someone who has already chosen a language on the panel. + // sign-in, the Google pairing wait, and the short replies. Ten columns for + // the device's eleven languages - the two Portuguese share the first - and + // these are seen once, by someone who has already chosen a language on the + // panel. // // The prototype's configuration form used to live here too. It was deleted // once the portal and the account replaced every part of it, and it is why @@ -70,77 +71,205 @@ namespace { W_SYNC_STARTED, W_FORGET_ASK, W_SYNC_TIMEOUT, W_NO_ROOM, W_N }; - const char* const WT[W_N][4] = { + const char* const WT[W_N][10] = { /* W_CFGMODE */ { "Modo de configuracao - escolhe a rede Wi-Fi e grava.", "Setup mode - pick the Wi-Fi network and save.", "Modo de configuracion - elige la red Wi-Fi y guarda.", - "Mode configuration - choisis le reseau Wi-Fi et enregistre." }, - /* W_RESCAN */ { "procurar de novo", "scan again", "buscar de nuevo", "rechercher a nouveau" }, + "Mode configuration - choisis le reseau Wi-Fi et enregistre.", + "Einrichtungsmodus - WLAN-Netzwerk wählen und speichern.", + "Modalità di configurazione - scegli la rete Wi-Fi e salva.", + "Tryb konfiguracji - wybierz sieć Wi-Fi i zapisz.", + "设置模式 - 选择 Wi-Fi 网络并保存。", + "Режим настройки - выберите сеть Wi-Fi и сохраните.", + "Instelmodus - kies het wifi-netwerk en sla op." }, + /* W_RESCAN */ { "procurar de novo", "scan again", "buscar de nuevo", "rechercher a nouveau", + "erneut suchen", "cerca di nuovo", "szukaj ponownie", "重新搜索", "искать снова", "opnieuw zoeken" }, /* W_STAR_PW */ { ". * = com password.", ". * = password-protected.", - ". * = con contrasena.", ". * = protege par mot de passe." }, - /* W_NETS_FOUND */ { "Redes encontradas", "Networks found", "Redes encontradas", "Reseaux trouves" }, - /* W_PICK */ { "-- escolhe --", "-- pick one --", "-- elige --", "-- choisir --" }, - /* W_NET */ { "Rede", "Network", "Red", "Reseau" }, - /* W_PASS */ { "Password", "Password", "Contrasena", "Mot de passe" }, - /* W_KEEP_EMPTY */ { " (vazio p/ manter)", " (blank to keep)", " (vacio para mantener)", " (vide pour garder)" }, - /* W_UNCHANGED */ { "(sem alteracao)", "(unchanged)", "(sin cambios)", "(inchange)" }, - /* W_LANG */ { "Idioma", "Language", "Idioma", "Langue" }, - /* W_PRINTERS */ { "Impressoras", "Printers", "Impresoras", "Imprimantes" }, + ". * = con contrasena.", ". * = protege par mot de passe.", + ". * = passwortgeschützt.", + ". * = protetta da password.", + ". * = chroniona hasłem.", + ". * = 有密码保护。", + ". * = защищено паролем.", + ". * = met wachtwoord beveiligd." }, + /* W_NETS_FOUND */ { "Redes encontradas", "Networks found", "Redes encontradas", "Reseaux trouves", + "Gefundene Netzwerke", "Reti trovate", "Znalezione sieci", "找到的网络", "Найденные сети", "Gevonden netwerken" }, + /* W_PICK */ { "-- escolhe --", "-- pick one --", "-- elige --", "-- choisir --", + "-- auswählen --", "-- scegli --", "-- wybierz --", "-- 请选择 --", "-- выберите --", "-- kies --" }, + /* W_NET */ { "Rede", "Network", "Red", "Reseau", + "Netzwerk", "Rete", "Sieć", "网络", "Сеть", "Netwerk" }, + /* W_PASS */ { "Password", "Password", "Contrasena", "Mot de passe", + "Passwort", "Password", "Hasło", "密码", "Пароль", "Wachtwoord" }, + /* W_KEEP_EMPTY */ { " (vazio p/ manter)", " (blank to keep)", " (vacio para mantener)", " (vide pour garder)", + " (leer lassen zum Behalten)", + " (vuoto per mantenere)", + " (puste = bez zmian)", + " (留空则保持不变)", + " (пусто - оставить как есть)", + " (leeg laten om te behouden)" }, + /* W_UNCHANGED */ { "(sem alteracao)", "(unchanged)", "(sin cambios)", "(inchange)", + "(unverändert)", "(invariato)", "(bez zmian)", "(未更改)", "(без изменений)", "(ongewijzigd)" }, + /* W_LANG */ { "Idioma", "Language", "Idioma", "Langue", + "Sprache", "Lingua", "Język", "语言", "Язык", "Taal" }, + /* W_PRINTERS */ { "Impressoras", "Printers", "Impresoras", "Imprimantes", + "Drucker", "Stampanti", "Drukarki", "打印机", "Принтеры", "Printers" }, /* W_LAN_HINT */ { "Ativa o Modo LAN em cada uma. K2: WebSocket :9999. FlashForge C5: HTTP :8898. Bambu: MQTT :8883. Serial + code do ecra da impressora.", "Enable LAN mode on each. K2: WebSocket :9999. FlashForge C5: HTTP :8898. Bambu: MQTT :8883. Serial + code from the printer screen.", "Activa el Modo LAN en cada una. K2: WebSocket :9999. FlashForge C5: HTTP :8898. Bambu: MQTT :8883. Serial + code de la pantalla de la impresora.", - "Active le mode LAN sur chacune. K2: WebSocket :9999. FlashForge C5: HTTP :8898. Bambu: MQTT :8883. Serie + code depuis l ecran de l imprimante." }, - /* W_PRINTER */ { "Impressora", "Printer", "Impresora", "Imprimante" }, - /* W_TYPE */ { "Tipo", "Type", "Tipo", "Type" }, - /* W_NAME */ { "Nome", "Name", "Nombre", "Nom" }, - /* W_SERIAL */ { "Serial (FF / Bambu)", "Serial (FF / Bambu)", "Numero de serie (FF / Bambu)", "Numero de serie (FF / Bambu)" }, + "Active le mode LAN sur chacune. K2: WebSocket :9999. FlashForge C5: HTTP :8898. Bambu: MQTT :8883. Serie + code depuis l ecran de l imprimante.", + "Aktiviere bei jedem den LAN-Modus. K2: WebSocket :9999. FlashForge C5: HTTP :8898. Bambu: MQTT :8883. Seriennummer + Code vom Druckerbildschirm.", + "Attiva la modalità LAN su ciascuna. K2: WebSocket :9999. FlashForge C5: HTTP :8898. Bambu: MQTT :8883. Seriale + codice dallo schermo della stampante.", + "Włącz tryb LAN w każdej. K2: WebSocket :9999. FlashForge C5: HTTP :8898. Bambu: MQTT :8883. Numer seryjny + kod z ekranu drukarki.", + "在每台打印机上启用局域网模式。K2:WebSocket :9999。FlashForge C5:HTTP :8898。Bambu:MQTT :8883。序列号 + 打印机屏幕上的代码。", + "Включите режим LAN на каждом. K2: WebSocket :9999. FlashForge C5: HTTP :8898. Bambu: MQTT :8883. Серийный номер + код с экрана принтера.", + "Schakel op elke printer de LAN-modus in. K2: WebSocket :9999. FlashForge C5: HTTP :8898. Bambu: MQTT :8883. Serienummer + code van het printerscherm." }, + /* W_PRINTER */ { "Impressora", "Printer", "Impresora", "Imprimante", + "Drucker", "Stampante", "Drukarka", "打印机", "Принтер", "Printer" }, + /* W_TYPE */ { "Tipo", "Type", "Tipo", "Type", + "Typ", "Tipo", "Typ", "类型", "Тип", "Type" }, + /* W_NAME */ { "Nome", "Name", "Nombre", "Nom", + "Name", "Nome", "Nazwa", "名称", "Название", "Naam" }, + /* W_SERIAL */ { "Serial (FF / Bambu)", "Serial (FF / Bambu)", "Numero de serie (FF / Bambu)", "Numero de serie (FF / Bambu)", + "Seriennummer (FF / Bambu)", + "Seriale (FF / Bambu)", + "Numer seryjny (FF / Bambu)", + "序列号 (FF / Bambu)", + "Серийный номер (FF / Bambu)", + "Serienummer (FF / Bambu)" }, /* W_CHECKCODE */ { "Check / Access code (FF / Bambu)", "Check / Access code (FF / Bambu)", - "Check / Access code (FF / Bambu)", "Check / Access code (FF / Bambu)" }, - /* W_SAVE_RESTART */ { "Guardar e reiniciar", "Save and restart", "Guardar y reiniciar", "Enregistrer et redemarrer" }, - /* W_TT_ACCOUNT */ { "Conta TigerTag", "TigerTag account", "Cuenta TigerTag", "Compte TigerTag" }, - /* W_CONNECTED */ { "Ligado: ", "Connected: ", "Conectado: ", "Connecte : " }, - /* W_SYNC_NOW */ { "Sincronizar maquinas agora", "Sync machines now", "Sincronizar maquinas ahora", "Synchroniser les machines" }, + "Check / Access code (FF / Bambu)", "Check / Access code (FF / Bambu)", + "Check / Access code (FF / Bambu)", + "Check / Access code (FF / Bambu)", + "Check / Access code (FF / Bambu)", + "Check / Access code (FF / Bambu)", + "Check / Access code (FF / Bambu)", + "Check / Access code (FF / Bambu)" }, + /* W_SAVE_RESTART */ { "Guardar e reiniciar", "Save and restart", "Guardar y reiniciar", "Enregistrer et redemarrer", + "Speichern und neu starten", + "Salva e riavvia", + "Zapisz i uruchom ponownie", + "保存并重启", + "Сохранить и перезапустить", + "Opslaan en herstarten" }, + /* W_TT_ACCOUNT */ { "Conta TigerTag", "TigerTag account", "Cuenta TigerTag", "Compte TigerTag", + "TigerTag-Konto", "Account TigerTag", "Konto TigerTag", "TigerTag 账户", "Аккаунт TigerTag", "TigerTag-account" }, + /* W_CONNECTED */ { "Ligado: ", "Connected: ", "Conectado: ", "Connecte : ", + "Verbunden: ", "Connesso: ", "Połączono: ", "已连接:", "Подключено: ", "Verbonden:" }, + /* W_SYNC_NOW */ { "Sincronizar maquinas agora", "Sync machines now", "Sincronizar maquinas ahora", "Synchroniser les machines", + "Drucker jetzt synchronisieren", + "Sincronizza le stampanti ora", + "Synchronizuj drukarki teraz", + "立即同步打印机", + "Синхронизировать принтеры сейчас", + "Printers nu synchroniseren" }, /* W_TT_FORGET */ { "Desligar a conta TigerTag", "Disconnect the TigerTag account", - "Desconectar la cuenta TigerTag", "Deconnecter le compte TigerTag" }, + "Desconectar la cuenta TigerTag", "Deconnecter le compte TigerTag", + "TigerTag-Konto trennen", + "Scollega l’account TigerTag", + "Odłącz konto TigerTag", + "断开 TigerTag 账户", + "Отключить аккаунт TigerTag", + "TigerTag-account loskoppelen" }, /* W_TT_HINT */ { "Importa as impressoras registadas na tua conta (Firebase). O login e so email/password.", "Imports the printers registered in your account (Firebase). Login is just email/password.", "Importa las impresoras registradas en tu cuenta (Firebase). El acceso es solo email/password.", - "Importe les imprimantes enregistrees dans ton compte (Firebase). La connexion est juste email/mot de passe." }, + "Importe les imprimantes enregistrees dans ton compte (Firebase). La connexion est juste email/mot de passe.", + "Importiert die in deinem Konto (Firebase) registrierten Drucker. Die Anmeldung erfolgt nur per E-Mail/Passwort.", + "Importa le stampanti registrate nel tuo account (Firebase). L’accesso è solo con email/password.", + "Importuje drukarki zarejestrowane na Twoim koncie (Firebase). Logowanie odbywa się tylko e-mailem i hasłem.", + "导入你账户(Firebase)中登记的打印机。登录只需邮箱和密码。", + "Импортирует принтеры, зарегистрированные в вашем аккаунте (Firebase). Вход только по e-mail и паролю.", + "Importeert de printers die in je account (Firebase) staan. Inloggen kan alleen met e-mail en wachtwoord." }, // A button says what happens when it is pressed. Importing the // printers is the consequence, not the action. - /* W_TT_LOGIN */ { "Entrar", "Sign in", "Iniciar sesión", "Se connecter" }, - /* W_RETRY_NET */ { "Tentar rede atual de novo", "Retry current network", "Reintentar la red actual", "Reessayer le reseau actuel" }, - /* W_WIPE */ { "Apagar tudo", "Wipe everything", "Borrar todo", "Tout effacer" }, - /* W_NONE */ { "Nenhuma", "None", "Ninguna", "Aucune" }, - /* W_SAVED */ { "Guardado.", "Saved.", "Guardado.", "Enregistre." }, + /* W_TT_LOGIN */ { "Entrar", "Sign in", "Iniciar sesión", "Se connecter", + "Anmelden", "Accedi", "Zaloguj", "登录", "Войти", "Inloggen" }, + /* W_RETRY_NET */ { "Tentar rede atual de novo", "Retry current network", "Reintentar la red actual", "Reessayer le reseau actuel", + "Aktuelles Netzwerk erneut versuchen", + "Riprova la rete attuale", + "Spróbuj ponownie z bieżącą siecią", + "重试当前网络", + "Повторить для текущей сети", + "Huidig netwerk opnieuw proberen" }, + /* W_WIPE */ { "Apagar tudo", "Wipe everything", "Borrar todo", "Tout effacer", + "Alles löschen", "Cancella tutto", "Wyczyść wszystko", "清除全部", "Стереть всё", "Alles wissen" }, + /* W_NONE */ { "Nenhuma", "None", "Ninguna", "Aucune", + "Keine", "Nessuna", "Brak", "无", "Нет", "Geen" }, + /* W_SAVED */ { "Guardado.", "Saved.", "Guardado.", "Enregistre.", + "Gespeichert.", "Salvato.", "Zapisano.", "已保存。", "Сохранено.", "Opgeslagen." }, /* W_RESTART_JOIN */ { "A reiniciar e a ligar a rede...", "Restarting and joining the network...", - "Reiniciando y conectando a la red...", "Redemarrage et connexion au reseau..." }, - /* W_WIPED */ { "Apagado.", "Wiped.", "Borrado.", "Efface." }, - /* W_RESTARTING */ { "A reiniciar...", "Restarting...", "Reiniciando...", "Redemarrage..." }, + "Reiniciando y conectando a la red...", "Redemarrage et connexion au reseau...", + "Neustart und Verbindung mit dem Netzwerk...", + "Riavvio e connessione alla rete...", + "Ponowne uruchamianie i łączenie z siecią...", + "正在重启并连接网络...", + "Перезапуск и подключение к сети...", + "Herstarten en verbinden met het netwerk..." }, + /* W_WIPED */ { "Apagado.", "Wiped.", "Borrado.", "Efface.", + "Gelöscht.", "Cancellato.", "Wyczyszczono.", "已清除。", "Стёрто.", "Gewist." }, + /* W_RESTARTING */ { "A reiniciar...", "Restarting...", "Reiniciando...", "Redemarrage...", + "Neustart...", "Riavvio...", "Ponowne uruchamianie...", "正在重启...", "Перезапуск...", "Herstarten..." }, /* W_RETRY_SAVED */ { "Nova tentativa na rede guardada.", "Retrying the saved network.", - "Reintentando la red guardada.", "Nouvel essai sur le reseau enregistre." }, - /* W_LOGIN_FAIL */ { "Login falhou", "Login failed", "Fallo de acceso", "Echec de connexion" }, - /* W_ACCT_LINKED */ { "Conta ligada", "Account linked", "Cuenta conectada", "Compte lie" }, - /* W_FAILED */ { "Falhou", "Failed", "Fallo", "Echoue" }, - /* W_ACCT_OFF */ { "Conta desligada", "Account disconnected", "Cuenta desconectada", "Compte deconnecte" }, + "Reintentando la red guardada.", "Nouvel essai sur le reseau enregistre.", + "Gespeichertes Netzwerk wird erneut versucht.", + "Nuovo tentativo con la rete salvata.", + "Ponawiam próbę z zapisaną siecią.", + "正在重试已保存的网络。", + "Повторная попытка с сохранённой сетью.", + "Opgeslagen netwerk wordt opnieuw geprobeerd." }, + /* W_LOGIN_FAIL */ { "Login falhou", "Login failed", "Fallo de acceso", "Echec de connexion", + "Anmeldung fehlgeschlagen", + "Accesso non riuscito", + "Logowanie nie powiodło się", + "登录失败", + "Не удалось войти", + "Inloggen mislukt" }, + /* W_ACCT_LINKED */ { "Conta ligada", "Account linked", "Cuenta conectada", "Compte lie", + "Konto verbunden", "Account collegato", "Konto połączone", "账户已绑定", "Аккаунт привязан", "Account gekoppeld" }, + /* W_FAILED */ { "Falhou", "Failed", "Fallo", "Echoue", + "Fehlgeschlagen", "Non riuscito", "Nie udało się", "失败", "Не удалось", "Mislukt" }, + /* W_ACCT_OFF */ { "Conta desligada", "Account disconnected", "Cuenta desconectada", "Compte deconnecte", + "Konto getrennt", "Account scollegato", "Konto odłączone", "账户已断开", "Аккаунт отключён", "Account losgekoppeld" }, /* W_GOOGLE */ { "Continuar com Google", "Continue with Google", - "Continuar con Google", "Continuer avec Google" }, + "Continuar con Google", "Continuer avec Google", + "Mit Google fortfahren", + "Continua con Google", + "Kontynuuj z Google", + "使用 Google 继续", + "Продолжить с Google", + "Doorgaan met Google" }, /* W_EMAIL */ { "Endereço de e-mail", "Email address", - "Dirección de correo", "Adresse e-mail" }, - /* W_OR */ { "ou", "or", "o", "ou" }, + "Dirección de correo", "Adresse e-mail", + "E-Mail-Adresse", "Indirizzo email", "Adres e-mail", "邮箱地址", "Адрес e-mail", "E-mailadres" }, + /* W_OR */ { "ou", "or", "o", "ou", + "oder", "oppure", "lub", "或", "или", "of" }, // Accents intact: this page is drawn by the phone's browser, so the // ASCII-only limit of the panel's compiled font never applied here. /* W_NO_ACCOUNT */ { "Ainda sem conta? Cria-a no Tiger Studio Manager e adiciona lá as tuas impressoras.", "No account yet? Create one in Tiger Studio Manager, then add your printers there.", "¿Todavía sin cuenta? Créala en Tiger Studio Manager y añade allí tus impresoras.", - "Pas encore de compte ? Créez-le dans Tiger Studio Manager, puis ajoutez-y vos imprimantes." }, + "Pas encore de compte ? Créez-le dans Tiger Studio Manager, puis ajoutez-y vos imprimantes.", + "Noch kein Konto? Erstelle eines in Tiger Studio Manager und füge dort deine Drucker hinzu.", + "Non hai ancora un account? Creane uno in Tiger Studio Manager, poi aggiungi lì le tue stampanti.", + "Nie masz jeszcze konta? Utwórz je w Tiger Studio Manager, a potem dodaj tam swoje drukarki.", + "还没有账户?请在 Tiger Studio Manager 中创建,然后在那里添加你的打印机。", + "Ещё нет аккаунта? Создайте его в Tiger Studio Manager, затем добавьте там свои принтеры.", + "Nog geen account? Maak er een aan in Tiger Studio Manager en voeg daar je printers toe." }, /* W_SHOW_PW */ { "Mostrar a password", "Show password", - "Mostrar la contraseña", "Afficher le mot de passe" }, + "Mostrar la contraseña", "Afficher le mot de passe", + "Passwort anzeigen", "Mostra password", "Pokaż hasło", "显示密码", "Показать пароль", "Wachtwoord tonen" }, /* W_PAIR_SCAN */ { "Lê o QR code no ecrã do TigerSpool", "Scan the QR code on the TigerSpool screen", "Escanea el código QR en la pantalla del TigerSpool", - "Scannez le QR code sur l'écran du TigerSpool" }, - /* W_PAIR_CODE */ { "codigo", "code", "codigo", "code" }, + "Scannez le QR code sur l'écran du TigerSpool", + "Scanne den QR-Code auf dem TigerSpool-Bildschirm", + "Scansiona il codice QR sullo schermo del TigerSpool", + "Zeskanuj kod QR na ekranie TigerSpool", + "扫描 TigerSpool 屏幕上的二维码", + "Отсканируйте QR-код на экране TigerSpool", + "Scan de QR-code op het scherm van de TigerSpool" }, + /* W_PAIR_CODE */ { "codigo", "code", "codigo", "code", + "Code", "codice", "kod", "代码", "код", "code" }, // No device named, for the same reason W_PAIR_OPEN was dropped: this // page is read from a phone that scanned the QR and from a PC where // someone typed the address off the device's screen, and it cannot @@ -148,30 +277,68 @@ namespace { /* W_PAIR_WAIT */ { "A aguardar aprovação...", "Waiting for approval...", "Esperando aprobación...", - "En attente d'approbation..." }, - /* W_PAIR_DENIED */ { "Pedido recusado", "Request denied", "Solicitud rechazada", "Demande refusee" }, + "En attente d'approbation...", + "Warte auf Bestätigung...", + "In attesa di approvazione...", + "Oczekiwanie na zatwierdzenie...", + "等待批准...", + "Ожидание подтверждения...", + "Wachten op goedkeuring..." }, + /* W_PAIR_DENIED */ { "Pedido recusado", "Request denied", "Solicitud rechazada", "Demande refusee", + "Anfrage abgelehnt", "Richiesta negata", "Żądanie odrzucone", "请求被拒绝", "Запрос отклонён", "Verzoek geweigerd" }, /* W_PAIR_EXPIRED */ { "Codigo expirado - tenta de novo", "Code expired - try again", - "Codigo expirado - intenta de nuevo", "Code expire - reessaie" }, + "Codigo expirado - intenta de nuevo", "Code expire - reessaie", + "Code abgelaufen - bitte erneut versuchen", + "Codice scaduto - riprova", + "Kod wygasł - spróbuj ponownie", + "代码已过期 - 请重试", + "Код истёк - попробуйте снова", + "Code verlopen - probeer het opnieuw" }, /* W_SYNC_STARTED */ { "A sincronizar as impressoras em segundo plano.", "Syncing your printers in the background.", "Sincronizando las impresoras en segundo plano.", - "Synchronisation des imprimantes en arrière-plan." }, + "Synchronisation des imprimantes en arrière-plan.", + "Deine Drucker werden im Hintergrund synchronisiert.", + "Sincronizzazione delle stampanti in background.", + "Synchronizacja drukarek w tle.", + "正在后台同步你的打印机。", + "Принтеры синхронизируются в фоновом режиме.", + "Je printers worden op de achtergrond gesynchroniseerd." }, /* W_FORGET_ASK */ { "Desligar a conta? O dispositivo vai reiniciar.", "Disconnect the account? The device will restart.", "¿Desconectar la cuenta? El dispositivo se reiniciará.", - "Déconnecter le compte ? Le TigerSpool va redémarrer." }, + "Déconnecter le compte ? Le TigerSpool va redémarrer.", + "Konto trennen? Das Gerät wird neu gestartet.", + "Scollegare l’account? Il dispositivo si riavvierà.", + "Odłączyć konto? Urządzenie uruchomi się ponownie.", + "断开账户?设备将重启。", + "Отключить аккаунт? Устройство перезапустится.", + "Account loskoppelen? Het apparaat start opnieuw op." }, /* W_SYNC_TIMEOUT */ { "Sem resposta da sincronização.", "The sync did not answer.", - "La sincronización no respondió.", "La synchronisation n’a pas répondu." }, + "La sincronización no respondió.", "La synchronisation n’a pas répondu.", + "Die Synchronisierung hat nicht geantwortet.", + "La sincronizzazione non ha risposto.", + "Synchronizacja nie odpowiedziała.", + "同步没有响应。", + "Синхронизация не ответила.", + "De synchronisatie reageerde niet." }, /* W_NO_ROOM */ { "Sem memória para ligar mais uma impressora.", "Not enough memory to switch on one more printer.", "Sin memoria para activar una impresora más.", - "Pas assez de mémoire pour activer une imprimante de plus." }, + "Pas assez de mémoire pour activer une imprimante de plus.", + "Nicht genug Speicher, um einen weiteren Drucker zu aktivieren.", + "Memoria insufficiente per attivare un’altra stampante.", + "Za mało pamięci, aby włączyć kolejną drukarkę.", + "内存不足,无法再启用一台打印机。", + "Недостаточно памяти, чтобы включить ещё один принтер.", + "Te weinig geheugen om nog een printer in te schakelen." }, }; - // The web form still carries its own four-column table (PT, EN, ES, FR), - // inherited from the prototype. The device now has eleven languages, so an - // unmapped index would read past the end of every row. + // The web form has its own table, inherited from the prototype, which began + // as four columns (PT, EN, ES, FR). The device speaks eleven languages and + // European and Brazilian Portuguese share a column, so every language maps + // to one of ten; an unmapped index would read past the end of every row. // - // This maps what it can and falls back to English. The real fix is phase 7: + // Anything not listed falls back to English. The real fix is phase 7: // serve a static page from LittleFS with proper locale files, the way // TigerScale does - see docs/MIGRATION.md. const char* wl(Wid id) { @@ -181,6 +348,12 @@ namespace { case LANG_PT_PT: col = 0; break; case LANG_ES: col = 2; break; case LANG_FR: col = 3; break; + case LANG_DE: col = 4; break; + case LANG_IT: col = 5; break; + case LANG_PL: col = 6; break; + case LANG_ZH: col = 7; break; + case LANG_RU: col = 8; break; + case LANG_NL: col = 9; break; default: col = 1; break; // English } return WT[id][col]; diff --git a/scripts/check-i18n.py b/scripts/check-i18n.py index e5a2ca6..321bd3d 100755 --- a/scripts/check-i18n.py +++ b/scripts/check-i18n.py @@ -18,9 +18,9 @@ Counting is not enough: order is the failure mode. This checks the comments against the enum position by position. -There are two tables. The second is the four-language set in webcfg.cpp used by -the legacy configuration page - a different axis from the device's eight, and -checked on its own terms rather than against them. +There are two tables. The second is the ten-column set in webcfg.cpp used by +the legacy configuration page - a different axis from the device's eleven +languages, and checked on its own terms rather than against them. """ import pathlib @@ -94,7 +94,7 @@ def main() -> int: check_table(problems, "STR", "firmware/src/i18n.cpp", rows, keys, len(langs), ", ".join(langs)) - # --- the legacy web table: a different, four-language axis ------------- + # --- the legacy web table: a different, ten-column axis ------------------ w = (REPO / "firmware/src/webcfg.cpp").read_text() wkeys = enum_members(w, "", "W_N") or [] wkeys = [k for k in wkeys if k.startswith("W_")] @@ -112,7 +112,7 @@ def main() -> int: r"/\*\s*(W_\w+)\s*\*/\s*\{(.*?)\}\s*,?\s*(?:(?://[^\n]*\n)\s*)*(?=/\*|\};)", w, re.S) check_table(problems, "WT", "firmware/src/webcfg.cpp", wrows, wkeys, - int(m.group(1)), "the legacy page's four languages") + int(m.group(1)), "the legacy page's ten columns") if checked == 0: print("error: found no translation tables to check", file=sys.stderr)