summaryrefslogtreecommitdiffhomepage
path: root/android
diff options
context:
space:
mode:
authorJonatan Rhodin <jonatan.rhodin@mullvad.net>2025-04-04 13:44:22 +0200
committerJonatan Rhodin <jonatan.rhodin@mullvad.net>2025-04-04 13:44:22 +0200
commit1e902d3a873ce0a789de0b32cfcf52ab72dacbdf (patch)
treeea375738f7fb1332a8388fe50dc85b9e2d05a939 /android
parent8feb87cfa9a41fe4cd8f70c2e167dc04edda9bfa (diff)
parentd257e6c49abb438f9c25e07109a36b1e13f57ea6 (diff)
downloadmullvadvpn-1e902d3a873ce0a789de0b32cfcf52ab72dacbdf.tar.xz
mullvadvpn-1e902d3a873ce0a789de0b32cfcf52ab72dacbdf.zip
Merge branch 'wrong-entryexit-entry-order-in-some-languages-droid-1901'
Diffstat (limited to 'android')
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DaitaScreen.kt3
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SelectLocationList.kt1
-rw-r--r--android/lib/resource/src/main/res/values-da/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-de/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-es/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-fi/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-fr/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-it/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-ja/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-ko/strings.xml6
-rw-r--r--android/lib/resource/src/main/res/values-my/strings.xml6
-rw-r--r--android/lib/resource/src/main/res/values-nb/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-nl/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-pl/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-pt/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-ru/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-sv/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-th/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-tr/strings.xml6
-rw-r--r--android/lib/resource/src/main/res/values-zh-rCN/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-zh-rTW/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values/strings.xml4
-rw-r--r--android/translations-converter/src/android/plurals.rs2
-rw-r--r--android/translations-converter/src/android/string_value.rs132
-rw-r--r--android/translations-converter/src/android/strings.rs17
-rw-r--r--android/translations-converter/src/gettext/messages.rs103
-rw-r--r--android/translations-converter/src/gettext/mod.rs2
-rw-r--r--android/translations-converter/src/main.rs16
-rw-r--r--android/translations-converter/src/normalize.rs13
29 files changed, 283 insertions, 92 deletions
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DaitaScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DaitaScreen.kt
index 8c8228b046..b0e12eeaab 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DaitaScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DaitaScreen.kt
@@ -239,9 +239,6 @@ private enum class DaitaPages(
@Composable {
stringResource(
R.string.daita_description_slide_2_third_paragraph,
- // Duplicated argument to keep compatibility with our common string template
- // (messages.pot) while also keeping lint happy.
- stringResource(id = R.string.daita),
stringResource(id = R.string.daita),
)
},
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SelectLocationList.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SelectLocationList.kt
index 95bcebdd28..d08a902ae3 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SelectLocationList.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SelectLocationList.kt
@@ -113,7 +113,6 @@ private fun LazyListScope.entryBlocked(openDaitaSettings: () -> Unit) {
stringResource(R.string.multihop).toLowerCase(Locale.current),
stringResource(id = R.string.daita),
stringResource(R.string.direct_only),
- stringResource(id = R.string.daita),
),
style = MaterialTheme.typography.labelMedium,
textAlign = TextAlign.Center,
diff --git a/android/lib/resource/src/main/res/values-da/strings.xml b/android/lib/resource/src/main/res/values-da/strings.xml
index e78e472973..3c9dfbfb62 100644
--- a/android/lib/resource/src/main/res/values-da/strings.xml
+++ b/android/lib/resource/src/main/res/values-da/strings.xml
@@ -113,7 +113,7 @@
<string name="daita_description_slide_1_third_paragraph">Ved at bruge sofistikeret AI er det muligt at analysere trafikken af datapakker, der går ind og ud af din enhed (selv hvis trafikken er krypteret).</string>
<string name="daita_description_slide_2_first_paragraph">Hvis en observatør overvåger disse datapakker, gør %1$s det betydeligt sværere for dem at identificere, hvilke hjemmesider du besøger, eller hvem du kommunikerer med.</string>
<string name="daita_description_slide_2_second_paragraph">%1$s gør dette ved omhyggeligt at tilføje netværksstøj og gøre alle netværkspakker lige store.</string>
- <string name="daita_description_slide_2_third_paragraph">Ikke alle vores servere er %1$s-kompatible. Derfor bruger vi automatisk multihop til at aktivere %2$s med enhver server.</string>
+ <string name="daita_description_slide_2_third_paragraph">Ikke alle vores servere er %1$s-kompatible. Derfor bruger vi automatisk multihop til at aktivere %1$s med enhver server.</string>
<string name="daita_info">Hvis du aktiverer \"%1$s\", skal du manuelt vælge en server, der er %2$s-aktiveret. Det kan medføre, at du ender i en blokeret tilstand, indtil du har valgt en kompatibel server i visningen \"Vælg placering\".</string>
<string name="delete">Slet</string>
<string name="delete_custom_list_confirmation_description">Vil du slette \"%1$s\"?</string>
@@ -236,7 +236,7 @@
<string name="mullvad_owned_only">Kun ejet af Mullvad</string>
<string name="multihop">Multihop</string>
<string name="multihop_description">Multihop dirigerer din trafik ind på en WireGuard-server og ud på en anden, hvilket gør det sværere at spore den. Dette resulterer i øget ventetid, men øger anonymiteten online.</string>
- <string name="multihop_entry_disabled_description">Indgangsserveren for %1$s tilsidesættes i øjeblikket af %2$s. Du skal først aktivere \"%3$s\" eller deaktivere \"%4$s\" i indstillingerne for at vælge en indgangsserver.</string>
+ <string name="multihop_entry_disabled_description">Indgangsserveren for %1$s tilsidesættes i øjeblikket af %2$s. Du skal først aktivere \"%3$s\" eller deaktivere \"%2$s\" i indstillingerne for at vælge en indgangsserver.</string>
<string name="name">Navn</string>
<string name="name_was_changed_to">Navnet blev ændret til %1$s</string>
<string name="new_changelog_notification_message">Klik her for at se nyhederne.</string>
diff --git a/android/lib/resource/src/main/res/values-de/strings.xml b/android/lib/resource/src/main/res/values-de/strings.xml
index a9b78955f0..e8c54ba41d 100644
--- a/android/lib/resource/src/main/res/values-de/strings.xml
+++ b/android/lib/resource/src/main/res/values-de/strings.xml
@@ -113,7 +113,7 @@
<string name="daita_description_slide_1_third_paragraph">Durch den Einsatz hochentwickelter KI ist es möglich, den Traffic von Datenpaketen zu analysieren, die auf Ihrem Gerät ein- und ausgehen (selbst wenn der Verkehr verschlüsselt ist).</string>
<string name="daita_description_slide_2_first_paragraph">Wenn ein Beobachter diese Datenpakete überwacht, macht %1$s es für ihn wesentlich schwieriger zu erkennen, welche Websites Sie besuchen oder mit wem Sie kommunizieren.</string>
<string name="daita_description_slide_2_second_paragraph">%1$s tut dies, indem es Netzwerkrauschen gezielt hinzufügt und alle Netzwerkpakete gleich groß macht.</string>
- <string name="daita_description_slide_2_third_paragraph">Nicht alle unsere Server sind %1$s-fähig. Daher verwenden wir automatisch Multihop, um %2$s mit jedem Server zu aktivieren.</string>
+ <string name="daita_description_slide_2_third_paragraph">Nicht alle unsere Server sind %1$s-fähig. Daher verwenden wir automatisch Multihop, um %1$s mit jedem Server zu aktivieren.</string>
<string name="daita_info">Wenn Sie „%1$s“ aktivieren, müssen Sie manuell einen Server auswählen, der %2$s-fähig ist. Dies kann dazu führen, dass Sie in einem blockierten Zustand landen, bis Sie einen kompatiblen Server in der Ansicht „Standort auswählen“ ausgewählt haben.</string>
<string name="delete">Löschen</string>
<string name="delete_custom_list_confirmation_description">„%1$s“ löschen?</string>
@@ -236,7 +236,7 @@
<string name="mullvad_owned_only">Nur im Besitz von Mullvad</string>
<string name="multihop">Multihop</string>
<string name="multihop_description">Multihop leitet Ihren Traffic in einen WireGuard-Server hinein und aus einem anderen heraus, so dass er schwerer zu verfolgen ist. Dies führt zu einer erhöhten Latenzzeit, erhöht aber die Anonymität im Internet.</string>
- <string name="multihop_entry_disabled_description">Der Eingangsserver für %1$s wird derzeit von %2$s überschrieben. Um einen Eingangsserver zu wählen, aktivieren Sie bitte zunächst „%3$s“ oder deaktivieren Sie „%4$s“ in den Einstellungen.</string>
+ <string name="multihop_entry_disabled_description">Der Eingangsserver für %1$s wird derzeit von %2$s überschrieben. Um einen Eingangsserver zu wählen, aktivieren Sie bitte zunächst „%3$s“ oder deaktivieren Sie „%2$s“ in den Einstellungen.</string>
<string name="name">Name</string>
<string name="name_was_changed_to">Name wurde geändert in %1$s</string>
<string name="new_changelog_notification_message">Klicken Sie hier, um die Änderungen zu sehen.</string>
diff --git a/android/lib/resource/src/main/res/values-es/strings.xml b/android/lib/resource/src/main/res/values-es/strings.xml
index 42e54adbdf..4312dacdb0 100644
--- a/android/lib/resource/src/main/res/values-es/strings.xml
+++ b/android/lib/resource/src/main/res/values-es/strings.xml
@@ -113,7 +113,7 @@
<string name="daita_description_slide_1_third_paragraph">Al utilizar IA sofisticada, se puede analizar el tráfico de paquetes de datos que entran y salen de su dispositivo (incluso si el tráfico está cifrado).</string>
<string name="daita_description_slide_2_first_paragraph">Si un observador supervisa estos paquetes de datos, %1$s les dificulta notablemente la tarea de identificar qué sitios web está visitando o con quién se está comunicando.</string>
<string name="daita_description_slide_2_second_paragraph">%1$s lo realiza añadiendo con cuidado ruido de red y haciendo que todos los paquetes de red tengan el mismo tamaño.</string>
- <string name="daita_description_slide_2_third_paragraph">No todos nuestros servidores están habilitados para %1$s. Por lo tanto, utilizamos el salto múltiple de forma automática para habilitar %2$s con cualquier servidor.</string>
+ <string name="daita_description_slide_2_third_paragraph">No todos nuestros servidores están habilitados para %1$s. Por lo tanto, utilizamos el salto múltiple de forma automática para habilitar %1$s con cualquier servidor.</string>
<string name="daita_info">Si habilita «%1$s», deberá seleccionar manualmente un servidor que esté habilitado para %2$s. Esto puede provocar que termine bloqueado hasta que seleccione un servidor compatible en la vista «Seleccionar ubicación».</string>
<string name="delete">Eliminar</string>
<string name="delete_custom_list_confirmation_description">¿Eliminar «%1$s»?</string>
@@ -236,7 +236,7 @@
<string name="mullvad_owned_only">Solo propiedad de Mullvad</string>
<string name="multihop">Salto múltiple</string>
<string name="multihop_description">El salto múltiple dirige su tráfico a través de un servidor WireGuard y lo envía a otro, lo que dificulta su rastreo. Esto genera una mayor latencia, pero aumenta el anonimato en Internet.</string>
- <string name="multihop_entry_disabled_description">%1$s está reemplazando actualmente el servidor de entrada para %2$s. Para seleccionar un servidor de entrada, active primero «%3$s» o desactive «%4$s» en la configuración.</string>
+ <string name="multihop_entry_disabled_description">%2$s está reemplazando actualmente el servidor de entrada para %1$s. Para seleccionar un servidor de entrada, active primero «%3$s» o desactive «%1$s» en la configuración.</string>
<string name="name">Nombre</string>
<string name="name_was_changed_to">Se ha cambiado el nombre a %1$s</string>
<string name="new_changelog_notification_message">Haga clic aquí para ver las novedades.</string>
diff --git a/android/lib/resource/src/main/res/values-fi/strings.xml b/android/lib/resource/src/main/res/values-fi/strings.xml
index 7ed3e5acbc..d2656bee8e 100644
--- a/android/lib/resource/src/main/res/values-fi/strings.xml
+++ b/android/lib/resource/src/main/res/values-fi/strings.xml
@@ -113,7 +113,7 @@
<string name="daita_description_slide_1_third_paragraph">Käyttämällä edistynyttä tekoälyä on mahdollista analysoida laitteestasi lähtevä ja siihen tuleva datapakettiliikenne (vaikka liikenne olisi salattu).</string>
<string name="daita_description_slide_2_first_paragraph">Jos havaitsija valvoo näitä datapaketteja, %1$s tekee hänelle huomattavasti hankalammaksi tunnistaa, millä verkkosivuilla käyt tai kenen kanssa viestit.</string>
<string name="daita_description_slide_2_second_paragraph">%1$s tekee tämän lisäämällä varovasti verkkokohinaa ja tekemällä kaikista paketeista saman kokoisia.</string>
- <string name="daita_description_slide_2_third_paragraph">Kaikissa palvelimissamme ei ole %1$s-tukea. Siksi käytämme multihopia automaattisesti mahdollistaaksemme %2$s:n millä tahansa palvelimella.</string>
+ <string name="daita_description_slide_2_third_paragraph">Kaikissa palvelimissamme ei ole %1$s-tukea. Siksi käytämme multihopia automaattisesti mahdollistaaksemme %1$s:n millä tahansa palvelimella.</string>
<string name="daita_info">Kun \"%1$s\" otetaan käyttöön, sinun on valittava manuaalisesti palvelin, jossa on %2$s-tuki. Tämä voi aiheuttaa sen, että päädyt estettyyn tilaan, kunnes olet valinnut yhteensopivan palvelimen \"Valitse sijainti\" -näkymästä.</string>
<string name="delete">Poista</string>
<string name="delete_custom_list_confirmation_description">Poistetaanko \"%1$s\"?</string>
@@ -236,7 +236,7 @@
<string name="mullvad_owned_only">Vain Mullvadin omistamat</string>
<string name="multihop">Multihop</string>
<string name="multihop_description">Multihop reitittää liikenteesi yhteen WireGuard-palvelimeen ja ulos toisesta palvelimesta, mikä tekee siitä hankalampaa jäljittää. Tuloksena on suurempi viive, mutta se parantaa nimettömyyttä verkossa.</string>
- <string name="multihop_entry_disabled_description">%1$s ohittaa tällä hetkellä %2$sin tulopalvelimen. Jos haluat valita tulopalvelimen, ota ensin käyttöön \"%3$s\" tai poista \"%4$s\" käytöstä asetuksista.</string>
+ <string name="multihop_entry_disabled_description">%2$s ohittaa tällä hetkellä %1$sin tulopalvelimen. Jos haluat valita tulopalvelimen, ota ensin käyttöön \"%3$s\" tai poista \"%1$s\" käytöstä asetuksista.</string>
<string name="name">Nimi</string>
<string name="name_was_changed_to">Nimeksi vaihdettiin \"%1$s\"</string>
<string name="new_changelog_notification_message">Katso uudet ominaisuudet napsauttamalla tästä.</string>
diff --git a/android/lib/resource/src/main/res/values-fr/strings.xml b/android/lib/resource/src/main/res/values-fr/strings.xml
index 86b6f07d2f..34f648c7ff 100644
--- a/android/lib/resource/src/main/res/values-fr/strings.xml
+++ b/android/lib/resource/src/main/res/values-fr/strings.xml
@@ -113,7 +113,7 @@
<string name="daita_description_slide_1_third_paragraph">Utiliser une IA sophistiquée peut permettre d\'analyser le trafic des paquets de données entrant et sortant de votre appareil (même si le trafic est chiffré).</string>
<string name="daita_description_slide_2_first_paragraph">Si un observateur surveille ces paquets de données, %1$s rend beaucoup plus difficile l\'identification des sites web que vous visitez ou des personnes avec lesquelles vous communiquez.</string>
<string name="daita_description_slide_2_second_paragraph">%1$s y parvient en ajoutant soigneusement du bruit au réseau et en faisant en sorte que tous les paquets du réseau aient la même taille.</string>
- <string name="daita_description_slide_2_third_paragraph">Tous nos serveurs ne sont pas compatibles %1$s. C\'est pourquoi nous utilisons automatiquement le multihop pour activer %2$s avec n\'importe quel serveur.</string>
+ <string name="daita_description_slide_2_third_paragraph">Tous nos serveurs ne sont pas compatibles %1$s. C\'est pourquoi nous utilisons automatiquement le multihop pour activer %1$s avec n\'importe quel serveur.</string>
<string name="daita_info">Si vous activez « %1$s », vous devez sélectionner manuellement un serveur avec %2$s activé. Vous risquez alors de vous retrouver dans une situation de blocage tant que vous n\'avez pas sélectionné un serveur compatible dans la vue « Sélectionner une localisation ».</string>
<string name="delete">Supprimer</string>
<string name="delete_custom_list_confirmation_description">Supprimer « %1$s » ?</string>
@@ -236,7 +236,7 @@
<string name="mullvad_owned_only">Propriété de Mullvad uniquement</string>
<string name="multihop">Multihop</string>
<string name="multihop_description">Le multihop fait passer votre trafic par un serveur WireGuard et le fait sortir par un autre, ce qui le rend plus difficile à tracer. Cela se traduit par une latence accrue, mais plus d\'anonymat en ligne.</string>
- <string name="multihop_entry_disabled_description">Le serveur d\'entrée pour %1$s est actuellement contourné par %2$s. pour sélectionner un serveur d\'entrée, veuillez d\'abord activer « %3$s » ou désactiver « %4$s » dans les paramètres.</string>
+ <string name="multihop_entry_disabled_description">Le serveur d\'entrée pour %1$s est actuellement contourné par %2$s. pour sélectionner un serveur d\'entrée, veuillez d\'abord activer « %3$s » ou désactiver « %2$s » dans les paramètres.</string>
<string name="name">Nom</string>
<string name="name_was_changed_to">Le nom a été changé en %1$s</string>
<string name="new_changelog_notification_message">Cliquez ici pour voir les nouveautés.</string>
diff --git a/android/lib/resource/src/main/res/values-it/strings.xml b/android/lib/resource/src/main/res/values-it/strings.xml
index 69135769a2..b27e9022dc 100644
--- a/android/lib/resource/src/main/res/values-it/strings.xml
+++ b/android/lib/resource/src/main/res/values-it/strings.xml
@@ -113,7 +113,7 @@
<string name="daita_description_slide_1_third_paragraph">Utilizzando un\'IA sofisticata è possibile analizzare il traffico dei pacchetti di dati in entrata e in uscita dal dispositivo (anche se il traffico è crittografato).</string>
<string name="daita_description_slide_2_first_paragraph">Se un osservatore monitora questi pacchetti di dati, %1$s rende molto più difficile per lui identificare quali siti web stai visitando o con chi stai comunicando.</string>
<string name="daita_description_slide_2_second_paragraph">%1$s lo fa aggiungendo con attenzione rumore di rete e rendendo tutti i pacchetti di rete della stessa dimensione.</string>
- <string name="daita_description_slide_2_third_paragraph">Non tutti i nostri server sono abilitati per %1$s. Pertanto, utilizziamo automaticamente il multihop per abilitare %2$s con un server qualsiasi.</string>
+ <string name="daita_description_slide_2_third_paragraph">Non tutti i nostri server sono abilitati per %1$s. Pertanto, utilizziamo automaticamente il multihop per abilitare %1$s con un server qualsiasi.</string>
<string name="daita_info">Abilitando “%1$s” dovrai selezionare manualmente un server abilitato per %2$s. Questo può comportare uno stato di blocco finché non selezioni un server compatibile nella vista “Seleziona posizione”.</string>
<string name="delete">Elimina</string>
<string name="delete_custom_list_confirmation_description">Eliminare \"%1$s\"?</string>
@@ -236,7 +236,7 @@
<string name="mullvad_owned_only">Solo di proprietà di Mullvad</string>
<string name="multihop">Multihop</string>
<string name="multihop_description">Il multihop instrada il tuo traffico in un server WireGuard in entrata e in un altro in uscita, rendendo più difficile il tracciamento. Questo aumenta la latenza ma aumenta anche l\'anonimato online.</string>
- <string name="multihop_entry_disabled_description">Il server di entrata per %1$s è attualmente sovrascritto da %2$s. Per selezionare un server di entrata, prima abilita \"%3$s\" o disabilita \"%4$s\" nelle impostazioni.</string>
+ <string name="multihop_entry_disabled_description">Il server di entrata per %1$s è attualmente sovrascritto da %2$s. Per selezionare un server di entrata, prima abilita \"%3$s\" o disabilita \"%2$s\" nelle impostazioni.</string>
<string name="name">Nome</string>
<string name="name_was_changed_to">Il nome è stato modificato in %1$s</string>
<string name="new_changelog_notification_message">Clicca qui per vedere le novità.</string>
diff --git a/android/lib/resource/src/main/res/values-ja/strings.xml b/android/lib/resource/src/main/res/values-ja/strings.xml
index 0759c8c121..2a3ccd3159 100644
--- a/android/lib/resource/src/main/res/values-ja/strings.xml
+++ b/android/lib/resource/src/main/res/values-ja/strings.xml
@@ -113,7 +113,7 @@
<string name="daita_description_slide_1_third_paragraph">高度なAIを使用することで、(トラフィックが暗号化されている場合でも) デバイスが送受信するデータパケットのトラフィックを分析することは可能です。</string>
<string name="daita_description_slide_2_first_paragraph">%1$sはこのようなデータパケットが監視されている場合でも、訪問先ウェブサイトや通信相手を特定するのを極めて困難にします。</string>
<string name="daita_description_slide_2_second_paragraph">%1$sはネットワークノイズを入念に追加し、すべてのネットワークパケットを同じサイズにすることによってこれを実現しています。</string>
- <string name="daita_description_slide_2_third_paragraph">すべてのサーバーが%1$sに対応しているわけではないため、どのサーバーでも%2$sが有効になるようにマルチホップを自動的に使用しています。</string>
+ <string name="daita_description_slide_2_third_paragraph">すべてのサーバーが%1$sに対応しているわけではないため、どのサーバーでも%1$sが有効になるようにマルチホップを自動的に使用しています。</string>
<string name="daita_info">“%1$s” を有効化した場合、%2$s対応のサーバーを手動で選択する必要があります。これにより、“場所を選択する” で互換性のあるサーバーを選択するまでブロック状態となる可能性があります。</string>
<string name="delete">削除</string>
<string name="delete_custom_list_confirmation_description">\"%1$s\" を削除しますか?</string>
@@ -236,7 +236,7 @@
<string name="mullvad_owned_only">Mullvad 所有サーバーのみ</string>
<string name="multihop">マルチホップ</string>
<string name="multihop_description">マルチホップはトラフィックをあるWireGuardサーバーにルーティングし、別サーバーに送出することで追跡を困難にします。これによって遅延が増加しますが、オンラインの匿名性は高まります。</string>
- <string name="multihop_entry_disabled_description">%1$sの入口サーバーは現在、%2$sによってオーバーライドされています。入口サーバーを選択するには、設定で [%3$s] を有効にするか、[%4$s] を無効にしてください。</string>
+ <string name="multihop_entry_disabled_description">%1$sの入口サーバーは現在、%2$sによってオーバーライドされています。入口サーバーを選択するには、設定で [%3$s] を有効にするか、[%2$s] を無効にしてください。</string>
<string name="name">名前</string>
<string name="name_was_changed_to">名前が %1$s に変更されました</string>
<string name="new_changelog_notification_message">新機能を確認するにはここをクリックしてください。</string>
diff --git a/android/lib/resource/src/main/res/values-ko/strings.xml b/android/lib/resource/src/main/res/values-ko/strings.xml
index 1aac37d260..24bc47028d 100644
--- a/android/lib/resource/src/main/res/values-ko/strings.xml
+++ b/android/lib/resource/src/main/res/values-ko/strings.xml
@@ -113,7 +113,7 @@
<string name="daita_description_slide_1_third_paragraph">정교한 AI를 사용하면, 트래픽이 암호화된 경우라도 장치를 드나드는 데이터 패킷의 트래픽을 분석하는 것이 가능합니다.</string>
<string name="daita_description_slide_2_first_paragraph">이러한 데이터 패킷을 모니터링하고 있는 관찰자가 있는 경우, %1$s는 사용자가 어느 웹사이트를 방문하고 있는지, 누구와 대화하고 있는지 아주 식별하기 어렵게 만듭니다.</string>
<string name="daita_description_slide_2_second_paragraph">%1$s는 정교하게 네트워크 노이즈를 추가하고 모든 네트워크 패킷을 동일한 크기로 만들어 이를 달성합니다.</string>
- <string name="daita_description_slide_2_third_paragraph">일부 서버에는 %1$s가 활성화되어 있지 않습니다. 따라서 당사는 모든 서버에서 %2$s를 활성화하기 위해 자동으로 멀티홉을 사용합니다.</string>
+ <string name="daita_description_slide_2_third_paragraph">일부 서버에는 %1$s가 활성화되어 있지 않습니다. 따라서 당사는 모든 서버에서 %1$s를 활성화하기 위해 자동으로 멀티홉을 사용합니다.</string>
<string name="daita_info">“%1$s”을 활성화하면 %2$s가 활성화된 서버를 수동으로 선택해야 합니다. 이로 인해 “위치 선택” 창에서 호환되는 서버를 선택할 때까지 차단된 상태에 빠질 수 있습니다.</string>
<string name="delete">삭제</string>
<string name="delete_custom_list_confirmation_description">\"%1$s\"을(를) 삭제하시겠습니까?</string>
@@ -236,7 +236,7 @@
<string name="mullvad_owned_only">Mullvad 소유만</string>
<string name="multihop">멀티홉</string>
<string name="multihop_description">멀티홉은 사용자의 트래픽을 하나의 WireGuard 서버로 라우팅하고 다른 서버로 전달하여 추적을 더 어렵게 만듭니다. 그로 인해 대기 시간은 증가하지만 온라인 익명성은 증대됩니다.</string>
- <string name="multihop_entry_disabled_description">%1$s 진입 서버가 현재 %2$s에 의해 재정의되었습니다. 진입 서버를 선택하려면 먼저 설정에서 \"%3$s\"을 활성화하거나 \"%4$s\"를 비활성화하세요.</string>
+ <string name="multihop_entry_disabled_description">%1$s 진입 서버가 현재 %2$s에 의해 재정의되었습니다. 진입 서버를 선택하려면 먼저 설정에서 \"%3$s\"을 활성화하거나 \"%2$s\"를 비활성화하세요.</string>
<string name="name">이름</string>
<string name="name_was_changed_to">이름이 %1$s(으)로 변경되었습니다</string>
<string name="new_changelog_notification_message">업데이트 내역을 확인하려면 여기를 클릭하세요.</string>
@@ -390,5 +390,5 @@
<string name="wireguard_port_title">WireGuard 포트</string>
<string name="x_entry">%1$s(진입)</string>
<string name="x_exit">%1$s(종료)</string>
- <string name="x_via_x">%1$s을(를) 통한 %2$s</string>
+ <string name="x_via_x">%2$s을(를) 통한 %1$s</string>
</resources>
diff --git a/android/lib/resource/src/main/res/values-my/strings.xml b/android/lib/resource/src/main/res/values-my/strings.xml
index 035cc0fc30..356bf4f745 100644
--- a/android/lib/resource/src/main/res/values-my/strings.xml
+++ b/android/lib/resource/src/main/res/values-my/strings.xml
@@ -113,7 +113,7 @@
<string name="daita_description_slide_1_third_paragraph">ခေတ်မီဆန်းပြားသော AI ကိုအသုံးပြုခြင်းဖြင့် (အသွားအလာကို ကုဒ်ဝှက်ထားသည့်တိုင်) သင့်စက်၏အဝင်အထွက်ဒေတာပက်ကတ်များ၏ အသွားအလာကို ပိုင်းခြားစိတ်ဖြာနိုင်သည်။</string>
<string name="daita_description_slide_2_first_paragraph">အကဲခတ်သူတစ်ဦးက ဤဒေတာပက်ကတ်များကို စောင့်ကြည့်လျှင် %1$s သည် သင်သွားရောက်ကြည့်ရှုနေသော ဝဘ်ဆိုက်များ သို့မဟုတ် သင်ဆက်သွယ်နေသည့်သူများကို ခွဲခြားဖော်ထုတ်ရန် ၎င်းတို့အတွက် သိသိသာသာ ခက်ခဲစေသည်။</string>
<string name="daita_description_slide_2_second_paragraph">%1$s သည် ကွန်ရက် အနှောင့်အယှက်လျှပ်လိုင်းကို ဂရုတစိုက် ထည့်ပြီး ကွန်ရက် ပက်ကက်အားလုံးကို အရွယ်အစားတူညီအောင် ပြုလုပ်၍ ထိုသို့လုပ်ဆောင်ခြင်းဖြစ်သည်။</string>
- <string name="daita_description_slide_2_third_paragraph">ကျွန်ုပ်တို့၏ဆာဗာအားလုံးတွင် %1$s ကိုဖွင့်ထားခြင်းမရှိပါ။ ထို့ကြောင့် ကျွန်ုပ်တို့သည် မည်သည့်ဆာဗာနှင့်မဆို %2$s ကိုဖွင့်ရန် မာလ်တီဟော့ပ်ကို အလိုအလျောက်အသုံးပြုပါသည်။</string>
+ <string name="daita_description_slide_2_third_paragraph">ကျွန်ုပ်တို့၏ဆာဗာအားလုံးတွင် %1$s ကိုဖွင့်ထားခြင်းမရှိပါ။ ထို့ကြောင့် ကျွန်ုပ်တို့သည် မည်သည့်ဆာဗာနှင့်မဆို %1$s ကိုဖွင့်ရန် မာလ်တီဟော့ပ်ကို အလိုအလျောက်အသုံးပြုပါသည်။</string>
<string name="daita_info">“%1$s” ကို ဖွင့်လိုက်လျှင် သင်သည် %2$s ကိုဖွင့်ထားသည့် ဆာဗာကို ကိုယ်တိုင်ရွေးချယ်ရမည်ဖြစ်သည်။ ၎င်းသည် \"တည်နေရာကိုရွေးချယ်ပါ\" မြင်ကွင်းတွင် တွဲဖက်သုံးနိုင်သောဆာဗာကို မရွေးချယ်ရသေးမချင်း ပိတ်ဆို့ခံထားသောအခြေအနေတွင် အဆုံးသတ်စေနိုင်သည်။</string>
<string name="delete">ဖျက်ရန်</string>
<string name="delete_custom_list_confirmation_description">\"%1$s\" ကို ဖျက်မည်လား။</string>
@@ -236,7 +236,7 @@
<string name="mullvad_owned_only">Mullvad ပိုင်ဆိုင်သည်များသာ</string>
<string name="multihop">မာလ်တီဟော့ပ်</string>
<string name="multihop_description">မာလ်တီဟော့ပ်သည် သင်၏အသွားအလာကို WireGuard ဆာဗာတစ်ခုသို့ လမ်းကြောင်းပေးပြီး အခြားတစ်နေရာမှ ထွက်စေသောကြောင့် ခြေရာခံရန် ပိုမိုခက်ခဲစေသည်။ ၎င်းသည် အချိန်ကို ပိုမိုကြန့်ကြာစေသော်လည်း အွန်လိုင်းတွင် ပို၍ သိုသိုသိပ်သိပ်ဖြစ်စေသည်။</string>
- <string name="multihop_entry_disabled_description">%1$s အတွက် အဝင်ဆာဗာအား လက်ရှိအချိန်၌ %2$s ဖြင့် ထပ်မံထည့်သွင်း ရေးမှတ်ထားသည်။ အဝင်ဆာဗာကို ရွေးချယ်ရန်အတွက် “%3$s” ကို ဦးစွာ ဖွင့်ပါ သို့မဟုတ် ဆက်တင်များထဲရှိ \"%4$s\" ကို ပိတ်ပါ။</string>
+ <string name="multihop_entry_disabled_description">%1$s အတွက် အဝင်ဆာဗာအား လက်ရှိအချိန်၌ %2$s ဖြင့် ထပ်မံထည့်သွင်း ရေးမှတ်ထားသည်။ အဝင်ဆာဗာကို ရွေးချယ်ရန်အတွက် “%3$s” ကို ဦးစွာ ဖွင့်ပါ သို့မဟုတ် ဆက်တင်များထဲရှိ \"%2$s\" ကို ပိတ်ပါ။</string>
<string name="name">အမည်</string>
<string name="name_was_changed_to">အမည်ကို %1$s သို့ ပြောင်းလိုက်ပါသည်</string>
<string name="new_changelog_notification_message">အသစ်ထူးသော အကြောင်းအရာကို ကြည့်ရန် ဤနေရာကို နှိပ်ပါ</string>
@@ -390,5 +390,5 @@
<string name="wireguard_port_title">WireGuard ပေါ့တ်</string>
<string name="x_entry">%1$s (အဝင်)</string>
<string name="x_exit">%1$s (အထွက်)</string>
- <string name="x_via_x">%1$s မှတစ်ဆင့် %2$s</string>
+ <string name="x_via_x">%2$s မှတစ်ဆင့် %1$s</string>
</resources>
diff --git a/android/lib/resource/src/main/res/values-nb/strings.xml b/android/lib/resource/src/main/res/values-nb/strings.xml
index e145b42f30..3bf161ba9d 100644
--- a/android/lib/resource/src/main/res/values-nb/strings.xml
+++ b/android/lib/resource/src/main/res/values-nb/strings.xml
@@ -113,7 +113,7 @@
<string name="daita_description_slide_1_third_paragraph">Ved hjelp av avansert kunstig intelligens er det mulig å analysere trafikken av datapakker som går inn og ut av enheten din (selv om trafikken er kryptert).</string>
<string name="daita_description_slide_2_first_paragraph">Hvis en observatør overvåker disse datapakkene, gjør %1$s det betydelig vanskeligere for dem å identifisere hvilke nettsteder du besøker, eller hvem du kommuniserer med.</string>
<string name="daita_description_slide_2_second_paragraph">%1$s gjør det ved å legge til nettverkstøy på en forsiktig måte og sørge for at alle nettverkspakker har den samme størrelsen.</string>
- <string name="daita_description_slide_2_third_paragraph">Ikke alle serverne våre er %1$s-aktiverte. Derfor bruker vi automatisk multihopp for å aktivere %2$s med alle servere.</string>
+ <string name="daita_description_slide_2_third_paragraph">Ikke alle serverne våre er %1$s-aktiverte. Derfor bruker vi automatisk multihopp for å aktivere %1$s med alle servere.</string>
<string name="daita_info">Hvis du aktiverer «%1$s», må du manuelt velge en server som har aktivert %2$s. Dette kan føre til at du havner i en blokkert tilstand inntil du har valgt en kompatibel server under «Velg plassering».</string>
<string name="delete">Slett</string>
<string name="delete_custom_list_confirmation_description">Slette «%1$s»?</string>
@@ -236,7 +236,7 @@
<string name="mullvad_owned_only">Kun eid av Mullvad</string>
<string name="multihop">Multihopp</string>
<string name="multihop_description">Multihopp dirigerer trafikken din inn på én WireGuard-server og ut på en annen, noe som gjør det vanskeligere å spore den. Dette resulterer i økt ventetid, men øker anonymiteten på nettet.</string>
- <string name="multihop_entry_disabled_description">Inngangsserveren for %1$s overstyres for øyeblikket av %2$s. For å velge en inngangsserver må du først aktivere «%3$s» eller deaktivere «%4$s» i innstillingene.</string>
+ <string name="multihop_entry_disabled_description">Inngangsserveren for %1$s overstyres for øyeblikket av %2$s. For å velge en inngangsserver må du først aktivere «%3$s» eller deaktivere «%2$s» i innstillingene.</string>
<string name="name">Navn</string>
<string name="name_was_changed_to">Navn ble endret til %1$s</string>
<string name="new_changelog_notification_message">Klikk her for å se hva som er nytt.</string>
diff --git a/android/lib/resource/src/main/res/values-nl/strings.xml b/android/lib/resource/src/main/res/values-nl/strings.xml
index 17b93ed3ca..89c55a946d 100644
--- a/android/lib/resource/src/main/res/values-nl/strings.xml
+++ b/android/lib/resource/src/main/res/values-nl/strings.xml
@@ -113,7 +113,7 @@
<string name="daita_description_slide_1_third_paragraph">Door gebruik te maken van geavanceerde AI is het mogelijk om het verkeer van datapakketten te analyseren die uw apparaat in- en uitgaan (zelfs als het verkeer versleuteld is).</string>
<string name="daita_description_slide_2_first_paragraph">Als een waarnemer deze gegevenspakketten in de gaten houdt, maakt %1$s het aanzienlijk moeilijker voor diegene om vast te stellen welke websites u bezoekt of met wie u communiceert.</string>
<string name="daita_description_slide_2_second_paragraph">%1$s doet dit door zorgvuldig netwerkruis toe te voegen en alle netwerkpakketten even groot te maken.</string>
- <string name="daita_description_slide_2_third_paragraph">Niet al onze servers zijn geschikt voor %1$s. Daarom gebruiken we automatisch multihop om %2$s in te schakelen bij elke server.</string>
+ <string name="daita_description_slide_2_third_paragraph">Niet al onze servers zijn geschikt voor %1$s. Daarom gebruiken we automatisch multihop om %1$s in te schakelen bij elke server.</string>
<string name="daita_info">Als u \"%1$s\" inschakelt, moet u handmatig een server selecteren die %2$s ondersteunt. Hierdoor kunt u in een geblokkeerde toestand terechtkomen totdat u een compatibele server hebt geselecteerd in het dialoogvenster \"Locatie selecteren\".</string>
<string name="delete">Verwijderen</string>
<string name="delete_custom_list_confirmation_description">\"%1$s\" verwijderen?</string>
@@ -236,7 +236,7 @@
<string name="mullvad_owned_only">Alleen in eigendom van Multivad</string>
<string name="multihop">Multihop</string>
<string name="multihop_description">Multihop leidt uw verkeer de ene WireGuard-server in en de andere uit, waardoor het moeilijker te traceren is. Dit leidt tot een hogere latentie, maar verhoogt de online anonimiteit.</string>
- <string name="multihop_entry_disabled_description">De ingangsserver voor %1$s is momenteel overschreven door %2$s. Om een ingangsserver te selecteren, moet u eerst \"%3$s\" inschakelen of \"%4$s\" uitschakelen in de instellingen.</string>
+ <string name="multihop_entry_disabled_description">De ingangsserver voor %1$s is momenteel overschreven door %2$s. Om een ingangsserver te selecteren, moet u eerst \"%3$s\" inschakelen of \"%2$s\" uitschakelen in de instellingen.</string>
<string name="name">Naam</string>
<string name="name_was_changed_to">Naam is gewijzigd in %1$s</string>
<string name="new_changelog_notification_message">Klik hier om te zien wat er nieuw is.</string>
diff --git a/android/lib/resource/src/main/res/values-pl/strings.xml b/android/lib/resource/src/main/res/values-pl/strings.xml
index b74ba02a22..b6d815487f 100644
--- a/android/lib/resource/src/main/res/values-pl/strings.xml
+++ b/android/lib/resource/src/main/res/values-pl/strings.xml
@@ -113,7 +113,7 @@
<string name="daita_description_slide_1_third_paragraph">Dzięki użyciu zaawansowanej sztucznej inteligencji możliwe jest analizowanie ruchu pakietów danych przychodzących i wychodzących z Twojego urządzenia (nawet jeśli ruch jest szyfrowany).</string>
<string name="daita_description_slide_2_first_paragraph">Jeśli obserwator monitoruje te pakiety danych, %1$s znacznie utrudnia mu zidentyfikowanie witryn internetowych, które odwiedzasz lub z którymi się komunikujesz.</string>
<string name="daita_description_slide_2_second_paragraph">%1$s w tym celu ostrożnie dodaje szum sieciowy i nadaje ten sam rozmiar wszystkim pakietom sieciowym.</string>
- <string name="daita_description_slide_2_third_paragraph">Nie wszystkie nasze serwery obsługują %1$s. Dlatego automatycznie używamy funkcji wielokrotnego przeskoku, aby umożliwić działanie %2$s z dowolnym serwerem.</string>
+ <string name="daita_description_slide_2_third_paragraph">Nie wszystkie nasze serwery obsługują %1$s. Dlatego automatycznie używamy funkcji wielokrotnego przeskoku, aby umożliwić działanie %1$s z dowolnym serwerem.</string>
<string name="daita_info">Po włączeniu opcji „%1$s” trzeba ręcznie wybrać serwer, który obsługuje %2$s. Może to skutkować zablokowaniem, dopóki nie wybierzesz zgodnego serwera w widoku „Wybierz lokalizację”.</string>
<string name="delete">Usuń</string>
<string name="delete_custom_list_confirmation_description">Usunąć „%1$s”?</string>
@@ -236,7 +236,7 @@
<string name="mullvad_owned_only">Wyłącznie firmy Mullvad</string>
<string name="multihop">Wielokrotny przeskok</string>
<string name="multihop_description">Funkcja wielokrotnego przeskoku kieruje Twój ruch przychodzący do jednego serwera WireGuard, a wychodzący wysyła z innego, co utrudnia jego śledzenie. Skutkuje to zwiększoną latencją, ale zwiększa anonimowość online.</string>
- <string name="multihop_entry_disabled_description">Serwer wejściowy dla %1$s jest obecnie zastępowany przez %2$s. Aby wybrać serwer wejściowy, należy najpierw włączyć opcję „%3$s” lub wyłączyć opcję „%4$s” w ustawieniach.</string>
+ <string name="multihop_entry_disabled_description">Serwer wejściowy dla %1$s jest obecnie zastępowany przez %2$s. Aby wybrać serwer wejściowy, należy najpierw włączyć opcję „%3$s” lub wyłączyć opcję „%2$s” w ustawieniach.</string>
<string name="name">Nazwa</string>
<string name="name_was_changed_to">Nazwę zmieniono na %1$s</string>
<string name="new_changelog_notification_message">Kliknij tutaj, aby zobaczyć, co nowego.</string>
diff --git a/android/lib/resource/src/main/res/values-pt/strings.xml b/android/lib/resource/src/main/res/values-pt/strings.xml
index e963042dde..0572cac958 100644
--- a/android/lib/resource/src/main/res/values-pt/strings.xml
+++ b/android/lib/resource/src/main/res/values-pt/strings.xml
@@ -113,7 +113,7 @@
<string name="daita_description_slide_1_third_paragraph">Utilizando uma IA sofisticada, é possível analisar o tráfego de pacotes de dados que entram e saem do seu dispositivo (mesmo que o tráfego esteja encriptado).</string>
<string name="daita_description_slide_2_first_paragraph">Se um observador monitorizar estes pacotes de dados, %1$s dificulta significativamente a identificação dos sites que visita ou com quem comunica.</string>
<string name="daita_description_slide_2_second_paragraph">%1$s consegue-o ao adicionar cuidadosamente ruído de rede e ao tornar todos os pacotes de rede do mesmo tamanho.</string>
- <string name="daita_description_slide_2_third_paragraph">Nem todos os servidores suportam %1$s. Por isso, utilizamos multihop automaticamente para ativar %2$s em qualquer servidor.</string>
+ <string name="daita_description_slide_2_third_paragraph">Nem todos os servidores suportam %1$s. Por isso, utilizamos multihop automaticamente para ativar %1$s em qualquer servidor.</string>
<string name="daita_info">Ao ativar “%1$s”, terá de selecionar manualmente um servidor que tenha %2$s ativada, o que pode fazer com que fique num estado bloqueado até selecionar um servidor compatível na vista \"Selecionar localização\".</string>
<string name="delete">Eliminar</string>
<string name="delete_custom_list_confirmation_description">Eliminar \"%1$s\"?</string>
@@ -236,7 +236,7 @@
<string name="mullvad_owned_only">Apenas propriedade de Mullvad</string>
<string name="multihop">Multihop</string>
<string name="multihop_description">Multihop encaminha o tráfego para entrar num servidor WireGuard e sair por outro, dificultando o seguimento. Isto resulta em maior latência, mas aumenta o anonimato online.</string>
- <string name="multihop_entry_disabled_description">O servidor de entrada para %1$s é atualmente substituído por %2$s. Para selecionar um servidor de entrada, ative primeiro \"%3$s\", ou desative \"%4$s\" nas definições.</string>
+ <string name="multihop_entry_disabled_description">O servidor de entrada para %1$s é atualmente substituído por %2$s. Para selecionar um servidor de entrada, ative primeiro \"%3$s\", ou desative \"%2$s\" nas definições.</string>
<string name="name">Nome</string>
<string name="name_was_changed_to">O nome foi alterado para %1$s</string>
<string name="new_changelog_notification_message">Clique aqui para ver as novidades.</string>
diff --git a/android/lib/resource/src/main/res/values-ru/strings.xml b/android/lib/resource/src/main/res/values-ru/strings.xml
index 8acd04c63a..2d3282df05 100644
--- a/android/lib/resource/src/main/res/values-ru/strings.xml
+++ b/android/lib/resource/src/main/res/values-ru/strings.xml
@@ -113,7 +113,7 @@
<string name="daita_description_slide_1_third_paragraph">С помощью сложных ИИ-алгоритмов можно анализировать входящий и исходящий трафик пакетов данных вашего устройства (даже если трафик зашифрован).</string>
<string name="daita_description_slide_2_first_paragraph">В случае, если наблюдатель отслеживает пакеты данных, %1$s значительно затрудняет определение того, какие веб-сайты вы посещаете или с кем общаетесь.</string>
<string name="daita_description_slide_2_second_paragraph">Для этого %1$s добавляет в трафик сетевой шум, а все пакеты приводятся к одному размеру.</string>
- <string name="daita_description_slide_2_third_paragraph">%1$s поддерживается не на всех серверах. Поэтому, чтобы функция %2$s работала с любым сервером, мы автоматически используем многократный переход.</string>
+ <string name="daita_description_slide_2_third_paragraph">%1$s поддерживается не на всех серверах. Поэтому, чтобы функция %1$s работала с любым сервером, мы автоматически используем многократный переход.</string>
<string name="daita_info">После включения параметра «%1$s» вы должны будете вручную выбрать сервер, который поддерживает %2$s. В результате вы можете оказаться заблокированы, пока не выберете совместимый сервер в окне выбора местоположения.</string>
<string name="delete">Удалить</string>
<string name="delete_custom_list_confirmation_description">Удалить список «%1$s»?</string>
@@ -236,7 +236,7 @@
<string name="mullvad_owned_only">Только принадлежащие Mullvad</string>
<string name="multihop">Многократный переход</string>
<string name="multihop_description">Функция «Многократный переход» перенаправляет трафик с одного сервера WireGuard на другой, что затрудняет отслеживание. Это увеличивает задержку, но зато повышает анонимность в сети.</string>
- <string name="multihop_entry_disabled_description">Сервер входа для функции «%1$s» в настоящее время переопределен функцией %2$s. Чтобы выбрать сервер входа вручную, сначала включите пункт «%3$s» или отключите %4$s в настройках.</string>
+ <string name="multihop_entry_disabled_description">Сервер входа для функции «%1$s» в настоящее время переопределен функцией %2$s. Чтобы выбрать сервер входа вручную, сначала включите пункт «%3$s» или отключите %2$s в настройках.</string>
<string name="name">Имя</string>
<string name="name_was_changed_to">Имя изменено на «%1$s»</string>
<string name="new_changelog_notification_message">Нажмите здесь и узнайте, что нового.</string>
diff --git a/android/lib/resource/src/main/res/values-sv/strings.xml b/android/lib/resource/src/main/res/values-sv/strings.xml
index fa3e6bcc35..2c256d8196 100644
--- a/android/lib/resource/src/main/res/values-sv/strings.xml
+++ b/android/lib/resource/src/main/res/values-sv/strings.xml
@@ -113,7 +113,7 @@
<string name="daita_description_slide_1_third_paragraph">Med sofistikerad AI är det möjligt att analysera trafiken för datapaket som går in och ut från din enhet (även om trafiken är krypterad).</string>
<string name="daita_description_slide_2_first_paragraph">Om dessa datapaket övervakas av en observatör, gör %1$s det svårare för dem att identifiera vilka webbplatser du besöker eller vem du kommunicerar med.</string>
<string name="daita_description_slide_2_second_paragraph">%1$s gör det genom att noggrant lägga till nätverksbrus och se till så att alla nätverkspaket har samma storlek.</string>
- <string name="daita_description_slide_2_third_paragraph">Det är inte alla våra servrar som är %1$s-aktiverade. Därför använder vi multihopp automatiskt för att aktivera %2$s med alla servrar.</string>
+ <string name="daita_description_slide_2_third_paragraph">Det är inte alla våra servrar som är %1$s-aktiverade. Därför använder vi multihopp automatiskt för att aktivera %1$s med alla servrar.</string>
<string name="daita_info">Om du aktiverar \"%1$s\" måste du manuellt välja en server som är %2$s-aktiverad. Det kan leda till ett blockerat tillstånd tills du väljer en kompatibel server i \"Välj plats\"-vyn.</string>
<string name="delete">Ta bort</string>
<string name="delete_custom_list_confirmation_description">Ta bort \"%1$s\"?</string>
@@ -236,7 +236,7 @@
<string name="mullvad_owned_only">Endast Mullvad-ägd</string>
<string name="multihop">Multihopp</string>
<string name="multihop_description">Multihopp dirigerar din trafik till en WireGuard-server och ut genom en annan, vilket gör det svårare att spåra. Detta leder till ökad fördröjning men bättre anonymitet online.</string>
- <string name="multihop_entry_disabled_description">Startservern för %1$s åsidosätts för tillfället av %2$s. Om du vill välja en startserver ska du först aktivera \"%3$s\" eller inaktivera \"%4$s\" i inställningarna.</string>
+ <string name="multihop_entry_disabled_description">Startservern för %1$s åsidosätts för tillfället av %2$s. Om du vill välja en startserver ska du först aktivera \"%3$s\" eller inaktivera \"%2$s\" i inställningarna.</string>
<string name="name">Namn</string>
<string name="name_was_changed_to">Namnet har ändrats till %1$s</string>
<string name="new_changelog_notification_message">Klicka här för att se nyheterna.</string>
diff --git a/android/lib/resource/src/main/res/values-th/strings.xml b/android/lib/resource/src/main/res/values-th/strings.xml
index 89f45039be..a596f4c2a3 100644
--- a/android/lib/resource/src/main/res/values-th/strings.xml
+++ b/android/lib/resource/src/main/res/values-th/strings.xml
@@ -113,7 +113,7 @@
<string name="daita_description_slide_1_third_paragraph">โดยการใช้ AI ที่ซับซ้อน จึงเป็นไปได้ที่จะวิเคราะห์ปริมาณการรับส่งข้อมูล ที่เข้าออกอุปกรณ์ของคุณได้ (แม้ว่าการรับส่งข้อมูลจะเข้ารหัสไว้ก็ตาม)</string>
<string name="daita_description_slide_2_first_paragraph">หากผู้สังเกตการณ์เฝ้าดูแพ็กเก็ตข้อมูลเหล่านี้ %1$s จะทำให้พวกเขาระบุเว็บไซต์ที่คุณกำลังเยี่ยมชม หรือผู้ที่คุณกำลังติดต่อสื่อสารด้วยได้ยากขึ้นอย่างมาก</string>
<string name="daita_description_slide_2_second_paragraph">%1$s ได้ดำเนินการนี้ ด้วยการเพิ่มสัญญาณรบกวนเครือข่ายอย่างระมัดระวัง และทำให้แพ็กเก็ตเครือข่ายทั้งหมดมีขนาดเท่ากัน</string>
- <string name="daita_description_slide_2_third_paragraph">ไม่ใช่ทุกเซิร์ฟเวอร์ของเราที่เปิดใช้งาน %1$s ด้วยเหตุนี้เอง เราจึงใช้การมัลติฮอปอัตโนมัติ เพื่อเปิดใช้งาน %2$s กับทุกเซิร์ฟเวอร์</string>
+ <string name="daita_description_slide_2_third_paragraph">ไม่ใช่ทุกเซิร์ฟเวอร์ของเราที่เปิดใช้งาน %1$s ด้วยเหตุนี้เอง เราจึงใช้การมัลติฮอปอัตโนมัติ เพื่อเปิดใช้งาน %1$s กับทุกเซิร์ฟเวอร์</string>
<string name="daita_info">โดยการเปิดใช้งาน “%1$s” คุณจะต้องเลือกเซิร์ฟเวอร์ที่เปิดใช้งาน %2$s ด้วยตนเอง ซึ่งอาจทำให้คุณอยู่ในสถานะถูกบล็อก จนกว่าคุณจะเลือกเซิร์ฟเวอร์ที่เข้ากันได้ในมุมมอง \"เลือกตำแหน่งที่ตั้ง\"</string>
<string name="delete">ลบ</string>
<string name="delete_custom_list_confirmation_description">ลบ \"%1$s\" หรือไม่</string>
@@ -236,7 +236,7 @@
<string name="mullvad_owned_only">ของ Mullvad เท่านั้น</string>
<string name="multihop">มัลติฮอป</string>
<string name="multihop_description">มัลติฮอปจะกำหนดเส้นทางการรับส่งข้อมูลของคุณ ไปยังหนึ่งในเซิร์ฟเวอร์ WireGuard และออกไปยังอีกเซิร์ฟเวอร์หนึ่ง ซึ่งทำให้ติดตามได้ยากขึ้น นี่จะส่งผลให้มีเวลาแฝงเพิ่มขึ้น แต่ก็จะช่วยปกปิดตัวตนออนไลน์ได้มากขึ้น</string>
- <string name="multihop_entry_disabled_description">เซิร์ฟเวอร์ทางเข้าสำหรับ %1$s ถูกเขียนทับโดย %2$s ในขณะนี้ หากต้องการเลือกเซิร์ฟเวอร์ทางเข้า โปรดเปิดใช้งาน “%3$s” ก่อน หรือปิดใช้งาน “%4$s” ในการตั้งค่า</string>
+ <string name="multihop_entry_disabled_description">เซิร์ฟเวอร์ทางเข้าสำหรับ %1$s ถูกเขียนทับโดย %2$s ในขณะนี้ หากต้องการเลือกเซิร์ฟเวอร์ทางเข้า โปรดเปิดใช้งาน “%3$s” ก่อน หรือปิดใช้งาน “%2$s” ในการตั้งค่า</string>
<string name="name">ชื่อ</string>
<string name="name_was_changed_to">ชื่อถูกเปลี่ยนเป็น %1$s</string>
<string name="new_changelog_notification_message">คลิกที่นี่ เพื่อดูว่ามีอะไรใหม่</string>
diff --git a/android/lib/resource/src/main/res/values-tr/strings.xml b/android/lib/resource/src/main/res/values-tr/strings.xml
index 94e967bc86..a5a7d4eb67 100644
--- a/android/lib/resource/src/main/res/values-tr/strings.xml
+++ b/android/lib/resource/src/main/res/values-tr/strings.xml
@@ -113,7 +113,7 @@
<string name="daita_description_slide_1_third_paragraph">Gelişmiş yapay zeka kullanarak cihazınıza gelen ve giden veri paketlerinin trafiğini (trafik şifrelenmiş olsa bile) analiz etmek mümkündür.</string>
<string name="daita_description_slide_2_first_paragraph">Bir gözlemci bu veri paketlerini izliyorsa, %1$s ziyaret ettiğiniz web sitelerini veya iletişim kurduğunuz alıcıları tespit etmesini önemli ölçüde zorlaştırır.</string>
<string name="daita_description_slide_2_second_paragraph">%1$s, dikkatli bir şekilde ağ paraziti ekleyerek ve tüm ağ paketlerini aynı boyuta getirerek sizi izlenmekten korur.</string>
- <string name="daita_description_slide_2_third_paragraph">%1$s, tüm sunucularımızda etkin değildir. Bu nedenle, %2$s özelliğini herhangi bir sunucuda etkinleştirmek için otomatik olarak çoklu geçişi kullanırız.</string>
+ <string name="daita_description_slide_2_third_paragraph">%1$s, tüm sunucularımızda etkin değildir. Bu nedenle, %1$s özelliğini herhangi bir sunucuda etkinleştirmek için otomatik olarak çoklu geçişi kullanırız.</string>
<string name="daita_info">\"%1$s\" seçeneğini etkinleştirdiğinizde %2$s özellikli bir sunucuyu manuel olarak seçmeniz gerekir. Bu, \"Konum seç\" görünümünde uyumlu bir sunucu seçilene kadar engellenmiş durumda kalmanıza neden olabilir.</string>
<string name="delete">Sil</string>
<string name="delete_custom_list_confirmation_description">\"%1$s\" silinsin mi\"?</string>
@@ -236,7 +236,7 @@
<string name="mullvad_owned_only">Sadece Mullvad\'a ait olanlar</string>
<string name="multihop">Çoklu geçiş</string>
<string name="multihop_description">Çoklu geçiş, trafiğinizi bir WireGuard sunucusundan diğerine yönlendirerek izlemeyi zorlaştırır. Bu, gecikmenin artmasına neden olur ancak çevrimiçi gizliliği artırır.</string>
- <string name="multihop_entry_disabled_description">%1$s için giriş sunucusu şu anda %2$s tarafından geçersiz kılınıyor. Bir giriş sunucusu seçmek için lütfen önce \"%3$s\"\' seçeneğini etkinleştirin veya \"%4$s\" seçeneğini devre dışı bırakın.</string>
+ <string name="multihop_entry_disabled_description">%1$s için giriş sunucusu şu anda %2$s tarafından geçersiz kılınıyor. Bir giriş sunucusu seçmek için lütfen önce \"%3$s\"\' seçeneğini etkinleştirin veya \"%2$s\" seçeneğini devre dışı bırakın.</string>
<string name="name">Ad</string>
<string name="name_was_changed_to">Ad, %1$s olarak değiştirildi</string>
<string name="new_changelog_notification_message">Yenilikleri incelemek için buraya tıklayın.</string>
@@ -390,5 +390,5 @@
<string name="wireguard_port_title">WireGuard portu</string>
<string name="x_entry">%1$s (Giriş)</string>
<string name="x_exit">%1$s (Çıkış)</string>
- <string name="x_via_x">%1$s aracılığıyla %2$s</string>
+ <string name="x_via_x">%2$s aracılığıyla %1$s</string>
</resources>
diff --git a/android/lib/resource/src/main/res/values-zh-rCN/strings.xml b/android/lib/resource/src/main/res/values-zh-rCN/strings.xml
index 0341560730..8b73b2ae72 100644
--- a/android/lib/resource/src/main/res/values-zh-rCN/strings.xml
+++ b/android/lib/resource/src/main/res/values-zh-rCN/strings.xml
@@ -113,7 +113,7 @@
<string name="daita_description_slide_1_third_paragraph">通过使用复杂 AI,可以分析传入和传出您的设备的数据包流量(即使流量已加密)。</string>
<string name="daita_description_slide_2_first_paragraph">如果某个观察者监视这些数据包,%1$s 会大大提高他们识别您所访问的网站或您沟通对象的难度。</string>
<string name="daita_description_slide_2_second_paragraph">%1$s 的实现方法是精心添加网络噪声并将所有网络数据包处理为相同的大小。</string>
- <string name="daita_description_slide_2_third_paragraph">我们的部分服务器未启用 %1$s。因此,我们使用多跳自动为任何服务器启用 %2$s。</string>
+ <string name="daita_description_slide_2_third_paragraph">我们的部分服务器未启用 %1$s。因此,我们使用多跳自动为任何服务器启用 %1$s。</string>
<string name="daita_info">启用“%1$s”后,您需要手动选择启用了 %2$s 的服务器。这可能导致您在“选择位置”视图中选择兼容服务器之前处于阻止状态。</string>
<string name="delete">删除</string>
<string name="delete_custom_list_confirmation_description">删除“%1$s”?</string>
@@ -236,7 +236,7 @@
<string name="mullvad_owned_only">仅 Mullvad 自有</string>
<string name="multihop">多跳</string>
<string name="multihop_description">多跳技术会将您的流量传输到一个 WireGuard 服务器并从另一个服务器传出,从而提高追踪的难度。这会导致延迟增加,但会提高在线匿名性。</string>
- <string name="multihop_entry_disabled_description">%1$s的入口服务器目前被 %2$s 覆盖。要选择入口服务器,请先在设置中启用“%3$s”或禁用“%4$s”。</string>
+ <string name="multihop_entry_disabled_description">%1$s的入口服务器目前被 %2$s 覆盖。要选择入口服务器,请先在设置中启用“%3$s”或禁用“%2$s”。</string>
<string name="name">名称</string>
<string name="name_was_changed_to">名称已更改为“%1$s”</string>
<string name="new_changelog_notification_message">点击此处查看最新变化。</string>
diff --git a/android/lib/resource/src/main/res/values-zh-rTW/strings.xml b/android/lib/resource/src/main/res/values-zh-rTW/strings.xml
index 632e30eb20..d74a94df99 100644
--- a/android/lib/resource/src/main/res/values-zh-rTW/strings.xml
+++ b/android/lib/resource/src/main/res/values-zh-rTW/strings.xml
@@ -113,7 +113,7 @@
<string name="daita_description_slide_1_third_paragraph">可透過精密的 AI 分析進出裝置的資料封包流量 (即使流量已加密)。</string>
<string name="daita_description_slide_2_first_paragraph">如果有觀察者正在監控這些資料封包,%1$s 會大大增加他們的難度,讓他們很難辨識您正在瀏覽哪些網站或者在和誰通訊。</string>
<string name="daita_description_slide_2_second_paragraph">%1$s 會仔細加入網路噪音,讓所有網路資料封包大小皆相同,以達到此目的。</string>
- <string name="daita_description_slide_2_third_paragraph">我們有些伺服器並未啟用 %1$s。因此,我們使用多點跳躍自動來為任意伺服器啟用 %2$s 。</string>
+ <string name="daita_description_slide_2_third_paragraph">我們有些伺服器並未啟用 %1$s。因此,我們使用多點跳躍自動來為任意伺服器啟用 %1$s 。</string>
<string name="daita_info">啟用「%1$s」後,您必須手動選取已啟用 %2$s 的伺服器。這有可能導致您後來處於封鎖狀態,直到您在「選取位置」檢視圖中選到相容的伺服器為止。</string>
<string name="delete">刪除</string>
<string name="delete_custom_list_confirmation_description">要刪除「%1$s」嗎?</string>
@@ -236,7 +236,7 @@
<string name="mullvad_owned_only">僅 Mullvad 自有</string>
<string name="multihop">多點跳躍</string>
<string name="multihop_description">多點跳躍可將您的流量傳入一個 WireGuard 伺服器,再傳出至另一個伺服器,使其更難以追蹤。雖然這會導致延遲時間增加,卻能提高線上的匿名程度。</string>
- <string name="multihop_entry_disabled_description">%1$s 的入口伺服器目前已由 %2$s 覆寫。若要選擇入口伺服器,請先在設定中啟用「%3$s」或停用「%4$s」。</string>
+ <string name="multihop_entry_disabled_description">%1$s 的入口伺服器目前已由 %2$s 覆寫。若要選擇入口伺服器,請先在設定中啟用「%3$s」或停用「%2$s」。</string>
<string name="name">名稱</string>
<string name="name_was_changed_to">名稱已變更為「%1$s」</string>
<string name="new_changelog_notification_message">按一下此處查看最新動態。</string>
diff --git a/android/lib/resource/src/main/res/values/strings.xml b/android/lib/resource/src/main/res/values/strings.xml
index 9ab087da43..4fc739770c 100644
--- a/android/lib/resource/src/main/res/values/strings.xml
+++ b/android/lib/resource/src/main/res/values/strings.xml
@@ -390,11 +390,11 @@
<string name="daita_description_slide_1_third_paragraph">By using sophisticated AI it’s possible to analyze the traffic of data packets going in and out of your device (even if the traffic is encrypted).</string>
<string name="daita_description_slide_2_first_paragraph">If an observer monitors these data packets, %1$s makes it significantly harder for them to identify which websites you are visiting or with whom you are communicating.</string>
<string name="daita_description_slide_2_second_paragraph">%1$s does this by carefully adding network noise and making all network packets the same size.</string>
- <string name="daita_description_slide_2_third_paragraph">Not all our servers are %1$s-enabled. Therefore, we use multihop automatically to enable %2$s with any server.</string>
+ <string name="daita_description_slide_2_third_paragraph">Not all our servers are %1$s-enabled. Therefore, we use multihop automatically to enable %1$s with any server.</string>
<string name="direct_only">Direct only</string>
<string name="enable_direct_only">Enable %1$s</string>
<string name="direct_only_description">Not all our servers are %1$s-enabled. In order to use the internet, you might have to select a new location after enabling.</string>
- <string name="multihop_entry_disabled_description">The entry server for %1$s is currently overridden by %2$s. To select an entry server, please first enable “%3$s” or disable \"%4$s\" in the settings.</string>
+ <string name="multihop_entry_disabled_description">The entry server for %1$s is currently overridden by %2$s. To select an entry server, please first enable “%3$s” or disable \"%2$s\" in the settings.</string>
<string name="open_feature_settings">Open %1$s settings</string>
<string name="search">Search</string>
<string name="obfuscation_info_shadowsocks_batteryusage">Attention: Shadowsocks can increase battery consumption depending on data usage, such as streaming a video.</string>
diff --git a/android/translations-converter/src/android/plurals.rs b/android/translations-converter/src/android/plurals.rs
index 81d8177449..288fe9c566 100644
--- a/android/translations-converter/src/android/plurals.rs
+++ b/android/translations-converter/src/android/plurals.rs
@@ -92,7 +92,7 @@ impl PluralResource {
let items = values
.map(|(quantity, string)| PluralVariant {
quantity,
- string: StringValue::from_unescaped(&string),
+ string: StringValue::from_unescaped(&string, None),
})
.collect();
diff --git a/android/translations-converter/src/android/string_value.rs b/android/translations-converter/src/android/string_value.rs
index 9a01e9df86..d7f56de35c 100644
--- a/android/translations-converter/src/android/string_value.rs
+++ b/android/translations-converter/src/android/string_value.rs
@@ -17,14 +17,14 @@ impl StringValue {
/// they don't have any. Indices are assigned sequentially starting from the previously
/// specified index plus one, or starting from one if there aren't any previously specified
/// indices.
- pub fn from_unescaped(string: &str) -> Self {
+ pub fn from_unescaped(string: &str, arg_ordering: Option<&Vec<u8>>) -> Self {
let value_with_parameters = htmlize::escape_text(string)
.replace('\\', r"\\")
.replace('\"', "\\\"")
.replace('\'', r"\'");
let value_without_line_breaks = Self::collapse_line_breaks(value_with_parameters);
- let value = Self::ensure_parameters_are_indexed(value_without_line_breaks);
+ let value = Self::ensure_parameters_are_indexed(value_without_line_breaks, arg_ordering);
StringValue(value)
}
@@ -42,7 +42,7 @@ impl StringValue {
/// A typical input would be something like `Things are %d, %3$s and %s`, and this method
/// would update the string so that all parameters have indices: `Things are %1$d, %3$s and
/// %4$s`.
- fn ensure_parameters_are_indexed(original: String) -> String {
+ fn ensure_parameters_are_indexed(original: String, arg_ordering: Option<&Vec<u8>>) -> String {
static PARAMETER_INDEX: LazyLock<Regex> =
LazyLock::new(|| Regex::new(r"^(\d+)\$").unwrap());
@@ -50,6 +50,18 @@ impl StringValue {
let mut output = parts.next().unwrap().to_owned();
let mut offset = 1;
+ if let Some(ordering) = arg_ordering {
+ // Check for mismatch between number of args in original and arg_ordering
+ if ordering.len() != parts.clone().enumerate().count() {
+ panic!("Input string has different number of parameters to arg_ordering")
+ }
+ // Check if any parameter index in arg_ordering is higher than
+ // the total number of args
+ if ordering.iter().any(|i| *i > ordering.len() as u8) {
+ panic!("arg_ordering contains parameter that is too large")
+ }
+ }
+
for (index, part) in parts.enumerate() {
let index = index as isize;
@@ -70,7 +82,19 @@ impl StringValue {
output.push('%');
} else {
// String doesn't have a parameter index, so it is added
- write!(&mut output, "%{}$", index + offset).expect("formatting failed");
+ // If we have a specific arg_ordering, we will use this,
+ // if not we will fall back on index + offset
+ let parameter_index = match arg_ordering {
+ Some(ordering) => ordering[index as usize] as isize,
+ None => index + offset,
+ };
+
+ // Check for illegal parameter index
+ if parameter_index == 0 {
+ panic!("Parameter index is less than 1")
+ }
+
+ write!(&mut output, "%{}$", parameter_index).expect("formatting failed");
}
output.push_str(part);
@@ -109,11 +133,14 @@ mod tests {
#[test]
fn android_escaping() {
- let input = StringValue::from_unescaped(concat!(
- r"A backslash \",
- r#""Inside double quotes""#,
- "'Inside single quotes'",
- ));
+ let input = StringValue::from_unescaped(
+ concat!(
+ r"A backslash \",
+ r#""Inside double quotes""#,
+ "'Inside single quotes'",
+ ),
+ None,
+ );
let expected = concat!(
r"A backslash \\",
@@ -131,6 +158,7 @@ mod tests {
a multi-line string
that should be
collapsed into a single line",
+ None,
);
let expected = "This is a multi-line string that should be collapsed into a single line";
@@ -140,10 +168,10 @@ mod tests {
#[test]
fn xml_escaping() {
- let input = StringValue::from_unescaped(concat!(
- "An ampersand: &",
- "<tag>A dummy fake XML tag</tag>",
- ));
+ let input = StringValue::from_unescaped(
+ concat!("An ampersand: &", "<tag>A dummy fake XML tag</tag>",),
+ None,
+ );
let expected = concat!(
"An ampersand: &amp;",
@@ -157,14 +185,14 @@ mod tests {
fn doesnt_change_parameter_indices() {
let original = "%1$d %3$s %9$s %6$d %7$d";
- let input = StringValue::from_unescaped(original);
+ let input = StringValue::from_unescaped(original, None);
assert_eq!(input.to_string(), original);
}
#[test]
fn adds_parameter_indices() {
- let input = StringValue::from_unescaped("%d %s %s %d");
+ let input = StringValue::from_unescaped("%d %s %s %d", None);
let expected = "%1$d %2$s %3$s %4$d";
@@ -173,7 +201,7 @@ mod tests {
#[test]
fn correctly_updates_generated_index_offset_based_on_existing_indices() {
- let input = StringValue::from_unescaped("%d %4$s %d %2$s %d");
+ let input = StringValue::from_unescaped("%d %4$s %d %2$s %d", None);
let expected = "%1$d %4$s %5$d %2$s %3$d";
@@ -201,4 +229,76 @@ mod tests {
assert_eq!(deserialized.value, expected);
}
+
+ #[test]
+ fn if_argument_ordering_is_none_should_use_sequential_order_of_arguments() {
+ let input = StringValue::from_unescaped("%s again %s", None);
+
+ let expected = "%1$s again %2$s";
+
+ assert_eq!(input.to_string(), expected);
+ }
+
+ #[test]
+ fn if_argument_ordering_is_reversed_should_use_argument_ordering() {
+ let input = StringValue::from_unescaped("%s almost %s", Some([2, 1].to_vec().as_ref()));
+
+ let expected = "%2$s almost %1$s";
+
+ assert_eq!(input.to_string(), expected);
+ }
+
+ #[test]
+ fn if_argument_is_repeated_should_use_argument_ordering() {
+ let input = StringValue::from_unescaped(
+ "%s was a %s and a %s and almost a %s",
+ Some([1, 2, 3, 1].to_vec().as_ref()),
+ );
+
+ let expected = "%1$s was a %2$s and a %3$s and almost a %1$s";
+
+ assert_eq!(input.to_string(), expected);
+ }
+
+ #[test]
+ #[should_panic]
+ fn if_arg_ordering_has_one_args_and_string_has_zero_arg_should_panic() {
+ StringValue::from_unescaped("", Some([1].to_vec().as_ref()));
+ }
+
+ #[test]
+ #[should_panic]
+ fn if_arg_ordering_has_zero_args_and_string_has_one_argument_should_panic() {
+ StringValue::from_unescaped("%s", Some([].to_vec().as_ref()));
+ }
+
+ #[test]
+ #[should_panic]
+ fn if_arg_ordering_has_zero_args_and_text_has_args_should_panic() {
+ StringValue::from_unescaped("%s", Some([].to_vec().as_ref()));
+ }
+
+ #[test]
+ #[should_panic]
+ fn if_arg_ordering_has_more_args_should_throw_should_panic() {
+ StringValue::from_unescaped("%s", Some([1, 2].to_vec().as_ref()));
+ }
+
+ #[test]
+ #[should_panic]
+ fn if_arg_ordering_has_less_args_should_panic() {
+ StringValue::from_unescaped("%s %s", Some([1].to_vec().as_ref()));
+ }
+
+ #[test]
+ #[should_panic]
+ fn if_arg_ordering_has_zero_as_arg_should_panic() {
+ StringValue::from_unescaped("%s", Some([0].to_vec().as_ref()));
+ }
+
+ #[test]
+ #[should_panic]
+ fn if_arg_ordering_has_no_1_as_arg_should_should_panic() {
+ StringValue::from_unescaped("%s", Some([2].to_vec().as_ref()));
+ }
}
diff --git a/android/translations-converter/src/android/strings.rs b/android/translations-converter/src/android/strings.rs
index 6a9156f341..a3bb25708a 100644
--- a/android/translations-converter/src/android/strings.rs
+++ b/android/translations-converter/src/android/strings.rs
@@ -73,11 +73,11 @@ impl StringResource {
/// Create a new Android string resource entry.
///
/// The name is the resource ID, and the value will be properly escaped.
- pub fn new(name: String, value: &str) -> Self {
+ pub fn new(name: String, value: &str, arg_ordering: Option<&Vec<u8>>) -> Self {
StringResource {
name,
translatable: true,
- value: StringValue::from_unescaped(value),
+ value: StringValue::from_unescaped(value, arg_ordering),
}
}
}
@@ -135,12 +135,12 @@ mod tests {
StringResource {
name: "first".to_owned(),
translatable: true,
- value: StringValue::from_unescaped("First string"),
+ value: StringValue::from_unescaped("First string", None),
},
StringResource {
name: "second".to_owned(),
translatable: false,
- value: StringValue::from_unescaped("Second string"),
+ value: StringValue::from_unescaped("Second string", None),
},
]);
@@ -171,15 +171,18 @@ mod tests {
StringResource {
name: "first".to_owned(),
translatable: true,
- value: StringValue::from_unescaped("First string is split in two lines"),
+ value: StringValue::from_unescaped("First string is split in two lines", None),
},
StringResource {
name: "second".to_owned(),
translatable: false,
- value: StringValue::from_unescaped(concat!(
+ value: StringValue::from_unescaped(
+ concat!(
"Second string is also split but it also has some weird whitespace inside the ",
"tags and some indentation",
- )),
+ ),
+ None,
+ ),
},
]);
diff --git a/android/translations-converter/src/gettext/messages.rs b/android/translations-converter/src/gettext/messages.rs
index 25316afae4..2f5d8c73c9 100644
--- a/android/translations-converter/src/gettext/messages.rs
+++ b/android/translations-converter/src/gettext/messages.rs
@@ -1,8 +1,10 @@
use super::{msg_string::MsgString, parser::Parser, plural_form::PluralForm};
+use regex::Regex;
use std::{
fs::File,
io::{BufRead, BufReader},
path::Path,
+ sync::LazyLock,
};
/// A parsed gettext messages file.
@@ -22,7 +24,7 @@ pub struct MsgEntry {
/// A message string or plural set in a gettext translation file.
#[derive(Clone, Debug)]
pub enum MsgValue {
- Invariant(MsgString),
+ Invariant(MsgString, Option<Vec<u8>>),
Plural {
plural_id: MsgString,
values: Vec<MsgString>,
@@ -57,8 +59,8 @@ impl Messages {
/// The plural form for the messages is left unconfigured.
pub fn starting_with(id: MsgString, msg_str: MsgString) -> Self {
let first_entry = MsgEntry {
- id,
- value: MsgValue::Invariant(msg_str),
+ id: id.clone(),
+ value: MsgValue::Invariant(msg_str.clone(), argument_ordering(id, msg_str)),
};
Messages {
@@ -70,8 +72,8 @@ impl Messages {
/// Add a non-plural entry.
pub fn add(&mut self, id: MsgString, msg_str: MsgString) {
let entry = MsgEntry {
- id,
- value: MsgValue::Invariant(msg_str),
+ id: id.clone(),
+ value: MsgValue::Invariant(msg_str.clone(), argument_ordering(id, msg_str)),
};
self.entries.push(entry);
@@ -99,10 +101,38 @@ impl IntoIterator for Messages {
impl From<MsgString> for MsgValue {
fn from(string: MsgString) -> Self {
- MsgValue::Invariant(string)
+ MsgValue::Invariant(string, None)
+ }
+}
+
+static NAMED_ARGUMENT: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"%\([a-zA-Z]+\)").unwrap());
+
+fn argument_ordering(id: MsgString, msg_str: MsgString) -> Option<Vec<u8>> {
+ if NAMED_ARGUMENT.is_match(&id) && NAMED_ARGUMENT.is_match(&msg_str) {
+ // Extract arguments in id
+ let id_args = extract_arguments(id);
+ // Extract arguments in translation
+ let value_args = extract_arguments(msg_str);
+ // Set index as id order and value as translation order
+ Some(
+ id_args
+ .iter()
+ .map(|id_arg| value_args.iter().position(|value_arg| value_arg == id_arg))
+ .map(|f| f.unwrap() as u8 + 1)
+ .collect(),
+ )
+ } else {
+ None
}
}
+fn extract_arguments(msg: MsgString) -> Vec<String> {
+ NAMED_ARGUMENT
+ .find_iter(&msg)
+ .map(|s| String::from(s.as_str()))
+ .collect()
+}
+
#[derive(Debug, thiserror::Error)]
pub enum Error {
/// Parser error while parsing file
@@ -113,3 +143,64 @@ pub enum Error {
#[error("Failed to read from the input file")]
Io(#[from] std::io::Error),
}
+
+#[cfg(test)]
+mod tests {
+ use crate::gettext::messages::argument_ordering;
+ use crate::gettext::MsgString;
+
+ #[test]
+ fn if_message_has_no_argument_should_have_no_argument_ordering() {
+ let msg_id = MsgString::from_escaped("This is a text");
+ let msg_str = MsgString::from_escaped("Det här är en text");
+ let argument_ordering = argument_ordering(msg_id, msg_str);
+
+ let expected = None;
+
+ assert_eq!(argument_ordering, expected);
+ }
+
+ #[test]
+ fn if_message_has_no_translation_should_have_no_argument_ordering() {
+ let msg_id = MsgString::from_escaped("This is a %(text)");
+ let msg_str = MsgString::from_escaped("");
+ let argument_ordering = argument_ordering(msg_id, msg_str);
+
+ let expected = None;
+
+ assert_eq!(argument_ordering, expected);
+ }
+
+ #[test]
+ fn if_argument_ordering_is_same_should_have_sequential_ordering() {
+ let msg_id = MsgString::from_escaped("This is a %(text) and %(star)");
+ let msg_str = MsgString::from_escaped("Det här är en %(text) och %(star)");
+ let argument_ordering = argument_ordering(msg_id, msg_str);
+
+ let expected = Some([1, 2].to_vec());
+
+ assert_eq!(argument_ordering, expected);
+ }
+
+ #[test]
+ fn if_argument_ordering_is_reversed_should_have_reversed_ordering() {
+ let msg_id = MsgString::from_escaped("This is a %(text) and %(star)");
+ let msg_str = MsgString::from_escaped("Det här är en %(star) och %(text)");
+ let argument_ordering = argument_ordering(msg_id, msg_str);
+
+ let expected = Some([2, 1].to_vec());
+
+ assert_eq!(argument_ordering, expected);
+ }
+
+ #[test]
+ fn if_argument_is_repeated_should_have_repeated_ordering() {
+ let msg_id = MsgString::from_escaped("This is a %(text) and %(text)");
+ let msg_str = MsgString::from_escaped("Det här är en %(text) och %(text)");
+ let argument_ordering = argument_ordering(msg_id, msg_str);
+
+ let expected = Some([1, 1].to_vec());
+
+ assert_eq!(argument_ordering, expected);
+ }
+}
diff --git a/android/translations-converter/src/gettext/mod.rs b/android/translations-converter/src/gettext/mod.rs
index ff92f9e6d4..5d4bad92a3 100644
--- a/android/translations-converter/src/gettext/mod.rs
+++ b/android/translations-converter/src/gettext/mod.rs
@@ -35,7 +35,7 @@ pub fn append_to_template(
writeln!(writer, r#"msgid "{}""#, entry.id)?;
match entry.value {
- MsgValue::Invariant(value) => writeln!(writer, r#"msgstr "{value}""#)?,
+ MsgValue::Invariant(value, _) => writeln!(writer, r#"msgstr "{value}""#)?,
MsgValue::Plural { plural_id, values } => {
writeln!(writer, r#"msgid_plural "{plural_id}""#)?;
diff --git a/android/translations-converter/src/main.rs b/android/translations-converter/src/main.rs
index 314bbf3e44..1d78fedf81 100644
--- a/android/translations-converter/src/main.rs
+++ b/android/translations-converter/src/main.rs
@@ -11,11 +11,6 @@
//! the message parameters are changed so that they are in a common format, and there is also a
//! small workaround for having different apostrophe characters in the GUI in some messages.
//!
-//! One dangerous assumption for the normalization is that the named parameters for the GUI are
-//! supplied in the declared order on Android. This is because it's not possible to figure out the
-//! order when only named parameters are used, and Android strings only supported numbered
-//! parameters.
-//!
//! Android's plural resources are also translated using the same principle. It's important to note
//! that the singular quantity item (i.e., the item where `quantity="one"`) for each Android plural
//! resource will be used as the `msgid` to be search for in the gettext translations file.
@@ -150,7 +145,7 @@ fn main() {
for message in template {
match message.value {
- MsgValue::Invariant(_) => missing_translations.remove(&message.id.normalize()),
+ MsgValue::Invariant(_, _) => missing_translations.remove(&message.id.normalize()),
MsgValue::Plural { .. } => missing_plurals.remove(&message.id.normalize()),
};
}
@@ -235,11 +230,12 @@ fn main() {
let mut localized_strings = android::StringResources::new();
for translation in default_translations {
match translation.value {
- MsgValue::Invariant(_) => {
+ MsgValue::Invariant(_, arg_ordering) => {
if !translation.id.is_empty() {
localized_strings.push(android::StringResource::new(
translation.id.normalize(),
&translation.id.normalize(),
+ arg_ordering.as_ref(),
));
}
}
@@ -326,10 +322,11 @@ fn generate_relay_translations(
for translation in translations {
match translation.value {
- MsgValue::Invariant(translation_value) => {
+ MsgValue::Invariant(translation_value, arg_ordering) => {
localized_strings.push(android::StringResource::new(
translation.id.normalize(),
&translation_value.normalize(),
+ arg_ordering.as_ref(),
));
}
MsgValue::Plural { .. } => {}
@@ -369,11 +366,12 @@ fn generate_translations(
for translation in translations {
match translation.value {
- MsgValue::Invariant(translation_value) => {
+ MsgValue::Invariant(translation_value, arg_ordering) => {
if let Some(android_key) = known_strings.remove(&translation.id.normalize()) {
localized_strings.push(android::StringResource::new(
android_key,
&translation_value.normalize(),
+ arg_ordering.as_ref(),
));
}
}
diff --git a/android/translations-converter/src/normalize.rs b/android/translations-converter/src/normalize.rs
index ace645570e..5428a15481 100644
--- a/android/translations-converter/src/normalize.rs
+++ b/android/translations-converter/src/normalize.rs
@@ -61,11 +61,14 @@ mod tests {
fn normalize_android_string_value() {
use crate::android::StringValue;
- let input = StringValue::from_unescaped(concat!(
- "'Inside single quotes'",
- r#""Inside double quotes""#,
- "With parameters: %1$d, %2$s",
- ));
+ let input = StringValue::from_unescaped(
+ concat!(
+ "'Inside single quotes'",
+ r#""Inside double quotes""#,
+ "With parameters: %1$d, %2$s",
+ ),
+ None,
+ );
let expected = concat!(
"'Inside single quotes'",