From 406df7bbad1903ca642ea1ec46d335f173a17e0f Mon Sep 17 00:00:00 2001 From: r4sas Date: Mon, 9 Feb 2026 01:27:49 +0300 Subject: [PATCH] [i18n] Added Esperanto, Filipino, Finnish Signed-off-by: r4sas --- i18n/Afrikaans.cpp | 9 +- i18n/Esperanto.cpp | 226 +++++++++++++++++++++++++++++++++++++++++++++ i18n/Filipino.cpp | 226 +++++++++++++++++++++++++++++++++++++++++++++ i18n/Finnish.cpp | 226 +++++++++++++++++++++++++++++++++++++++++++++ i18n/Hindi.cpp | 4 +- i18n/I18N_langs.h | 6 ++ 6 files changed, 692 insertions(+), 5 deletions(-) create mode 100644 i18n/Esperanto.cpp create mode 100644 i18n/Filipino.cpp create mode 100644 i18n/Finnish.cpp diff --git a/i18n/Afrikaans.cpp b/i18n/Afrikaans.cpp index 0afa086f..28adf2e2 100644 --- a/i18n/Afrikaans.cpp +++ b/i18n/Afrikaans.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2021-2025, The PurpleI2P Project +* Copyright (c) 2021-2026, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -34,8 +34,12 @@ namespace afrikaans // language namespace static const LocaleStrings strings { + {"%.2f KiB", "%.2f KiB"}, + {"%.2f MiB", "%.2f MiB"}, + {"%.2f GiB", "%.2f GiB"}, {"failed", "Het misluk"}, {"unknown", "onbekend"}, + {"Main page", "Hoof Blad"}, {"Tunnels", "Tonnels"}, {"I2P tunnels", "I2P tonnels"}, {"SAM sessions", "SAM sessies"}, @@ -43,13 +47,13 @@ namespace afrikaans // language namespace {"Testing", "Besig om te toets"}, {"Firewalled", "Vuurmuur'd"}, {"Unknown", "Onbekend"}, - {"Error", "Fout"}, {"Offline", "Aflyn"}, {"Uptime", "Optyd"}, {"Network status", "Netwerk status"}, {"Network status v6", "Netwerk status v6"}, {"Family", "Familie"}, {"Received", "Ontvang"}, + {"%.2f KiB/s", "%.2f KiB/s"}, {"Sent", "Gestuur"}, {"Hidden content. Press on text to see.", "Hidden content. Druk om te sien."}, {"Router Ident", "Router Ident"}, @@ -61,7 +65,6 @@ namespace afrikaans // language namespace {"Description", "Beskrywing"}, {"Submit", "Stuur"}, {"Proxy error", "Proxy-fout"}, - {"Host", "Gasheer"}, {"", ""}, }; diff --git a/i18n/Esperanto.cpp b/i18n/Esperanto.cpp new file mode 100644 index 00000000..77dab833 --- /dev/null +++ b/i18n/Esperanto.cpp @@ -0,0 +1,226 @@ +/* +* Copyright (c) 2026, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + +#include +#include +#include +#include +#include "I18N.h" + +// Esperanto localization file + +namespace i2p +{ +namespace i18n +{ +namespace esperanto // language namespace +{ + // language name in lowercase + static std::string language = "esperanto"; + + // See for language plural forms here: + // https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html + static int plural (int n) { + return n != 1 ? 1 : 0; + } + + // Right to Left language? + static bool rtl = false; + + static const LocaleStrings strings + { + {"%.2f KiB", "%.2f KiB"}, + {"%.2f MiB", "%.2f MiB"}, + {"%.2f GiB", "%.2f GiB"}, + {"building", "konstruas"}, + {"failed", "malsukceso"}, + {"expiring", "pasas"}, + {"established", "funkcias"}, + {"unknown", "nesciate"}, + {"exploratory", "esplora"}, + {"Purple I2P Webconsole", "Reteja Konzolo de Purple I2P"}, + {"i2pd webconsole", "Reteja konzolo de i2pd"}, + {"Main page", "Ĉefa paĝo"}, + {"Router commands", "Enkursigilaj komandoj"}, + {"Local Destinations", "Lokaj destinaĵoj"}, + {"LeaseSets", "Luaĵoj"}, + {"Tunnels", "Tuneloj"}, + {"Transit Tunnels", "Transitaj tuneloj"}, + {"Transports", "Transportoj"}, + {"I2P tunnels", "I2P tuneloj"}, + {"SAM sessions", "SAM sesioj"}, + {"ERROR", "ERARO"}, + {"OK", "BONE"}, + {"Testing", "Ekzamenas"}, + {"Firewalled", "Fajromuro"}, + {"Unknown", "Nesciate"}, + {"Proxy", "Prokurilo"}, + {"Mesh", "Maŝo"}, + {"Clock skew", "Tempa oblikviĝo"}, + {"Offline", "Eksterrete"}, + {"Symmetric NAT", "Simetria NAT"}, + {"Full cone NAT", "Plenkonusa NAT"}, + {"No Descriptors", "Malhavas priskribilojn"}, + {"Uptime", "Funkcidaŭro"}, + {"Network status", "Reta statuso"}, + {"Network status v6", "Reta statuso v6"}, + {"Stopping in", "Ĝis haltigo restis"}, + {"Family", "Familio"}, + {"Tunnel creation success rate", "Sukcese konstruitaj tuneloj"}, + {"Total tunnel creation success rate", "Tute sukceseco de tunela konstruado"}, + {"Received", "Ricevite"}, + {"%.2f KiB/s", "%.2f KiB/s"}, + {"Sent", "Sendite"}, + {"Transit", "Transito"}, + {"Data path", "Vojo al datumoj"}, + {"Hidden content. Press on text to see.", "Kaŝitaj informoj. Alklaku ĉi tie por malkovri."}, + {"Router Ident", "Enkursigila identigilo"}, + {"Router Family", "Enkursigila familio"}, + {"Router Caps", "Enkursigilaj markoj"}, + {"Version", "Versio"}, + {"Our external address", "Nia ekstera adreso"}, + {"supported", "subtenas"}, + {"Routers", "Enkursigiloj"}, + {"Floodfills", "Inundiloj"}, + {"Client Tunnels", "Klientaj tuneloj"}, + {"Services", "Priserviloj"}, + {"Enabled", "Ŝaltite"}, + {"Disabled", "Malŝaltite"}, + {"Encrypted B33 address", "Ĉifrita B33-adreso"}, + {"Address registration line", "Adresa registrada ĉeno"}, + {"Domain", "Domajno"}, + {"Generate", "Generi"}, + {"Note: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "Rimarko: la rezultan ĉenon vi povas uzi nur por registrado de duanivelaj domajnoj (ekz. example.i2p). Por registrado de subdomajnoj uzu i2pd-tools'n."}, + {"Address", "Adreso"}, + {"Type", "Tipo"}, + {"EncType", "Tipo de ĉifro"}, + {"Expire LeaseSet", "Pasigu luaĵon"}, + {"Inbound tunnels", "Ricevataj tuneloj"}, + {"%dms", "%dms"}, + {"Outbound tunnels", "Sendataj tuneloj"}, + {"Tags", "Etikedoj"}, + {"Incoming", "Ricevatoj"}, + {"Outgoing", "Sendatoj"}, + {"Destination", "Destinaĵo"}, + {"Amount", "Kvanto"}, + {"Incoming Tags", "Ricevataj etikedoj"}, + {"Tags sessions", "Etikedaj sesioj"}, + {"Status", "Statuso"}, + {"Local Destination", "Loka destinaĵo"}, + {"Streams", "Fluoj"}, + {"Close stream", "Fermi fluon"}, + {"Such destination is not found", "Ne trovis tian destinaĵon"}, + {"I2CP session not found", "Ne trovis la sesion de I2CP"}, + {"I2CP is not enabled", "I2CP estas neŝaltita"}, + {"Invalid", "Misa"}, + {"Store type", "Tipo de konservilo"}, + {"Expires", "Pasas"}, + {"Non Expired Leases", "Malpasintaj luaĵoj"}, + {"Gateway", "Kluzo"}, + {"TunnelID", "Tunela identigilo"}, + {"EndDate", "Dato de fino"}, + {"floodfill mode is disabled", "la inundila konduto estas malŝaltita"}, + {"Queue size", "Amplekso de la vico"}, + {"Run peer test", "Startigi punkto-al-punktan testadon"}, + {"Reload tunnels configuration", "Reŝargi la tunelajn agordojn"}, + {"Decline transit tunnels", "Malakcepti transitajn tunelojn"}, + {"Accept transit tunnels", "Akcepti transitajn tunelojn"}, + {"Cancel graceful shutdown", "Nuligi la pravan haltigon"}, + {"Start graceful shutdown", "Startigi la pravan haltigon"}, + {"Force shutdown", "Perforte haltigi"}, + {"Reload external CSS styles", "Reŝargi eksterajn stilojn de CSS"}, + {"Note: any action done here are not persistent and not changes your config files.", "Rimarko: ĉiu ago estante tie ne estas konstanta kaj ne ŝanĝis viajn dosierojn de la agordoj."}, + {"Logging level", "Nivelo de loka-raportado"}, + {"Transit tunnels limit", "Limigo de transitaj tuneloj"}, + {"Change", "Ŝanĝi"}, + {"Change language", "Ŝanĝi lingvon"}, + {"no transit tunnels currently built", "malhavas konstruitajn transitajn tunelojn"}, + {"SAM disabled", "SAM estas malŝaltita"}, + {"no sessions currently running", "malhavas funkciantajn sesiojn"}, + {"SAM session not found", "Ne trovis la sesion de SAM"}, + {"SAM Session", "Sesio de SAM"}, + {"Server Tunnels", "Servilaj tuneloj"}, + {"Client Forwards", "Klientaj alidirektoj"}, + {"Server Forwards", "Servilaj alidirektoj"}, + {"Unknown page", "Nesciata paĝo"}, + {"Invalid token", "Misa ĵetono"}, + {"SUCCESS", "SUKCESO"}, + {"Stream closed", "Fermita fluo"}, + {"Stream not found or already was closed", "Ne trovis la fluon aŭ la fluo jam estis fermita"}, + {"Destination not found", "Ne trovis la destinaĵon"}, + {"StreamID can't be null", "Flua identigilo ne povas esti nula"}, + {"Return to destination page", "Returni al la destinaĵa paĝo"}, + {"You will be redirected in %d seconds", "Vin alidirektos tra %d sekundoj"}, + {"LeaseSet expiration time updated", "Ŝanĝis la luaĵan pas-tempon"}, + {"LeaseSet is not found or already expired", "Ne trovis la luaĵon aŭ la luaĵo jam estis pasinta"}, + {"Transit tunnels count must not exceed %d", "Kvanto da transitaj tuneloj devas nesuperi %d"}, + {"Back to commands list", "Returni al la listo de komandoj"}, + {"Register at reg.i2p", "Registri per reg.i2p"}, + {"Description", "Priskribo"}, + {"A bit information about service on domain", "Iomete informoj pri priservilo je la domajno"}, + {"Submit", "Sendi"}, + {"Domain can't end with .b32.i2p", "Domajno ne povas finiĝi per .b32.i2p"}, + {"Domain must end with .i2p", "Domajno devas finiĝi per .i2p"}, + {"Unknown command", "Nesciata komando"}, + {"Command accepted", "Komando estas akceptita"}, + {"Proxy error", "Eraro de prokurilo"}, + {"Proxy info", "Informo pri prokurilo"}, + {"Proxy error: Host not found", "Eraro de prokurilo: Ne trovis la retnodon"}, + {"Remote host not found in router's addressbook", "Ne trovis la foran retnodon en la enkursigila adreslibro"}, + {"You may try to find this host on jump services below", "Vi povas provi trovi ĉi tiun retnodon per ĉi tiuj salt-serviloj"}, + {"Invalid request", "Misa peto"}, + {"Proxy unable to parse your request", "Prokurilo ne povas analizi vian peton"}, + {"Addresshelper is not supported", "Adreshelpilon ne subtenas"}, + {"Host %s is already in router's addressbook. Be careful: source of this URL may be harmful! Click here to update record: Continue.", "Retnodo %s jam estas en la enkursigila adreslibro. Estu atente: fonto de tiu URL povas esti danĝere! Alklaku ĉi tie por renovigi la skribon: Daŭrige."}, + {"Addresshelper forced update rejected", "Perforta renovigo de la adreshelpilo estas rifuzita"}, + {"To add host %s in router's addressbook, click here: Continue.", "Por aldono de la retnodo %s en la enkursigila adreslibro, alklaku ĉi tie: Daŭrige."}, + {"Addresshelper request", "Peto por aldono de adreshelpilo"}, + {"Host %s added to router's addressbook from helper. Click here to proceed: Continue.", "Retnodon %s aldonis en la enkursigila adreslibro per la adreshelpilo. Alklaku ĉi tie por daŭrigo: Daŭrige."}, + {"Addresshelper adding", "Aldono de la adreshelpilo"}, + {"Host %s is already in router's addressbook. Click here to update record: Continue.", "Retnodo %s jam estas en la enkursigila adreslibro. Alklaku ĉi tie por renovigi la skribon: Daŭrige."}, + {"Addresshelper update", "Renovigo de la skribo per la adreshelpilo"}, + {"Invalid request URI", "Misa URI de la peto"}, + {"Can't detect destination host from request", "Ne povas determeni la destinaĵan retnodon el la peto"}, + {"Outproxy failure", "Eraro de ekster-prokurilo"}, + {"Bad outproxy settings", "Misaj agordoj de ekster-prokurilo"}, + {"Host %s is not inside I2P network, but outproxy is not enabled", "Retnodo %s ne estas ene de I2P reto, tamen la ekster-prokurilo estas malŝaltita"}, + {"Unknown outproxy URL", "Nesciata URL de ekster-prokurilo"}, + {"Cannot resolve upstream proxy", "Ne povas determeni la supra-prokurilon"}, + {"Hostname is too long", "Retnoda nomo estas tro longa"}, + {"Cannot connect to upstream SOCKS proxy", "Malsukcesis konekti kun la supra-prokurilo de SOCKS"}, + {"Cannot negotiate with SOCKS proxy", "Ne povas interkonsenti kun la prokurilo de SOCKS"}, + {"CONNECT error", "eraro de KONEKTO"}, + {"Failed to connect", "Malsukcesis konekti"}, + {"SOCKS proxy error", "Prokurila eraro de SOCKS"}, + {"Failed to send request to upstream", "Malsukcesis sendi peton al superaĵo"}, + {"No reply from SOCKS proxy", "Malhavas respondon disde la prokurilo de SOCKS"}, + {"Cannot connect", "Ne povas konekti"}, + {"HTTP out proxy not implemented", "Subteno de la ekster-prokurilo ne estas realigita"}, + {"Cannot connect to upstream HTTP proxy", "Ne povas konekti kun la supera-prokurilo de HTTP"}, + {"Host is down", "Retnodo estas eksterreta"}, + {"Can't create connection to requested host, it may be down. Please try again later.", "Ne povas krei konekton kun la petita retnodo, eble ĝi estas eksterreta. Bonvolu provi poste."}, + {"", ""}, + }; + + static std::map> plurals + { + {"%d days", {"%d tago", "%d tagoj"}}, + {"%d hours", {"%d horo", "%d horoj"}}, + {"%d minutes", {"%d minuto", "%d minutoj"}}, + {"%d seconds", {"%d sekundo", "%d sekundo"}}, + {"", {"", ""}}, + }; + + std::shared_ptr GetLocale() + { + return std::make_shared(language, rtl, strings, plurals, [] (int n)->int { return plural(n); }); + } + +} // language +} // i18n +} // i2p diff --git a/i18n/Filipino.cpp b/i18n/Filipino.cpp new file mode 100644 index 00000000..b39657d4 --- /dev/null +++ b/i18n/Filipino.cpp @@ -0,0 +1,226 @@ +/* +* Copyright (c) 2026, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + +#include +#include +#include +#include +#include "I18N.h" + +// Filipino localization file + +namespace i2p +{ +namespace i18n +{ +namespace filipino // language namespace +{ + // language name in lowercase + static std::string language = "filipino"; + + // See for language plural forms here: + // https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html + static int plural (int n) { + return n > 1 ? 1 : 0; + } + + // Right to Left language? + static bool rtl = false; + + static const LocaleStrings strings + { + {"%.2f KiB", "%.2f KiB"}, + {"%.2f MiB", "%.2f MiB"}, + {"%.2f GiB", "%.2f GiB"}, + {"building", "ginagawa"}, + {"failed", "nabigo"}, + {"expiring", "nage-expire"}, + {"established", "na-establish"}, + {"unknown", "hindi alam"}, + {"exploratory", "eksplorasyon"}, + {"Purple I2P Webconsole", "Webconsole ng Purple I2P"}, + {"i2pd webconsole", "Webconsole ng i2pd"}, + {"Main page", "Unang pahina"}, + {"Router commands", "Mga utos sa router"}, + {"Local Destinations", "Mga lokal na patutunguhan"}, + {"LeaseSets", "Mga LeaseSet"}, + {"Tunnels", "Mga tunnel"}, + {"Transit Tunnels", "Mga transit tunnel"}, + {"Transports", "Mga transport"}, + {"I2P tunnels", "Mga I2P tunnel"}, + {"SAM sessions", "Mga SAM session"}, + {"ERROR", "ERROR"}, + {"OK", "OK"}, + {"Testing", "Sinusubukan"}, + {"Firewalled", "Naka-firewall"}, + {"Unknown", "Hindi matukoy"}, + {"Proxy", "Proxy"}, + {"Mesh", "Mesh"}, + {"Clock skew", "Clock skew"}, + {"Offline", "Offline"}, + {"Symmetric NAT", "Symmetric na NAT"}, + {"Full cone NAT", "Full cone na NAT"}, + {"No Descriptors", "Walang Mga Deskriptor"}, + {"Uptime", "Uptime"}, + {"Network status", "Status ng network"}, + {"Network status v6", "Status ng network (v6)"}, + {"Stopping in", "Titigil sa"}, + {"Family", "Pamilya"}, + {"Tunnel creation success rate", "Rate ng matagumpay na paggawa ng tunnel"}, + {"Total tunnel creation success rate", "Kabuuang rate ng matagumpay na paggawa ng tunnel"}, + {"Received", "Nakatanggap"}, + {"%.2f KiB/s", "%.2f KiB/s"}, + {"Sent", "Naipadala"}, + {"Transit", "Transit"}, + {"Data path", "Path ng data"}, + {"Hidden content. Press on text to see.", "Nakatagong nilalaman. Pindutin ang text para makita."}, + {"Router Ident", "Pagkakakilanlan ng Router"}, + {"Router Family", "Pamilya ng Router"}, + {"Router Caps", "Mga Kakayahan ng Router"}, + {"Version", "Bersyon"}, + {"Our external address", "Ang ating external na address"}, + {"supported", "sinusuportahan"}, + {"Routers", "Mga router"}, + {"Floodfills", "Mga floodfill"}, + {"Client Tunnels", "Mga tunnel ng kliyente"}, + {"Services", "Mga Serbisyo"}, + {"Enabled", "Pinagana"}, + {"Disabled", "Hindi pinagana"}, + {"Encrypted B33 address", "Naka-encrypt na B33 address"}, + {"Address registration line", "Linya ng pagrehistro ng address"}, + {"Domain", "Domain"}, + {"Generate", "I-generate"}, + {"Note: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "Tandaan: magagamit lamang ang string para sa pagrehistro ng mga 2LD domain (example.i2p). Para sa pagrehistro ng mga subdomain mangyaring gamitin ang i2pd-tools."}, + {"Address", "Address"}, + {"Type", "Uri"}, + {"EncType", "Uri ng Encryption"}, + {"Expire LeaseSet", "I-expire ang LeaseSet"}, + {"Inbound tunnels", "Mga papasok na tunnel"}, + {"%dms", "%dms"}, + {"Outbound tunnels", "Mga palabas na tunnel"}, + {"Tags", "Mga tag"}, + {"Incoming", "Papasok"}, + {"Outgoing", "Papalabas"}, + {"Destination", "Patutunguhan"}, + {"Amount", "Halaga"}, + {"Incoming Tags", "Mga Papasok na Tag"}, + {"Tags sessions", "Mga session ng tag"}, + {"Status", "Status"}, + {"Local Destination", "Lokal na Patutunguhan"}, + {"Streams", "Mga stream"}, + {"Close stream", "Isara ang stream"}, + {"Such destination is not found", "Hindi nahanap ang patutunguhan"}, + {"I2CP session not found", "Hindi nahanap ang I2CP session"}, + {"I2CP is not enabled", "Hindi pinagana ang I2CP"}, + {"Invalid", "Hindi wasto"}, + {"Store type", "Uri ng store"}, + {"Expires", "Mage-expire"}, + {"Non Expired Leases", "Mga hindi nag-expire na lease"}, + {"Gateway", "Gateway"}, + {"TunnelID", "ID ng Tunnel"}, + {"EndDate", "EndDate"}, + {"floodfill mode is disabled", "hindi pinagana ang floodfill mode"}, + {"Queue size", "Size ng queue"}, + {"Run peer test", "Patakbuhin ang pagsubok ng peer"}, + {"Reload tunnels configuration", "I-reload ang pagsasaayos ng tunnel"}, + {"Decline transit tunnels", "Tanggihan ang mga transit tunnel"}, + {"Accept transit tunnels", "Tanggapin ang mga transit tunnel"}, + {"Cancel graceful shutdown", "Kanselahin ang graceful shutdown"}, + {"Start graceful shutdown", "Simulan ang graceful shutdown"}, + {"Force shutdown", "Pwersahang mag-shutdown"}, + {"Reload external CSS styles", "I-reload ang mga external na istilio ng CSS"}, + {"Note: any action done here are not persistent and not changes your config files.", "Tandaan: hindi mananatili ang mga pagbabago na ginawa dito at hindi babaguhin ang mga config file."}, + {"Logging level", "Antas ng pag-log"}, + {"Transit tunnels limit", "Pinakamataas na transit tunnel"}, + {"Change", "Palitan"}, + {"Change language", "Baguhin ang wika"}, + {"no transit tunnels currently built", "wala pang mga nagawang transit tunnel"}, + {"SAM disabled", "hindi pinagana ang SAM"}, + {"no sessions currently running", "walang mga session na tumatakbo sa ngayon"}, + {"SAM session not found", "Hindi nahanap ang SAM session"}, + {"SAM Session", "SAM Session"}, + {"Server Tunnels", "Mga Server Tunnel"}, + {"Client Forwards", "Mga Client Forward"}, + {"Server Forwards", "Mga Server Forward"}, + {"Unknown page", "Hindi kilalang pahina"}, + {"Invalid token", "Hindi wastong token"}, + {"SUCCESS", "MATAGUMPAY"}, + {"Stream closed", "Sinara ang stream"}, + {"Stream not found or already was closed", "Hindi nahanap o sinara na ang stream"}, + {"Destination not found", "Hindi nahanap ang patutunguhan"}, + {"StreamID can't be null", "Hindi maaaring null ang StreamID"}, + {"Return to destination page", "Bumalik sa destination page"}, + {"You will be redirected in %d seconds", "Mare-redirect ka sa loob ng %d segundo"}, + {"LeaseSet expiration time updated", "Na-update ang expiration time ng LeaseSet"}, + {"LeaseSet is not found or already expired", "Hindi nahanap o nag-expire na ang LeaseSet"}, + {"Transit tunnels count must not exceed %d", "Hindi maaaring lumagpas sa %d ang bilang ng mga transit tunnel"}, + {"Back to commands list", "Bumalik sa listahan ng mga utos"}, + {"Register at reg.i2p", "Irehistro sa reg.i2p"}, + {"Description", "Paglalarawan"}, + {"A bit information about service on domain", "Kaunting impormasyon tungkol sa serbisyo sa domain"}, + {"Submit", "Isumite"}, + {"Domain can't end with .b32.i2p", "Hindi maaaring matapos sa .b32.i2p ang domain"}, + {"Domain must end with .i2p", "Dapat matapos sa .i2p ang domain"}, + {"Unknown command", "Hindi alam na utos"}, + {"Command accepted", "Tinanggap ang utos"}, + {"Proxy error", "Error sa proxy"}, + {"Proxy info", "Impormasyon ng proxy"}, + {"Proxy error: Host not found", "Error sa proxy: Hindi nahanap ang proxy"}, + {"Remote host not found in router's addressbook", "Hindi nahanap ang remote host sa addressbook ng router"}, + {"You may try to find this host on jump services below", "Maaari mong subukang hanapin ang host na ito sa pamamagitan ng mga jump service sa ibaba"}, + {"Invalid request", "Hindi wastong hiling"}, + {"Proxy unable to parse your request", "Hindi ma-parse ng proxy ang iyong hiling"}, + {"Addresshelper is not supported", "Hindi sinusuportahan ang Addresshelper"}, + {"Host %s is already in router's addressbook. Be careful: source of this URL may be harmful! Click here to update record: Continue.", "Nasa addressbook ng router na ang host na %s. Mag-ingat ka: baka mapanganib ang pinagmulan ng URL na ito! Mag-click dito para baguhin ang record: Magpatuloy."}, + {"Addresshelper forced update rejected", "Tinanggihan ang pinilit na pagbago ng addresshelper"}, + {"To add host %s in router's addressbook, click here: Continue.", "Para idagdag ang host na %s sa addressbook ng router, mag-click dito: Magpatuloy."}, + {"Addresshelper request", "Hiling sa addresshelper"}, + {"Host %s added to router's addressbook from helper. Click here to proceed: Continue.", "Dinagdag ang host na %s sa addressbook ng router mula sa helper. Mag-click dito para magpatuloy: Magpatuloy."}, + {"Addresshelper adding", "Pagdagdag ng addresshelper"}, + {"Host %s is already in router's addressbook. Click here to update record: Continue.", "Nasa addressbook ng router na ang host na %s. Mag-click dito para baguhin ang record: Magpatuloy."}, + {"Addresshelper update", "Pagbago sa addresshelper"}, + {"Invalid request URI", "Hindi wastong request URI"}, + {"Can't detect destination host from request", "Hindi ma-detect ang destination host mula sa hiling"}, + {"Outproxy failure", "Nabigo ang outproxy"}, + {"Bad outproxy settings", "Hindi wastong mga setting ng outproxy"}, + {"Host %s is not inside I2P network, but outproxy is not enabled", "Hindi nasa loob ng I2P network ang %s, ngunit hindi pinagana ang outproxy."}, + {"Unknown outproxy URL", "Hindi alam na outproxy URL"}, + {"Cannot resolve upstream proxy", "Hindi maresolba ang upstream proxy"}, + {"Hostname is too long", "Masyadong mahaba ang hostname"}, + {"Cannot connect to upstream SOCKS proxy", "Hindi makakonekta sa upstream SOCKS proxy"}, + {"Cannot negotiate with SOCKS proxy", "Hindi makapag-ugnayan sa SOCKS proxy"}, + {"CONNECT error", "Error sa CONNECT"}, + {"Failed to connect", "Nabigong kumonekta"}, + {"SOCKS proxy error", "Error sa SOCKS proxy"}, + {"Failed to send request to upstream", "Nabigong ipadala ang hiling sa upstream"}, + {"No reply from SOCKS proxy", "Walang tugon mula sa SOCKS proxy"}, + {"Cannot connect", "Hindi makakonekta"}, + {"HTTP out proxy not implemented", "Hindi pa na-implement ang HTTP outproxy"}, + {"Cannot connect to upstream HTTP proxy", "Hindi makakonekta sa upstream HTTP proxy"}, + {"Host is down", "Down ang host"}, + {"Can't create connection to requested host, it may be down. Please try again later.", "Hindi makakonekta sa hiniling na host, baka down ito. Subukan muli sa ibang pagkakataon."}, + {"", ""}, + }; + + static std::map> plurals + { + {"%d days", {"%d araw", "%d (na) araw"}}, + {"%d hours", {"%d oras", "%d (na) oras"}}, + {"%d minutes", {"%d minuto", "%d (na) minuto"}}, + {"%d seconds", {"%d segundo", "%d (na) segundo"}}, + {"", {"", ""}}, + }; + + std::shared_ptr GetLocale() + { + return std::make_shared(language, rtl, strings, plurals, [] (int n)->int { return plural(n); }); + } + +} // language +} // i18n +} // i2p diff --git a/i18n/Finnish.cpp b/i18n/Finnish.cpp new file mode 100644 index 00000000..ba3502ad --- /dev/null +++ b/i18n/Finnish.cpp @@ -0,0 +1,226 @@ +/* +* Copyright (c) 2026, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + +#include +#include +#include +#include +#include "I18N.h" + +// Finnish localization file + +namespace i2p +{ +namespace i18n +{ +namespace finnish // language namespace +{ + // language name in lowercase + static std::string language = "finnish"; + + // See for language plural forms here: + // https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html + static int plural (int n) { + return n != 1 ? 1 : 0; + } + + // Right to Left language? + static bool rtl = false; + + static const LocaleStrings strings + { + {"%.2f KiB", "%.2f kt"}, + {"%.2f MiB", "%.2f Mt"}, + {"%.2f GiB", "%.2f Gt"}, + {"building", "rakentaa"}, + {"failed", "epäonnistui"}, + {"expiring", "vanhentumassa"}, + {"established", "muodostettu"}, + {"unknown", "tuntematon"}, + {"exploratory", "selvittely"}, + {"Purple I2P Webconsole", "Purple I2P web-konsoli"}, + {"i2pd webconsole", "i2pd web-konsoli"}, + {"Main page", "Pääsivu"}, + {"Router commands", "Reitittimen komennot"}, + {"Local Destinations", "Paikalliset osoitteet"}, + {"LeaseSets", "LeaseSetit"}, + {"Tunnels", "Tunnelit"}, + {"Transit Tunnels", "Välitystunnelit"}, + {"Transports", "Siirtomenetelmät"}, + {"I2P tunnels", "I2P tunnelit"}, + {"SAM sessions", "SAM istunnot"}, + {"ERROR", "VIRHE"}, + {"OK", "OK"}, + {"Testing", "Testataan"}, + {"Firewalled", "Palomuurin takana"}, + {"Unknown", "Tuntematon"}, + {"Proxy", "Välityspalvelin"}, + {"Mesh", "Verkkopinta"}, + {"Clock skew", "Kellon synkronointivirhe"}, + {"Offline", "Offline-tilassa"}, + {"Symmetric NAT", "Symmetrinen NAT"}, + {"Full cone NAT", "Täyskartoitettu NAT"}, + {"No Descriptors", "Ei deskriptoritietoja"}, + {"Uptime", "Käynnissäoloaika"}, + {"Network status", "Verkon tila"}, + {"Network status v6", "Verkon tila v6"}, + {"Stopping in", "Pysäytetään"}, + {"Family", "Perhe"}, + {"Tunnel creation success rate", "Tunnelin luontiyritysten onnistumisprosentti"}, + {"Total tunnel creation success rate", "Tunnelien luontien kokonaisonnistumisprosentti"}, + {"Received", "Vastaanotettu"}, + {"%.2f KiB/s", "%.2f kt/s"}, + {"Sent", "Lähetetty"}, + {"Transit", "Siirto"}, + {"Data path", "Tiedostojen polku"}, + {"Hidden content. Press on text to see.", "Piilotettu sisältö. Paina tekstiä nähdäksesi."}, + {"Router Ident", "Reitittimen Identiteetti"}, + {"Router Family", "Reitittimen Perhe"}, + {"Router Caps", "Reitittimen ominaisuudet"}, + {"Version", "Versio"}, + {"Our external address", "Ulkoinen osoite"}, + {"supported", "tuettu"}, + {"Routers", "Reitittimet"}, + {"Floodfills", "Floodfill-solmut"}, + {"Client Tunnels", "Asiakkaan Tunnelit"}, + {"Services", "Palvelut"}, + {"Enabled", "Käytössä"}, + {"Disabled", "Poissa käytöstä"}, + {"Encrypted B33 address", "Salattu B33-osoite"}, + {"Address registration line", "Osoitteen rekisteröintirivi"}, + {"Domain", "Verkkotunnus"}, + {"Generate", "Luo"}, + {"Note: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "Huom: tulosmerkkijonoa voi käyttää vain 2. tason verkkotunnusten (esim. example.i2p) rekisteröintiin. Aliverkkotunnusten rekisteröintiin käytä i2pd-työkaluja."}, + {"Address", "Osoite"}, + {"Type", "Tyyppi"}, + {"EncType", "Salaustyyppi"}, + {"Expire LeaseSet", "LeaseSetin vanheneminen"}, + {"Inbound tunnels", "Saapuvat tunnelit"}, + {"%dms", "%d ms"}, + {"Outbound tunnels", "Lähtevät tunnelit"}, + {"Tags", "Tunnisteet"}, + {"Incoming", "Saapuva"}, + {"Outgoing", "Lähtevä"}, + {"Destination", "Kohde"}, + {"Amount", "Määrä"}, + {"Incoming Tags", "Saapuvat Tunnisteet"}, + {"Tags sessions", "Tunnisteiden istunnot"}, + {"Status", "Tila"}, + {"Local Destination", "Paikallinen Kohde"}, + {"Streams", "Streamit"}, + {"Close stream", "Sulje streami"}, + {"Such destination is not found", "Tällaista määränpäätä ei löydy"}, + {"I2CP session not found", "I2CP-istuntoa ei löytynyt"}, + {"I2CP is not enabled", "I2CP ei ole päällä"}, + {"Invalid", "Virheellinen"}, + {"Store type", "Tallennustyyppi"}, + {"Expires", "Vanhenee"}, + {"Non Expired Leases", "Vanhentumattomat leaset"}, + {"Gateway", "Yhdyskäytävä"}, + {"TunnelID", "TunnelID"}, + {"EndDate", "Päättymispäivä"}, + {"floodfill mode is disabled", "Floodfill-tila on poistettu käytöstä"}, + {"Queue size", "Jonon koko"}, + {"Run peer test", "Suorita yhteystesti"}, + {"Reload tunnels configuration", "Lataa tunnelikonfiguraatio uudelleen"}, + {"Decline transit tunnels", "Hylkää läpikulkutunnelit"}, + {"Accept transit tunnels", "Hyväksy läpikulkutunnelit"}, + {"Cancel graceful shutdown", "Keskeytä hallittu sulkeminen"}, + {"Start graceful shutdown", "Käynnistä hallittu sulkeminen"}, + {"Force shutdown", "Pakota sammutus"}, + {"Reload external CSS styles", "Lataa ulkoiset CSS-tyylit uudelleen"}, + {"Note: any action done here are not persistent and not changes your config files.", "Huom: täällä tehdyt toimet eivät ole pysyviä, eikä niillä muuteta asetustiedostojasi."}, + {"Logging level", "Lokitustaso"}, + {"Transit tunnels limit", "Läpikulkutunneleiden enimmäismäärä"}, + {"Change", "Vaihda"}, + {"Change language", "Vaihda kieltä"}, + {"no transit tunnels currently built", "läpikulkutunneleita ei ole tällä hetkellä rakennettu"}, + {"SAM disabled", "SAM poistettu käytöstä"}, + {"no sessions currently running", "ei käynnissä olevia istuntoja"}, + {"SAM session not found", "SAM-istuntoa ei löydy"}, + {"SAM Session", "SAM Istunto"}, + {"Server Tunnels", "Palvelimen Tunnelit"}, + {"Client Forwards", "Asiakasohjaukset"}, + {"Server Forwards", "Serveriohjaukset"}, + {"Unknown page", "Tuntematon sivu"}, + {"Invalid token", "Virheellinen tunniste"}, + {"SUCCESS", "ONNISTUI"}, + {"Stream closed", "Yhteys suljettu"}, + {"Stream not found or already was closed", "Yhteyttä ei löytynyt tai se oli jo suljettuna"}, + {"Destination not found", "Kohdetta ei löydy"}, + {"StreamID can't be null", "StreamID ei voi olla tyhjä"}, + {"Return to destination page", "Palaa kohdesivulle"}, + {"You will be redirected in %d seconds", "Sinut ohjataan uudelleen %d sekunnissa"}, + {"LeaseSet expiration time updated", "LeaseSetin vanhentumisaika päivitetty"}, + {"LeaseSet is not found or already expired", "LeaseSetia ei löydy tai se on jo vanhentunut"}, + {"Transit tunnels count must not exceed %d", "Läpikulkutunnelien määrä ei saa ylittää %d"}, + {"Back to commands list", "Takaisin komentoluetteloon"}, + {"Register at reg.i2p", "Rekisteröidy osoitteessa reg.i2p"}, + {"Description", "Kuvaus"}, + {"A bit information about service on domain", "Vähän tietoa palvelusta verkkotunnuksella"}, + {"Submit", "Lähetä"}, + {"Domain can't end with .b32.i2p", "Verkkotunnus ei voi päättyä .b32.i2p"}, + {"Domain must end with .i2p", "Verkkotunnuksen täytyy päättyä .i2p"}, + {"Unknown command", "Tuntematon komento"}, + {"Command accepted", "Komento hyväksytty"}, + {"Proxy error", "Välityspalvelimen virhe"}, + {"Proxy info", "Välityspalvelimen tiedot"}, + {"Proxy error: Host not found", "Välityspalvelimen virhe: Palvelinta ei löydy"}, + {"Remote host not found in router's addressbook", "Etäpalvelinta ei löytynyt reitittimen osoitekirjasta"}, + {"You may try to find this host on jump services below", "Voit yrittää löytää tämän isännän alla olevilta jump-palveluilta"}, + {"Invalid request", "Virheellinen pyyntö"}, + {"Proxy unable to parse your request", "Välityspalvelin ei voi jäsentää pyyntöäsi"}, + {"Addresshelper is not supported", "Addresshelperia ei tueta"}, + {"Host %s is already in router's addressbook. Be careful: source of this URL may be harmful! Click here to update record: Continue.", "Isäntä %s on jo reitittimen osoitekirjassa. Ole varovainen: tämän URL-osoitteen lähde saattaa olla haitallinen! Klikkaa tästä päivittääksesi tiedot: Jatka."}, + {"Addresshelper forced update rejected", "Addresshelperin pakotettu päivitys hylätty"}, + {"To add host %s in router's addressbook, click here: Continue.", "Lisätäksesi isännän %s reitittimen osoitekirjaan, klikkaa tästä: Jatka."}, + {"Addresshelper request", "Addresshelper-pyyntö"}, + {"Host %s added to router's addressbook from helper. Click here to proceed: Continue.", "Isäntä %s lisätty reitittimen osoitekirjaan helperin kautta. Klikkaa tästä jatkaaksesi: Jatka."}, + {"Addresshelper adding", "Addresshelper lisääminen"}, + {"Host %s is already in router's addressbook. Click here to update record: Continue.", "Isäntä %s on jo reitittimen osoitekirjassa. Klikkaa tästä päivittääksesi tiedot: Jatka."}, + {"Addresshelper update", "Addresshelper päivitys"}, + {"Invalid request URI", "Virheellinen pyyntö URI"}, + {"Can't detect destination host from request", "Määränpään isäntää ei voitu tunnistaa pyynnöstä"}, + {"Outproxy failure", "Outproxy virhe"}, + {"Bad outproxy settings", "Virheelliset outproxy-asetukset"}, + {"Host %s is not inside I2P network, but outproxy is not enabled", "Isäntä %s ei ole I2P-verkossa, mutta outproxy ei ole käytössä"}, + {"Unknown outproxy URL", "Tuntematon outproxy URL"}, + {"Cannot resolve upstream proxy", "Ei pystytä selvittämään yläproxy-palvelinta"}, + {"Hostname is too long", "Isäntänimi on liian pitkä"}, + {"Cannot connect to upstream SOCKS proxy", "Ei voida yhdistää SOCKS- välityspalvelimeen"}, + {"Cannot negotiate with SOCKS proxy", "Ei voida neuvotella SOCKS- välityspalvelimen kanssa"}, + {"CONNECT error", "YHDISTÄ error"}, + {"Failed to connect", "Yhteyden muodostaminen epäonnistui"}, + {"SOCKS proxy error", "SOCKS- välityspalvelinvirhe"}, + {"Failed to send request to upstream", "Pyyntöä ylätason palvelimelle ei voitu lähettää"}, + {"No reply from SOCKS proxy", "Ei vastausta SOCKS- välityspalvelimen kautta"}, + {"Cannot connect", "Yhdistäminen ei onnistunut"}, + {"HTTP out proxy not implemented", "HTTP-ulkovälityspalvelinta ei ole toteutettu"}, + {"Cannot connect to upstream HTTP proxy", "Yhteyttä HTTP-yläproxyyn ei saada"}, + {"Host is down", "Isäntä on alhaalla"}, + {"Can't create connection to requested host, it may be down. Please try again later.", "Yhteyden muodostaminen pyydettyyn isäntään ei onnistunut, se saattaa olla pois käytöstä. Yritä myöhemmin uudelleen."}, + {"", ""}, + }; + + static std::map> plurals + { + {"%d days", {"%d päivä", "%d päivää"}}, + {"%d hours", {"%d tunti", "%d tuntia"}}, + {"%d minutes", {"%d minuutti", "%d minuuttia"}}, + {"%d seconds", {"%d sekunti", "%d sekuntia"}}, + {"", {"", ""}}, + }; + + std::shared_ptr GetLocale() + { + return std::make_shared(language, rtl, strings, plurals, [] (int n)->int { return plural(n); }); + } + +} // language +} // i18n +} // i2p diff --git a/i18n/Hindi.cpp b/i18n/Hindi.cpp index 7ce9b65b..d320f5d4 100644 --- a/i18n/Hindi.cpp +++ b/i18n/Hindi.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2025, The PurpleI2P Project +* Copyright (c) 2025-2026, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -213,7 +213,7 @@ namespace hindi // language namespace {"%d hours", {"%d घंटा", "%dघंटे"}}, {"%d minutes", {"%d मिनट", "%d मिनट"}}, {"%d seconds", {"%d सेकंड", "%d सेकंड"}}, - {"", {"", "", ""}}, + {"", {"", ""}}, }; std::shared_ptr GetLocale() diff --git a/i18n/I18N_langs.h b/i18n/I18N_langs.h index b3d09af8..774f5cbb 100644 --- a/i18n/I18N_langs.h +++ b/i18n/I18N_langs.h @@ -28,6 +28,9 @@ namespace i18n namespace chinese { std::shared_ptr GetLocale (); } namespace czech { std::shared_ptr GetLocale (); } namespace english { std::shared_ptr GetLocale (); } + namespace esperanto { std::shared_ptr GetLocale (); } + namespace filipino { std::shared_ptr GetLocale (); } + namespace finnish { std::shared_ptr GetLocale (); } namespace french { std::shared_ptr GetLocale (); } namespace german { std::shared_ptr GetLocale (); } namespace hebrew { std::shared_ptr GetLocale (); } @@ -53,6 +56,9 @@ namespace i18n { "chinese", {"简体字", "zh-CN", i2p::i18n::chinese::GetLocale} }, { "czech", {"čeština", "cs", i2p::i18n::czech::GetLocale} }, { "english", {"English", "en", i2p::i18n::english::GetLocale} }, + { "esperanto", {"Esperanto", "eo", i2p::i18n::esperanto::GetLocale} }, + { "filipino", {"Wikang Filipino", "fil", i2p::i18n::filipino::GetLocale} }, + { "finnish", {"Suomi", "fi", i2p::i18n::finnish::GetLocale} }, { "french", {"Français", "fr", i2p::i18n::french::GetLocale} }, { "german", {"Deutsch", "de", i2p::i18n::german::GetLocale} }, { "hebrew", {"עִבְרִית‎", "he", i2p::i18n::hebrew::GetLocale} },