feat(i18n): complete message parity across all 25 locales
Gitea Actions Runner Test / test-job (push) Successful in 1s
CI / check (push) Successful in 37s
CI / tests-unit (push) Successful in 1m49s
CI / tests-integration (push) Successful in 1m50s
CI / tests-ui (push) Successful in 2m29s
CI / preflight (push) Skipped
CI / deploy (push) Failing after 1m37s

The admin.studio.nitroCleanup section (102 keys) only existed in en and
nl, so 23 locales fell back to English for the entire Nitro Cleanup
panel. The referrals and dailyRewards keys were missing from the same
23 locales, and en itself was missing 6 keys that nl had.

Add the missing keys to every locale with translations, so all 25
locales now carry the same 6063 keys.
This commit is contained in:
openhands committed 2026-09-27 18:38:58 +02:00
1 parent 944527e078
commit bc00ecf08c
24 files changed
+4483 -182

No files matched your search

+195 -8
View File
@@ -817,9 +817,9 @@
"enable": "Habilitar 2FA",
"rateLimit": "Too many attempts. Please wait before trying again."
},
"title": "Contas conectadas",
"subtitle": "Vincule uma conta social para poder fazer login com um clique",
"connected": "Conectado",
"title": "Contas vinculadas",
"subtitle": "Vincule uma conta social para iniciar sessão com um clique",
"connected": "Vinculado",
"unavailable": "Indisponível",
"login": {
"title": "Faça login",
@@ -882,7 +882,9 @@
"hidePassword": "Hide",
"accountDetails": "Account details",
"credentials": "Credentials & security",
"newestCitizens": "Newest citizens"
"newestCitizens": "Newest citizens",
"ageVerified": "Tenho 18+ e aceito o requisito de idade.",
"invitedBy": "Convidado por {username}"
},
"forgot": {
"title": "Redefinir senha",
@@ -1048,7 +1050,9 @@
"cmsErrors": "CMS errors",
"themeBuilder": "Theme builder",
"openSidebar": "Open menu",
"closeSidebar": "Close menu"
"closeSidebar": "Close menu",
"referrals": "Indicações",
"dailyRewards": "Recompensas diárias"
},
"dashboard": {
"title": "Painel",
@@ -4336,7 +4340,9 @@
"importAudit": "Audit",
"themeBuilder": "Theme Builder",
"studio": "Studio",
"cmsErrors": "CMS errors"
"cmsErrors": "CMS errors",
"referrals": "Indicações",
"dailyRewards": "Recompensas diárias"
},
"events": "Events",
"eventsSubtitle": "Hotel events and event types",
@@ -5843,6 +5849,64 @@
"NoscopescreatedyetAddonebelow": "No scopes created yet. Add one below.",
"Rename": "Rename"
}
},
"referrals": {
"title": "Indicações",
"subtitle": "Sistema de convites",
"referralsToday": "Indicações hoje",
"referralsTotal": "Indicações totais",
"invitedTotal": "Convites contados",
"claims": "Recompensas resgatadas",
"settings": "Configurações de recompensa",
"needed": "Indicações necessárias",
"rewardAmount": "Valor da recompensa",
"rewardCurrency": "Moeda da recompensa",
"blockSameIp": "Rejeitar indicações que compartilham o IP atual do convidador",
"save": "Salvar configurações",
"saving": "Salvando…",
"saved": "Configurações de indicação salvas.",
"saveError": "As configurações de indicação não puderam ser salvas.",
"recent": "Indicações recentes",
"unavailable": "Os dados de indicação estão temporariamente indisponíveis.",
"empty": "Nenhuma indicação ainda.",
"inviter": "Convidador",
"invitee": "Usuário convidado",
"ip": "IP",
"date": "Data"
},
"dailyRewards": {
"title": "Recompensas diárias de login",
"subtitle": "Programa de recompensas diárias de login",
"enabled": "Status da funcionalidade",
"yes": "Ativado",
"no": "Desativado",
"scheduleDays": "Dias do programa",
"claimsToday": "Resgates hoje",
"claimsTotal": "Resgates totais",
"status": "Status da funcionalidade",
"statusHint": "Quando desativado, o cartão de recompensa é ocultado e novos resgates são rejeitados.",
"disable": "Desativar",
"enable": "Ativar",
"schedule": "Programa de recompensas",
"day": "Dia {day}",
"reward": "Recompensa",
"amount": "Valor",
"actions": "Ações",
"addDay": "Dia",
"add": "Adicionar dia",
"save": "Salvar",
"saving": "Salvando…",
"saved": "Programa de recompensas salvo.",
"cancel": "Cancelar",
"edit": "Editar",
"delete": "Excluir",
"created": "Dia de recompensa adicionado.",
"updated": "Dia de recompensa atualizado.",
"deleted": "Dia de recompensa removido.",
"saveError": "O dia de recompensa não pôde ser salvo.",
"deleteError": "O dia de recompensa não pôde ser removido.",
"confirmDeleteTitle": "Remover dia de recompensa",
"confirmDeleteBody": "Este dia de recompensa não será mais concedido. Resgates passados permanecem registrados."
}
},
"error": {
@@ -6223,8 +6287,27 @@
"empty": "You're all caught up. No actions waiting.",
"unavailable": "Some actions could not be checked. Available actions are shown above.",
"retry": "Try again",
"rewardUnavailable": "Referral progress is temporarily unavailable. Please try again."
}
"rewardUnavailable": "Referral progress is temporarily unavailable. Please try again.",
"dailyReward": "Sua recompensa diária está pronta para resgate"
},
"dailyClaimed": "Recompensa diária resgatada — até amanhã!",
"dailyErrors": {
"already_claimed": "Você já resgatou a recompensa diária de hoje.",
"disabled": "As recompensas diárias estão desativadas atualmente.",
"bad_config": "O programa de recompensas diárias não está configurado corretamente. Contate a equipe.",
"ratelimit": "Muitas tentativas. Aguarde um momento e tente novamente.",
"error": "A recompensa diária não pôde ser resgatada. Tente novamente."
},
"dailyRewardTitle": "Recompensas diárias",
"dailyRewardHint": "Faça login todos os dias e resgate sua recompensa — as sequências crescem até os grandes dias.",
"dailyRewardDay": "Dia {day}",
"dailyRewardStreak": "{count, plural, one {Sequência: # dia} other {Sequência: # dias}}",
"dailyRewardNextClaim": "Próximo resgate: {amount} {currency}",
"dailyRewardTomorrow": "Amanhã: {amount} {currency}",
"dailyRewardClaim": "Resgatar recompensa diária",
"dailyRewardClaimedToday": "Resgatado hoje — volte amanhã para a próxima recompensa.",
"dailyRewardDisabled": "As recompensas diárias estão desativadas atualmente. Você pode explorar o hotel.",
"dailyRewardUnavailable": "O programa de recompensas diárias não pôde ser carregado. Tente novamente."
},
"housekeeping": {
"preview": {
@@ -6502,6 +6585,110 @@
},
"admin": {
"studio": {
"nitroCleanup": {
"alreadyRunning": "Uma verificação já está em andamento — conectada a ela.",
"ageUnknown": "idade desconhecida",
"ageBelow": "< 1d",
"scanButton": "Verificar recursos de móveis",
"scanningAssets": "Verificando recursos…",
"cancelButton": "Cancelar",
"deleteSelected": "Excluir selecionados ({count})",
"deleting": "Excluindo…",
"redownloadBroken": "Baixar novamente os danificados",
"redownloading": "Baixando novamente…",
"autoClean": "Limpar automaticamente os falsos antigos",
"cleaning": "Limpando…",
"exportManifest": "Exportar manifesto",
"exporting": "Exportando…",
"phaseStems": "Carregando caules de móveis…",
"phaseReaddir": "Lendo diretórios de recursos…",
"phaseValidate": "Validando pacotes .nitro…",
"phaseScanning": "Verificando…",
"scanProgressFiles": "{count} arquivos",
"repairProgress": "ok {ok}, falharam {failed}",
"attachedNotice": "A verificação continua em segundo plano — os resultados aparecerão quando terminar.",
"sessionCancelled": "Verificação cancelada.",
"onlyOldLabel": "Mostrar apenas arquivos mais antigos que",
"onlyOldAgeLabel": "Idade mínima em dias para exibição",
"onlyOldToggle": "Ocultar arquivos recentes",
"daysLabel": "dias",
"autoAgeLabel": "Idade mínima em dias para limpeza automática",
"loadingResult": "Carregando resultado da verificação…",
"scannedStat": "arquivos de recursos verificados",
"cachedNotice": "(em cache — os diretórios não mudaram)",
"fakeStat": "Nitros falsos (sem item correspondente)",
"brokenStat": "Nitros danificados (ilegíveis)",
"groupEmpty": "Nada encontrado",
"selectedCount": "{count} selecionados",
"copiesBadge": "{count} cópias",
"groupFakeLabel": "Nitros falsos",
"groupFakeDescription": "Estes arquivos não correspondem a nenhum item em items_base — restos de móveis excluídos ou renomeados.",
"groupBrokenLabel": "Nitros danificados",
"groupBrokenDescription": "Estes arquivos pertencem a um item, mas não podem ser lidos como um pacote Nitro válido.",
"groupSwfLabel": "SWFs órfãos",
"groupSwfDescription": "Arquivos .swf que não correspondem a nenhum item em items_base.",
"groupIconLabel": "Ícones órfãos",
"groupIconDescription": "Arquivos de ícones que não correspondem a nenhum item em items_base.",
"warningText": "Excluir um .nitro danificado deixa seu item no banco de dados sem pacote — prefira baixá-lo novamente, ou deixe a auditoria do catálogo obtê-lo mais tarde. As linhas do banco de dados nunca são removidas por esta ferramenta.",
"onlyAssetsTouched": "Apenas os arquivos de recursos são alterados — FurnitureData.json e as linhas do banco de dados permanecem intactas.",
"emptyHint": "Verifique cada diretório de recursos de móveis para encontrar pacotes nitro falsos e danificados, além de SWFs e ícones órfãos. Exclua-os, baixe novamente os danificados ou limpe automaticamente os restos antigos.",
"noResult": "Nenhum resultado de verificação ainda — execute primeiro uma verificação de recursos de móveis.",
"scanFailed": "A verificação falhou.",
"confirmDeleteTitle": "Excluir {count} arquivo(s) de recursos?",
"confirmDeleteDescription": "Os arquivos serão removidos de todos os diretórios (public + gamedata espelhada). As linhas do banco de dados nunca são alteradas.",
"confirmDeleteLabel": "Excluir",
"confirmRepairTitle": "Baixar novamente {count} pacote(s) .nitro danificado(s)?",
"confirmRepairDescription": "Os pacotes serão obtidos novamente das fontes nitro configuradas e gravados sobre todos os diretórios (public + gamedata espelhada).",
"confirmRepairLabel": "Baixar novamente",
"confirmAutoCleanTitle": "Limpar automaticamente nitros falsos mais antigos que {days} dia(s)?",
"confirmAutoCleanDescription": "Apenas arquivos .nitro falsos (sem item correspondente) mais antigos que o limite são removidos. Pacotes danificados e arquivos recentes nunca são alterados.",
"confirmAutoCleanLabel": "Limpar automaticamente",
"toastDeletePartial": "Excluídas {copies} cópias, mas alguns arquivos não puderam ser removidos",
"toastDeleteDone": "Excluídas {copies} cópias de arquivos ({deleted} arquivos)",
"toastRepairDone": "Reparados {count} pacotes .nitro",
"toastRepairFailed": "Não foi possível obter nenhum pacote ({failed} falharam)",
"toastRepairCancelled": "Reparo cancelado",
"toastAutoCleanDone": "Limpados {deleted} arquivos .nitro falsos antigos ({copies} cópias). Ignorados {recent} recentes + {broken} danificados.",
"toastAutoCleanNothing": "Nada velho o suficiente para remover (ignorados {recent} recentes, {broken} danificados)",
"toastManifestDownload": "Manifesto da verificação baixado",
"gamedataTitle": "Limpeza de dados do jogo",
"gamedataHint": "Visualize primeiro: isso reescreve FurnitureData.json, FigureMap.json e FigureData.json. Ao contrário das ferramentas de recursos acima, remove linhas que não referenciam nada — revise as contagens antes de executá-lo.",
"gamedataScan": "Visualizar dados do jogo",
"gamedataScanning": "Verificando…",
"gamedataRun": "Executar selecionados",
"gamedataRunning": "Limpando…",
"gamedataNoResult": "Nenhuma visualização ainda — verifique primeiro os arquivos JSON dos dados do jogo.",
"gamedataCount_duplicates": "Duplicatas de FurnitureData",
"gamedataCount_orphans": "FurnitureData órfãos",
"gamedataCount_figureMap": "Problemas de FigureMap",
"gamedataCount_figureData": "FigureData não utilizado",
"gamedataPass_dedupeFurnitureData": "Desduplicar FurnitureData",
"gamedataPassDesc_dedupeFurnitureData": "Remove classnames repetidos dentro de uma seção, mantendo a entrada com a revisão mais alta.",
"gamedataPass_cleanFurnitureData": "Limpar FurnitureData",
"gamedataPassDesc_cleanFurnitureData": "Remove as entradas cujo pacote .nitro está ausente em todos os diretórios.",
"gamedataPass_cleanFigureMap": "Limpar FigureMap",
"gamedataPassDesc_cleanFigureMap": "Remove as partes que apontam para um conjunto ausente em FigureData, além de duplicatas exatas.",
"gamedataPass_cleanFigureData": "Limpar FigureData",
"gamedataPassDesc_cleanFigureData": "Remove os conjuntos que nenhuma parte de FigureMap referencia, depois as paletas que nenhum tipo de conjunto usa. Deve ser executado após Limpar FigureMap.",
"gamedataNothingSelected": "Selecione pelo menos uma etapa de limpeza",
"gamedataConfirmTitle": "Reescrever os arquivos JSON dos dados do jogo?",
"gamedataConfirmDescription": "{passes} etapa(s) serão executadas em {duplicates} grupo(s) duplicado(s), {orphans} linha(s) órfã(s), {figureMap} problema(s) de FigureMap e {figureData} entrada(s) FigureData não utilizada(s). As linhas são removidas sem backup — isso não pode ser desfeito.",
"gamedataConfirmLabel": "Reescrever arquivos",
"gamedataDifferingWarning": "Pelo menos uma duplicata não é uma cópia exata da entrada que é mantida, então a linha excluída continha dados que o sobrevivente não tem.",
"gamedataCrossSectionNote": "{count} classname(s) existem tanto em roomitemtypes quanto em wallitemtypes. Estes são apenas relatados — remover um mudaria o tipo de um item.",
"gamedataToastDone": "A limpeza de dados do jogo removeu {removed} linha(s)",
"gamedataToastNothing": "Os dados do jogo já estavam limpos",
"gamedataMaxRemovalsLabel": "Máx. linhas por etapa",
"gamedataMaxRemovalsHint": "0 usa o padrão 500. Uma etapa que removeria mais para e pergunta em vez de gravar.",
"gamedataLimitTitle": "{pass} removeria {wouldRemove} linha(s), acima do limite de {maxRemovals}.",
"gamedataLimitDescription": "Essa etapa não gravou nada, então os arquivos estão inalterados. Verifique primeiro os caminhos dos recursos — um diretório errado faz cada linha parecer órfã. Aumentar o limite é uma execução separada e deliberada.",
"gamedataLimitOverride": "Remover {wouldRemove} linha(s) mesmo assim",
"historyTitle": "Histórico de limpeza automática",
"historyScheduled": "agendado",
"historyManual": "manual",
"historyEntry": "Removidos {deleted} ({copies} cópias); ignorados {recent} recentes e {broken} danificados",
"historyErrors": "{count} erros"
},
"importDiagnostics": {
"attempts": "Diagnóstico dos ficheiros",
"preliminary": "Verificação preliminar dos endereços; o conteúdo será validado na importação.",